Relocate Source to proper directory.

This commit is contained in:
AlgorithmX2
2014-09-23 19:26:27 -05:00
parent fe927ce65d
commit 386d18a059
785 changed files with 35585 additions and 35580 deletions
@@ -0,0 +1,154 @@
package appeng.tile;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.block.AEBaseBlock;
import appeng.tile.events.TileEventType;
import appeng.tile.inventory.IAEAppEngInventory;
import appeng.tile.inventory.InvOperation;
public abstract class AEBaseInvTile extends AEBaseTile implements ISidedInventory, IAEAppEngInventory
{
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_AEBaseInvTile(net.minecraft.nbt.NBTTagCompound data)
{
IInventory inv = getInternalInventory();
NBTTagCompound opt = data.getCompoundTag( "inv" );
for (int x = 0; x < inv.getSizeInventory(); x++)
{
NBTTagCompound item = opt.getCompoundTag( "item" + x );
inv.setInventorySlotContents( x, ItemStack.loadItemStackFromNBT( item ) );
}
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_AEBaseInvTile(net.minecraft.nbt.NBTTagCompound data)
{
IInventory inv = getInternalInventory();
NBTTagCompound opt = new NBTTagCompound();
for (int x = 0; x < inv.getSizeInventory(); x++)
{
NBTTagCompound item = new NBTTagCompound();
ItemStack is = getStackInSlot( x );
if ( is != null )
is.writeToNBT( item );
opt.setTag( "item" + x, item );
}
data.setTag( "inv", opt );
}
@Override
public int getSizeInventory()
{
return getInternalInventory().getSizeInventory();
}
@Override
public ItemStack getStackInSlot(int i)
{
return getInternalInventory().getStackInSlot( i );
}
@Override
public ItemStack decrStackSize(int i, int j)
{
return getInternalInventory().decrStackSize( i, j );
}
@Override
public ItemStack getStackInSlotOnClosing(int i)
{
return null;
}
@Override
public void setInventorySlotContents(int i, ItemStack itemstack)
{
getInternalInventory().setInventorySlotContents( i, itemstack );
}
@Override
public void openInventory()
{
}
@Override
public void closeInventory()
{
}
@Override
public int getInventoryStackLimit()
{
return 64;
}
@Override
public boolean isUseableByPlayer(EntityPlayer p)
{
return this.worldObj.getTileEntity( this.xCoord, this.yCoord, this.zCoord ) != this ? false : p.getDistanceSq( (double) this.xCoord + 0.5D,
(double) this.yCoord + 0.5D, (double) this.zCoord + 0.5D ) <= 32.0D;
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack)
{
return true;
}
@Override
public boolean canInsertItem(int i, ItemStack itemstack, int j)
{
return isItemValidForSlot( i, itemstack );
}
@Override
public boolean canExtractItem(int i, ItemStack itemstack, int j)
{
return true;
}
public abstract IInventory getInternalInventory();
@Override
public abstract void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removed, ItemStack added);
public abstract int[] getAccessibleSlotsBySide(ForgeDirection whichSide);
@Override
final public int[] getAccessibleSlotsFromSide(int side)
{
Block blk = worldObj.getBlock( xCoord, yCoord, zCoord );
if ( blk instanceof AEBaseBlock )
{
ForgeDirection mySide = ForgeDirection.getOrientation( side );
return getAccessibleSlotsBySide( ((AEBaseBlock) blk).mapRotation( this, mySide ) );
}
return getAccessibleSlotsBySide( ForgeDirection.getOrientation( side ) );
}
/**
* Returns the name of the inventory
*/
@Override
public String getInventoryName()
{
return getCustomName();
}
/**
* Returns if the inventory is named
*/
@Override
public boolean hasCustomInventoryName()
{
return hasCustomName();
}
}
+503
View File
@@ -0,0 +1,503 @@
package appeng.tile;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.implementations.tiles.ISegmentedInventory;
import appeng.api.util.ICommonTile;
import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject;
import appeng.api.util.IOrientable;
import appeng.core.AELog;
import appeng.core.features.ItemStackSrc;
import appeng.helpers.ICustomNameObject;
import appeng.helpers.IPriorityHost;
import appeng.tile.events.AETileEventHandler;
import appeng.tile.events.TileEventType;
import appeng.tile.inventory.AppEngInternalAEInventory;
import appeng.util.Platform;
import appeng.util.SettingsFrom;
public class AEBaseTile extends TileEntity implements IOrientable, ICommonTile, ICustomNameObject
{
static private final HashMap<Class, EnumMap<TileEventType, List<AETileEventHandler>>> handlers = new HashMap<Class, EnumMap<TileEventType, List<AETileEventHandler>>>();
static private final HashMap<Class, ItemStackSrc> myItem = new HashMap();
private ForgeDirection forward = ForgeDirection.UNKNOWN;
private ForgeDirection up = ForgeDirection.UNKNOWN;
public static ThreadLocal<WeakReference<AEBaseTile>> dropNoItems = new ThreadLocal();
public void disableDrops()
{
dropNoItems.set( new WeakReference<AEBaseTile>( this ) );
}
public boolean dropItems()
{
WeakReference<AEBaseTile> what = dropNoItems.get();
return what == null || what.get() != this;
}
public int renderFragment = 0;
public String customName;
public boolean notLoaded()
{
return !worldObj.blockExists( xCoord, yCoord, zCoord );
}
public TileEntity getTile()
{
return this;
}
static public void registerTileItem(Class c, ItemStackSrc wat)
{
myItem.put( c, wat );
}
protected ItemStack getItemFromTile(Object obj)
{
ItemStackSrc src = myItem.get( obj.getClass() );
if ( src == null )
return null;
return src.stack( 1 );
}
protected boolean hasHandlerFor(TileEventType type)
{
List<AETileEventHandler> list = getHandlerListFor( type );
return list != null && !list.isEmpty();
}
protected List<AETileEventHandler> getHandlerListFor(TileEventType type)
{
Class clz = getClass();
EnumMap<TileEventType, List<AETileEventHandler>> handlerSet = handlers.get( clz );
if ( handlerSet == null )
{
handlers.put( clz, handlerSet = new EnumMap<TileEventType, List<AETileEventHandler>>( TileEventType.class ) );
for (Method m : clz.getMethods())
{
TileEvent te = m.getAnnotation( TileEvent.class );
if ( te != null )
{
addHandler( handlerSet, te.value(), m );
}
}
}
List<AETileEventHandler> list = handlerSet.get( type );
if ( list == null )
handlerSet.put( type, list = new LinkedList<AETileEventHandler>() );
return list;
}
private void addHandler(EnumMap<TileEventType, List<AETileEventHandler>> handlerSet, TileEventType value, Method m)
{
List<AETileEventHandler> list = handlerSet.get( value );
if ( list == null )
handlerSet.put( value, list = new ArrayList() );
list.add( new AETileEventHandler( m, value ) );
}
@Override
final public boolean canUpdate()
{
return hasHandlerFor( TileEventType.TICK );
}
final public void Tick()
{
}
@Override
final public void updateEntity()
{
for (AETileEventHandler h : getHandlerListFor( TileEventType.TICK ))
h.Tick( this );
}
@Override
public void onChunkUnload()
{
if ( !isInvalid() )
invalidate();
}
/**
* for dormant chunk cache.
*/
public void onChunkLoad()
{
if ( isInvalid() )
validate();
}
@Override
// NOTE: WAS FINAL, changed for Immibis
final public void writeToNBT(NBTTagCompound data)
{
super.writeToNBT( data );
if ( canBeRotated() )
{
data.setString( "orientation_forward", forward.name() );
data.setString( "orientation_up", up.name() );
}
if ( customName != null )
data.setString( "customName", customName );
for (AETileEventHandler h : getHandlerListFor( TileEventType.WORLD_NBT_WRITE ))
h.writeToNBT( this, data );
}
@Override
// NOTE: WAS FINAL, changed for Immibis
final public void readFromNBT(NBTTagCompound data)
{
super.readFromNBT( data );
if ( data.hasKey( "customName" ) )
customName = data.getString( "customName" );
else
customName = null;
try
{
if ( canBeRotated() )
{
forward = ForgeDirection.valueOf( data.getString( "orientation_forward" ) );
up = ForgeDirection.valueOf( data.getString( "orientation_up" ) );
}
}
catch (IllegalArgumentException iae)
{
}
for (AETileEventHandler h : getHandlerListFor( TileEventType.WORLD_NBT_READ ))
{
h.readFromNBT( this, data );
}
}
final public void writeToStream(ByteBuf data)
{
try
{
if ( canBeRotated() )
{
byte orientation = (byte) ((up.ordinal() << 3) | forward.ordinal());
data.writeByte( orientation );
}
for (AETileEventHandler h : getHandlerListFor( TileEventType.NETWORK_WRITE ))
h.writeToStream( this, data );
}
catch (Throwable t)
{
AELog.error( t );
}
}
final public boolean readFromStream(ByteBuf data)
{
boolean output = false;
try
{
if ( canBeRotated() )
{
ForgeDirection old_Forward = forward;
ForgeDirection old_Up = up;
byte orientation = data.readByte();
forward = ForgeDirection.getOrientation( orientation & 0x7 );
up = ForgeDirection.getOrientation( orientation >> 3 );
output = !forward.equals( old_Forward ) || !up.equals( old_Up );
}
renderFragment = 100;
for (AETileEventHandler h : getHandlerListFor( TileEventType.NETWORK_READ ))
if ( h.readFromStream( this, data ) )
output = true;
if ( (renderFragment & 1) == 1 )
output = true;
renderFragment = 0;
}
catch (Throwable t)
{
AELog.error( t );
}
return output;
}
/**
* By default all blocks can have orientation, this handles saving, and loading, as well as synchronization.
*
* @return
*/
@Override
public boolean canBeRotated()
{
return true;
}
@Override
public ForgeDirection getForward()
{
return forward;
}
@Override
public ForgeDirection getUp()
{
return up;
}
@Override
public void setOrientation(ForgeDirection inForward, ForgeDirection inUp)
{
forward = inForward;
up = inUp;
markForUpdate();
Platform.notifyBlocksOfNeighbors( worldObj, xCoord, yCoord, zCoord );
}
public void onPlacement(ItemStack stack, EntityPlayer player, int side)
{
if ( stack.hasTagCompound() )
{
uploadSettings( SettingsFrom.DISMANTLE_ITEM, stack.getTagCompound() );
}
}
@Override
public Packet getDescriptionPacket()
{
NBTTagCompound data = new NBTTagCompound();
ByteBuf stream = Unpooled.buffer();
try
{
writeToStream( stream );
if ( stream.readableBytes() == 0 )
return null;
}
catch (Throwable t)
{
AELog.error( t );
}
stream.capacity( stream.readableBytes() );
data.setByteArray( "X", stream.array() );
return new S35PacketUpdateTileEntity( xCoord, yCoord, zCoord, 64, data );
}
@Override
public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt)
{
// / pkt.actionType
if ( pkt.func_148853_f() == 64 )
{
ByteBuf stream = Unpooled.copiedBuffer( pkt.func_148857_g().getByteArray( "X" ) );
if ( readFromStream( stream ) )
markForUpdate();
}
}
public void markForUpdate()
{
if ( renderFragment > 0 )
renderFragment = renderFragment | 1;
else
{
// TODO: Optimize Network Load
if ( worldObj != null )
{
AELog.blockUpdate( xCoord, yCoord, zCoord, this );
worldObj.markBlockForUpdate( xCoord, yCoord, zCoord );
}
}
}
/**
* returns the contents of the tile entity, into the world, defaults to dropping everything in the inventory.
*
* @param w
* @param x
* @param y
* @param z
* @param drops
*/
@Override
public void getDrops(World w, int x, int y, int z, ArrayList<ItemStack> drops)
{
if ( this instanceof IInventory )
{
IInventory inv = (IInventory) this;
for (int l = 0; l < inv.getSizeInventory(); l++)
{
ItemStack is = inv.getStackInSlot( l );
if ( is != null )
drops.add( is );
}
}
}
public void getNoDrops(World w, int x, int y, int z, ArrayList<ItemStack> drops)
{
}
public void onReady()
{
}
/**
* depending on the from, different settings will be accepted, don't call this with null
*
* @param from
* @param compound
*/
public void uploadSettings(SettingsFrom from, NBTTagCompound compound)
{
if ( compound != null && this instanceof IConfigurableObject )
{
IConfigManager cm = ((IConfigurableObject) this).getConfigManager();
if ( cm != null )
cm.readFromNBT( compound );
}
if ( this instanceof IPriorityHost )
{
IPriorityHost pHost = (IPriorityHost) this;
pHost.setPriority( compound.getInteger( "priority" ) );
}
if ( this instanceof ISegmentedInventory )
{
IInventory inv = ((ISegmentedInventory) this).getInventoryByName( "config" );
if ( inv != null && inv instanceof AppEngInternalAEInventory )
{
AppEngInternalAEInventory target = (AppEngInternalAEInventory) inv;
AppEngInternalAEInventory tmp = new AppEngInternalAEInventory( null, target.getSizeInventory() );
tmp.readFromNBT( compound, "config" );
for (int x = 0; x < tmp.getSizeInventory(); x++)
target.setInventorySlotContents( x, tmp.getStackInSlot( x ) );
}
}
}
/**
* null means nothing to store...
*
* @param from
* @return
*/
public NBTTagCompound downloadSettings(SettingsFrom from)
{
NBTTagCompound output = new NBTTagCompound();
if ( hasCustomName() )
{
NBTTagCompound dsp = new NBTTagCompound();
dsp.setString( "Name", getCustomName() );
output.setTag( "display", dsp );
}
if ( this instanceof IConfigurableObject )
{
IConfigManager cm = ((IConfigurableObject) this).getConfigManager();
if ( cm != null )
cm.writeToNBT( output );
}
if ( this instanceof IPriorityHost )
{
IPriorityHost pHost = (IPriorityHost) this;
output.setInteger( "priority", pHost.getPriority() );
}
if ( this instanceof ISegmentedInventory )
{
IInventory inv = ((ISegmentedInventory) this).getInventoryByName( "config" );
if ( inv != null && inv instanceof AppEngInternalAEInventory )
{
((AppEngInternalAEInventory) inv).writeToNBT( output, "config" );
}
}
return output.hasNoTags() ? null : output;
}
public void securityBreak()
{
worldObj.func_147480_a( xCoord, yCoord, zCoord, true );
disableDrops();
}
public void saveChanges()
{
super.markDirty();
}
public boolean requiresTESR()
{
return false;
}
public void setName(String name)
{
this.customName = name;
}
@Override
public String getCustomName()
{
return hasCustomName() ? customName : getClass().getSimpleName();
}
@Override
public boolean hasCustomName()
{
return customName != null && customName.length() > 0;
}
}
+13
View File
@@ -0,0 +1,13 @@
package appeng.tile;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import appeng.tile.events.TileEventType;
@Retention(RetentionPolicy.RUNTIME)
public @interface TileEvent {
TileEventType value();
}
@@ -0,0 +1,129 @@
package appeng.tile.crafting;
import io.netty.buffer.ByteBuf;
import java.io.IOException;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.implementations.tiles.IColorableTile;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.AEColor;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.util.item.AEItemStack;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class TileCraftingMonitorTile extends TileCraftingTile implements IColorableTile
{
@SideOnly(Side.CLIENT)
public Integer dspList;
@SideOnly(Side.CLIENT)
public boolean updateList;
IAEItemStack dspPlay;
AEColor paintedColor = AEColor.Transparent;
@TileEvent(TileEventType.NETWORK_READ)
public boolean readFromStream_TileCraftingMonitorTile(ByteBuf data) throws IOException
{
AEColor oldPaintedColor = paintedColor;
paintedColor = AEColor.values()[data.readByte()];
boolean hasItem = data.readBoolean();
if ( hasItem )
dspPlay = AEItemStack.loadItemStackFromPacket( data );
else
dspPlay = null;
updateList = true;
return oldPaintedColor != paintedColor; // tesr!
}
@TileEvent(TileEventType.NETWORK_WRITE)
public void writeToStream_TileCraftingMonitorTile(ByteBuf data) throws IOException
{
data.writeByte( paintedColor.ordinal() );
if ( dspPlay == null )
data.writeBoolean( false );
else
{
data.writeBoolean( true );
dspPlay.writeToPacket( data );
}
}
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_TileCraftingMonitorTile(NBTTagCompound data)
{
if ( data.hasKey( "paintedColor" ) )
paintedColor = AEColor.values()[data.getByte( "paintedColor" )];
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_TileCraftingMonitorTile(NBTTagCompound data)
{
data.setByte( "paintedColor", (byte) paintedColor.ordinal() );
}
public boolean isAccelerator()
{
return false;
}
public boolean isStatus()
{
return true;
}
public void setJob(IAEItemStack is)
{
if ( (is == null) != (dspPlay == null) )
{
dspPlay = is == null ? null : is.copy();
markForUpdate();
}
else if ( is != null && dspPlay != null )
{
if ( is.getStackSize() != dspPlay.getStackSize() )
{
dspPlay = is == null ? null : is.copy();
markForUpdate();
}
}
}
public IAEItemStack getJobProgress()
{
return dspPlay;// AEItemStack.create( new ItemStack( Items.diamond, 64 ) );
}
@Override
public boolean requiresTESR()
{
return getJobProgress() != null;
}
public AEColor getColor()
{
return paintedColor;
}
@Override
public boolean recolourBlock(ForgeDirection side, AEColor newPaintedColor, EntityPlayer who)
{
if ( paintedColor == newPaintedColor )
return false;
paintedColor = newPaintedColor;
markDirty();
markForUpdate();
return true;
}
}
@@ -0,0 +1,56 @@
package appeng.tile.crafting;
import net.minecraft.item.ItemStack;
import appeng.api.AEApi;
public class TileCraftingStorageTile extends TileCraftingTile
{
static final ItemStack stackStorage4k = AEApi.instance().blocks().blockCraftingStorage4k.stack( 1 );
static final ItemStack stackStorage16k = AEApi.instance().blocks().blockCraftingStorage16k.stack( 1 );
static final ItemStack stackStorage64k = AEApi.instance().blocks().blockCraftingStorage64k.stack( 1 );
@Override
protected ItemStack getItemFromTile(Object obj)
{
int storage = ((TileCraftingTile) obj).getStorageBytes() / 1024;
if ( storage == 4 )
return stackStorage4k;
if ( storage == 16 )
return stackStorage16k;
if ( storage == 64 )
return stackStorage64k;
return super.getItemFromTile( obj );
}
public boolean isAccelerator()
{
return false;
}
public boolean isStorage()
{
return true;
}
public int getStorageBytes()
{
if ( worldObj == null || notLoaded() )
return 0;
switch (worldObj.getBlockMetadata( xCoord, yCoord, zCoord ) & 3)
{
default:
case 0:
return 1 * 1024;
case 1:
return 4 * 1024;
case 2:
return 16 * 1024;
case 3:
return 64 * 1024;
}
}
}
@@ -0,0 +1,287 @@
package appeng.tile.crafting;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.LinkedList;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.implementations.IPowerChannelState;
import appeng.api.networking.GridFlags;
import appeng.api.networking.IGridHost;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.parts.ISimplifiedBundle;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.WorldCoord;
import appeng.me.cluster.IAECluster;
import appeng.me.cluster.IAEMultiBlock;
import appeng.me.cluster.implementations.CraftingCPUCalculator;
import appeng.me.cluster.implementations.CraftingCPUCluster;
import appeng.me.helpers.AENetworkProxy;
import appeng.me.helpers.AENetworkProxyMultiblock;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkTile;
import appeng.util.Platform;
public class TileCraftingTile extends AENetworkTile implements IAEMultiBlock, IPowerChannelState
{
CraftingCPUCluster clust;
final CraftingCPUCalculator calc = new CraftingCPUCalculator( this );
public ISimplifiedBundle lightCache;
public NBTTagCompound previousState = null;
public boolean isCoreBlock = false;
static final ItemStack coProcessorStack = AEApi.instance().blocks().blockCraftingAccelerator.stack( 1 );
@Override
protected AENetworkProxy createProxy()
{
return new AENetworkProxyMultiblock( this, "proxy", getItemFromTile( this ), true );
}
@Override
protected ItemStack getItemFromTile(Object obj)
{
if ( ((TileCraftingTile) obj).isAccelerator() )
return coProcessorStack;
return super.getItemFromTile( obj );
}
public void updateStatus(CraftingCPUCluster c)
{
if ( clust != null && clust != c )
clust.breakCluster();
clust = c;
updateMeta( true );
}
public void updateMultiBlock()
{
calc.calculateMultiblock( worldObj, getLocation() );
}
public void setName(String name)
{
super.setName( name );
if ( clust != null )
clust.updateName();
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_TileCraftingTile(NBTTagCompound data)
{
data.setBoolean( "core", isCoreBlock );
if ( isCoreBlock && clust != null )
clust.writeToNBT( data );
}
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_TileCraftingTile(NBTTagCompound data)
{
isCoreBlock = data.getBoolean( "core" );
if ( isCoreBlock )
{
if ( clust != null )
clust.readFromNBT( data );
else
previousState = (NBTTagCompound) data.copy();
}
}
public TileCraftingTile() {
gridProxy.setFlags( GridFlags.MULTIBLOCK, GridFlags.REQUIRE_CHANNEL );
gridProxy.setValidSides( EnumSet.noneOf( ForgeDirection.class ) );
}
@Override
public void onReady()
{
super.onReady();
gridProxy.setVisualRepresentation( getItemFromTile( this ) );
updateMultiBlock();
}
@Override
public boolean canBeRotated()
{
return true;// return BlockCraftingUnit.checkType( worldObj.getBlockMetadata( xCoord, yCoord, zCoord ),
// BlockCraftingUnit.BASE_MONITOR );
}
@Override
public void disconnect(boolean update)
{
if ( clust != null )
{
clust.destroy();
if ( update )
updateMeta( true );
}
}
@MENetworkEventSubscribe
public void onPowerStateChange(MENetworkChannelsChanged ev)
{
updateMeta( false );
}
@MENetworkEventSubscribe
public void onPowerStateChange(MENetworkPowerStatusChange ev)
{
updateMeta( false );
}
public void updateMeta(boolean updateFormed)
{
if ( worldObj == null || notLoaded() )
return;
boolean formed = isFormed();
boolean power = false;
if ( gridProxy.isReady() )
power = gridProxy.isActive();
int current = worldObj.getBlockMetadata( xCoord, yCoord, zCoord );
int newmeta = (current & 3) | (formed ? 8 : 0) | (power ? 4 : 0);
if ( current != newmeta )
worldObj.setBlockMetadataWithNotify( xCoord, yCoord, zCoord, newmeta, 2 );
if ( updateFormed )
{
if ( formed )
gridProxy.setValidSides( EnumSet.allOf( ForgeDirection.class ) );
else
gridProxy.setValidSides( EnumSet.noneOf( ForgeDirection.class ) );
}
}
@Override
public IAECluster getCluster()
{
return clust;
}
@Override
public boolean isValid()
{
return true;
}
@Override
public boolean isPowered()
{
if ( Platform.isClient() )
return (worldObj.getBlockMetadata( xCoord, yCoord, zCoord ) & 4) == 4;
return gridProxy.isActive();
}
public boolean isFormed()
{
if ( Platform.isClient() )
return (worldObj.getBlockMetadata( xCoord, yCoord, zCoord ) & 8) == 8;
return clust != null;
}
public boolean isAccelerator()
{
if ( worldObj == null )
return false;
return (worldObj.getBlockMetadata( xCoord, yCoord, zCoord ) & 3) == 1;
}
public boolean isStatus()
{
return false;
}
public boolean isStorage()
{
return false;
}
public int getStorageBytes()
{
return 0;
}
@Override
public boolean isActive()
{
if ( Platform.isServer() )
return gridProxy.isActive();
return isPowered() && isFormed();
}
public void breakCluster()
{
if ( clust != null )
{
clust.cancel();
IMEInventory<IAEItemStack> inv = clust.getInventory();
LinkedList<WorldCoord> places = new LinkedList<WorldCoord>();
Iterator<IGridHost> i = clust.getTiles();
while (i.hasNext())
{
IGridHost h = i.next();
if ( h == this )
places.add( new WorldCoord( this ) );
else
{
TileEntity te = (TileEntity) h;
for (ForgeDirection d : ForgeDirection.VALID_DIRECTIONS)
{
WorldCoord wc = new WorldCoord( te );
wc.add( d, 1 );
if ( worldObj.isAirBlock( wc.x, wc.y, wc.z ) )
places.add( wc );
}
}
}
Collections.shuffle( places );
if ( places.isEmpty() )
throw new RuntimeException( "No air or even the tile hat was destroyed?!?!" );
for (IAEItemStack ais : inv.getAvailableItems( AEApi.instance().storage().createItemList() ))
{
ais = ais.copy();
ais.setStackSize( ais.getItemStack().getMaxStackSize() );
while (true)
{
IAEItemStack g = inv.extractItems( ais.copy(), Actionable.MODULATE, clust.getActionSource() );
if ( g == null )
break;
WorldCoord wc = places.poll();
places.add( wc );
Platform.spawnDrops( worldObj, wc.x, wc.y, wc.z, Arrays.asList( g.getItemStack() ) );
}
}
clust.destroy();
}
}
}
@@ -0,0 +1,587 @@
package appeng.tile.crafting;
import io.netty.buffer.ByteBuf;
import java.io.IOException;
import java.util.ArrayList;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.config.RedstoneMode;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
import appeng.api.implementations.IPowerChannelState;
import appeng.api.implementations.IUpgradeableHost;
import appeng.api.implementations.tiles.ICraftingMachine;
import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.parts.ISimplifiedBundle;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.AECableType;
import appeng.api.util.DimensionalCoord;
import appeng.api.util.IConfigManager;
import appeng.container.ContainerNull;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketAssemblerAnimation;
import appeng.items.misc.ItemEncodedPattern;
import appeng.me.GridAccessException;
import appeng.parts.automation.UpgradeInventory;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkInvTile;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.IAEAppEngInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
public class TileMolecularAssembler extends AENetworkInvTile implements IAEAppEngInventory, ISidedInventory, IUpgradeableHost, IConfigManagerHost,
IGridTickable, ICraftingMachine, IPowerChannelState
{
static final int[] sides = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
static final ItemStack assemblerStack = AEApi.instance().blocks().blockMolecularAssembler.stack( 1 );
private InventoryCrafting craftingInv = new InventoryCrafting( new ContainerNull(), 3, 3 );
private AppEngInternalInventory inv = new AppEngInternalInventory( this, 9 + 2 );
private IConfigManager settings = new ConfigManager( this );
private UpgradeInventory upgrades = new UpgradeInventory( assemblerStack, this, getUpgradeSlots() );
private ForgeDirection pushDirection = ForgeDirection.UNKNOWN;
private ItemStack myPattern = null;
private ICraftingPatternDetails myPlan = null;
private double progress = 0;
private boolean isAwake = false;
private boolean forcePlan = false;
private boolean reboot = true;
public ISimplifiedBundle lightCache;
public boolean pushPattern(ICraftingPatternDetails patternDetails, InventoryCrafting table, ForgeDirection where)
{
if ( myPattern == null )
{
boolean isEmpty = true;
for (int x = 0; x < inv.getSizeInventory(); x++)
isEmpty = inv.getStackInSlot( x ) == null && isEmpty;
if ( isEmpty && patternDetails.isCraftable() )
{
forcePlan = true;
myPlan = patternDetails;
pushDirection = where;
for (int x = 0; x < table.getSizeInventory(); x++)
inv.setInventorySlotContents( x, table.getStackInSlot( x ) );
updateSleepiness();
markDirty();
return true;
}
}
return false;
}
private void recalculatePlan()
{
reboot = true;
if ( forcePlan )
return;
ItemStack is = inv.getStackInSlot( 10 );
if ( is != null && is.getItem() instanceof ItemEncodedPattern )
{
if ( !Platform.isSameItem( is, myPattern ) )
{
World w = getWorldObj();
ItemEncodedPattern iep = (ItemEncodedPattern) is.getItem();
ICraftingPatternDetails ph = iep.getPatternForItem( is, w );
if ( ph != null && ph.isCraftable() )
{
progress = 0;
myPattern = is;
myPlan = ph;
}
}
}
else
{
progress = 0;
forcePlan = false;
myPlan = null;
myPattern = null;
pushDirection = ForgeDirection.UNKNOWN;
}
updateSleepiness();
}
private void updateSleepiness()
{
boolean wasEnabled = isAwake;
isAwake = myPlan != null && hasMats() || canPush();
if ( wasEnabled != isAwake )
{
try
{
if ( isAwake )
gridProxy.getTick().wakeDevice( gridProxy.getNode() );
else
gridProxy.getTick().sleepDevice( gridProxy.getNode() );
}
catch (GridAccessException e)
{
// :P
}
}
}
private boolean canPush()
{
return inv.getStackInSlot( 9 ) != null;
}
@Override
public int getInstalledUpgrades(Upgrades u)
{
return upgrades.getInstalledUpgrades( u );
}
protected int getUpgradeSlots()
{
return 5;
}
@TileEvent(TileEventType.NETWORK_READ)
public boolean readFromStream_TileMolecularAssembler(ByteBuf data) throws IOException
{
boolean oldPower = isPowered;
isPowered = data.readBoolean();
return isPowered != oldPower;
}
@TileEvent(TileEventType.NETWORK_WRITE)
public void writeToStream_TileMolecularAssembler(ByteBuf data) throws IOException
{
data.writeBoolean( isPowered );
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_TileMolecularAssembler(NBTTagCompound data)
{
if ( forcePlan && myPlan != null )
{
ItemStack pattern = myPlan.getPattern();
if ( pattern != null )
{
NBTTagCompound pdata = new NBTTagCompound();
pattern.writeToNBT( pdata );
data.setTag( "myPlan", pdata );
data.setInteger( "pushDirection", pushDirection.ordinal() );
}
}
upgrades.writeToNBT( data, "upgrades" );
inv.writeToNBT( data, "inv" );
settings.writeToNBT( data );
}
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_TileMolecularAssembler(NBTTagCompound data)
{
if ( data.hasKey( "myPlan" ) )
{
ItemStack myPat = ItemStack.loadItemStackFromNBT( data.getCompoundTag( "myPlan" ) );
if ( myPat != null && myPat.getItem() instanceof ItemEncodedPattern )
{
World w = getWorldObj();
ItemEncodedPattern iep = (ItemEncodedPattern) myPat.getItem();
ICraftingPatternDetails ph = iep.getPatternForItem( myPat, w );
if ( ph != null && ph.isCraftable() )
{
forcePlan = true;
myPlan = ph;
pushDirection = ForgeDirection.getOrientation( data.getInteger( "pushDirection" ) );
}
}
}
upgrades.readFromNBT( data, "upgrades" );
inv.readFromNBT( data, "inv" );
settings.readFromNBT( data );
recalculatePlan();
}
public TileMolecularAssembler() {
settings.registerSetting( Settings.REDSTONE_CONTROLLED, RedstoneMode.IGNORE );
inv.setMaxStackSize( 1 );
gridProxy.setIdlePowerUsage( 0.0 );
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack)
{
if ( i >= 9 )
return false;
if ( hasPattern() )
return myPlan.isValidItemForSlot( i, itemstack, getWorldObj() );
return false;
}
@Override
public boolean acceptsPlans()
{
return inv.getStackInSlot( 10 ) == null;
}
private boolean hasPattern()
{
return myPlan != null && inv.getStackInSlot( 10 ) != null;
}
@Override
public boolean canExtractItem(int i, ItemStack itemstack, int j)
{
return i == 9;
}
@Override
public IInventory getInternalInventory()
{
return inv;
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removed, ItemStack added)
{
if ( inv == this.inv )
recalculatePlan();
}
@Override
public int[] getAccessibleSlotsBySide(ForgeDirection whichSide)
{
return sides;
}
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
return AECableType.COVERED;
}
@Override
public DimensionalCoord getLocation()
{
return new DimensionalCoord( this );
}
@Override
public IConfigManager getConfigManager()
{
return settings;
}
@Override
public IInventory getInventoryByName(String name)
{
if ( name.equals( "upgrades" ) )
return upgrades;
if ( name.equals( "mac" ) )
return inv;
return null;
}
@Override
public void updateSetting(IConfigManager manager, Enum settingName, Enum newValue)
{
}
@Override
public int getInventoryStackLimit()
{
return 1;
}
public int getCraftingProgress()
{
return (int) progress;
}
@Override
public void getDrops(World w, int x, int y, int z, ArrayList<ItemStack> drops)
{
super.getDrops( w, x, y, z, drops );
for (int h = 0; h < upgrades.getSizeInventory(); h++)
{
ItemStack is = upgrades.getStackInSlot( h );
if ( is != null )
drops.add( is );
}
}
@Override
public TickingRequest getTickingRequest(IGridNode node)
{
recalculatePlan();
updateSleepiness();
return new TickingRequest( 1, 1, !isAwake, false );
}
private boolean hasMats()
{
if ( myPlan == null )
return false;
for (int x = 0; x < craftingInv.getSizeInventory(); x++)
craftingInv.setInventorySlotContents( x, inv.getStackInSlot( x ) );
return myPlan.getOutput( craftingInv, getWorldObj() ) != null;
}
@Override
public TickRateModulation tickingRequest(IGridNode node, int TicksSinceLastCall)
{
if ( inv.getStackInSlot( 9 ) != null )
{
pushOut( inv.getStackInSlot( 9 ) );
// did it eject?
if ( inv.getStackInSlot( 9 ) == null )
markDirty();
ejectHeldItems();
updateSleepiness();
progress = 0;
return isAwake ? TickRateModulation.IDLE : TickRateModulation.SLEEP;
}
if ( myPlan == null )
{
updateSleepiness();
return TickRateModulation.SLEEP;
}
if ( reboot )
TicksSinceLastCall = 1;
if ( !isAwake )
return TickRateModulation.SLEEP;
reboot = false;
int speed = 10;
switch (upgrades.getInstalledUpgrades( Upgrades.SPEED ))
{
case 0:
progress += userPower( TicksSinceLastCall, speed = 10, 1.0 );
break;
case 1:
progress += userPower( TicksSinceLastCall, speed = 13, 1.3 );
break;
case 2:
progress += userPower( TicksSinceLastCall, speed = 17, 1.7 );
break;
case 3:
progress += userPower( TicksSinceLastCall, speed = 20, 2.0 );
break;
case 4:
progress += userPower( TicksSinceLastCall, speed = 25, 2.5 );
break;
case 5:
progress += userPower( TicksSinceLastCall, speed = 50, 5.0 );
break;
}
if ( progress >= 100 )
{
for (int x = 0; x < craftingInv.getSizeInventory(); x++)
craftingInv.setInventorySlotContents( x, inv.getStackInSlot( x ) );
progress = 0;
ItemStack output = myPlan.getOutput( craftingInv, getWorldObj() );
if ( output != null )
{
FMLCommonHandler.instance().firePlayerCraftingEvent( Platform.getPlayer( (WorldServer) getWorldObj() ), output, craftingInv );
pushOut( output.copy() );
for (int x = 0; x < craftingInv.getSizeInventory(); x++)
inv.setInventorySlotContents( x, Platform.getContainerItem( craftingInv.getStackInSlot( x ) ) );
if ( inv.getStackInSlot( 10 ) == null )
{
forcePlan = false;
myPlan = null;
pushDirection = ForgeDirection.UNKNOWN;
}
ejectHeldItems();
try
{
TargetPoint where = new TargetPoint( worldObj.provider.dimensionId, xCoord, yCoord, zCoord, 32 );
IAEItemStack item = AEItemStack.create( output );
NetworkHandler.instance.sendToAllAround( new PacketAssemblerAnimation( xCoord, yCoord, zCoord, (byte) speed, item ), where );
}
catch (IOException e)
{
// ;P
}
markDirty();
updateSleepiness();
return isAwake ? TickRateModulation.IDLE : TickRateModulation.SLEEP;
}
}
return TickRateModulation.FASTER;
}
private void ejectHeldItems()
{
if ( inv.getStackInSlot( 9 ) == null )
{
for (int x = 0; x < 9; x++)
{
ItemStack is = inv.getStackInSlot( x );
if ( is != null )
{
if ( myPlan == null || !myPlan.isValidItemForSlot( x, is, worldObj ) )
{
inv.setInventorySlotContents( 9, is );
inv.setInventorySlotContents( x, null );
markDirty();
return;
}
}
}
}
}
private int userPower(int ticksPassed, int bonusValue, double acceleratorTax)
{
try
{
return (int) (gridProxy.getEnergy().extractAEPower( ticksPassed * bonusValue * acceleratorTax, Actionable.MODULATE, PowerMultiplier.CONFIG ) / acceleratorTax);
}
catch (GridAccessException e)
{
return 0;
}
}
private void pushOut(ItemStack output)
{
if ( pushDirection == ForgeDirection.UNKNOWN )
{
for (ForgeDirection d : ForgeDirection.VALID_DIRECTIONS)
output = pushTo( output, d );
}
else
output = pushTo( output, pushDirection );
if ( output == null && forcePlan )
{
forcePlan = false;
recalculatePlan();
}
inv.setInventorySlotContents( 9, output );
}
private ItemStack pushTo(ItemStack output, ForgeDirection d)
{
if ( output == null )
return output;
TileEntity te = getWorldObj().getTileEntity( xCoord + d.offsetX, yCoord + d.offsetY, zCoord + d.offsetZ );
if ( te == null )
return output;
InventoryAdaptor adaptor = InventoryAdaptor.getAdaptor( te, d.getOpposite() );
if ( adaptor == null )
return output;
int size = output.stackSize;
output = adaptor.addItems( output );
int newSize = output == null ? 0 : output.stackSize;
if ( size != newSize )
markDirty();
return output;
}
boolean isPowered = false;
@MENetworkEventSubscribe
public void onPowerEvent(MENetworkPowerStatusChange p)
{
updatePowerState();
}
private void updatePowerState()
{
boolean newState = false;
try
{
newState = gridProxy.isActive() && gridProxy.getEnergy().extractAEPower( 1, Actionable.SIMULATE, PowerMultiplier.CONFIG ) > 0.0001;
}
catch (GridAccessException e)
{
}
if ( newState != isPowered )
{
isPowered = newState;
markForUpdate();
}
}
@Override
public boolean isPowered()
{
return isPowered;
}
@Override
public boolean isActive()
{
return isPowered;
}
}
@@ -0,0 +1,138 @@
package appeng.tile.events;
import io.netty.buffer.ByteBuf;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import net.minecraft.nbt.NBTTagCompound;
import appeng.tile.AEBaseTile;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class AETileEventHandler
{
private final Method method;
private final TileEventType type;
public AETileEventHandler(Method m, TileEventType which) {
method = m;
type = which;
}
// TICK
public void Tick(AEBaseTile tile)
{
try
{
method.invoke( tile );
}
catch (IllegalAccessException e)
{
throw new RuntimeException( e );
}
catch (IllegalArgumentException e)
{
throw new RuntimeException( e );
}
catch (InvocationTargetException e)
{
throw new RuntimeException( e );
}
}
// WORLD_NBT
public void writeToNBT(AEBaseTile tile, NBTTagCompound data)
{
try
{
method.invoke( tile, data );
}
catch (IllegalAccessException e)
{
throw new RuntimeException( e );
}
catch (IllegalArgumentException e)
{
throw new RuntimeException( e );
}
catch (InvocationTargetException e)
{
throw new RuntimeException( e );
}
}
// WORLD NBT
public void readFromNBT(AEBaseTile tile, NBTTagCompound data)
{
try
{
method.invoke( tile, data );
}
catch (IllegalAccessException e)
{
throw new RuntimeException( e );
}
catch (IllegalArgumentException e)
{
throw new RuntimeException( e );
}
catch (InvocationTargetException e)
{
throw new RuntimeException( e );
}
}
// NETWORK
public void writeToStream(AEBaseTile tile, ByteBuf data) throws IOException
{
try
{
method.invoke( tile, data );
}
catch (IllegalAccessException e)
{
throw new RuntimeException( e );
}
catch (IllegalArgumentException e)
{
throw new RuntimeException( e );
}
catch (InvocationTargetException e)
{
throw new RuntimeException( e );
}
}
// NETWORK
/**
* returning true from this method, will update the block's render
*
* @param data
* @return
* @throws IOException
*/
@SideOnly(Side.CLIENT)
public boolean readFromStream(AEBaseTile tile, ByteBuf data) throws IOException
{
try
{
return (Boolean) method.invoke( tile, data );
}
catch (IllegalAccessException e)
{
throw new RuntimeException( e );
}
catch (IllegalArgumentException e)
{
throw new RuntimeException( e );
}
catch (InvocationTargetException e)
{
throw new RuntimeException( e );
}
}
}
@@ -0,0 +1,10 @@
package appeng.tile.events;
public enum TileEventType
{
TICK,
WORLD_NBT_READ, WORLD_NBT_WRITE,
NETWORK_READ, NETWORK_WRITE
}
@@ -0,0 +1,81 @@
package appeng.tile.grid;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.networking.IGridNode;
import appeng.api.networking.security.IActionHost;
import appeng.me.helpers.AENetworkProxy;
import appeng.me.helpers.IGridProxyable;
import appeng.tile.AEBaseInvTile;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
public abstract class AENetworkInvTile extends AEBaseInvTile implements IActionHost, IGridProxyable
{
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_AENetwork(NBTTagCompound data)
{
gridProxy.readFromNBT( data );
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_AENetwork(NBTTagCompound data)
{
gridProxy.writeToNBT( data );
}
protected AENetworkProxy gridProxy = new AENetworkProxy( this, "proxy", getItemFromTile( this ), true );
@Override
public AENetworkProxy getProxy()
{
return gridProxy;
}
@Override
public IGridNode getGridNode(ForgeDirection dir)
{
return gridProxy.getNode();
}
@Override
public void onReady()
{
super.onReady();
gridProxy.onReady();
}
@Override
public void onChunkUnload()
{
super.onChunkUnload();
gridProxy.onChunkUnload();
}
@Override
public void validate()
{
super.validate();
gridProxy.validate();
}
@Override
public void invalidate()
{
super.invalidate();
gridProxy.invalidate();
}
@Override
public void gridChanged()
{
}
@Override
public IGridNode getActionableNode()
{
return gridProxy.getNode();
}
}
@@ -0,0 +1,95 @@
package appeng.tile.grid;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.networking.IGridNode;
import appeng.api.networking.security.IActionHost;
import appeng.api.util.AECableType;
import appeng.api.util.DimensionalCoord;
import appeng.me.helpers.AENetworkProxy;
import appeng.me.helpers.IGridProxyable;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.powersink.AEBasePoweredTile;
public abstract class AENetworkPowerTile extends AEBasePoweredTile implements IActionHost, IGridProxyable
{
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_AENetwork(NBTTagCompound data)
{
gridProxy.readFromNBT( data );
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_AENetwork(NBTTagCompound data)
{
gridProxy.writeToNBT( data );
}
protected AENetworkProxy gridProxy = new AENetworkProxy( this, "proxy", getItemFromTile( this ), true );
@Override
public AENetworkProxy getProxy()
{
return gridProxy;
}
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
return AECableType.SMART;
}
@Override
public DimensionalCoord getLocation()
{
return new DimensionalCoord( this );
}
@Override
public IGridNode getGridNode(ForgeDirection dir)
{
return gridProxy.getNode();
}
@Override
public void onReady()
{
super.onReady();
gridProxy.onReady();
}
@Override
public void onChunkUnload()
{
super.onChunkUnload();
gridProxy.onChunkUnload();
}
@Override
public void validate()
{
super.validate();
gridProxy.validate();
}
@Override
public void invalidate()
{
super.invalidate();
gridProxy.invalidate();
}
@Override
public void gridChanged()
{
}
@Override
public IGridNode getActionableNode()
{
return gridProxy.getNode();
}
}
@@ -0,0 +1,100 @@
package appeng.tile.grid;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.networking.IGridNode;
import appeng.api.networking.security.IActionHost;
import appeng.api.util.AECableType;
import appeng.api.util.DimensionalCoord;
import appeng.me.helpers.AENetworkProxy;
import appeng.me.helpers.IGridProxyable;
import appeng.tile.AEBaseTile;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
public class AENetworkTile extends AEBaseTile implements IActionHost, IGridProxyable
{
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_AENetwork(NBTTagCompound data)
{
gridProxy.readFromNBT( data );
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_AENetwork(NBTTagCompound data)
{
gridProxy.writeToNBT( data );
}
final protected AENetworkProxy gridProxy = createProxy();
protected AENetworkProxy createProxy()
{
return new AENetworkProxy( this, "proxy", getItemFromTile( this ), true );
}
@Override
public IGridNode getGridNode(ForgeDirection dir)
{
return gridProxy.getNode();
}
@Override
public void onReady()
{
super.onReady();
gridProxy.onReady();
}
@Override
public void onChunkUnload()
{
super.onChunkUnload();
gridProxy.onChunkUnload();
}
@Override
public void validate()
{
super.validate();
gridProxy.validate();
}
@Override
public void invalidate()
{
super.invalidate();
gridProxy.invalidate();
}
@Override
public DimensionalCoord getLocation()
{
return new DimensionalCoord( this );
}
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
return AECableType.SMART;
}
@Override
public void gridChanged()
{
}
@Override
public AENetworkProxy getProxy()
{
return gridProxy;
}
@Override
public IGridNode getActionableNode()
{
return gridProxy.getNode();
}
}
@@ -0,0 +1,143 @@
package appeng.tile.grindstone;
import io.netty.buffer.ByteBuf;
import java.util.Arrays;
import java.util.List;
import net.minecraft.entity.Entity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.implementations.tiles.ICrankable;
import appeng.helpers.ICustomCollision;
import appeng.tile.AEBaseTile;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.util.Platform;
public class TileCrank extends AEBaseTile implements ICustomCollision
{
final int ticksPerRotation = 18;
// sided values..
public float visibleRotation = 0;
public int charge = 0;
public int hits = 0;
public int rotation = 0;
@TileEvent(TileEventType.TICK)
public void Tick_TileCrank()
{
if ( rotation > 0 )
{
visibleRotation -= 360 / (ticksPerRotation);
charge++;
if ( charge >= ticksPerRotation )
{
charge -= ticksPerRotation;
ICrankable g = getGrinder();
if ( g != null )
g.applyTurn();
}
rotation--;
}
}
@TileEvent(TileEventType.NETWORK_READ)
public boolean readFromStream_TileCrank(ByteBuf data) throws java.io.IOException
{
rotation = data.readInt();
return false;
}
@TileEvent(TileEventType.NETWORK_WRITE)
public void writeToStream_TileCrank(ByteBuf data) throws java.io.IOException
{
data.writeInt( rotation );
}
public ICrankable getGrinder()
{
if ( Platform.isClient() )
return null;
ForgeDirection grinder = getUp().getOpposite();
TileEntity te = worldObj.getTileEntity( xCoord + grinder.offsetX, yCoord + grinder.offsetY, zCoord + grinder.offsetZ );
if ( te instanceof ICrankable )
return (ICrankable) te;
return null;
}
@Override
public void setOrientation(ForgeDirection inForward, ForgeDirection inUp)
{
super.setOrientation( inForward, inUp );
getBlockType().onNeighborBlockChange( worldObj, xCoord, yCoord, zCoord, Platform.air );
}
/**
* return true if this should count towards stats.
*/
public boolean power()
{
if ( Platform.isClient() )
return false;
if ( rotation < 3 )
{
ICrankable g = getGrinder();
if ( g != null )
{
if ( g.canTurn() )
{
hits = 0;
rotation += ticksPerRotation;
this.markForUpdate();
return true;
}
else
{
hits++;
if ( hits > 10 )
{
worldObj.func_147480_a( xCoord, yCoord, zCoord, false );
// worldObj.destroyBlock( xCoord, yCoord, zCoord, false );
}
}
}
}
return false;
}
@Override
public Iterable<AxisAlignedBB> getSelectedBoundingBoxesFromPool(World w, int x, int y, int z, Entity e, boolean isVisual)
{
double xOff = -0.15 * getUp().offsetX;
double yOff = -0.15 * getUp().offsetY;
double zOff = -0.15 * getUp().offsetZ;
return Arrays
.asList( new AxisAlignedBB[] { AxisAlignedBB.getBoundingBox( xOff + 0.15, yOff + 0.15, zOff + 0.15, xOff + 0.85, yOff + 0.85, zOff + 0.85 ) } );
}
@Override
public void addCollidingBlockToList(World w, int x, int y, int z, AxisAlignedBB bb, List out, Entity e)
{
double xOff = -0.15 * getUp().offsetX;
double yOff = -0.15 * getUp().offsetY;
double zOff = -0.15 * getUp().offsetZ;
out.add( AxisAlignedBB.getBoundingBox( xOff + (double) 0.15, yOff + (double) 0.15, zOff + (double) 0.15,// ahh
xOff + (double) 0.85, yOff + (double) 0.85, zOff + (double) 0.85 ) );
}
@Override
public boolean requiresTESR()
{
return true;
}
}
@@ -0,0 +1,164 @@
package appeng.tile.grindstone;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.AEApi;
import appeng.api.features.IGrinderEntry;
import appeng.api.implementations.tiles.ICrankable;
import appeng.api.util.WorldCoord;
import appeng.tile.AEBaseInvTile;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.inv.WrapperInventoryRange;
public class TileGrinder extends AEBaseInvTile implements ICrankable
{
int points;
final int inputs[] = new int[] { 0, 1, 2 };
final int sides[] = new int[] { 0, 1, 2, 3, 4, 5 };
AppEngInternalInventory inv = new AppEngInternalInventory( this, 7 );
@Override
public void setOrientation(ForgeDirection inForward, ForgeDirection inUp)
{
super.setOrientation( inForward, inUp );
getBlockType().onNeighborBlockChange( worldObj, xCoord, yCoord, zCoord, Platform.air );
}
private void addItem(InventoryAdaptor sia, ItemStack output)
{
if ( output == null )
return;
ItemStack notAdded = sia.addItems( output );
if ( notAdded != null )
{
WorldCoord wc = new WorldCoord( xCoord, yCoord, zCoord );
wc.add( getForward(), 1 );
List<ItemStack> out = new ArrayList();
out.add( notAdded );
Platform.spawnDrops( worldObj, wc.x, wc.y, wc.z, out );
}
}
@Override
public boolean canInsertItem(int i, ItemStack itemstack, int j)
{
if ( AEApi.instance().registries().grinder().getRecipeForInput( itemstack ) == null )
return false;
return i >= 0 && i <= 2;
}
@Override
public boolean canExtractItem(int i, ItemStack itemstack, int j)
{
return i >= 3 && i <= 5;
}
@Override
public IInventory getInternalInventory()
{
return inv;
}
@Override
public int[] getAccessibleSlotsBySide(ForgeDirection side)
{
return sides;
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removed, ItemStack added)
{
}
@Override
public boolean canTurn()
{
if ( Platform.isClient() )
return false;
if ( null == this.getStackInSlot( 6 ) ) // Add if there isn't one...
{
IInventory src = new WrapperInventoryRange( this, inputs, true );
for (int x = 0; x < src.getSizeInventory(); x++)
{
ItemStack item = src.getStackInSlot( x );
if ( item == null )
continue;
IGrinderEntry r = AEApi.instance().registries().grinder().getRecipeForInput( item );
if ( r != null )
{
if ( item.stackSize >= r.getInput().stackSize )
{
item.stackSize -= r.getInput().stackSize;
ItemStack ais = item.copy();
ais.stackSize = r.getInput().stackSize;
if ( item.stackSize <= 0 )
item = null;
src.setInventorySlotContents( x, item );
this.setInventorySlotContents( 6, ais );
return true;
}
}
}
return false;
}
return true;
}
@Override
public void applyTurn()
{
if ( Platform.isClient() )
return;
points++;
ItemStack processing = this.getStackInSlot( 6 );
IGrinderEntry r = AEApi.instance().registries().grinder().getRecipeForInput( processing );
if ( r != null )
{
if ( r.getEnergyCost() > points )
return;
points = 0;
InventoryAdaptor sia = InventoryAdaptor.getAdaptor( new WrapperInventoryRange( this, 3, 3, true ), ForgeDirection.EAST );
addItem( sia, r.getOutput() );
float chance = (Platform.getRandomInt() % 2000) / 2000.0f;
if ( chance <= r.getOptionalChance() )
addItem( sia, r.getOptionalOutput() );
chance = (Platform.getRandomInt() % 2000) / 2000.0f;
if ( chance <= r.getSecondOptionalChance() )
addItem( sia, r.getSecondOptionalOutput() );
this.setInventorySlotContents( 6, null );
}
}
@Override
public boolean canCrankAttach(ForgeDirection directionToCrank)
{
return getUp().equals( directionToCrank );
}
}
@@ -0,0 +1,247 @@
package appeng.tile.inventory;
import java.util.Iterator;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import appeng.api.AEApi;
import appeng.api.storage.data.IAEItemStack;
import appeng.core.AELog;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
import appeng.util.iterators.AEInvIterator;
import appeng.util.iterators.InvIterator;
public class AppEngInternalAEInventory implements IInventory, Iterable<ItemStack>
{
protected IAEAppEngInventory te;
int size;
int maxStack;
protected IAEItemStack inv[];
public boolean isEmpty()
{
for (int x = 0; x < getSizeInventory(); x++)
if ( getStackInSlot( x ) != null )
return false;
return true;
}
public AppEngInternalAEInventory(IAEAppEngInventory _te, int s) {
te = _te;
size = s;
maxStack = 64;
inv = new IAEItemStack[s];
}
public void setMaxStackSize(int s)
{
maxStack = s;
}
public IAEItemStack getAEStackInSlot(int var1)
{
return inv[var1];
}
@Override
public ItemStack getStackInSlot(int var1)
{
if ( inv[var1] == null )
return null;
return inv[var1].getItemStack();
}
@Override
public ItemStack decrStackSize(int slot, int qty)
{
if ( inv[slot] != null )
{
ItemStack split = getStackInSlot( slot );
ItemStack ns = null;
if ( qty >= split.stackSize )
{
ns = getStackInSlot( slot );
inv[slot] = null;
}
else
ns = split.splitStack( qty );
if ( te != null && Platform.isServer() )
{
te.onChangeInventory( this, slot, InvOperation.decrStackSize, ns, null );
}
return ns;
}
return null;
}
@Override
public ItemStack getStackInSlotOnClosing(int var1)
{
return null;
}
@Override
public void setInventorySlotContents(int slot, ItemStack newItemStack)
{
ItemStack oldStack = getStackInSlot( slot );
inv[slot] = AEApi.instance().storage().createItemStack( newItemStack );
if ( te != null && Platform.isServer() )
{
ItemStack removed = oldStack;
ItemStack added = newItemStack;
if ( oldStack != null && newItemStack != null && Platform.isSameItem( oldStack, newItemStack ) )
{
if ( oldStack.stackSize > newItemStack.stackSize )
{
removed = removed.copy();
removed.stackSize -= newItemStack.stackSize;
added = null;
}
else if ( oldStack.stackSize < newItemStack.stackSize )
{
added = added.copy();
added.stackSize -= oldStack.stackSize;
removed = null;
}
else
{
removed = added = null;
}
}
te.onChangeInventory( this, slot, InvOperation.setInventorySlotContents, removed, added );
}
}
@Override
public void markDirty()
{
if ( te != null && Platform.isServer() )
{
te.onChangeInventory( this, -1, InvOperation.markDirty, null, null );
}
}
@Override
public int getInventoryStackLimit()
{
return maxStack > 64 ? 64 : maxStack;
}
@Override
public boolean isUseableByPlayer(EntityPlayer var1)
{
return true;
}
@Override
public void openInventory()
{
}
@Override
public void closeInventory()
{
}
public void writeToNBT(NBTTagCompound target)
{
for (int x = 0; x < size; x++)
{
try
{
NBTTagCompound c = new NBTTagCompound();
if ( inv[x] != null )
{
inv[x].writeToNBT( c );
}
target.setTag( "#" + x, c );
}
catch (Exception err)
{
}
}
}
public void readFromNBT(NBTTagCompound target)
{
for (int x = 0; x < size; x++)
{
try
{
NBTTagCompound c = target.getCompoundTag( "#" + x );
if ( c != null )
inv[x] = AEItemStack.loadItemStackFromNBT( c );
}
catch (Exception e)
{
AELog.error( e );
}
}
}
public void writeToNBT(NBTTagCompound data, String name)
{
NBTTagCompound c = new NBTTagCompound();
writeToNBT( c );
data.setTag( name, c );
}
public void readFromNBT(NBTTagCompound data, String name)
{
NBTTagCompound c = data.getCompoundTag( name );
if ( c != null )
readFromNBT( c );
}
@Override
public int getSizeInventory()
{
return size;
}
@Override
public String getInventoryName()
{
return "appeng-internal";
}
@Override
public boolean hasCustomInventoryName()
{
return false;
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack)
{
return true;
}
@Override
public Iterator<ItemStack> iterator()
{
return new InvIterator( this );
}
public Iterator<IAEItemStack> aeiterator()
{
return new AEInvIterator( this );
}
}
@@ -0,0 +1,256 @@
package appeng.tile.inventory;
import java.util.Iterator;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import appeng.api.storage.IMEInventory;
import appeng.core.AELog;
import appeng.me.storage.MEIInventoryWrapper;
import appeng.util.Platform;
import appeng.util.iterators.InvIterator;
public class AppEngInternalInventory implements IInventory, Iterable<ItemStack>
{
protected IAEAppEngInventory te;
protected int size;
protected int maxStack;
public boolean enableClientEvents = false;
protected ItemStack inv[];
public IMEInventory getIMEI()
{
return new MEIInventoryWrapper( this, null );
}
public boolean isEmpty()
{
for (int x = 0; x < getSizeInventory(); x++)
if ( getStackInSlot( x ) != null )
return false;
return true;
}
public AppEngInternalInventory(IAEAppEngInventory _te, int s) {
te = _te;
size = s;
maxStack = 64;
inv = new ItemStack[s];
}
protected boolean eventsEnabled()
{
return Platform.isServer() || enableClientEvents;
}
public void setMaxStackSize(int s)
{
maxStack = s;
}
@Override
public ItemStack getStackInSlot(int var1)
{
return inv[var1];
}
@Override
public ItemStack decrStackSize(int slot, int qty)
{
if ( inv[slot] != null )
{
ItemStack split = getStackInSlot( slot );
ItemStack ns = null;
if ( qty >= split.stackSize )
{
ns = inv[slot];
inv[slot] = null;
}
else
ns = split.splitStack( qty );
if ( te != null && eventsEnabled() )
{
te.onChangeInventory( this, slot, InvOperation.decrStackSize, ns, null );
}
markDirty();
return ns;
}
return null;
}
@Override
public ItemStack getStackInSlotOnClosing(int var1)
{
return null;
}
@Override
public void setInventorySlotContents(int slot, ItemStack newItemStack)
{
ItemStack oldStack = inv[slot];
inv[slot] = newItemStack;
if ( te != null && eventsEnabled() )
{
ItemStack removed = oldStack;
ItemStack added = newItemStack;
if ( oldStack != null && newItemStack != null && Platform.isSameItem( oldStack, newItemStack ) )
{
if ( oldStack.stackSize > newItemStack.stackSize )
{
removed = removed.copy();
removed.stackSize -= newItemStack.stackSize;
added = null;
}
else if ( oldStack.stackSize < newItemStack.stackSize )
{
added = added.copy();
added.stackSize -= oldStack.stackSize;
removed = null;
}
else
{
removed = added = null;
}
}
te.onChangeInventory( this, slot, InvOperation.setInventorySlotContents, removed, added );
markDirty();
}
}
@Override
public void markDirty()
{
if ( te != null && eventsEnabled() )
{
te.onChangeInventory( this, -1, InvOperation.markDirty, null, null );
}
}
// for guis...
public void markDirty(int slotIndex)
{
if ( te != null && eventsEnabled() )
{
te.onChangeInventory( this, slotIndex, InvOperation.markDirty, null, null );
}
}
@Override
public int getInventoryStackLimit()
{
return maxStack > 64 ? 64 : maxStack;
}
@Override
public boolean isUseableByPlayer(EntityPlayer var1)
{
return true;
}
@Override
public void closeInventory()
{
}
@Override
public void openInventory()
{
}
public void writeToNBT(NBTTagCompound target)
{
for (int x = 0; x < size; x++)
{
try
{
NBTTagCompound c = new NBTTagCompound();
if ( inv[x] != null )
{
inv[x].writeToNBT( c );
}
target.setTag( "#" + x, c );
}
catch (Exception err)
{
}
}
}
public void readFromNBT(NBTTagCompound target)
{
for (int x = 0; x < size; x++)
{
try
{
NBTTagCompound c = target.getCompoundTag( "#" + x );
if ( c != null )
inv[x] = ItemStack.loadItemStackFromNBT( c );
}
catch (Exception e)
{
AELog.error( e );
}
}
}
public void writeToNBT(NBTTagCompound data, String name)
{
NBTTagCompound c = new NBTTagCompound();
writeToNBT( c );
data.setTag( name, c );
}
public void readFromNBT(NBTTagCompound data, String name)
{
NBTTagCompound c = data.getCompoundTag( name );
if ( c != null )
readFromNBT( c );
}
@Override
public int getSizeInventory()
{
return size;
}
@Override
public String getInventoryName()
{
return "appeng-internal";
}
@Override
public boolean hasCustomInventoryName()
{
return false;
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack)
{
return true;
}
@Override
public Iterator<ItemStack> iterator()
{
return new InvIterator( this );
}
}
@@ -0,0 +1,94 @@
package appeng.tile.inventory;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
public class AppEngNullInventory implements IInventory
{
public AppEngNullInventory() {
}
@Override
public ItemStack getStackInSlot(int var1)
{
return null;
}
@Override
public ItemStack decrStackSize(int slot, int qty)
{
return null;
}
@Override
public ItemStack getStackInSlotOnClosing(int var1)
{
return null;
}
@Override
public void setInventorySlotContents(int slot, ItemStack newItemStack)
{
}
@Override
public void markDirty()
{
}
@Override
public int getInventoryStackLimit()
{
return 0;
}
@Override
public boolean isUseableByPlayer(EntityPlayer var1)
{
return false;
}
@Override
public void openInventory()
{
}
@Override
public void closeInventory()
{
}
public void writeToNBT(NBTTagCompound target)
{
}
@Override
public int getSizeInventory()
{
return 0;
}
@Override
public String getInventoryName()
{
return "appeng-internal";
}
@Override
public boolean hasCustomInventoryName()
{
return false;
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack)
{
return false;
}
}
@@ -0,0 +1,13 @@
package appeng.tile.inventory;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
public interface IAEAppEngInventory
{
void saveChanges();
void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack);
}
@@ -0,0 +1,7 @@
package appeng.tile.inventory;
public enum InvOperation
{
decrStackSize, setInventorySlotContents, markDirty
}
@@ -0,0 +1,210 @@
package appeng.tile.misc;
import java.util.ArrayList;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import appeng.api.config.CopyMode;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
import appeng.api.implementations.IUpgradeableHost;
import appeng.api.storage.ICellWorkbenchItem;
import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject;
import appeng.tile.AEBaseTile;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.inventory.AppEngInternalAEInventory;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.IAEAppEngInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost;
public class TileCellWorkbench extends AEBaseTile implements IUpgradeableHost, IAEAppEngInventory, IConfigurableObject, IConfigManagerHost
{
AppEngInternalInventory cell = new AppEngInternalInventory( this, 1 );
AppEngInternalAEInventory config = new AppEngInternalAEInventory( this, 63 );
ConfigManager cm = new ConfigManager( this );
IInventory cacheUpgrades = null;
IInventory cacheConfig = null;
public IInventory getCellUpgradeInventory()
{
if ( cacheUpgrades == null )
{
ICellWorkbenchItem cwbi = getCell();
if ( cwbi == null )
return null;
ItemStack is = cell.getStackInSlot( 0 );
if ( is == null )
return null;
IInventory inv = cwbi.getUpgradesInventory( is );
if ( inv == null )
return null;
return cacheUpgrades = inv;
}
return cacheUpgrades;
}
public IInventory getCellConfigInventory()
{
if ( cacheConfig == null )
{
ICellWorkbenchItem cwbi = getCell();
if ( cwbi == null )
return null;
ItemStack is = cell.getStackInSlot( 0 );
if ( is == null )
return null;
IInventory inv = cwbi.getConfigInventory( is );
if ( inv == null )
return null;
return cacheConfig = inv;
}
return cacheConfig;
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_TileCellWorkbench(NBTTagCompound data)
{
cell.writeToNBT( data, "cell" );
config.writeToNBT( data, "config" );
cm.writeToNBT( data );
}
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_TileCellWorkbench(NBTTagCompound data)
{
cell.readFromNBT( data, "cell" );
config.readFromNBT( data, "config" );
cm.readFromNBT( data );
}
public TileCellWorkbench() {
cm.registerSetting( Settings.COPY_MODE, CopyMode.CLEAR_ON_REMOVE );
cell.enableClientEvents = true;
}
@Override
public IInventory getInventoryByName(String name)
{
if ( name.equals( "config" ) )
return config;
if ( name.equals( "cell" ) )
return cell;
return null;
}
@Override
public int getInstalledUpgrades(Upgrades u)
{
return 0;
}
private boolean locked = false;
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack)
{
if ( inv == cell && locked == false )
{
locked = true;
cacheUpgrades = null;
cacheConfig = null;
IInventory c = getCellConfigInventory();
if ( c != null )
{
boolean cellHasConfig = false;
for (int x = 0; x < c.getSizeInventory(); x++)
{
if ( c.getStackInSlot( x ) != null )
{
cellHasConfig = true;
break;
}
}
if ( cellHasConfig )
{
for (int x = 0; x < config.getSizeInventory(); x++)
config.setInventorySlotContents( x, c.getStackInSlot( x ) );
}
else
{
for (int x = 0; x < config.getSizeInventory(); x++)
c.setInventorySlotContents( x, config.getStackInSlot( x ) );
c.markDirty();
}
}
else if ( cm.getSetting( Settings.COPY_MODE ) == CopyMode.CLEAR_ON_REMOVE )
{
for (int x = 0; x < config.getSizeInventory(); x++)
config.setInventorySlotContents( x, null );
this.markDirty();
}
locked = false;
}
else if ( inv == config && locked == false )
{
IInventory c = getCellConfigInventory();
if ( c != null )
{
for (int x = 0; x < config.getSizeInventory(); x++)
c.setInventorySlotContents( x, config.getStackInSlot( x ) );
c.markDirty();
}
}
}
@Override
public void getDrops(World w, int x, int y, int z, ArrayList<ItemStack> drops)
{
super.getDrops( w, x, y, z, drops );
if ( cell.getStackInSlot( 0 ) != null )
drops.add( cell.getStackInSlot( 0 ) );
}
public ICellWorkbenchItem getCell()
{
if ( cell.getStackInSlot( 0 ) == null )
return null;
if ( cell.getStackInSlot( 0 ).getItem() instanceof ICellWorkbenchItem )
return ((ICellWorkbenchItem) cell.getStackInSlot( 0 ).getItem());
return null;
}
@Override
public IConfigManager getConfigManager()
{
return cm;
}
@Override
public void updateSetting(IConfigManager manager, Enum settingName, Enum newValue)
{
// nothing here..
}
}
@@ -0,0 +1,245 @@
package appeng.tile.misc;
import io.netty.buffer.ByteBuf;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.config.PowerUnits;
import appeng.api.implementations.items.IAEItemPowerStorage;
import appeng.api.implementations.tiles.ICrankable;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.AECableType;
import appeng.api.util.DimensionalCoord;
import appeng.me.GridAccessException;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkPowerTile;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
public class TileCharger extends AENetworkPowerTile implements ICrankable
{
final int sides[] = new int[] { 0 };
AppEngInternalInventory inv = new AppEngInternalInventory( this, 1 );
int tickTickTimer = 0;
int lastUpdate = 0;
boolean requiresUpdate = false;
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
return AECableType.COVERED;
}
@TileEvent(TileEventType.NETWORK_READ)
public boolean readFromStream_TileCharger(ByteBuf data) throws IOException
{
try
{
IAEItemStack item = AEItemStack.loadItemStackFromPacket( data );
ItemStack is = item.getItemStack();
inv.setInventorySlotContents( 0, is );
}
catch (Throwable t)
{
inv.setInventorySlotContents( 0, null );
}
return false; // TESR doesn't need updates!
}
@TileEvent(TileEventType.NETWORK_WRITE)
public void writeToStream_TileCharger(ByteBuf data) throws IOException
{
AEItemStack is = AEItemStack.create( getStackInSlot( 0 ) );
if ( is != null )
is.writeToPacket( data );
}
@TileEvent(TileEventType.TICK)
public void Tick_TileCharger()
{
if ( lastUpdate > 60 && requiresUpdate )
{
requiresUpdate = false;
markForUpdate();
lastUpdate = 0;
}
lastUpdate++;
tickTickTimer++;
if ( tickTickTimer < 20 )
return;
tickTickTimer = 0;
ItemStack myItem = getStackInSlot( 0 );
// charge from the network!
if ( internalCurrentPower < 1499 )
{
try
{
injectExternalPower( PowerUnits.AE,
gridProxy.getEnergy().extractAEPower( Math.min( 150.0, 1500.0 - internalCurrentPower ), Actionable.MODULATE, PowerMultiplier.ONE ) );
tickTickTimer = 20; // keep ticking...
}
catch (GridAccessException e)
{
// continue!
}
}
if ( myItem == null )
return;
if ( internalCurrentPower > 149 && Platform.isChargeable( myItem ) )
{
IAEItemPowerStorage ps = (IAEItemPowerStorage) myItem.getItem();
if ( ps.getAEMaxPower( myItem ) > ps.getAECurrentPower( myItem ) )
{
double oldPower = internalCurrentPower;
double adjustment = ps.injectAEPower( myItem, extractAEPower( 150.0, Actionable.MODULATE, PowerMultiplier.CONFIG ) );
internalCurrentPower += adjustment;
if ( oldPower > internalCurrentPower )
requiresUpdate = true;
tickTickTimer = 20; // keep ticking...
}
}
else if ( internalCurrentPower > 1499 && AEApi.instance().materials().materialCertusQuartzCrystal.sameAsStack( myItem ) )
{
if ( Platform.getRandomFloat() > 0.8f ) // simulate wait
{
extractAEPower( internalMaxPower, Actionable.MODULATE, PowerMultiplier.CONFIG );// 1500
setInventorySlotContents( 0, AEApi.instance().materials().materialCertusQuartzCrystalCharged.stack( myItem.stackSize ) );
}
}
}
public TileCharger() {
gridProxy.setValidSides( EnumSet.noneOf( ForgeDirection.class ) );
gridProxy.setFlags();
internalMaxPower = 1500;
gridProxy.setIdlePowerUsage( 0 );
}
@Override
public void setOrientation(ForgeDirection inForward, ForgeDirection inUp)
{
super.setOrientation( inForward, inUp );
gridProxy.setValidSides( EnumSet.of( getUp(), getUp().getOpposite() ) );
setPowerSides( EnumSet.of( getUp(), getUp().getOpposite() ) );
}
@Override
public boolean canTurn()
{
return internalCurrentPower < internalMaxPower;
}
@Override
public void applyTurn()
{
injectExternalPower( PowerUnits.AE, 150 );
ItemStack myItem = getStackInSlot( 0 );
if ( internalCurrentPower > 1499 && AEApi.instance().materials().materialCertusQuartzCrystal.sameAsStack( myItem ) )
{
extractAEPower( internalMaxPower, Actionable.MODULATE, PowerMultiplier.CONFIG );// 1500
setInventorySlotContents( 0, AEApi.instance().materials().materialCertusQuartzCrystalCharged.stack( myItem.stackSize ) );
}
}
@Override
public boolean canCrankAttach(ForgeDirection directionToCrank)
{
return getUp().equals( directionToCrank ) || getUp().getOpposite().equals( directionToCrank );
}
@Override
public IInventory getInternalInventory()
{
return inv;
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removed, ItemStack added)
{
markForUpdate();
}
@Override
public int[] getAccessibleSlotsBySide(ForgeDirection whichSide)
{
return sides;
}
@Override
public int getInventoryStackLimit()
{
return 1;
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack)
{
return Platform.isChargeable( itemstack ) || AEApi.instance().materials().materialCertusQuartzCrystal.sameAsStack( itemstack );
}
@Override
public boolean canExtractItem(int i, ItemStack itemstack, int j)
{
if ( Platform.isChargeable( itemstack ) )
{
IAEItemPowerStorage ips = (IAEItemPowerStorage) itemstack.getItem();
if ( ips.getAECurrentPower( itemstack ) >= ips.getAEMaxPower( itemstack ) )
return true;
}
return AEApi.instance().materials().materialCertusQuartzCrystalCharged.sameAsStack( itemstack );
}
public void activate(EntityPlayer player)
{
if ( !Platform.hasPermissions( new DimensionalCoord( this ), player ) )
return;
ItemStack myItem = getStackInSlot( 0 );
if ( myItem == null )
{
ItemStack held = player.inventory.getCurrentItem();
if ( AEApi.instance().materials().materialCertusQuartzCrystal.sameAsStack( held ) || Platform.isChargeable( held ) )
{
held = player.inventory.decrStackSize( player.inventory.currentItem, 1 );
setInventorySlotContents( 0, held );
}
}
else
{
List<ItemStack> drops = new ArrayList();
drops.add( myItem );
setInventorySlotContents( 0, null );
Platform.spawnDrops( worldObj, xCoord + getForward().offsetX, yCoord + getForward().offsetY, zCoord + getForward().offsetZ, drops );
}
}
@Override
public boolean requiresTESR()
{
return true;
}
}
@@ -0,0 +1,241 @@
package appeng.tile.misc;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
import appeng.api.AEApi;
import appeng.api.config.CondenserOutput;
import appeng.api.config.Settings;
import appeng.api.implementations.items.IStorageComponent;
import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject;
import appeng.tile.AEBaseInvTile;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.IAEAppEngInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost;
import appeng.util.Platform;
public class TileCondenser extends AEBaseInvTile implements IAEAppEngInventory, IFluidHandler, IConfigManagerHost, IConfigurableObject
{
int sides[] = new int[] { 0, 1 };
static private FluidTankInfo[] empty = new FluidTankInfo[] { new FluidTankInfo( null, 10 ) };
AppEngInternalInventory inv = new AppEngInternalInventory( this, 3 );
ConfigManager cm = new ConfigManager( this );
public double storedPower = 0;
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_TileCondenser(NBTTagCompound data)
{
cm.writeToNBT( data );
data.setDouble( "storedPower", storedPower );
}
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_TileCondenser(NBTTagCompound data)
{
cm.readFromNBT( data );
storedPower = data.getDouble( "storedPower" );
}
public TileCondenser() {
cm.registerSetting( Settings.CONDENSER_OUTPUT, CondenserOutput.TRASH );
}
public double getStorage()
{
ItemStack is = inv.getStackInSlot( 2 );
if ( is != null )
{
if ( is.getItem() instanceof IStorageComponent )
{
IStorageComponent sc = (IStorageComponent) is.getItem();
if ( sc.isStorageComponent( is ) )
return sc.getBytes( is ) * 8;
}
}
return 0;
}
public void addPower(double rawPower)
{
storedPower += rawPower;
storedPower = Math.max( 0.0, Math.min( getStorage(), storedPower ) );
double requiredPower = getRequiredPower();
ItemStack output = getOutput();
while (requiredPower <= storedPower && output != null && requiredPower > 0)
{
if ( canAddOutput( output ) )
{
storedPower -= requiredPower;
addOutput( output );
}
else
break;
}
}
private boolean canAddOutput(ItemStack output)
{
ItemStack outputStack = getStackInSlot( 1 );
return outputStack == null || (Platform.isSameItem( outputStack, output ) && outputStack.stackSize < outputStack.getMaxStackSize());
}
/**
* make sure you validate with canAddOutput prior to this.
*
* @param output
*/
private void addOutput(ItemStack output)
{
ItemStack outputStack = getStackInSlot( 1 );
if ( outputStack == null )
setInventorySlotContents( 1, output.copy() );
else
{
outputStack.stackSize++;
setInventorySlotContents( 1, outputStack );
}
}
private ItemStack getOutput()
{
switch ((CondenserOutput) cm.getSetting( Settings.CONDENSER_OUTPUT ))
{
case MATTER_BALLS:
return AEApi.instance().materials().materialMatterBall.stack( 1 );
case SINGULARITY:
return AEApi.instance().materials().materialSingularity.stack( 1 );
case TRASH:
default:
}
return null;
}
public double getRequiredPower()
{
return ((CondenserOutput) cm.getSetting( Settings.CONDENSER_OUTPUT )).requiredPower;
}
@Override
public void setInventorySlotContents(int i, ItemStack itemstack)
{
if ( i == 0 )
{
if ( itemstack != null )
addPower( itemstack.stackSize );
}
else
{
inv.setInventorySlotContents( 1, itemstack );
}
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack)
{
return i == 0;
}
@Override
public boolean canExtractItem(int i, ItemStack itemstack, int j)
{
return i != 0;
}
@Override
public boolean canInsertItem(int i, ItemStack itemstack, int j)
{
return i == 0;
}
@Override
public int[] getAccessibleSlotsBySide(ForgeDirection side)
{
return sides;
}
@Override
public IInventory getInternalInventory()
{
return inv;
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removed, ItemStack added)
{
if ( slot == 0 )
{
ItemStack is = inv.getStackInSlot( 0 );
if ( is != null )
{
addPower( is.stackSize );
inv.setInventorySlotContents( 0, null );
}
}
}
@Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
{
if ( doFill )
addPower( (resource == null ? 0.0 : (double) resource.amount) / 500.0 );
return resource == null ? 0 : resource.amount;
}
@Override
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
{
return null;
}
@Override
public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
{
return null;
}
@Override
public boolean canFill(ForgeDirection from, Fluid fluid)
{
return true;
}
@Override
public boolean canDrain(ForgeDirection from, Fluid fluid)
{
return false;
}
@Override
public FluidTankInfo[] getTankInfo(ForgeDirection from)
{
return empty;
}
@Override
public void updateSetting(IConfigManager manager, Enum settingName, Enum newValue)
{
addPower( 0 );
}
@Override
public IConfigManager getConfigManager()
{
return cm;
}
}
@@ -0,0 +1,400 @@
package appeng.tile.misc;
import io.netty.buffer.ByteBuf;
import java.io.IOException;
import java.util.EnumSet;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.networking.IGridNode;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.energy.IEnergySource;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.util.AECableType;
import appeng.core.settings.TickRates;
import appeng.me.GridAccessException;
import appeng.recipes.handlers.Inscribe;
import appeng.recipes.handlers.Inscribe.InscriberRecipe;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkPowerTile;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.inv.WrapperInventoryRange;
import appeng.util.item.AEItemStack;
public class TileInscriber extends AENetworkPowerTile implements IGridTickable
{
final int top[] = new int[] { 0 };
final int bottom[] = new int[] { 1 };
final int sides[] = new int[] { 2, 3 };
AppEngInternalInventory inv = new AppEngInternalInventory( this, 4 );
public final int maxProcessingTime = 100;
public int processingTime = 0;
// cycles from 0 - 16, at 8 it preforms the action, at 16 it re-enables the normal routine.
public boolean smash;
public int finalStep;
public long clientStart;
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
return AECableType.COVERED;
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_TileInscriber(NBTTagCompound data)
{
inv.writeToNBT( data, "inscriberInv" );
}
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_TileInscriber(NBTTagCompound data)
{
inv.readFromNBT( data, "inscriberInv" );
}
@TileEvent(TileEventType.NETWORK_READ)
public boolean readFromStream_TileInscriber(ByteBuf data) throws IOException
{
int slot = data.readByte();
boolean oldSmash = smash;
boolean newSmash = (slot & 64) == 64;
if ( oldSmash != newSmash && newSmash )
{
smash = true;
clientStart = System.currentTimeMillis();
}
for (int num = 0; num < inv.getSizeInventory(); num++)
{
if ( (slot & (1 << num)) > 0 )
inv.setInventorySlotContents( num, AEItemStack.loadItemStackFromPacket( data ).getItemStack() );
else
inv.setInventorySlotContents( num, null );
}
return false;
}
@TileEvent(TileEventType.NETWORK_WRITE)
public void writeToStream_TileInscriber(ByteBuf data) throws IOException
{
int slot = smash ? 64 : 0;
for (int num = 0; num < inv.getSizeInventory(); num++)
{
if ( inv.getStackInSlot( num ) != null )
slot = slot | (1 << num);
}
data.writeByte( slot );
for (int num = 0; num < inv.getSizeInventory(); num++)
{
if ( (slot & (1 << num)) > 0 )
{
AEItemStack st = AEItemStack.create( inv.getStackInSlot( num ) );
st.writeToPacket( data );
}
}
}
@Override
public boolean requiresTESR()
{
return true;
}
public TileInscriber() {
gridProxy.setValidSides( EnumSet.noneOf( ForgeDirection.class ) );
internalMaxPower = 1500;
gridProxy.setIdlePowerUsage( 0 );
}
@Override
public void setOrientation(ForgeDirection inForward, ForgeDirection inUp)
{
super.setOrientation( inForward, inUp );
gridProxy.setValidSides( EnumSet.complementOf( EnumSet.of( getForward() ) ) );
setPowerSides( EnumSet.complementOf( EnumSet.of( getForward() ) ) );
}
@Override
public IInventory getInternalInventory()
{
return inv;
}
@Override
public int[] getAccessibleSlotsBySide(ForgeDirection d)
{
if ( d == ForgeDirection.UP )
return top;
if ( d == ForgeDirection.DOWN )
return bottom;
return sides;
}
@Override
public int getInventoryStackLimit()
{
return 1;
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack)
{
if ( smash )
return false;
if ( i == 0 || i == 1 )
{
if ( AEApi.instance().materials().materialNamePress.sameAsStack( itemstack ) )
return true;
for (ItemStack s : Inscribe.plates)
if ( Platform.isSameItemPrecise( s, itemstack ) )
return true;
}
if ( i == 2 )
{
return true;
// for (ItemStack s : Inscribe.inputs)
// if ( Platform.isSameItemPrecise( s, itemstack ) )
// return true;
}
return false;
}
@Override
public boolean canExtractItem(int i, ItemStack itemstack, int j)
{
if ( smash )
return false;
return i == 0 || i == 1 || i == 3;
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removed, ItemStack added)
{
try
{
if ( mc != InvOperation.markDirty )
{
if ( slot != 3 )
processingTime = 0;
if ( !smash )
markForUpdate();
gridProxy.getTick().wakeDevice( gridProxy.getNode() );
}
}
catch (GridAccessException e)
{
// :P
}
}
public InscriberRecipe getTask()
{
ItemStack PlateA = getStackInSlot( 0 );
ItemStack PlateB = getStackInSlot( 1 );
ItemStack renamedItem = getStackInSlot( 2 );
if ( PlateA != null && PlateA.stackSize > 1 )
return null;
if ( PlateB != null && PlateB.stackSize > 1 )
return null;
if ( renamedItem != null && renamedItem.stackSize > 1 )
return null;
boolean isNameA = AEApi.instance().materials().materialNamePress.sameAsStack( PlateA );
boolean isNameB = AEApi.instance().materials().materialNamePress.sameAsStack( PlateB );
if ( (isNameA || isNameB) && (isNameA || PlateA == null) && (isNameB || PlateB == null) )
{
if ( renamedItem != null )
{
String name = "";
if ( PlateA != null )
{
NBTTagCompound tag = Platform.openNbtData( PlateA );
name += tag.getString( "InscribeName" );
}
if ( PlateB != null )
{
NBTTagCompound tag = Platform.openNbtData( PlateB );
if ( name.length() > 0 )
name += " ";
name += tag.getString( "InscribeName" );
}
ItemStack startingItem = renamedItem.copy();
renamedItem = renamedItem.copy();
NBTTagCompound tag = Platform.openNbtData( renamedItem );
NBTTagCompound display = tag.getCompoundTag( "display" );
tag.setTag( "display", display );
if ( name.length() > 0 )
display.setString( "Name", name );
else
display.removeTag( "Name" );
return new InscriberRecipe( new ItemStack[] { startingItem }, PlateA, PlateB, renamedItem, false );
}
}
for (InscriberRecipe i : Inscribe.recipes)
{
boolean matchA = (PlateA == null && i.plateA == null) || (Platform.isSameItemPrecise( PlateA, i.plateA )) && // and...
(PlateB == null && i.plateB == null) | (Platform.isSameItemPrecise( PlateB, i.plateB ));
boolean matchB = (PlateB == null && i.plateA == null) || (Platform.isSameItemPrecise( PlateB, i.plateA )) && // and...
(PlateA == null && i.plateB == null) | (Platform.isSameItemPrecise( PlateA, i.plateB ));
if ( matchA || matchB )
{
for (ItemStack option : i.imprintable)
{
if ( Platform.isSameItemPrecise( option, getStackInSlot( 2 ) ) )
return i;
}
}
}
return null;
}
private boolean hasWork()
{
if ( getTask() != null )
return true;
processingTime = 0;
return false || smash;
}
@Override
public TickingRequest getTickingRequest(IGridNode node)
{
return new TickingRequest( TickRates.Inscriber.min, TickRates.Inscriber.max, !hasWork(), false );
}
@Override
public TickRateModulation tickingRequest(IGridNode node, int TicksSinceLastCall)
{
if ( smash )
{
finalStep++;
if ( finalStep == 8 )
{
InscriberRecipe out = getTask();
if ( out != null )
{
ItemStack is = out.output.copy();
InventoryAdaptor ad = InventoryAdaptor.getAdaptor( new WrapperInventoryRange( inv, 3, 1, true ), ForgeDirection.UNKNOWN );
if ( ad.addItems( is ) == null )
{
processingTime = 0;
if ( out.usePlates )
{
setInventorySlotContents( 0, null );
setInventorySlotContents( 1, null );
}
setInventorySlotContents( 2, null );
}
}
markDirty();
}
else if ( finalStep == 16 )
{
finalStep = 0;
smash = false;
markForUpdate();
}
}
else
{
IEnergyGrid eg;
try
{
eg = gridProxy.getEnergy();
IEnergySource src = this;
double powerReq = extractAEPower( 10, Actionable.SIMULATE, PowerMultiplier.CONFIG );
if ( powerReq <= 9.99 )
{
src = eg;
powerReq = eg.extractAEPower( 10, Actionable.SIMULATE, PowerMultiplier.CONFIG );
}
if ( powerReq > 9.99 )
{
src.extractAEPower( 10, Actionable.MODULATE, PowerMultiplier.CONFIG );
if ( processingTime == 0 )
processingTime++;
else
processingTime += TicksSinceLastCall;
}
}
catch (GridAccessException e)
{
// :P
}
if ( processingTime > maxProcessingTime )
{
processingTime = maxProcessingTime;
InscriberRecipe out = getTask();
if ( out != null )
{
ItemStack is = out.output.copy();
InventoryAdaptor ad = InventoryAdaptor.getAdaptor( new WrapperInventoryRange( inv, 3, 1, true ), ForgeDirection.UNKNOWN );
if ( ad.simulateAdd( is ) == null )
{
smash = true;
finalStep = 0;
markForUpdate();
}
}
}
}
return hasWork() ? TickRateModulation.URGENT : TickRateModulation.SLEEP;
}
}
@@ -0,0 +1,288 @@
package appeng.tile.misc;
import java.util.ArrayList;
import java.util.EnumSet;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.config.Actionable;
import appeng.api.config.Upgrades;
import appeng.api.implementations.tiles.ISegmentedInventory;
import appeng.api.implementations.tiles.ITileStorageMonitorable;
import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.ICraftingLink;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.networking.crafting.ICraftingProviderHelper;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.IStorageMonitorable;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.AECableType;
import appeng.api.util.DimensionalCoord;
import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject;
import appeng.helpers.DualityInterface;
import appeng.helpers.IInterfaceHost;
import appeng.helpers.IPriorityHost;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkInvTile;
import appeng.tile.inventory.InvOperation;
import appeng.util.Platform;
import appeng.util.inv.IInventoryDestination;
import com.google.common.collect.ImmutableSet;
public class TileInterface extends AENetworkInvTile implements IGridTickable, ISegmentedInventory, ITileStorageMonitorable, IStorageMonitorable,
IInventoryDestination, IInterfaceHost, IConfigurableObject, IPriorityHost
{
ForgeDirection pointAt = ForgeDirection.UNKNOWN;
DualityInterface duality = new DualityInterface( gridProxy, this );
@MENetworkEventSubscribe
public void stateChange(MENetworkChannelsChanged c)
{
duality.notifyNeightbors();
}
@MENetworkEventSubscribe
public void stateChange(MENetworkPowerStatusChange c)
{
duality.notifyNeightbors();
}
public void setSide(ForgeDirection axis)
{
if ( Platform.isClient() )
return;
if ( pointAt == axis.getOpposite() )
pointAt = axis;
else if ( pointAt == axis || pointAt == axis.getOpposite() )
pointAt = ForgeDirection.UNKNOWN;
else if ( pointAt == ForgeDirection.UNKNOWN )
pointAt = axis.getOpposite();
else
pointAt = Platform.rotateAround( pointAt, axis );
if ( ForgeDirection.UNKNOWN == pointAt )
setOrientation( pointAt, pointAt );
else
setOrientation( pointAt.offsetY != 0 ? ForgeDirection.SOUTH : ForgeDirection.UP, pointAt.getOpposite() );
gridProxy.setValidSides( EnumSet.complementOf( EnumSet.of( pointAt ) ) );
markForUpdate();
markDirty();
}
@Override
public void getDrops(World w, int x, int y, int z, ArrayList<ItemStack> drops)
{
duality.addDrops( drops );
}
@Override
public void gridChanged()
{
duality.gridChanged();
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_TileInterface(NBTTagCompound data)
{
data.setInteger( "pointAt", pointAt.ordinal() );
duality.writeToNBT( data );
}
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_TileInterface(NBTTagCompound data)
{
int val = data.getInteger( "pointAt" );
if ( val >= 0 && val < ForgeDirection.values().length )
pointAt = ForgeDirection.values()[val];
else
pointAt = ForgeDirection.UNKNOWN;
duality.readFromNBT( data );
}
@Override
public void onReady()
{
gridProxy.setValidSides( EnumSet.complementOf( EnumSet.of( pointAt ) ) );
super.onReady();
duality.initialize();
}
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
return duality.getCableConnectionType( dir );
}
@Override
public DimensionalCoord getLocation()
{
return duality.getLocation();
}
@Override
public TileEntity getTileEntity()
{
return this;
}
@Override
public boolean canInsert(ItemStack stack)
{
return duality.canInsert( stack );
}
@Override
public IMEMonitor<IAEItemStack> getItemInventory()
{
return duality.getItemInventory();
}
@Override
public IMEMonitor<IAEFluidStack> getFluidInventory()
{
return duality.getFluidInventory();
}
@Override
public IInventory getInventoryByName(String name)
{
return duality.getInventoryByName( name );
}
@Override
public TickingRequest getTickingRequest(IGridNode node)
{
return duality.getTickingRequest( node );
}
@Override
public TickRateModulation tickingRequest(IGridNode node, int TicksSinceLastCall)
{
return duality.tickingRequest( node, TicksSinceLastCall );
}
@Override
public IInventory getInternalInventory()
{
return duality.getInternalInventory();
}
@Override
public void markDirty()
{
duality.markDirty();
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removed, ItemStack added)
{
duality.onChangeInventory( inv, slot, mc, removed, added );
}
@Override
public int[] getAccessibleSlotsBySide(ForgeDirection side)
{
return duality.getAccessibleSlotsFromSide( side.ordinal() );
}
@Override
public DualityInterface getInterfaceDuality()
{
return duality;
}
@Override
public IStorageMonitorable getMonitorable(ForgeDirection side, BaseActionSource src)
{
return duality.getMonitorable( side, src, this );
}
@Override
public IConfigManager getConfigManager()
{
return duality.getConfigManager();
}
@Override
public boolean pushPattern(ICraftingPatternDetails patternDetails, InventoryCrafting table)
{
return duality.pushPattern( patternDetails, table );
}
@Override
public void provideCrafting(ICraftingProviderHelper craftingTracker)
{
duality.provideCrafting( craftingTracker );
}
@Override
public EnumSet<ForgeDirection> getTargets()
{
if ( pointAt == null || pointAt == ForgeDirection.UNKNOWN )
return EnumSet.complementOf( EnumSet.of( ForgeDirection.UNKNOWN ) );
return EnumSet.of( pointAt );
}
@Override
public boolean isBusy()
{
return duality.isBusy();
}
@Override
public int getInstalledUpgrades(Upgrades u)
{
return duality.getInstalledUpgrades( u );
}
@Override
public ImmutableSet<ICraftingLink> getRequestedJobs()
{
return duality.getRequestedJobs();
}
@Override
public IAEItemStack injectCraftedItems(ICraftingLink link, IAEItemStack items, Actionable mode)
{
return duality.injectCraftedItems( link, items, mode );
}
@Override
public void jobStateChange(ICraftingLink link)
{
duality.jobStateChange( link );
}
@Override
public int getPriority()
{
return duality.getPriority();
}
@Override
public void setPriority(int newValue)
{
duality.setPriority( newValue );
}
}
@@ -0,0 +1,47 @@
package appeng.tile.misc;
import appeng.tile.AEBaseTile;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.util.Platform;
public class TileLightDetector extends AEBaseTile
{
int lastCheck = 30;
int lastLight = 0;
public boolean isReady()
{
return lastLight > 0;
}
@TileEvent(TileEventType.TICK)
public void Tick_TileLightDetector()
{
lastCheck++;
if ( lastCheck > 30 )
{
lastCheck = 0;
updateLight();
}
}
public void updateLight()
{
int val = worldObj.getBlockLightValue( xCoord, yCoord, zCoord );
if ( lastLight != val )
{
lastLight = val;
Platform.notifyBlocksOfNeighbors( worldObj, xCoord, yCoord, zCoord );
}
}
@Override
public boolean canBeRotated()
{
return false;
}
}
@@ -0,0 +1,216 @@
package appeng.tile.misc;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.Vec3;
import net.minecraft.world.EnumSkyBlock;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.util.AEColor;
import appeng.helpers.Splot;
import appeng.items.misc.ItemPaintBall;
import appeng.tile.AEBaseTile;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import com.google.common.collect.ImmutableList;
public class TilePaint extends AEBaseTile
{
static final int LIGHT_PER_DOT = 12;
int isLit = 0;
ArrayList<Splot> dots = null;
void writeBuffer(ByteBuf out)
{
if ( dots == null )
{
out.writeByte( 0 );
return;
}
out.writeByte( dots.size() );
for (Splot s : dots)
s.writeToStream( out );
}
void readBuffer(ByteBuf in)
{
byte howMany = in.readByte();
if ( howMany == 0 )
{
isLit = 0;
dots = null;
return;
}
dots = new ArrayList( howMany );
for (int x = 0; x < howMany; x++)
dots.add( new Splot( in ) );
isLit = 0;
for (Splot s : dots)
{
if ( s.lumen )
{
isLit += LIGHT_PER_DOT;
}
}
maxLit();
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_TilePaint(NBTTagCompound data)
{
ByteBuf myDat = Unpooled.buffer();
writeBuffer( myDat );
if ( myDat.hasArray() )
data.setByteArray( "dots", myDat.array() );
}
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_TilePaint(NBTTagCompound data)
{
if ( data.hasKey( "dots" ) )
readBuffer( Unpooled.copiedBuffer( data.getByteArray( "dots" ) ) );
}
@TileEvent(TileEventType.NETWORK_WRITE)
public void writeToStream_TilePaint(ByteBuf data) throws IOException
{
writeBuffer( data );
}
@TileEvent(TileEventType.NETWORK_READ)
public boolean readFromStream_TilePaint(ByteBuf data) throws IOException
{
readBuffer( data );
return true;
}
public void onNeighborBlockChange()
{
if ( dots == null )
return;
for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS)
{
if ( !isSideValid( side ) )
removeSide( side );
}
updateData();
}
private void updateData()
{
isLit = 0;
for (Splot s : dots)
{
if ( s.lumen )
{
isLit += LIGHT_PER_DOT;
}
}
maxLit();
if ( dots.isEmpty() )
dots = null;
if ( dots == null )
worldObj.setBlock( xCoord, yCoord, zCoord, Blocks.air );
}
public void cleanSide(ForgeDirection side)
{
if ( dots == null )
return;
removeSide( side );
updateData();
}
public boolean isSideValid(ForgeDirection side)
{
Block blk = worldObj.getBlock( xCoord + side.offsetX, yCoord + side.offsetY, zCoord + side.offsetZ );
return blk.isSideSolid( worldObj, xCoord + side.offsetX, yCoord + side.offsetY, zCoord + side.offsetZ, side.getOpposite() );
}
private void removeSide(ForgeDirection side)
{
Iterator<Splot> i = dots.iterator();
while (i.hasNext())
{
Splot s = i.next();
if ( s.side == side )
i.remove();
}
markForUpdate();
markDirty();
}
public int getLightLevel()
{
return isLit;
}
public void addBlot(ItemStack type, ForgeDirection side, Vec3 hitVec)
{
Block blk = worldObj.getBlock( xCoord + side.offsetX, yCoord + side.offsetY, zCoord + side.offsetZ );
if ( blk.isSideSolid( worldObj, xCoord + side.offsetX, yCoord + side.offsetY, zCoord + side.offsetZ, side.getOpposite() ) )
{
ItemPaintBall ipb = (ItemPaintBall) type.getItem();
AEColor col = ipb.getColor( type );
boolean lit = ipb.isLumen( type );
if ( dots == null )
dots = new ArrayList();
if ( dots.size() > 20 )
dots.remove( 0 );
dots.add( new Splot( col, lit, side, hitVec ) );
if ( lit )
isLit += LIGHT_PER_DOT;
maxLit();
markForUpdate();
markDirty();
}
}
private void maxLit()
{
if ( isLit > 14 )
isLit = 14;
if ( worldObj != null )
worldObj.updateLightByType( EnumSkyBlock.Block, xCoord, yCoord, zCoord );
}
public Collection<Splot> getDots()
{
if ( dots == null )
return ImmutableList.of();
return dots;
}
}
@@ -0,0 +1,95 @@
package appeng.tile.misc;
import io.netty.buffer.ByteBuf;
import java.io.IOException;
import java.util.EnumSet;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.implementations.IPowerChannelState;
import appeng.api.implementations.tiles.ICrystalGrowthAccelerator;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.util.AECableType;
import appeng.me.GridAccessException;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkTile;
import appeng.util.Platform;
public class TileQuartzGrowthAccelerator extends AENetworkTile implements IPowerChannelState, ICrystalGrowthAccelerator
{
public boolean hasPower = false;
@MENetworkEventSubscribe
public void onPower(MENetworkPowerStatusChange ch)
{
markForUpdate();
}
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
return AECableType.COVERED;
}
@TileEvent(TileEventType.NETWORK_READ)
public boolean readFromStream_TileQuartzGrowthAccelerator(ByteBuf data) throws IOException
{
boolean hadPower = hasPower;
hasPower = data.readBoolean();
return hasPower != hadPower;
}
@TileEvent(TileEventType.NETWORK_WRITE)
public void writeToStream_TileQuartzGrowthAccelerator(ByteBuf data) throws IOException
{
try
{
data.writeBoolean( gridProxy.getEnergy().isNetworkPowered() );
}
catch (GridAccessException e)
{
data.writeBoolean( false );
}
}
public TileQuartzGrowthAccelerator() {
gridProxy.setValidSides( EnumSet.noneOf( ForgeDirection.class ) );
gridProxy.setFlags();
gridProxy.setIdlePowerUsage( 8 );
}
@Override
public void setOrientation(ForgeDirection inForward, ForgeDirection inUp)
{
super.setOrientation( inForward, inUp );
gridProxy.setValidSides( EnumSet.of( getUp(), getUp().getOpposite() ) );
}
@Override
public boolean isPowered()
{
if ( Platform.isServer() )
{
try
{
return gridProxy.getEnergy().isNetworkPowered();
}
catch (GridAccessException e)
{
return false;
}
}
return hasPower;
}
@Override
public boolean isActive()
{
return isPowered();
}
}
@@ -0,0 +1,331 @@
package appeng.tile.misc;
import appeng.helpers.PlayerSecurityWrapper;
import io.netty.buffer.ByteBuf;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.AEApi;
import appeng.api.config.SecurityPermissions;
import appeng.api.config.Settings;
import appeng.api.config.SortDir;
import appeng.api.config.SortOrder;
import appeng.api.config.ViewItems;
import appeng.api.events.LocatableEventAnnounce;
import appeng.api.events.LocatableEventAnnounce.LocatableEvent;
import appeng.api.features.ILocatable;
import appeng.api.features.IPlayerRegistry;
import appeng.api.implementations.items.IBiometricCard;
import appeng.api.implementations.tiles.IColorableTile;
import appeng.api.networking.GridFlags;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.events.MENetworkSecurityChange;
import appeng.api.networking.security.ISecurityProvider;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.ITerminalHost;
import appeng.api.storage.MEMonitorHandler;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.AECableType;
import appeng.api.util.AEColor;
import appeng.api.util.DimensionalCoord;
import appeng.api.util.IConfigManager;
import appeng.me.GridAccessException;
import appeng.me.storage.SecurityInventory;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkTile;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.IAEAppEngInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
public class TileSecurity extends AENetworkTile implements ITerminalHost, IAEAppEngInventory, ILocatable, IConfigManagerHost, ISecurityProvider, IColorableTile
{
private static int difference = 0;
private IConfigManager cm = new ConfigManager( this );
private SecurityInventory inventory = new SecurityInventory( this );
private MEMonitorHandler<IAEItemStack> securityMonitor = new MEMonitorHandler<IAEItemStack>( inventory );
private boolean isActive = false;
AEColor paintedColor = AEColor.Transparent;
public long securityKey;
public AppEngInternalInventory configSlot = new AppEngInternalInventory( this, 1 );
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack)
{
}
@Override
public void getDrops(World w, int x, int y, int z, ArrayList<ItemStack> drops)
{
if ( !configSlot.isEmpty() )
drops.add( configSlot.getStackInSlot( 0 ) );
for (IAEItemStack ais : inventory.storedItems)
drops.add( ais.getItemStack() );
}
IMEInventoryHandler<IAEItemStack> getSecurityInventory()
{
return inventory;
}
@Override
public void onReady()
{
super.onReady();
if ( Platform.isServer() )
{
isActive = true;
MinecraftForge.EVENT_BUS.post( new LocatableEventAnnounce( this, LocatableEvent.Register ) );
}
}
@Override
public void onChunkUnload()
{
super.onChunkUnload();
MinecraftForge.EVENT_BUS.post( new LocatableEventAnnounce( this, LocatableEvent.Unregister ) );
isActive = false;
}
@Override
public void invalidate()
{
super.invalidate();
MinecraftForge.EVENT_BUS.post( new LocatableEventAnnounce( this, LocatableEvent.Unregister ) );
isActive = false;
}
@TileEvent(TileEventType.NETWORK_READ)
public boolean readFromStream_TileSecurity(ByteBuf data) throws IOException
{
boolean wasActive = isActive;
isActive = data.readBoolean();
AEColor oldPaintedColor = paintedColor;
paintedColor = AEColor.values()[data.readByte()];
return oldPaintedColor != paintedColor || wasActive != isActive;
}
@TileEvent(TileEventType.NETWORK_WRITE)
public void writeToStream_TileSecurity(ByteBuf data) throws IOException
{
data.writeBoolean( gridProxy.isActive() );
data.writeByte( paintedColor.ordinal() );
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_TileSecurity(NBTTagCompound data)
{
cm.writeToNBT( data );
data.setByte( "paintedColor", (byte) paintedColor.ordinal() );
data.setLong( "securityKey", securityKey );
configSlot.writeToNBT( data, "config" );
NBTTagCompound storedItems = new NBTTagCompound();
int offset = 0;
for (IAEItemStack ais : inventory.storedItems)
{
NBTTagCompound it = new NBTTagCompound();
ais.getItemStack().writeToNBT( it );
storedItems.setTag( "" + (offset++), it );
}
data.setTag( "storedItems", storedItems );
}
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_TileSecurity(NBTTagCompound data)
{
cm.readFromNBT( data );
if ( data.hasKey( "paintedColor" ) )
paintedColor = AEColor.values()[data.getByte( "paintedColor" )];
securityKey = data.getLong( "securityKey" );
configSlot.readFromNBT( data, "config" );
NBTTagCompound storedItems = data.getCompoundTag( "storedItems" );
for (Object key : storedItems.func_150296_c())
{
NBTBase obj = storedItems.getTag( (String) key );
if ( obj instanceof NBTTagCompound )
{
inventory.storedItems.add( AEItemStack.create( ItemStack.loadItemStackFromNBT( (NBTTagCompound) obj ) ) );
}
}
}
public void inventoryChanged()
{
try
{
saveChanges();
gridProxy.getGrid().postEvent( new MENetworkSecurityChange() );
}
catch (GridAccessException e)
{
// :P
}
}
public void readPermissions(HashMap<Integer, EnumSet<SecurityPermissions>> playerPerms)
{
IPlayerRegistry pr = AEApi.instance().registries().players();
// read permissions
for (IAEItemStack ais : inventory.storedItems)
{
ItemStack is = ais.getItemStack();
Item i = is.getItem();
if ( i instanceof IBiometricCard )
{
IBiometricCard bc = (IBiometricCard) i;
bc.registerPermissions( new PlayerSecurityWrapper( playerPerms ), pr, is );
}
}
// make sure thea admin is Boss.
playerPerms.put( gridProxy.getNode().getPlayerID(), EnumSet.allOf( SecurityPermissions.class ) );
}
@MENetworkEventSubscribe
public void bootUpdate(MENetworkChannelsChanged changed)
{
markForUpdate();
}
@MENetworkEventSubscribe
public void powerUpdate(MENetworkPowerStatusChange changed)
{
markForUpdate();
}
public boolean isSecurityEnabled()
{
return isActive && gridProxy.isActive();
}
public TileSecurity() {
gridProxy.setFlags( GridFlags.REQUIRE_CHANNEL );
gridProxy.setIdlePowerUsage( 2.0 );
difference++;
securityKey = System.currentTimeMillis() * 10 + difference;
if ( difference > 10 )
difference = 0;
cm.registerSetting( Settings.SORT_BY, SortOrder.NAME );
cm.registerSetting( Settings.VIEW_MODE, ViewItems.ALL );
cm.registerSetting( Settings.SORT_DIRECTION, SortDir.ASCENDING );
}
public int getOwner()
{
return gridProxy.getNode().getPlayerID();
}
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
return AECableType.SMART;
}
@Override
public DimensionalCoord getLocation()
{
return new DimensionalCoord( this );
}
public boolean isActive()
{
return isActive;
}
@Override
public IMEMonitor<IAEItemStack> getItemInventory()
{
return securityMonitor;
}
@Override
public IMEMonitor<IAEFluidStack> getFluidInventory()
{
return null;
}
@Override
public long getLocatableSerial()
{
return securityKey;
}
public boolean isPowered()
{
return gridProxy.isActive();
}
@Override
public IConfigManager getConfigManager()
{
return cm;
}
@Override
public void updateSetting(IConfigManager manager, Enum settingName, Enum newValue)
{
}
@Override
public long getSecurityKey()
{
return securityKey;
}
public AEColor getColor()
{
return paintedColor;
}
@Override
public boolean recolourBlock(ForgeDirection side, AEColor newPaintedColor, EntityPlayer who)
{
if ( paintedColor == newPaintedColor )
return false;
paintedColor = newPaintedColor;
markDirty();
markForUpdate();
return true;
}
}
@@ -0,0 +1,14 @@
package appeng.tile.misc;
import appeng.tile.AEBaseTile;
public class TileSkyCompass extends AEBaseTile
{
@Override
public boolean requiresTESR()
{
return true;
}
}
@@ -0,0 +1,253 @@
package appeng.tile.misc;
import io.netty.buffer.ByteBuf;
import java.io.IOException;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntityFurnace;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.config.Actionable;
import appeng.api.networking.IGridNode;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.util.AECableType;
import appeng.api.util.DimensionalCoord;
import appeng.core.settings.TickRates;
import appeng.me.GridAccessException;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkInvTile;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.InvOperation;
public class TileVibrationChamber extends AENetworkInvTile implements IGridTickable
{
final double powerPerTick = 5;
final int sides[] = new int[] { 0 };
AppEngInternalInventory inv = new AppEngInternalInventory( this, 1 );
public int burnSpeed = 100;
public double burnTime = 0;
public double maxBurnTime = 0;
// client side..
public boolean isOn;
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
return AECableType.COVERED;
}
@TileEvent(TileEventType.NETWORK_READ)
public boolean readFromStream_TileVibrationChamber(ByteBuf data) throws IOException
{
boolean wasOn = isOn;
isOn = data.readBoolean();
return wasOn != isOn; // TESR doesn't need updates!
}
@TileEvent(TileEventType.NETWORK_WRITE)
public void writeToStream_TileVibrationChamber(ByteBuf data) throws IOException
{
data.writeBoolean( burnTime > 0 );
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_TileVibrationChamber(NBTTagCompound data)
{
data.setDouble( "burnTime", burnTime );
data.setDouble( "maxBurnTime", maxBurnTime );
data.setInteger( "burnSpeed", burnSpeed );
}
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_TileVibrationChamber(NBTTagCompound data)
{
burnTime = data.getDouble( "burnTime" );
maxBurnTime = data.getDouble( "maxBurnTime" );
burnSpeed = data.getInteger( "burnSpeed" );
}
public TileVibrationChamber() {
gridProxy.setIdlePowerUsage( 0 );
gridProxy.setFlags();
}
@Override
public IInventory getInternalInventory()
{
return inv;
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removed, ItemStack added)
{
if ( burnTime <= 0 )
{
if ( canEatFuel() )
{
try
{
gridProxy.getTick().wakeDevice( gridProxy.getNode() );
}
catch (GridAccessException e)
{
// wake up!
}
}
}
}
@Override
public int[] getAccessibleSlotsBySide(ForgeDirection side)
{
return sides;
}
@Override
public int getInventoryStackLimit()
{
return 64;
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack)
{
return TileEntityFurnace.getItemBurnTime( itemstack ) > 0;
}
@Override
public boolean canExtractItem(int i, ItemStack itemstack, int j)
{
return false;
}
@Override
public DimensionalCoord getLocation()
{
return new DimensionalCoord( this );
}
@Override
public TickingRequest getTickingRequest(IGridNode node)
{
if ( burnTime <= 0 )
eatFuel();
return new TickingRequest( TickRates.VibrationChamber.min, TickRates.VibrationChamber.max, burnTime <= 0, false );
}
@Override
public TickRateModulation tickingRequest(IGridNode node, int TicksSinceLastCall)
{
if ( burnTime <= 0 )
{
eatFuel();
if ( burnTime > 0 )
return TickRateModulation.URGENT;
burnSpeed = 100;
return TickRateModulation.SLEEP;
}
burnSpeed = Math.max( 20, Math.min( burnSpeed, 200 ) );
double dialiation = burnSpeed / 100.0;
double timePassed = (double) TicksSinceLastCall * dialiation;
burnTime -= timePassed;
if ( burnTime < 0 )
{
timePassed += burnTime;
burnTime = 0;
}
try
{
IEnergyGrid grid = gridProxy.getEnergy();
double newPower = timePassed * powerPerTick;
double overFlow = grid.injectPower( newPower, Actionable.SIMULATE );
// burn the over flow.
grid.injectPower( Math.max( 0.0, newPower - overFlow ), Actionable.MODULATE );
if ( overFlow > 0 )
burnSpeed -= TicksSinceLastCall;
else
burnSpeed += TicksSinceLastCall;
burnSpeed = Math.max( 20, Math.min( burnSpeed, 200 ) );
return overFlow > 0 ? TickRateModulation.SLOWER : TickRateModulation.FASTER;
}
catch (GridAccessException e)
{
burnSpeed -= TicksSinceLastCall;
burnSpeed = Math.max( 20, Math.min( burnSpeed, 200 ) );
return TickRateModulation.SLOWER;
}
}
private boolean canEatFuel()
{
ItemStack is = getStackInSlot( 0 );
if ( is != null )
{
int newBurnTime = TileEntityFurnace.getItemBurnTime( is );
if ( newBurnTime > 0 && is.stackSize > 0 )
return true;
}
return false;
}
private void eatFuel()
{
ItemStack is = getStackInSlot( 0 );
if ( is != null )
{
int newBurnTime = TileEntityFurnace.getItemBurnTime( is );
if ( newBurnTime > 0 && is.stackSize > 0 )
{
burnTime += newBurnTime;
maxBurnTime = burnTime;
is.stackSize--;
if ( is.stackSize <= 0 )
{
ItemStack container = null;
if ( is.getItem().hasContainerItem( is ) )
container = is.getItem().getContainerItem( is );
setInventorySlotContents( 0, container );
}
else
setInventorySlotContents( 0, is );
}
}
if ( burnTime > 0 )
{
try
{
gridProxy.getTick().wakeDevice( gridProxy.getNode() );
}
catch (GridAccessException e)
{
// gah!
}
}
if ( (!isOn && burnTime > 0) || (isOn && burnTime <= 0) )
{
isOn = burnTime > 0;
markForUpdate();
}
}
}
@@ -0,0 +1,356 @@
package appeng.tile.networking;
import io.netty.buffer.ByteBuf;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.networking.IGridNode;
import appeng.api.parts.IFacadeContainer;
import appeng.api.parts.IPart;
import appeng.api.parts.LayerFlags;
import appeng.api.parts.SelectedPart;
import appeng.api.util.AECableType;
import appeng.api.util.AEColor;
import appeng.api.util.DimensionalCoord;
import appeng.block.networking.BlockCableBus;
import appeng.core.AppEng;
import appeng.helpers.AEMultiTile;
import appeng.helpers.ICustomCollision;
import appeng.hooks.TickHandler;
import appeng.integration.IntegrationType;
import appeng.integration.abstraction.IImmibisMicroblocks;
import appeng.parts.CableBusContainer;
import appeng.tile.AEBaseTile;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.util.Platform;
public class TileCableBus extends AEBaseTile implements AEMultiTile, ICustomCollision
{
public CableBusContainer cb = new CableBusContainer( this );
private int oldLV = -1; // on re-calculate light when it changes
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_TileCableBus(NBTTagCompound data)
{
cb.readFromNBT( data );
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_TileCableBus(NBTTagCompound data)
{
cb.writeToNBT( data );
}
@TileEvent(TileEventType.NETWORK_READ)
public boolean readFromStream_TileCableBus(ByteBuf data) throws IOException
{
boolean ret = cb.readFromStream( data );
int newLV = cb.getLightValue();
if ( newLV != oldLV )
{
oldLV = newLV;
worldObj.func_147451_t( xCoord, yCoord, zCoord );
// worldObj.updateAllLightTypes( xCoord, yCoord, zCoord );
}
updateTileSetting();
return ret;
}
@TileEvent(TileEventType.NETWORK_WRITE)
public void writeToStream_TileCableBus(ByteBuf data) throws IOException
{
cb.writeToStream( data );
}
@Override
public boolean isInWorld()
{
return cb.isInWorld();
}
protected void updateTileSetting()
{
if ( cb.requiresDynamicRender )
{
TileCableBus tcb;
try
{
tcb = (TileCableBus) BlockCableBus.tesrTile.newInstance();
tcb.copyFrom( this );
getWorldObj().setTileEntity( xCoord, yCoord, zCoord, tcb );
}
catch (Throwable t)
{
}
}
}
protected void copyFrom(TileCableBus oldTile)
{
CableBusContainer tmpCB = cb;
cb = oldTile.cb;
oldLV = oldTile.oldLV;
oldTile.cb = tmpCB;
}
@Override
public void onReady()
{
super.onReady();
if ( cb.isEmpty() )
{
if ( worldObj.getTileEntity( xCoord, yCoord, zCoord ) == this )
worldObj.func_147480_a( xCoord, yCoord, zCoord, true );
}
else
cb.addToWorld();
}
@Override
public void onChunkUnload()
{
super.onChunkUnload();
cb.removeFromWorld();
}
@Override
public void validate()
{
super.validate();
TickHandler.instance.addInit( this );
}
@Override
public void invalidate()
{
super.invalidate();
cb.removeFromWorld();
}
@Override
public boolean canBeRotated()
{
return false;
}
@Override
public double getMaxRenderDistanceSquared()
{
return 900.0;
}
@Override
public void getDrops(World w, int x, int y, int z, ArrayList drops)
{
cb.getDrops( drops );
}
public void getNoDrops(World w, int x, int y, int z, ArrayList<ItemStack> drops)
{
cb.getNoDrops( drops );
}
@Override
public IGridNode getGridNode(ForgeDirection dir)
{
return cb.getGridNode( dir );
}
@Override
public boolean canAddPart(ItemStack is, ForgeDirection side)
{
return cb.canAddPart( is, side );
}
@Override
public ForgeDirection addPart(ItemStack is, ForgeDirection side, EntityPlayer player)
{
return cb.addPart( is, side, player );
}
@Override
public void removePart(ForgeDirection side, boolean suppressUpdate)
{
cb.removePart( side, suppressUpdate );
}
@Override
public IPart getPart(ForgeDirection side)
{
return cb.getPart( side );
}
@Override
public DimensionalCoord getLocation()
{
return new DimensionalCoord( this );
}
@Override
public TileEntity getTile()
{
return this;
}
@Override
public Iterable<AxisAlignedBB> getSelectedBoundingBoxesFromPool(World w, int x, int y, int z, Entity e, boolean visual)
{
return cb.getSelectedBoundingBoxsFromPool( false, true, e, visual );
}
@Override
public void addCollidingBlockToList(World w, int x, int y, int z, AxisAlignedBB bb, List out, Entity e)
{
for (AxisAlignedBB bx : getSelectedBoundingBoxesFromPool( w, x, y, z, e, false ))
out.add( AxisAlignedBB.getBoundingBox( bx.minX, bx.minY, bx.minZ, bx.maxX, bx.maxY, bx.maxZ ) );
}
@Override
public AECableType getCableConnectionType(ForgeDirection side)
{
return cb.getCableConnectionType( side );
}
@Override
public AEColor getColor()
{
return cb.getColor();
}
@Override
public IFacadeContainer getFacadeContainer()
{
return cb.getFacadeContainer();
}
@Override
public void clearContainer()
{
cb = new CableBusContainer( this );
}
@Override
public boolean isBlocked(ForgeDirection side)
{
return !ImmibisMicroblocks_isSideOpen( side.ordinal() );
}
@Override
public void markForUpdate()
{
if ( worldObj == null )
return;
int newLV = cb.getLightValue();
if ( newLV != oldLV )
{
oldLV = newLV;
worldObj.func_147451_t( xCoord, yCoord, zCoord );
// worldObj.updateAllLightTypes( xCoord, yCoord, zCoord );
}
super.markForUpdate();
}
@Override
public SelectedPart selectPart(Vec3 pos)
{
return cb.selectPart( pos );
}
@Override
public void partChanged()
{
notifyNeighbors();
}
@Override
public void notifyNeighbors()
{
if ( worldObj != null && worldObj.blockExists( xCoord, yCoord, zCoord ) && !CableBusContainer.isLoading() )
Platform.notifyBlocksOfNeighbors( worldObj, xCoord, yCoord, zCoord );
}
@Override
public void markForSave()
{
super.markDirty();
}
@Override
public boolean hasRedstone(ForgeDirection side)
{
return cb.hasRedstone( side );
}
@Override
public boolean isEmpty()
{
return cb.isEmpty();
}
@Override
public boolean requiresTESR()
{
return cb.requiresDynamicRender;
}
@Override
public Set<LayerFlags> getLayerFlags()
{
return cb.getLayerFlags();
}
@Override
public void cleanup()
{
if ( AppEng.instance.isIntegrationEnabled( IntegrationType.ImmibisMicroblocks ) )
{
IImmibisMicroblocks imb = (IImmibisMicroblocks) AppEng.instance.getIntegration( IntegrationType.ImmibisMicroblocks );
if ( imb != null && imb.leaveParts( this ) )
return;
}
getWorldObj().setBlock( xCoord, yCoord, zCoord, Platform.air );
}
/**
* Immibis MB Support
*/
boolean ImmibisMicroblocks_TransformableTileEntityMarker = true;
public boolean ImmibisMicroblocks_isSideOpen(int side)
{
return true;
}
public void ImmibisMicroblocks_onMicroblocksChanged()
{
cb.updateConnections();
}
@Override
public boolean recolourBlock(ForgeDirection side, AEColor colour, EntityPlayer who)
{
return cb.recolourBlock( side, colour, who );
}
}
@@ -0,0 +1,27 @@
package appeng.tile.networking;
import appeng.block.networking.BlockCableBus;
public class TileCableBusTESR extends TileCableBus
{
@Override
protected void updateTileSetting()
{
if ( !cb.requiresDynamicRender )
{
TileCableBus tcb;
try
{
tcb = (TileCableBus) BlockCableBus.noTesrTile.newInstance();
tcb.copyFrom( this );
getWorldObj().setTileEntity( xCoord, yCoord, zCoord, tcb );
}
catch (Throwable t)
{
}
}
}
}
@@ -0,0 +1,178 @@
package appeng.tile.networking;
import java.util.EnumSet;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.config.Actionable;
import appeng.api.networking.GridFlags;
import appeng.api.networking.energy.IAEPowerStorage;
import appeng.api.networking.events.MENetworkControllerChange;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.events.MENetworkPowerStorage;
import appeng.api.networking.events.MENetworkPowerStorage.PowerEventType;
import appeng.api.networking.pathing.ControllerState;
import appeng.api.util.AECableType;
import appeng.me.GridAccessException;
import appeng.tile.grid.AENetworkPowerTile;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.InvOperation;
public class TileController extends AENetworkPowerTile implements IAEPowerStorage
{
boolean isValid = false;
public TileController() {
internalMaxPower = 8000;
internalPublicPowerStorage = true;
gridProxy.setIdlePowerUsage( 3 );
gridProxy.setFlags( GridFlags.CANNOT_CARRY, GridFlags.DENSE_CAPACITY );
}
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
return AECableType.DENSE;
}
@Override
protected double getFunnelPowerDemand(double maxReceived)
{
try
{
return gridProxy.getEnergy().getEnergyDemand( 8000 );
}
catch (GridAccessException e)
{
// no grid? use local...
return super.getFunnelPowerDemand( maxReceived );
}
}
@Override
protected double funnelPowerIntoStorage(double AEUnits, Actionable mode)
{
try
{
double ret = gridProxy.getEnergy().injectPower( AEUnits, mode );
if ( mode == Actionable.SIMULATE )
return ret;
return 0;
}
catch (GridAccessException e)
{
// no grid? use local...
return super.funnelPowerIntoStorage( AEUnits, mode );
}
}
@Override
protected void PowerEvent(PowerEventType x)
{
try
{
gridProxy.getGrid().postEvent( new MENetworkPowerStorage( this, x ) );
}
catch (GridAccessException e)
{
// not ready!
}
}
@MENetworkEventSubscribe
public void onControllerChange(MENetworkControllerChange status)
{
updateMeta();
}
@MENetworkEventSubscribe
public void onPowerChange(MENetworkPowerStatusChange status)
{
updateMeta();
}
@Override
public void onReady()
{
onNeighborChange( true );
super.onReady();
}
public void onNeighborChange(boolean force)
{
boolean xx = worldObj.getTileEntity( xCoord - 1, yCoord, zCoord ) instanceof TileController
&& worldObj.getTileEntity( xCoord + 1, yCoord, zCoord ) instanceof TileController;
boolean yy = worldObj.getTileEntity( xCoord, yCoord - 1, zCoord ) instanceof TileController
&& worldObj.getTileEntity( xCoord, yCoord + 1, zCoord ) instanceof TileController;
boolean zz = worldObj.getTileEntity( xCoord, yCoord, zCoord - 1 ) instanceof TileController
&& worldObj.getTileEntity( xCoord, yCoord, zCoord + 1 ) instanceof TileController;
// int meta = world.getBlockMetadata( xCoord, yCoord, zCoord );
// boolean hasPower = meta > 0;
// boolean isConflict = meta == 2;
boolean oldValid = isValid;
isValid = (xx && !yy && !zz) || (!xx && yy && !zz) || (!xx && !yy && zz) || ((xx ? 1 : 0) + (yy ? 1 : 0) + (zz ? 1 : 0) <= 1);
if ( oldValid != isValid || force )
{
if ( isValid )
gridProxy.setValidSides( EnumSet.allOf( ForgeDirection.class ) );
else
gridProxy.setValidSides( EnumSet.noneOf( ForgeDirection.class ) );
}
updateMeta();
}
private void updateMeta()
{
if ( !gridProxy.isReady() )
return;
int meta = 0;
try
{
if ( gridProxy.getEnergy().isNetworkPowered() )
{
meta = 1;
if ( gridProxy.getPath().getControllerState() == ControllerState.CONTROLLER_CONFLICT )
meta = 2;
}
}
catch (GridAccessException e)
{
meta = 0;
}
worldObj.setBlockMetadataWithNotify( xCoord, yCoord, zCoord, meta, 2 );
}
final int sides[] = new int[] {};
static final AppEngInternalInventory inv = new AppEngInternalInventory( null, 0 );
@Override
public IInventory getInternalInventory()
{
return inv;
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removed, ItemStack added)
{
}
@Override
public int[] getAccessibleSlotsBySide(ForgeDirection side)
{
return sides;
}
}
@@ -0,0 +1,60 @@
package appeng.tile.networking;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.networking.energy.IAEPowerStorage;
import appeng.api.util.AECableType;
import appeng.tile.grid.AENetworkTile;
public class TileCreativeEnergyCell extends AENetworkTile implements IAEPowerStorage
{
public TileCreativeEnergyCell() {
gridProxy.setIdlePowerUsage( 0 );
}
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
return AECableType.COVERED;
}
@Override
public double injectAEPower(double amt, Actionable mode)
{
return 0;
}
@Override
public double extractAEPower(double amt, Actionable mode, PowerMultiplier pm)
{
return amt;
}
@Override
public double getAEMaxPower()
{
return Long.MAX_VALUE / 10000;
}
@Override
public double getAECurrentPower()
{
return Long.MAX_VALUE / 10000;
}
@Override
public boolean isAEPublicPowerStorage()
{
return true;
}
@Override
public AccessRestriction getPowerFlow()
{
return AccessRestriction.READ_WRITE;
}
}
@@ -0,0 +1,10 @@
package appeng.tile.networking;
public class TileDenseEnergyCell extends TileEnergyCell
{
public TileDenseEnergyCell() {
internalMaxPower = 200000 * 8;
}
}
@@ -0,0 +1,106 @@
package appeng.tile.networking;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.util.AECableType;
import appeng.me.GridAccessException;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkPowerTile;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.InvOperation;
public class TileEnergyAcceptor extends AENetworkPowerTile
{
final int sides[] = new int[] {};
final static AppEngInternalInventory inv = new AppEngInternalInventory( null, 0 );
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
return AECableType.COVERED;
}
@TileEvent(TileEventType.TICK)
public void Tick_TileEnergyAcceptor()
{
if ( internalCurrentPower > 0 )
{
try
{
IEnergyGrid eg = gridProxy.getEnergy();
double powerRequested = internalCurrentPower - eg.injectPower( internalCurrentPower, Actionable.SIMULATE );
if ( powerRequested > 0 )
{
eg.injectPower( extractAEPower( powerRequested, Actionable.MODULATE, PowerMultiplier.ONE ), Actionable.MODULATE );
}
}
catch (GridAccessException e)
{
// null net, probably bads.
}
}
}
@Override
protected double getFunnelPowerDemand(double maxRequired)
{
try
{
IEnergyGrid grid = gridProxy.getEnergy();
return grid.getEnergyDemand( maxRequired );
}
catch (GridAccessException e)
{
return super.getFunnelPowerDemand( maxRequired );
}
}
@Override
protected double funnelPowerIntoStorage(double newPower, Actionable mode)
{
try
{
IEnergyGrid grid = gridProxy.getEnergy();
double leftOver = grid.injectPower( newPower, mode );
if ( mode == Actionable.SIMULATE )
return leftOver;
return 0.0;
}
catch (GridAccessException e)
{
return super.funnelPowerIntoStorage( newPower, mode );
}
}
public TileEnergyAcceptor() {
gridProxy.setIdlePowerUsage( 0.0 );
internalMaxPower = 100;
}
@Override
public IInventory getInternalInventory()
{
return inv;
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removed, ItemStack added)
{
}
@Override
public int[] getAccessibleSlotsBySide(ForgeDirection side)
{
return sides;
}
}
@@ -0,0 +1,202 @@
package appeng.tile.networking;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.networking.energy.IAEPowerStorage;
import appeng.api.networking.events.MENetworkPowerStorage;
import appeng.api.networking.events.MENetworkPowerStorage.PowerEventType;
import appeng.api.util.AECableType;
import appeng.me.GridAccessException;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkTile;
import appeng.util.SettingsFrom;
public class TileEnergyCell extends AENetworkTile implements IAEPowerStorage
{
protected double internalCurrentPower = 0.0;
protected double internalMaxPower = 200000.0;
private byte currentMeta = -1;
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
return AECableType.COVERED;
}
private void changePowerLevel()
{
if ( notLoaded() )
return;
byte leel = (byte) (8.0 * (internalCurrentPower / internalMaxPower));
if ( leel > 7 )
leel = 7;
if ( leel < 0 )
leel = 0;
if ( currentMeta != leel )
{
currentMeta = leel;
worldObj.setBlockMetadataWithNotify( xCoord, yCoord, zCoord, currentMeta, 2 );
}
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_TileEnergyCell(NBTTagCompound data)
{
if ( !worldObj.isRemote )
data.setDouble( "internalCurrentPower", internalCurrentPower );
}
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_TileEnergyCell(NBTTagCompound data)
{
internalCurrentPower = data.getDouble( "internalCurrentPower" );
}
public TileEnergyCell() {
gridProxy.setIdlePowerUsage( 0 );
}
@Override
public boolean canBeRotated()
{
return false;
}
@Override
final public double injectAEPower(double amt, Actionable mode)
{
if ( mode == Actionable.SIMULATE )
{
double fakeBattery = internalCurrentPower + amt;
if ( fakeBattery > internalMaxPower )
{
return fakeBattery - internalMaxPower;
}
return 0;
}
if ( internalCurrentPower < 0.01 && amt > 0.01 )
gridProxy.getNode().getGrid().postEvent( new MENetworkPowerStorage( this, PowerEventType.PROVIDE_POWER ) );
internalCurrentPower += amt;
if ( internalCurrentPower > internalMaxPower )
{
amt = internalCurrentPower - internalMaxPower;
internalCurrentPower = internalMaxPower;
changePowerLevel();
return amt;
}
changePowerLevel();
return 0;
}
final private double extractAEPower(double amt, Actionable mode)
{
if ( mode == Actionable.SIMULATE )
{
if ( internalCurrentPower > amt )
return amt;
return internalCurrentPower;
}
boolean wasFull = internalCurrentPower >= internalMaxPower - 0.001;
if ( wasFull && amt > 0.001 )
{
try
{
gridProxy.getGrid().postEvent( new MENetworkPowerStorage( this, PowerEventType.REQUEST_POWER ) );
}
catch (GridAccessException e)
{
}
}
if ( internalCurrentPower > amt )
{
internalCurrentPower -= amt;
changePowerLevel();
return amt;
}
amt = internalCurrentPower;
internalCurrentPower = 0;
changePowerLevel();
return amt;
}
@Override
final public double extractAEPower(double amt, Actionable mode, PowerMultiplier pm)
{
return pm.divide( extractAEPower( pm.multiply( amt ), mode ) );
}
@Override
public double getAEMaxPower()
{
return internalMaxPower;
}
@Override
public double getAECurrentPower()
{
return internalCurrentPower;
}
@Override
public boolean isAEPublicPowerStorage()
{
return true;
}
@Override
public AccessRestriction getPowerFlow()
{
return AccessRestriction.READ_WRITE;
}
@Override
public void onReady()
{
super.onReady();
currentMeta = (byte) worldObj.getBlockMetadata( xCoord, yCoord, zCoord );
changePowerLevel();
}
@Override
public NBTTagCompound downloadSettings(SettingsFrom from)
{
if ( from == SettingsFrom.DISMANTLE_ITEM )
{
NBTTagCompound tag = new NBTTagCompound();
tag.setDouble( "internalCurrentPower", internalCurrentPower );
tag.setDouble( "internalMaxPower", internalMaxPower ); // used for tool tip.
return tag;
}
return null;
}
@Override
public void uploadSettings(SettingsFrom from, NBTTagCompound compound)
{
if ( from == SettingsFrom.DISMANTLE_ITEM )
{
internalCurrentPower = compound.getDouble( "internalCurrentPower" );
}
}
}
@@ -0,0 +1,182 @@
package appeng.tile.networking;
import io.netty.buffer.ByteBuf;
import java.io.IOException;
import java.util.EnumSet;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.implementations.IPowerChannelState;
import appeng.api.implementations.tiles.IWirelessAccessPoint;
import appeng.api.networking.GridFlags;
import appeng.api.networking.IGrid;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.util.AECableType;
import appeng.api.util.DimensionalCoord;
import appeng.core.AEConfig;
import appeng.me.GridAccessException;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkInvTile;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.Platform;
public class TileWireless extends AENetworkInvTile implements IWirelessAccessPoint, IPowerChannelState
{
public static final int POWERED_FLAG = 1;
public static final int CHANNEL_FLAG = 2;
final int sides[] = new int[] { 0 };
AppEngInternalInventory inv = new AppEngInternalInventory( this, 1 );
public int clientFlags = 0;
public TileWireless() {
gridProxy.setFlags( GridFlags.REQUIRE_CHANNEL );
gridProxy.setValidSides( EnumSet.noneOf( ForgeDirection.class ) );
}
@Override
public void setOrientation(ForgeDirection inForward, ForgeDirection inUp)
{
super.setOrientation( inForward, inUp );
gridProxy.setValidSides( EnumSet.of( getForward().getOpposite() ) );
}
@MENetworkEventSubscribe
public void chanRender(MENetworkChannelsChanged c)
{
markForUpdate();
}
@MENetworkEventSubscribe
public void powerRender(MENetworkPowerStatusChange c)
{
markForUpdate();
}
@TileEvent(TileEventType.NETWORK_READ)
public boolean readFromStream_TileWireless(ByteBuf data) throws IOException
{
int old = clientFlags;
clientFlags = data.readByte();
return old != clientFlags;
}
@TileEvent(TileEventType.NETWORK_WRITE)
public void writeToStream_TileWireless(ByteBuf data) throws IOException
{
clientFlags = 0;
try
{
if ( gridProxy.getEnergy().isNetworkPowered() )
clientFlags |= POWERED_FLAG;
if ( gridProxy.getNode().meetsChannelRequirements() )
clientFlags |= CHANNEL_FLAG;
}
catch (GridAccessException e)
{
// meh
}
data.writeByte( (byte) clientFlags );
}
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
return AECableType.SMART;
}
@Override
public DimensionalCoord getLocation()
{
return new DimensionalCoord( this );
}
@Override
public IInventory getInternalInventory()
{
return inv;
}
@Override
public void onReady()
{
updatePower();
super.onReady();
}
@Override
public void markDirty()
{
updatePower();
}
private void updatePower()
{
gridProxy.setIdlePowerUsage( AEConfig.instance.wireless_getPowerDrain( getBoosters() ) );
}
@Override
public int[] getAccessibleSlotsBySide(ForgeDirection side)
{
return sides;
}
@Override
public double getRange()
{
return AEConfig.instance.wireless_getMaxRange( getBoosters() );
}
@Override
public boolean isActive()
{
if ( Platform.isClient() )
return isPowered() && (CHANNEL_FLAG == (clientFlags & CHANNEL_FLAG));
return gridProxy.isActive();
}
@Override
public IGrid getGrid()
{
try
{
return gridProxy.getGrid();
}
catch (GridAccessException e)
{
return null;
}
}
private int getBoosters()
{
ItemStack boosters = inv.getStackInSlot( 0 );
return boosters == null ? 0 : boosters.stackSize;
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removed, ItemStack added)
{
// :P
}
@Override
public boolean isPowered()
{
return POWERED_FLAG == (clientFlags & POWERED_FLAG);
}
}
@@ -0,0 +1,6 @@
package appeng.tile.powersink;
public abstract class AEBasePoweredTile extends MekJoules
{
}
@@ -0,0 +1,167 @@
package appeng.tile.powersink;
import java.util.EnumSet;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.config.PowerUnits;
import appeng.api.networking.energy.IAEPowerStorage;
import appeng.api.networking.events.MENetworkPowerStorage.PowerEventType;
import appeng.tile.AEBaseInvTile;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
public abstract class AERootPoweredTile extends AEBaseInvTile implements IAEPowerStorage
{
// values that determine general function, are set by inheriting classes if
// needed. These should generally remain static.
protected double internalMaxPower = 10000;
protected boolean internalCanAcceptPower = true;
protected boolean internalPublicPowerStorage = false;
private EnumSet<ForgeDirection> internalPowerSides = EnumSet.allOf( ForgeDirection.class );
protected AccessRestriction internalPowerFlow = AccessRestriction.READ_WRITE;
// the current power buffer.
protected double internalCurrentPower = 0;
protected void setPowerSides(EnumSet<ForgeDirection> sides)
{
internalPowerSides = sides;
// trigger re-calc!
}
protected EnumSet<ForgeDirection> getPowerSides()
{
return internalPowerSides.clone();
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_AERootPoweredTile(NBTTagCompound data)
{
data.setDouble( "internalCurrentPower", internalCurrentPower );
}
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_AERootPoweredTile(NBTTagCompound data)
{
internalCurrentPower = data.getDouble( "internalCurrentPower" );
}
final protected double getExternalPowerDemand(PowerUnits externalUnit, double maxPowerRequired)
{
return PowerUnits.AE.convertTo( externalUnit, Math.max( 0.0, getFunnelPowerDemand( externalUnit.convertTo( PowerUnits.AE, maxPowerRequired ) ) ) );
}
protected double getFunnelPowerDemand(double maxRequired)
{
return internalMaxPower - internalCurrentPower;
}
final public double injectExternalPower(PowerUnits input, double amt)
{
return PowerUnits.AE.convertTo( input, funnelPowerIntoStorage( input.convertTo( PowerUnits.AE, amt ), Actionable.MODULATE ) );
}
protected double funnelPowerIntoStorage(double AEUnits, Actionable mode)
{
return injectAEPower( AEUnits, mode );
}
@Override
final public double injectAEPower(double amt, Actionable mode)
{
if ( amt < 0.000001 )
return 0;
if ( mode == Actionable.SIMULATE )
{
double fakeBattery = internalCurrentPower + amt;
if ( fakeBattery > internalMaxPower )
return fakeBattery - internalMaxPower;
return 0;
}
else
{
if ( internalCurrentPower < 0.01 && amt > 0.01 )
PowerEvent( PowerEventType.PROVIDE_POWER );
internalCurrentPower += amt;
if ( internalCurrentPower > internalMaxPower )
{
amt = internalCurrentPower - internalMaxPower;
internalCurrentPower = internalMaxPower;
return amt;
}
return 0;
}
}
protected void PowerEvent(PowerEventType x)
{
// nothing.
}
protected double extractAEPower(double amt, Actionable mode)
{
if ( mode == Actionable.SIMULATE )
{
if ( internalCurrentPower > amt )
return amt;
return internalCurrentPower;
}
boolean wasFull = internalCurrentPower >= internalMaxPower - 0.001;
if ( wasFull && amt > 0.001 )
{
PowerEvent( PowerEventType.REQUEST_POWER );
}
if ( internalCurrentPower > amt )
{
internalCurrentPower -= amt;
return amt;
}
amt = internalCurrentPower;
internalCurrentPower = 0;
return amt;
}
@Override
final public double extractAEPower(double amt, Actionable mode, PowerMultiplier multiplier)
{
return multiplier.divide( extractAEPower( multiplier.multiply( amt ), mode ) );
}
@Override
final public double getAEMaxPower()
{
return internalMaxPower;
}
@Override
final public double getAECurrentPower()
{
return internalCurrentPower;
}
@Override
final public boolean isAEPublicPowerStorage()
{
return internalPublicPowerStorage;
}
@Override
final public AccessRestriction getPowerFlow()
{
return internalPowerFlow;
}
}
@@ -0,0 +1,105 @@
package appeng.tile.powersink;
import ic2.api.energy.tile.IEnergySink;
import java.util.EnumSet;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.config.PowerUnits;
import appeng.core.AppEng;
import appeng.integration.IntegrationType;
import appeng.integration.abstraction.IIC2;
import appeng.transformer.annotations.integration.Interface;
import appeng.util.Platform;
@Interface(iname = "IC2", iface = "ic2.api.energy.tile.IEnergySink")
public abstract class IC2 extends MinecraftJoules6 implements IEnergySink
{
boolean isInIC2 = false;
@Override
final public boolean acceptsEnergyFrom(TileEntity emitter, ForgeDirection direction)
{
return internalCanAcceptPower && getPowerSides().contains( direction );
}
@Override
final public double getDemandedEnergy()
{
return getExternalPowerDemand( PowerUnits.EU, Double.MAX_VALUE );
}
@Override
final public double injectEnergy(ForgeDirection directionFrom, double amount, double voltage)
{
// just store the excess in the current block, if I return the waste,
// IC2 will just disintegrate it - Oct 20th 2013
double overflow = PowerUnits.EU.convertTo( PowerUnits.AE, injectExternalPower( PowerUnits.EU, amount ) );
internalCurrentPower += overflow;
return 0; // see above comment.
}
@Override
final public int getSinkTier()
{
return Integer.MAX_VALUE;
}
@Override
public void invalidate()
{
super.invalidate();
removeFromENet();
}
@Override
public void onChunkUnload()
{
super.onChunkUnload();
removeFromENet();
}
@Override
public void onReady()
{
super.onReady();
addToENet();
}
@Override
protected void setPowerSides(EnumSet<ForgeDirection> sides)
{
super.setPowerSides( sides );
removeFromENet();
addToENet();
}
final private void addToENet()
{
if ( AppEng.instance.isIntegrationEnabled( IntegrationType.IC2 ) )
{
IIC2 ic2Integration = (IIC2) AppEng.instance.getIntegration( IntegrationType.IC2 );
if ( !isInIC2 && Platform.isServer() && ic2Integration != null )
{
ic2Integration.addToEnergyNet( this );
isInIC2 = true;
}
}
}
final private void removeFromENet()
{
if ( AppEng.instance.isIntegrationEnabled( IntegrationType.IC2 ) )
{
IIC2 ic2Integration = (IIC2) AppEng.instance.getIntegration( IntegrationType.IC2 );
if ( isInIC2 && Platform.isServer() && ic2Integration != null )
{
ic2Integration.removeFromEnergyNet( this );
isInIC2 = false;
}
}
}
}
@@ -0,0 +1,43 @@
package appeng.tile.powersink;
import mekanism.api.energy.IStrictEnergyAcceptor;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.config.PowerUnits;
import appeng.transformer.annotations.integration.Interface;
@Interface(iname = "Mekanism", iface = "mekanism.api.energy.IStrictEnergyAcceptor")
public abstract class MekJoules extends RedstoneFlux implements IStrictEnergyAcceptor {
@Override
public double getEnergy() {
return 0;
}
@Override
public void setEnergy(double energy) {
double extra = injectExternalPower( PowerUnits.MK, energy );
internalCurrentPower += PowerUnits.MK.convertTo(PowerUnits.AE, extra );
}
@Override
public double getMaxEnergy() {
return this.getExternalPowerDemand( PowerUnits.MK, 100000 );
}
@Override
public double transferEnergyToAcceptor(ForgeDirection side, double amount)
{
double demand = getExternalPowerDemand( PowerUnits.MK, Double.MAX_VALUE );
if ( amount > demand )
amount = demand;
double overflow = injectExternalPower( PowerUnits.MK, amount );
return amount - overflow;
}
@Override
public boolean canReceiveEnergy(ForgeDirection side) {
return getPowerSides().contains(side);
}
}
@@ -0,0 +1,82 @@
package appeng.tile.powersink;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.config.PowerUnits;
import appeng.core.AppEng;
import appeng.integration.IntegrationType;
import appeng.integration.abstraction.IMJ5;
import appeng.integration.abstraction.helpers.BaseMJperdition;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.transformer.annotations.integration.Interface;
import appeng.transformer.annotations.integration.Method;
import appeng.util.Platform;
import buildcraft.api.power.IPowerReceptor;
import buildcraft.api.power.PowerHandler;
import buildcraft.api.power.PowerHandler.PowerReceiver;
@Interface(iname = "MJ5", iface = "buildcraft.api.power.IPowerReceptor")
public abstract class MinecraftJoules5 extends AERootPoweredTile implements IPowerReceptor
{
BaseMJperdition bcPowerWrapper;
@Method(iname = "MJ5")
@TileEvent(TileEventType.TICK)
public void Tick_MinecraftJoules5()
{
if ( bcPowerWrapper != null )
bcPowerWrapper.Tick();
}
public MinecraftJoules5() {
if ( Platform.isServer() )
{
try
{
if ( AppEng.instance.isIntegrationEnabled( IntegrationType.MJ5 ) )
{
IMJ5 mjIntegration = (IMJ5) AppEng.instance.getIntegration( IntegrationType.MJ5 );
if ( mjIntegration != null )
{
bcPowerWrapper = (BaseMJperdition) mjIntegration.createPerdition( this );
if ( bcPowerWrapper != null )
bcPowerWrapper.configure( 1, 380, 1.0f / 5.0f, 1000 );
}
}
}
catch (Throwable t)
{
// ignore.. no bc?
}
}
}
@Override
@Method(iname = "MJ5")
final public PowerReceiver getPowerReceiver(ForgeDirection side)
{
if ( internalCanAcceptPower && getPowerSides().contains( side ) && bcPowerWrapper != null )
return bcPowerWrapper.getPowerReceiver();
return null;
}
@Override
@Method(iname = "MJ5")
final public void doWork(PowerHandler workProvider)
{
float required = (float) getExternalPowerDemand( PowerUnits.MJ, bcPowerWrapper.getPowerReceiver().getEnergyStored() );
double failed = injectExternalPower( PowerUnits.MJ, bcPowerWrapper.useEnergy( 0.0f, required, true ) );
if ( failed > 0.01 )
bcPowerWrapper.addEnergy( (float) failed );
}
@Override
@Method(iname = "MJ5")
final public World getWorld()
{
return worldObj;
}
}
@@ -0,0 +1,98 @@
package appeng.tile.powersink;
import appeng.api.config.PowerUnits;
import appeng.transformer.annotations.integration.Interface;
import appeng.transformer.annotations.integration.InterfaceList;
import appeng.transformer.annotations.integration.Method;
import buildcraft.api.mj.IBatteryObject;
import buildcraft.api.mj.IBatteryProvider;
@InterfaceList(value = { @Interface(iname = "MJ6", iface = "buildcraft.api.mj.IBatteryProvider"),
@Interface(iname = "MJ6", iface = "buildcraft.api.mj.IBatteryObject") })
public abstract class MinecraftJoules6 extends MinecraftJoules5 implements IBatteryProvider, IBatteryObject
{
@Override
@Method(iname = "MJ6")
public String kind()
{
return null;
}
@Override
@Method(iname = "MJ6")
public double getEnergyRequested()
{
return getExternalPowerDemand( PowerUnits.MJ, Double.MAX_VALUE );
}
@Override
@Method(iname = "MJ6")
public double addEnergy(double amount)
{
double demand = getExternalPowerDemand( PowerUnits.MJ, Double.MAX_VALUE );
if ( amount > demand )
amount = demand;
double overflow = injectExternalPower( PowerUnits.MJ, amount );
return amount - overflow;
}
@Override
@Method(iname = "MJ6")
public double addEnergy(double amount, boolean ignoreCycleLimit)
{
double overflow = injectExternalPower( PowerUnits.MJ, amount );
return amount - overflow;
}
@Override
@Method(iname = "MJ6")
public double getEnergyStored()
{
return PowerUnits.AE.convertTo( PowerUnits.MJ, internalCurrentPower );
}
@Override
@Method(iname = "MJ6")
public void setEnergyStored(double mj)
{
internalCurrentPower = PowerUnits.MJ.convertTo( PowerUnits.AE, mj );
}
@Override
@Method(iname = "MJ6")
public double maxCapacity()
{
return PowerUnits.AE.convertTo( PowerUnits.MJ, internalMaxPower );
}
@Override
@Method(iname = "MJ6")
public double minimumConsumption()
{
return 0.1;
}
@Override
@Method(iname = "MJ6")
public double maxReceivedPerCycle()
{
return 999999.0;
}
@Override
@Method(iname = "MJ6")
public IBatteryObject reconfigure(double maxCapacity, double maxReceivedPerCycle, double minimumConsumption)
{
return getMjBattery( "" );
}
@Override
@Method(iname = "MJ6")
public IBatteryObject getMjBattery(String kind)
{
return this;
}
}
@@ -0,0 +1,65 @@
package appeng.tile.powersink;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.config.PowerUnits;
import appeng.transformer.annotations.integration.Interface;
import cofh.api.energy.IEnergyHandler;
@Interface(iname = "RF", iface = "cofh.api.energy.IEnergyHandler")
public abstract class RedstoneFlux extends RotaryCraft implements IEnergyHandler
{
@Override
final public int receiveEnergy(ForgeDirection from, int maxReceive, boolean simulate)
{
if ( simulate )
{
double demand = getExternalPowerDemand( PowerUnits.RF, maxReceive );
if ( demand > maxReceive )
return maxReceive;
return (int) Math.floor( maxReceive - demand );
}
else
{
int demand = (int) Math.floor( getExternalPowerDemand( PowerUnits.RF, maxReceive ) );
int ignored = 0;
int insertAmt = maxReceive;
if ( insertAmt > demand )
{
ignored = insertAmt - demand;
insertAmt = demand;
}
double overFlow = injectExternalPower( PowerUnits.RF, insertAmt );
double ox = Math.floor( overFlow );
internalCurrentPower += PowerUnits.RF.convertTo( PowerUnits.AE, overFlow - ox );
return maxReceive - ((int) ox + ignored);
}
}
@Override
final public int extractEnergy(ForgeDirection from, int maxExtract, boolean simulate)
{
return 0;
}
final public boolean canConnectEnergy(ForgeDirection from)
{
return internalCanAcceptPower && getPowerSides().contains( from );
}
@Override
final public int getEnergyStored(ForgeDirection from)
{
return (int) Math.floor( PowerUnits.AE.convertTo( PowerUnits.RF, getAECurrentPower() ) );
}
@Override
final public int getMaxEnergyStored(ForgeDirection from)
{
return (int) Math.floor( PowerUnits.AE.convertTo( PowerUnits.RF, getAEMaxPower() ) );
}
}
@@ -0,0 +1,148 @@
package appeng.tile.powersink;
import net.minecraftforge.common.util.ForgeDirection;
import Reika.RotaryCraft.API.ShaftPowerReceiver;
import appeng.api.config.PowerUnits;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.transformer.annotations.integration.Interface;
import appeng.transformer.annotations.integration.Method;
import appeng.util.Platform;
@Interface(iname = "RotaryCraft", iface = "Reika.RotaryCraft.API.ShaftPowerReceiver")
public abstract class RotaryCraft extends IC2 implements ShaftPowerReceiver
{
private int omega = 0;
private int torque = 0;
private long power = 0;
private int alpha = 0;
@TileEvent(TileEventType.TICK)
@Method(iname = "RotaryCraft")
public void Tick_RotaryCraft()
{
if ( worldObj != null && !worldObj.isRemote && power > 0 )
injectExternalPower( PowerUnits.WA, power );
}
@Override
final public int getOmega()
{
return omega;
}
@Override
final public int getTorque()
{
return torque;
}
@Override
final public long getPower()
{
return power;
}
@Override
final public String getName()
{
return "AE";
}
@Override
final public int getIORenderAlpha()
{
return alpha;
}
@Override
final public void setIORenderAlpha(int io)
{
alpha = io;
}
final public int getMachineX()
{
return xCoord;
}
final public int getMachineY()
{
return yCoord;
}
final public int getMachineZ()
{
return zCoord;
}
@Override
final public void setOmega(int o)
{
omega = o;
}
@Override
final public void setTorque(int t)
{
torque = t;
}
@Override
final public void setPower(long p)
{
if ( Platform.isClient() )
return;
power = p;
}
final public boolean canReadFromBlock(int x, int y, int z)
{
ForgeDirection side = ForgeDirection.UNKNOWN;
if ( x == xCoord - 1 )
side = ForgeDirection.WEST;
else if ( x == xCoord + 1 )
side = ForgeDirection.EAST;
else if ( z == zCoord - 1 )
side = ForgeDirection.NORTH;
else if ( z == zCoord + 1 )
side = ForgeDirection.SOUTH;
else if ( y == yCoord - 1 )
side = ForgeDirection.DOWN;
else if ( y == yCoord + 1 )
side = ForgeDirection.UP;
return internalCanAcceptPower && getPowerSides().contains( side );
}
@Override
final public boolean isReceiving()
{
return true;
}
@Override
final public void noInputMachine()
{
power = 0;
torque = 0;
omega = 0;
}
@Override
final public boolean canReadFrom(ForgeDirection side)
{
return internalCanAcceptPower && getPowerSides().contains( side );
}
@Override
final public int getMinTorque(int available)
{
return 0;
}
}
@@ -0,0 +1,65 @@
package appeng.tile.powersink;
/*
import net.minecraftforge.common.util.ForgeDirection;
import universalelectricity.core.block.IElectrical;
import universalelectricity.core.electricity.ElectricityPack;
import appeng.api.config.PowerUnits;
public abstract class UniversalElectricity extends ThermalExpansion implements IElectrical
{
@Override
final public boolean canConnect(ForgeDirection direction)
{
return internalCanAcceptPower && getPowerSides().contains( direction );
}
@Override
final public float receiveElectricity(ForgeDirection from, ElectricityPack receive, boolean doReceive)
{
float accepted = 0;
double receivedPower = receive.getWatts();
if ( doReceive )
{
accepted = (float) (receivedPower - injectExternalPower( PowerUnits.KJ, receivedPower ));
}
else
{
double whatIWant = getExternalPowerDemand( PowerUnits.KJ );
if ( whatIWant > receivedPower )
accepted = (float) receivedPower;
else
accepted = (float) whatIWant;
}
return accepted;
}
@Override
final public float getRequest(ForgeDirection direction)
{
return (float) getExternalPowerDemand( PowerUnits.KJ );
}
@Override
final public float getVoltage()
{
return 120;
}
@Override
final public ElectricityPack provideElectricity(ForgeDirection from, ElectricityPack request, boolean doProvide)
{
return null; // cannot be dis-charged
}
@Override
final public float getProvide(ForgeDirection direction)
{
return 0;
}
}
*/
@@ -0,0 +1,281 @@
package appeng.tile.qnb;
import io.netty.buffer.ByteBuf;
import java.io.IOException;
import java.util.EnumSet;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.AEApi;
import appeng.api.networking.GridFlags;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.util.AECableType;
import appeng.api.util.DimensionalCoord;
import appeng.me.GridAccessException;
import appeng.me.cluster.IAECluster;
import appeng.me.cluster.IAEMultiBlock;
import appeng.me.cluster.implementations.QuantumCalculator;
import appeng.me.cluster.implementations.QuantumCluster;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkInvTile;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.Platform;
public class TileQuantumBridge extends AENetworkInvTile implements IAEMultiBlock
{
final private static ItemStack ring = AEApi.instance().blocks().blockQuantumRing.stack( 1 );
final int sidesRing[] = new int[] {};
final int sidesLink[] = new int[] { 0 };
AppEngInternalInventory inv = new AppEngInternalInventory( this, 1 );
public final byte corner = 16;
final byte hasSingularity = 32;
final byte powered = 64;
private QuantumCalculator calc = new QuantumCalculator( this );
byte xdex = -1;
QuantumCluster clust;
public boolean bridgePowered;
private boolean updateStatus = false;
@TileEvent(TileEventType.TICK)
public void Tick_TileQuantumBridge()
{
if ( updateStatus )
{
updateStatus = false;
if ( clust != null )
clust.updateStatus( true );
markForUpdate();
}
}
@TileEvent(TileEventType.NETWORK_WRITE)
public void writeToStream_TileQuantumBridge(ByteBuf data) throws IOException
{
int out = xdex;
if ( getStackInSlot( 0 ) != null && xdex != -1 )
out = out | hasSingularity;
if ( gridProxy.isActive() && xdex != -1 )
out = out | powered;
data.writeByte( (byte) out );
}
@TileEvent(TileEventType.NETWORK_READ)
public boolean readFromStream_TileQuantumBridge(ByteBuf data) throws IOException
{
int oldValue = xdex;
xdex = data.readByte();
bridgePowered = (xdex | powered) == powered;
return xdex != oldValue;
}
public TileQuantumBridge() {
gridProxy.setValidSides( EnumSet.noneOf( ForgeDirection.class ) );
gridProxy.setFlags( GridFlags.DENSE_CAPACITY );
gridProxy.setIdlePowerUsage( 22 );
inv.setMaxStackSize( 1 );
}
public IInventory getInternalInventory()
{
return inv;
}
@MENetworkEventSubscribe
public void PowerSwitch(MENetworkPowerStatusChange c)
{
updateStatus = true;
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removed, ItemStack added)
{
if ( clust != null )
clust.updateStatus( true );
}
@Override
public int[] getAccessibleSlotsBySide(ForgeDirection side)
{
if ( isCenter() )
return sidesLink;
return sidesRing;
}
@Override
public void disconnect(boolean affectWorld)
{
if ( clust != null )
{
if ( !affectWorld )
clust.updateStatus = false;
clust.destroy();
}
clust = null;
if ( affectWorld )
gridProxy.setValidSides( EnumSet.noneOf( ForgeDirection.class ) );
}
@Override
public IAECluster getCluster()
{
return clust;
}
@Override
public boolean isValid()
{
return !isInvalid();
}
@Override
public void onReady()
{
super.onReady();
if ( worldObj.getBlock( xCoord, yCoord, zCoord ) == AEApi.instance().blocks().blockQuantumRing.block() )
gridProxy.setVisualRepresentation( ring );
}
@Override
public void invalidate()
{
disconnect( false );
super.invalidate();
}
@Override
public void onChunkUnload()
{
disconnect( false );
super.onChunkUnload();
}
public void updateStatus(QuantumCluster c, byte flags, boolean affectWorld)
{
clust = c;
if ( affectWorld )
{
if ( xdex != flags )
{
xdex = flags;
markForUpdate();
}
if ( isCorner() || isCenter() )
{
gridProxy.setValidSides( getConnections() );
}
else
gridProxy.setValidSides( EnumSet.allOf( ForgeDirection.class ) );
}
}
public long getQEDest()
{
ItemStack is = inv.getStackInSlot( 0 );
if ( is != null )
{
NBTTagCompound c = is.getTagCompound();
if ( c != null )
return c.getLong( "freq" );
}
return 0;
}
public boolean isCenter()
{
return getBlockType() == AEApi.instance().blocks().blockQuantumLink.block();
}
public boolean isCorner()
{
return (xdex & corner) == corner && xdex != -1;
}
public boolean isPowered()
{
if ( Platform.isClient() )
return (xdex & powered) == powered && xdex != -1;
try
{
return gridProxy.getEnergy().isNetworkPowered();
}
catch (GridAccessException e)
{
// :P
}
return false;
}
public boolean isFormed()
{
return xdex != -1;
}
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
return AECableType.DENSE;
}
@Override
public DimensionalCoord getLocation()
{
return new DimensionalCoord( this );
}
public void neighborUpdate()
{
calc.calculateMultiblock( worldObj, getLocation() );
}
public EnumSet<ForgeDirection> getConnections()
{
EnumSet<ForgeDirection> set = EnumSet.noneOf( ForgeDirection.class );
for (ForgeDirection d : ForgeDirection.VALID_DIRECTIONS)
{
TileEntity te = worldObj.getTileEntity( xCoord + d.offsetX, yCoord + d.offsetY, zCoord + d.offsetZ );
if ( te instanceof TileQuantumBridge )
set.add( d );
}
return set;
}
public boolean hasQES()
{
if ( xdex == -1 )
return false;
return (xdex & hasSingularity) == hasSingularity;
}
public void breakCluster()
{
if ( clust != null )
clust.destroy();
}
}
@@ -0,0 +1,182 @@
package appeng.tile.spatial;
import java.util.concurrent.Callable;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.config.YesNo;
import appeng.api.implementations.TransitionResult;
import appeng.api.implementations.items.ISpatialStorageCell;
import appeng.api.networking.GridFlags;
import appeng.api.networking.IGrid;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.events.MENetworkEvent;
import appeng.api.networking.events.MENetworkSpatialEvent;
import appeng.api.networking.spatial.ISpatialCache;
import appeng.api.util.AECableType;
import appeng.api.util.DimensionalCoord;
import appeng.hooks.TickHandler;
import appeng.items.storage.ItemSpatialStorageCell;
import appeng.me.cache.SpatialPylonCache;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkInvTile;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.Platform;
public class TileSpatialIOPort extends AENetworkInvTile implements Callable
{
final int sides[] = { 0, 1 };
AppEngInternalInventory inv = new AppEngInternalInventory( this, 2 );
YesNo lastRedstoneState = YesNo.UNDECIDED;
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_TileSpatialIOPort(NBTTagCompound data)
{
data.setInteger( "lastRedstoneState", lastRedstoneState.ordinal() );
}
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_TileSpatialIOPort(NBTTagCompound data)
{
if ( data.hasKey( "lastRedstoneState" ) )
lastRedstoneState = YesNo.values()[data.getInteger( "lastRedstoneState" )];
}
public TileSpatialIOPort() {
gridProxy.setFlags( GridFlags.REQUIRE_CHANNEL );
}
public void updateRedstoneState()
{
YesNo currentState = worldObj.isBlockIndirectlyGettingPowered( xCoord, yCoord, zCoord ) ? YesNo.YES : YesNo.NO;
if ( lastRedstoneState != currentState )
{
lastRedstoneState = currentState;
if ( lastRedstoneState == YesNo.YES )
triggerTransition();
}
}
public boolean getRedstoneState()
{
if ( lastRedstoneState == YesNo.UNDECIDED )
updateRedstoneState();
return lastRedstoneState == YesNo.YES;
}
private void triggerTransition()
{
if ( Platform.isServer() )
{
ItemStack cell = getStackInSlot( 0 );
if ( isSpatialCell( cell ) )
{
TickHandler.instance.addCallable( null, this );// this needs to be cross world synced.
}
}
}
@Override
public Object call() throws Exception
{
ItemStack cell = getStackInSlot( 0 );
if ( isSpatialCell( cell ) && getStackInSlot( 1 ) == null )
{
IGrid gi = gridProxy.getGrid();
IEnergyGrid energy = gridProxy.getEnergy();
ItemSpatialStorageCell sc = (ItemSpatialStorageCell) cell.getItem();
SpatialPylonCache spc = (SpatialPylonCache) gi.getCache( ISpatialCache.class );
if ( spc.hasRegion() && spc.isValidRegion() )
{
double req = spc.requiredPower();
double pr = energy.extractAEPower( req, Actionable.SIMULATE, PowerMultiplier.CONFIG );
if ( Math.abs( pr - req ) < req * 0.001 )
{
MENetworkEvent res = gi.postEvent( new MENetworkSpatialEvent( this, req ) );
if ( !res.isCanceled() )
{
TransitionResult tr = sc.doSpatialTransition( cell, worldObj, spc.getMin(), spc.getMax(), true );
if ( tr.success )
{
energy.extractAEPower( req, Actionable.MODULATE, PowerMultiplier.CONFIG );
setInventorySlotContents( 0, null );
setInventorySlotContents( 1, cell );
}
}
}
}
}
return null;
}
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
return AECableType.SMART;
}
@Override
public DimensionalCoord getLocation()
{
return new DimensionalCoord( this );
}
@Override
public IInventory getInternalInventory()
{
return inv;
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack)
{
return (i == 0 ? isSpatialCell( itemstack ) : false);
}
private boolean isSpatialCell(ItemStack cell)
{
if ( cell != null && cell.getItem() instanceof ISpatialStorageCell )
{
ISpatialStorageCell sc = (ISpatialStorageCell) cell.getItem();
return sc != null && sc.isSpatialStorage( cell );
}
return false;
}
@Override
public boolean canInsertItem(int i, ItemStack itemstack, int j)
{
return isItemValidForSlot( i, itemstack );
}
@Override
public boolean canExtractItem(int i, ItemStack itemstack, int j)
{
return i == 1;
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removed, ItemStack added)
{
}
@Override
public int[] getAccessibleSlotsBySide(ForgeDirection side)
{
return sides;
}
}
@@ -0,0 +1,220 @@
package appeng.tile.spatial;
import io.netty.buffer.ByteBuf;
import java.io.IOException;
import java.util.EnumSet;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.networking.GridFlags;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.me.GridAccessException;
import appeng.me.cluster.IAEMultiBlock;
import appeng.me.cluster.implementations.SpatialPylonCalculator;
import appeng.me.cluster.implementations.SpatialPylonCluster;
import appeng.me.helpers.AENetworkProxy;
import appeng.me.helpers.AENetworkProxyMultiblock;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkTile;
public class TileSpatialPylon extends AENetworkTile implements IAEMultiBlock
{
public final int DISPLAY_ENDMIN = 0x01;
public final int DISPLAY_ENDMAX = 0x02;
public final int DISPLAY_MIDDLE = 0x01 + 0x02;
public final int DISPLAY_X = 0x04;
public final int DISPLAY_Y = 0x08;
public final int DISPLAY_Z = 0x04 + 0x08;
public final int MB_STATUS = 0x01 + 0x02 + 0x04 + 0x08;
public final int DISPLAY_ENABLED = 0x10;
public final int DISPLAY_POWEREDENABLED = 0x20;
public final int NET_STATUS = 0x10 + 0x20;
int displayBits = 0;
SpatialPylonCluster clust;
final SpatialPylonCalculator calc = new SpatialPylonCalculator( this );
boolean didHaveLight = false;
@Override
protected AENetworkProxy createProxy()
{
return new AENetworkProxyMultiblock( this, "proxy", getItemFromTile( this ), true );
}
@Override
public boolean canBeRotated()
{
return false;
}
@TileEvent(TileEventType.NETWORK_READ)
public boolean readFromStream_TileSpatialPylon(ByteBuf data) throws IOException
{
int old = displayBits;
displayBits = data.readByte();
return old != displayBits;
}
@TileEvent(TileEventType.NETWORK_WRITE)
public void writeToStream_TileSpatialPylon(ByteBuf data) throws IOException
{
data.writeByte( displayBits );
}
public TileSpatialPylon() {
gridProxy.setFlags( GridFlags.REQUIRE_CHANNEL, GridFlags.MULTIBLOCK );
gridProxy.setIdlePowerUsage( 0.5 );
gridProxy.setValidSides( EnumSet.noneOf( ForgeDirection.class ) );
}
@Override
public void onReady()
{
super.onReady();
onNeighborBlockChange();
}
@Override
public void markForUpdate()
{
super.markForUpdate();
boolean hasLight = getLightValue() > 0;
if ( hasLight != didHaveLight )
{
didHaveLight = hasLight;
worldObj.func_147451_t( xCoord, yCoord, zCoord );
// worldObj.updateAllLightTypes( xCoord, yCoord, zCoord );
}
}
public int getLightValue()
{
if ( (displayBits & DISPLAY_POWEREDENABLED) == DISPLAY_POWEREDENABLED )
{
return 8;
}
return 0;
}
@MENetworkEventSubscribe
public void powerRender(MENetworkPowerStatusChange c)
{
recalculateDisplay();
}
@MENetworkEventSubscribe
public void activeRender(MENetworkChannelsChanged c)
{
recalculateDisplay();
}
@Override
public void invalidate()
{
disconnect( false );
super.invalidate();
}
@Override
public void onChunkUnload()
{
disconnect( false );
super.onChunkUnload();
}
public void onNeighborBlockChange()
{
calc.calculateMultiblock( worldObj, getLocation() );
}
@Override
public SpatialPylonCluster getCluster()
{
return clust;
}
public void recalculateDisplay()
{
int oldBits = displayBits;
displayBits = 0;
if ( clust != null )
{
if ( clust.min.equals( getLocation() ) )
displayBits = DISPLAY_ENDMIN;
else if ( clust.max.equals( getLocation() ) )
displayBits = DISPLAY_ENDMAX;
else
displayBits = DISPLAY_MIDDLE;
switch (clust.currentAxis)
{
case X:
displayBits |= DISPLAY_X;
break;
case Y:
displayBits |= DISPLAY_Y;
break;
case Z:
displayBits |= DISPLAY_Z;
break;
default:
displayBits = 0;
break;
}
try
{
if ( gridProxy.getEnergy().isNetworkPowered() )
displayBits |= DISPLAY_POWEREDENABLED;
if ( clust.isValid && gridProxy.isActive() )
displayBits |= DISPLAY_ENABLED;
}
catch (GridAccessException e)
{
// nothing?
}
}
if ( oldBits != displayBits )
markForUpdate();
}
public void updateStatus(SpatialPylonCluster c)
{
clust = c;
gridProxy.setValidSides( c == null ? EnumSet.noneOf( ForgeDirection.class ) : EnumSet.allOf( ForgeDirection.class ) );
recalculateDisplay();
}
@Override
public void disconnect(boolean b)
{
if ( clust != null )
{
clust.destroy();
updateStatus( null );
}
}
@Override
public boolean isValid()
{
return true;
}
public int getDisplayBits()
{
return displayBits;
}
}
@@ -0,0 +1,840 @@
package appeng.tile.storage;
import io.netty.buffer.ByteBuf;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
import appeng.api.AEApi;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.config.Settings;
import appeng.api.config.SortDir;
import appeng.api.config.SortOrder;
import appeng.api.config.ViewItems;
import appeng.api.implementations.tiles.IColorableTile;
import appeng.api.implementations.tiles.IMEChest;
import appeng.api.networking.GridFlags;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.events.MENetworkCellArrayUpdate;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.events.MENetworkPowerStorage;
import appeng.api.networking.events.MENetworkPowerStorage.PowerEventType;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.security.MachineSource;
import appeng.api.networking.security.PlayerSource;
import appeng.api.networking.storage.IBaseMonitor;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.storage.ICellHandler;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.IMEMonitorHandlerReceiver;
import appeng.api.storage.IStorageMonitorable;
import appeng.api.storage.ITerminalHost;
import appeng.api.storage.MEMonitorHandler;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import appeng.api.util.AEColor;
import appeng.api.util.IConfigManager;
import appeng.helpers.IPriorityHost;
import appeng.me.GridAccessException;
import appeng.me.storage.MEInventoryHandler;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkPowerTile;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost;
import appeng.util.Platform;
import appeng.util.item.AEFluidStack;
public class TileChest extends AENetworkPowerTile implements IMEChest, IFluidHandler, ITerminalHost, IPriorityHost, IConfigManagerHost, IColorableTile
{
static private class ChestNoHandler extends Exception
{
private static final long serialVersionUID = 7995805326136526631L;
}
static final ChestNoHandler noHandler = new ChestNoHandler();
static final int sides[] = new int[] { 0 };
static final int front[] = new int[] { 1 };
static final int noslots[] = new int[] {};
AppEngInternalInventory inv = new AppEngInternalInventory( this, 2 );
BaseActionSource mySrc = new MachineSource( this );
IConfigManager config = new ConfigManager( this );
ItemStack storageType;
long lastStateChange = 0;
int priority = 0;
int state = 0;
boolean wasActive = false;
AEColor paintedColor = AEColor.Transparent;
private void recalculateDisplay()
{
int oldState = state;
for (int x = 0; x < getCellCount(); x++)
state |= (getCellStatus( x ) << (3 * x));
if ( isPowered() )
state |= 0x40;
else
state &= ~0x40;
boolean currentActive = gridProxy.isActive();
if ( wasActive != currentActive )
{
wasActive = currentActive;
try
{
gridProxy.getGrid().postEvent( new MENetworkCellArrayUpdate() );
}
catch (GridAccessException e)
{
// :P
}
}
if ( oldState != state )
markForUpdate();
}
@Override
protected void PowerEvent(PowerEventType x)
{
if ( x == PowerEventType.REQUEST_POWER )
{
try
{
gridProxy.getGrid().postEvent( new MENetworkPowerStorage( this, PowerEventType.REQUEST_POWER ) );
}
catch (GridAccessException e)
{
// :(
}
}
else
recalculateDisplay();
}
@TileEvent(TileEventType.TICK)
public void Tick_TileChest()
{
if ( worldObj.isRemote )
return;
double idleUsage = gridProxy.getIdlePowerUsage();
try
{
if ( !gridProxy.getEnergy().isNetworkPowered() )
{
double powerUsed = extractAEPower( idleUsage, Actionable.MODULATE, PowerMultiplier.CONFIG ); // drain
if ( powerUsed + 0.1 >= idleUsage != (state & 0x40) > 0 )
recalculateDisplay();
}
}
catch (GridAccessException e)
{
double powerUsed = extractAEPower( gridProxy.getIdlePowerUsage(), Actionable.MODULATE, PowerMultiplier.CONFIG ); // drain
if ( powerUsed + 0.1 >= idleUsage != (state & 0x40) > 0 )
recalculateDisplay();
}
if ( inv.getStackInSlot( 0 ) != null )
{
tryToStoreContents();
}
}
@TileEvent(TileEventType.NETWORK_WRITE)
public void writeToStream_TileChest(ByteBuf data) throws IOException
{
if ( worldObj.getTotalWorldTime() - lastStateChange > 8 )
state = 0;
else
state &= 0x24924924; // just keep the blinks...
for (int x = 0; x < getCellCount(); x++)
state |= (getCellStatus( x ) << (3 * x));
if ( isPowered() )
state |= 0x40;
else
state &= ~0x40;
data.writeByte( state );
data.writeByte( paintedColor.ordinal() );
ItemStack is = inv.getStackInSlot( 1 );
if ( is == null )
{
data.writeInt( 0 );
}
else
{
data.writeInt( (is.getItemDamage() << Platform.DEF_OFFSET) | Item.getIdFromItem( is.getItem() ) );
}
}
@TileEvent(TileEventType.NETWORK_READ)
public boolean readFromStream_TileChest(ByteBuf data) throws IOException
{
int oldState = state;
ItemStack oldType = storageType;
state = data.readByte();
AEColor oldPaintedColor = paintedColor;
paintedColor = AEColor.values()[data.readByte()];
int item = data.readInt();
if ( item == 0 )
storageType = null;
else
storageType = new ItemStack( Item.getItemById( item & 0xffff ), 1, item >> Platform.DEF_OFFSET );
lastStateChange = worldObj.getTotalWorldTime();
return oldPaintedColor != paintedColor || (state & 0xDB6DB6DB) != (oldState & 0xDB6DB6DB) || !Platform.isSameItemPrecise( oldType, storageType );
}
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_TileChest(NBTTagCompound data)
{
config.readFromNBT( data );
priority = data.getInteger( "priority" );
if ( data.hasKey( "paintedColor" ) )
paintedColor = AEColor.values()[data.getByte( "paintedColor" )];
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_TileChest(NBTTagCompound data)
{
config.writeToNBT( data );
data.setInteger( "priority", priority );
data.setByte( "paintedColor", (byte) paintedColor.ordinal() );
}
@MENetworkEventSubscribe
public void powerRender(MENetworkPowerStatusChange c)
{
recalculateDisplay();
}
@MENetworkEventSubscribe
public void channelRender(MENetworkChannelsChanged c)
{
recalculateDisplay();
}
public TileChest()
{
internalMaxPower = PowerMultiplier.CONFIG.multiply( 40 );
gridProxy.setFlags( GridFlags.REQUIRE_CHANNEL );
config.registerSetting( Settings.SORT_BY, SortOrder.NAME );
config.registerSetting( Settings.VIEW_MODE, ViewItems.ALL );
config.registerSetting( Settings.SORT_DIRECTION, SortDir.ASCENDING );
internalPublicPowerStorage = true;
internalPowerFlow = AccessRestriction.WRITE;
}
boolean isCached = false;
private ICellHandler cellHandler;
private MEMonitorHandler icell;
private MEMonitorHandler fcell;
@Override
public IMEMonitor getItemInventory()
{
return icell;
}
@Override
public IMEMonitor getFluidInventory()
{
return fcell;
}
class ChestNetNotifier<T extends IAEStack<T>> implements IMEMonitorHandlerReceiver<T>
{
final StorageChannel chan;
public ChestNetNotifier(StorageChannel chan)
{
this.chan = chan;
}
@Override
public void postChange(IBaseMonitor<T> monitor, Iterable<T> change, BaseActionSource source)
{
if ( source == mySrc || (source instanceof PlayerSource && ((PlayerSource) source).via == TileChest.this) )
{
try
{
if ( gridProxy.isActive() )
gridProxy.getStorage().postAlterationOfStoredItems( chan, change, mySrc );
}
catch (GridAccessException e)
{
// :(
}
}
blinkCell( 0 );
}
@Override
public boolean isValid(Object verificationToken)
{
if ( chan == StorageChannel.ITEMS )
return verificationToken == icell;
if ( chan == StorageChannel.FLUIDS )
return verificationToken == fcell;
return false;
}
@Override
public void onListUpdate()
{
// not used here
}
};
class ChestMonitorHandler<T extends IAEStack> extends MEMonitorHandler<T>
{
public ChestMonitorHandler(IMEInventoryHandler<T> t)
{
super( t );
}
public IMEInventoryHandler<T> getInternalHandler()
{
IMEInventoryHandler<T> h = getHandler();
if ( h instanceof MEInventoryHandler )
return (IMEInventoryHandler<T>) ((MEInventoryHandler) h).getInternal();
return this.getHandler();
}
};
private <StackType extends IAEStack> MEMonitorHandler<StackType> wrap(IMEInventoryHandler h)
{
if ( h == null )
return null;
MEInventoryHandler ih = new MEInventoryHandler( h, h.getChannel() );
ih.myPriority = priority;
MEMonitorHandler<StackType> g = new ChestMonitorHandler<StackType>( ih );
g.addListener( new ChestNetNotifier( h.getChannel() ), g );
return g;
}
public IMEInventoryHandler getHandler(StorageChannel channel) throws ChestNoHandler
{
if ( !isCached )
{
icell = null;
fcell = null;
ItemStack is = inv.getStackInSlot( 1 );
if ( is != null )
{
isCached = true;
cellHandler = AEApi.instance().registries().cell().getHandler( is );
if ( cellHandler != null )
{
double power = 1.0;
IMEInventoryHandler<IAEItemStack> itemCell = cellHandler.getCellInventory( is, this, StorageChannel.ITEMS );
IMEInventoryHandler<IAEFluidStack> fluidCell = cellHandler.getCellInventory( is, this, StorageChannel.FLUIDS );
if ( itemCell != null )
power += cellHandler.cellIdleDrain( is, itemCell );
else if ( fluidCell != null )
power += cellHandler.cellIdleDrain( is, fluidCell );
gridProxy.setIdlePowerUsage( power );
icell = wrap( itemCell );
fcell = wrap( fluidCell );
}
}
}
switch (channel)
{
case FLUIDS:
if ( fcell == null )
throw noHandler;
return fcell;
case ITEMS:
if ( icell == null )
throw noHandler;
return icell;
default:
}
return null;
}
@Override
public IInventory getInternalInventory()
{
return inv;
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removed, ItemStack added)
{
if ( slot == 1 )
{
icell = null;
fcell = null;
isCached = false; // recalculate the storage cell.
try
{
gridProxy.getGrid().postEvent( new MENetworkCellArrayUpdate() );
IStorageGrid gs = gridProxy.getStorage();
Platform.postChanges( gs, removed, added, mySrc );
}
catch (GridAccessException e)
{
}
// update the neighbors
if ( worldObj != null )
{
Platform.notifyBlocksOfNeighbors( worldObj, xCoord, yCoord, zCoord );
markForUpdate();
}
}
}
@Override
public void setInventorySlotContents(int i, ItemStack itemstack)
{
inv.setInventorySlotContents( i, itemstack );
tryToStoreContents();
}
private void tryToStoreContents()
{
try
{
if ( getStackInSlot( 0 ) != null )
{
IMEInventory<IAEItemStack> cell = getHandler( StorageChannel.ITEMS );
IAEItemStack returns = Platform.poweredInsert( this, cell, AEApi.instance().storage().createItemStack( inv.getStackInSlot( 0 ) ), mySrc );
if ( returns == null )
inv.setInventorySlotContents( 0, null );
else
inv.setInventorySlotContents( 0, returns.getItemStack() );
}
}
catch (ChestNoHandler t)
{
}
}
@Override
public boolean canExtractItem(int i, ItemStack itemstack, int j)
{
return i == 1;
}
@Override
public boolean canInsertItem(int i, ItemStack itemstack, int j)
{
if ( i == 1 )
{
if ( AEApi.instance().registries().cell().getCellInventory( itemstack, this, StorageChannel.ITEMS ) != null )
return true;
if ( AEApi.instance().registries().cell().getCellInventory( itemstack, this, StorageChannel.FLUIDS ) != null )
return true;
}
else
{
try
{
IMEInventory<IAEItemStack> cell = getHandler( StorageChannel.ITEMS );
IAEItemStack returns = cell.injectItems( AEApi.instance().storage().createItemStack( inv.getStackInSlot( 0 ) ), Actionable.SIMULATE, mySrc );
return returns == null || returns.getStackSize() != itemstack.stackSize;
}
catch (ChestNoHandler t)
{
}
}
return false;
}
@Override
public int[] getAccessibleSlotsBySide(ForgeDirection side)
{
if ( ForgeDirection.SOUTH == side )
return front;
if ( isPowered() )
{
try
{
if ( getHandler( StorageChannel.ITEMS ) != null )
return sides;
}
catch (ChestNoHandler e)
{
// nope!
}
}
return noslots;
}
@Override
public List<IMEInventoryHandler> getCellArray(StorageChannel channel)
{
if ( gridProxy.isActive() )
{
try
{
return Arrays.asList( new IMEInventoryHandler[] { getHandler( channel ) } );
}
catch (ChestNoHandler e)
{
// :P
}
}
return new ArrayList();
}
@Override
public int getPriority()
{
return priority;
}
@Override
public int getCellCount()
{
return 1;
}
@Override
public void blinkCell(int slot)
{
long now = worldObj.getTotalWorldTime();
if ( now - lastStateChange > 8 )
state = 0;
lastStateChange = now;
state |= 1 << (slot * 3 + 2);
recalculateDisplay();
}
@Override
public boolean isCellBlinking(int slot)
{
long now = worldObj.getTotalWorldTime();
if ( now - lastStateChange > 8 )
return false;
return ((state >> (slot * 3 + 2)) & 0x01) == 0x01;
}
@Override
public int getCellStatus(int slot)
{
if ( Platform.isClient() )
return (state >> (slot * 3)) & 3;
ItemStack cell = inv.getStackInSlot( 1 );
ICellHandler ch = AEApi.instance().registries().cell().getHandler( cell );
if ( ch != null )
{
try
{
IMEInventoryHandler handler = getHandler( StorageChannel.ITEMS );
if ( ch != null && handler instanceof ChestMonitorHandler )
return ch.getStatusForCell( cell, ((ChestMonitorHandler) handler).getInternalHandler() );
}
catch (ChestNoHandler e)
{
}
try
{
IMEInventoryHandler handler = getHandler( StorageChannel.FLUIDS );
if ( ch != null && handler instanceof ChestMonitorHandler )
return ch.getStatusForCell( cell, ((ChestMonitorHandler) handler).getInternalHandler() );
}
catch (ChestNoHandler e)
{
}
}
return 0;
}
@Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
{
double req = resource.amount / 500.0;
double available = extractAEPower( req, Actionable.SIMULATE, PowerMultiplier.CONFIG );
if ( available >= req - 0.01 )
{
try
{
IMEInventoryHandler h = getHandler( StorageChannel.FLUIDS );
extractAEPower( req, Actionable.MODULATE, PowerMultiplier.CONFIG );
IAEStack results = h.injectItems( AEFluidStack.create( resource ), doFill ? Actionable.MODULATE : Actionable.SIMULATE, mySrc );
if ( results == null )
return resource.amount;
return resource.amount - (int) results.getStackSize();
}
catch (ChestNoHandler e)
{
}
}
return 0;
}
@Override
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
{
return null;
}
@Override
public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
{
return null;
}
@Override
public boolean canFill(ForgeDirection from, Fluid fluid)
{
try
{
IMEInventoryHandler h = getHandler( StorageChannel.FLUIDS );
return h.canAccept( AEFluidStack.create( new FluidStack( fluid, 1 ) ) );
}
catch (ChestNoHandler e)
{
}
return false;
}
@Override
public boolean canDrain(ForgeDirection from, Fluid fluid)
{
return false;
}
@Override
public FluidTankInfo[] getTankInfo(ForgeDirection from)
{
try
{
IMEInventoryHandler h = getHandler( StorageChannel.FLUIDS );
if ( h.getChannel() == StorageChannel.FLUIDS )
return new FluidTankInfo[] { new FluidTankInfo( null, 1 ) }; // eh?
}
catch (ChestNoHandler e)
{
}
return null;
}
@Override
protected double extractAEPower(double amt, Actionable mode)
{
double stash = 0.0;
IEnergyGrid eg;
try
{
eg = gridProxy.getEnergy();
stash = eg.extractAEPower( amt, mode, PowerMultiplier.ONE );
if ( stash >= amt )
return stash;
}
catch (GridAccessException e)
{
// no grid :(
}
// local battery!
return super.extractAEPower( amt - stash, mode ) + stash;
}
@Override
public boolean isPowered()
{
if ( Platform.isClient() )
return (state & 0x40) == 0x40;
boolean gridPowered = getAECurrentPower() > 64;
if ( !gridPowered )
{
try
{
gridPowered = gridProxy.getEnergy().isNetworkPowered();
}
catch (GridAccessException e)
{
}
}
return super.getAECurrentPower() > 1 || gridPowered;
}
@Override
public IStorageMonitorable getMonitorable(ForgeDirection side, BaseActionSource src)
{
if ( Platform.canAccess( gridProxy, src ) && side != getForward() )
return this;
return null;
}
public ItemStack getStorageType()
{
if ( isPowered() )
return storageType;
return null;
}
@Override
public void setPriority(int newValue)
{
priority = newValue;
icell = null;
fcell = null;
isCached = false; // recalculate the storage cell.
try
{
gridProxy.getGrid().postEvent( new MENetworkCellArrayUpdate() );
}
catch (GridAccessException e)
{
// :P
}
}
@Override
public IConfigManager getConfigManager()
{
return config;
}
@Override
public void updateSetting(IConfigManager manager, Enum settingName, Enum newValue)
{
}
public boolean openGui(EntityPlayer p, ICellHandler ch, ItemStack cell, int side)
{
try
{
IMEInventoryHandler ih = this.getHandler( StorageChannel.ITEMS );
if ( ch != null && ih != null )
{
IMEInventoryHandler mine = ih;
ch.openChestGui( p, this, ch, mine, cell, StorageChannel.ITEMS );
return true;
}
}
catch (ChestNoHandler e)
{
// :P
}
try
{
IMEInventoryHandler fh = this.getHandler( StorageChannel.FLUIDS );
if ( ch != null && fh != null )
{
IMEInventoryHandler mine = fh;
ch.openChestGui( p, this, ch, mine, cell, StorageChannel.FLUIDS );
return true;
}
}
catch (ChestNoHandler e)
{
// :P
}
return false;
}
public AEColor getColor()
{
return paintedColor;
}
@Override
public boolean recolourBlock(ForgeDirection side, AEColor newPaintedColor, EntityPlayer who)
{
if ( paintedColor == newPaintedColor )
return false;
paintedColor = newPaintedColor;
markDirty();
markForUpdate();
return true;
}
@Override
public void saveChanges(IMEInventory cellInventory)
{
worldObj.markTileEntityChunkModified( this.xCoord, this.yCoord, this.zCoord, this );
}
}
@@ -0,0 +1,370 @@
package appeng.tile.storage;
import io.netty.buffer.ByteBuf;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.AEApi;
import appeng.api.implementations.tiles.IChestOrDrive;
import appeng.api.networking.GridFlags;
import appeng.api.networking.events.MENetworkCellArrayUpdate;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.security.MachineSource;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.storage.ICellHandler;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.AECableType;
import appeng.api.util.DimensionalCoord;
import appeng.helpers.IPriorityHost;
import appeng.me.GridAccessException;
import appeng.me.storage.DriveWatcher;
import appeng.me.storage.MEInventoryHandler;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkInvTile;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.Platform;
public class TileDrive extends AENetworkInvTile implements IChestOrDrive, IPriorityHost
{
final int sides[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
AppEngInternalInventory inv = new AppEngInternalInventory( this, 10 );
boolean isCached = false;
ICellHandler handlersBySlot[] = new ICellHandler[10];
DriveWatcher<IAEItemStack> invBySlot[] = new DriveWatcher[10];
List<MEInventoryHandler> items = new LinkedList();
List<MEInventoryHandler> fluids = new LinkedList();
BaseActionSource mySrc;
long lastStateChange = 0;
int state = 0;
int priority = 0;
boolean wasActive = false;
private void recalculateDisplay()
{
int oldState = 0;
boolean currentActive;
if ( currentActive = gridProxy.isActive() )
state |= 0x80000000;
else
state &= ~0x80000000;
if ( wasActive != currentActive )
{
wasActive = currentActive;
try
{
gridProxy.getGrid().postEvent( new MENetworkCellArrayUpdate() );
}
catch (GridAccessException e)
{
// :P
}
}
for (int x = 0; x < getCellCount(); x++)
state |= (getCellStatus( x ) << (3 * x));
if ( oldState != state )
markForUpdate();
}
@TileEvent(TileEventType.NETWORK_WRITE)
public void writeToStream_TileDrive(ByteBuf data) throws IOException
{
if ( worldObj.getTotalWorldTime() - lastStateChange > 8 )
state = 0;
else
state &= 0x24924924; // just keep the blinks...
if ( gridProxy.isActive() )
state |= 0x80000000;
else
state &= ~0x80000000;
for (int x = 0; x < getCellCount(); x++)
state |= (getCellStatus( x ) << (3 * x));
data.writeInt( state );
}
@TileEvent(TileEventType.NETWORK_READ)
public boolean readFromStream_TileDrive(ByteBuf data) throws IOException
{
int oldState = state;
state = data.readInt();
lastStateChange = worldObj.getTotalWorldTime();
return (state & 0xDB6DB6DB) != (oldState & 0xDB6DB6DB);
}
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_TileDrive(NBTTagCompound data)
{
isCached = false;
priority = data.getInteger( "priority" );
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_TileDrive(NBTTagCompound data)
{
data.setInteger( "priority", priority );
}
@MENetworkEventSubscribe
public void powerRender(MENetworkPowerStatusChange c)
{
recalculateDisplay();
}
@MENetworkEventSubscribe
public void channelRender(MENetworkChannelsChanged c)
{
recalculateDisplay();
}
public TileDrive() {
mySrc = new MachineSource( this );
gridProxy.setFlags( GridFlags.REQUIRE_CHANNEL );
}
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
return AECableType.SMART;
}
@Override
public DimensionalCoord getLocation()
{
return new DimensionalCoord( this );
}
@Override
public IInventory getInternalInventory()
{
return inv;
}
@Override
public void onReady()
{
super.onReady();
updateState();
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removed, ItemStack added)
{
if ( isCached )
{
isCached = false; // recalculate the storage cell.
updateState();
}
try
{
gridProxy.getGrid().postEvent( new MENetworkCellArrayUpdate() );
IStorageGrid gs = gridProxy.getStorage();
Platform.postChanges( gs, removed, added, mySrc );
}
catch (GridAccessException e)
{
}
markForUpdate();
}
@Override
public int[] getAccessibleSlotsBySide(ForgeDirection side)
{
return sides;
}
public void updateState()
{
if ( !isCached )
{
items = new LinkedList();
fluids = new LinkedList();
double power = 2.0;
for (int x = 0; x < inv.getSizeInventory(); x++)
{
ItemStack is = inv.getStackInSlot( x );
invBySlot[x] = null;
handlersBySlot[x] = null;
if ( is != null )
{
handlersBySlot[x] = AEApi.instance().registries().cell().getHandler( is );
if ( handlersBySlot[x] != null )
{
IMEInventoryHandler cell = handlersBySlot[x].getCellInventory( is, this, StorageChannel.ITEMS );
if ( cell != null )
{
power += handlersBySlot[x].cellIdleDrain( is, cell );
DriveWatcher<IAEItemStack> ih = new DriveWatcher( cell, is, handlersBySlot[x], this );
ih.myPriority = priority;
invBySlot[x] = ih;
items.add( ih );
}
else
{
cell = handlersBySlot[x].getCellInventory( is, this, StorageChannel.FLUIDS );
if ( cell != null )
{
power += handlersBySlot[x].cellIdleDrain( is, cell );
DriveWatcher<IAEItemStack> ih = new DriveWatcher( cell, is, handlersBySlot[x], this );
ih.myPriority = priority;
invBySlot[x] = ih;
fluids.add( ih );
}
}
}
}
}
gridProxy.setIdlePowerUsage( power );
isCached = true;
}
}
@Override
public List<IMEInventoryHandler> getCellArray(StorageChannel channel)
{
if ( gridProxy.isActive() )
{
updateState();
return (List) (channel == StorageChannel.ITEMS ? items : fluids);
}
return new ArrayList();
}
@Override
public int getPriority()
{
return priority;
}
@Override
public int getCellCount()
{
return 10;
}
@Override
public void blinkCell(int slot)
{
long now = worldObj.getTotalWorldTime();
if ( now - lastStateChange > 8 )
state = 0;
lastStateChange = now;
state |= 1 << (slot * 3 + 2);
recalculateDisplay();
}
@Override
public boolean isCellBlinking(int slot)
{
long now = worldObj.getTotalWorldTime();
if ( now - lastStateChange > 8 )
return false;
return ((state >> (slot * 3 + 2)) & 0x01) == 0x01;
}
@Override
public int getCellStatus(int slot)
{
if ( Platform.isClient() )
return (state >> (slot * 3)) & 3;
ItemStack cell = inv.getStackInSlot( 2 );
ICellHandler ch = handlersBySlot[slot];
MEInventoryHandler handler = invBySlot[slot];
if ( handler == null )
return 0;
if ( handler.getChannel() == StorageChannel.ITEMS )
{
if ( ch != null )
return ch.getStatusForCell( cell, handler.getInternal() );
}
if ( handler.getChannel() == StorageChannel.FLUIDS )
{
if ( ch != null )
return ch.getStatusForCell( cell, handler.getInternal() );
}
return 0;
}
@Override
public boolean isPowered()
{
if ( Platform.isClient() )
return (state & 0x80000000) == 0x80000000;
return gridProxy.isActive();
}
@Override
public void setPriority(int newValue)
{
priority = newValue;
markDirty();
isCached = false; // recalculate the storage cell.
updateState();
try
{
gridProxy.getGrid().postEvent( new MENetworkCellArrayUpdate() );
}
catch (GridAccessException e)
{
// :P
}
}
public boolean isItemValidForSlot(int i, ItemStack itemstack)
{
return itemstack != null && AEApi.instance().registries().cell().isCellHandled( itemstack );
}
@Override
public void saveChanges(IMEInventory cellInventory)
{
worldObj.markTileEntityChunkModified( this.xCoord, this.yCoord, this.zCoord, this );
}
}
@@ -0,0 +1,422 @@
package appeng.tile.storage;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.FullnessMode;
import appeng.api.config.OperationMode;
import appeng.api.config.RedstoneMode;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
import appeng.api.config.YesNo;
import appeng.api.implementations.IUpgradeableHost;
import appeng.api.networking.GridFlags;
import appeng.api.networking.IGridNode;
import appeng.api.networking.energy.IEnergySource;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.security.MachineSource;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.api.util.AECableType;
import appeng.api.util.DimensionalCoord;
import appeng.api.util.IConfigManager;
import appeng.core.settings.TickRates;
import appeng.me.GridAccessException;
import appeng.parts.automation.UpgradeInventory;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkInvTile;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.inv.WrapperInventoryRange;
public class TileIOPort extends AENetworkInvTile implements IUpgradeableHost, IConfigManagerHost, IGridTickable
{
ConfigManager cm = new ConfigManager( this );
final int input[] = { 0, 1, 2, 3, 4, 5 };
final int output[] = { 6, 7, 8, 9, 10, 11 };
final int outputSlots[] = { 6, 7, 8, 9, 10, 11 };
AppEngInternalInventory cells = new AppEngInternalInventory( this, 12 );
UpgradeInventory upgrades = new UpgradeInventory( AEApi.instance().blocks().blockIOPort.block(), this, 3 );
BaseActionSource mySrc = new MachineSource( this );
YesNo lastRedstoneState = YesNo.UNDECIDED;
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBT_TileIOPort(NBTTagCompound data)
{
cm.writeToNBT( data );
cells.writeToNBT( data, "cells" );
upgrades.writeToNBT( data, "upgrades" );
data.setInteger( "lastRedstoneState", lastRedstoneState.ordinal() );
}
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBT_TileIOPort(NBTTagCompound data)
{
cm.readFromNBT( data );
cells.readFromNBT( data, "cells" );
upgrades.readFromNBT( data, "upgrades" );
if ( data.hasKey( "lastRedstoneState" ) )
lastRedstoneState = YesNo.values()[data.getInteger( "lastRedstoneState" )];
}
public TileIOPort() {
gridProxy.setFlags( GridFlags.REQUIRE_CHANNEL );
cm.registerSetting( Settings.REDSTONE_CONTROLLED, RedstoneMode.IGNORE );
cm.registerSetting( Settings.FULLNESS_MODE, FullnessMode.EMPTY );
cm.registerSetting( Settings.OPERATION_MODE, OperationMode.EMPTY );
}
@Override
public AECableType getCableConnectionType(ForgeDirection dir)
{
return AECableType.SMART;
}
@Override
public DimensionalCoord getLocation()
{
return new DimensionalCoord( this );
}
@Override
public IInventory getInternalInventory()
{
return cells;
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removed, ItemStack added)
{
if ( cells == inv )
{
updateTask();
}
}
private void updateTask()
{
try
{
if ( hasWork() )
gridProxy.getTick().wakeDevice( gridProxy.getNode() );
else
gridProxy.getTick().sleepDevice( gridProxy.getNode() );
}
catch (GridAccessException e)
{
// :P
}
}
public void updateRedstoneState()
{
YesNo currentState = worldObj.isBlockIndirectlyGettingPowered( xCoord, yCoord, zCoord ) ? YesNo.YES : YesNo.NO;
if ( lastRedstoneState != currentState )
{
lastRedstoneState = currentState;
updateTask();
}
}
public boolean getRedstoneState()
{
if ( lastRedstoneState == YesNo.UNDECIDED )
updateRedstoneState();
return lastRedstoneState == YesNo.YES;
}
private boolean isEnabled()
{
if ( getInstalledUpgrades( Upgrades.REDSTONE ) == 0 )
return true;
RedstoneMode rs = (RedstoneMode) cm.getSetting( Settings.REDSTONE_CONTROLLED );
if ( rs == RedstoneMode.HIGH_SIGNAL )
return getRedstoneState();
return !getRedstoneState();
}
@Override
public int[] getAccessibleSlotsBySide(ForgeDirection d)
{
if ( d == ForgeDirection.UP || d == ForgeDirection.DOWN )
return input;
return output;
}
@Override
public IConfigManager getConfigManager()
{
return cm;
}
@Override
public IInventory getInventoryByName(String name)
{
if ( name.equals( "upgrades" ) )
return upgrades;
if ( name.equals( "cells" ) )
return cells;
return null;
}
@Override
public int getInstalledUpgrades(Upgrades u)
{
return upgrades.getInstalledUpgrades( u );
}
@Override
public void updateSetting(IConfigManager manager, Enum settingName, Enum newValue)
{
updateTask();
}
boolean hasWork()
{
if ( isEnabled() )
{
for (int x = 0; x < 6; x++)
if ( cells.getStackInSlot( x ) != null )
return true;
}
return false;
}
@Override
public TickingRequest getTickingRequest(IGridNode node)
{
return new TickingRequest( TickRates.IOPort.min, TickRates.IOPort.max, hasWork(), false );
}
@Override
public TickRateModulation tickingRequest(IGridNode node, int TicksSinceLastCall)
{
if ( !gridProxy.isActive() )
return TickRateModulation.IDLE;
long ItemsToMove = 256;
switch (getInstalledUpgrades( Upgrades.SPEED ))
{
case 1:
ItemsToMove *= 2;
break;
case 2:
ItemsToMove *= 4;
break;
case 3:
ItemsToMove *= 8;
break;
}
try
{
IMEInventory<IAEItemStack> itemNet = gridProxy.getStorage().getItemInventory();
IMEInventory<IAEFluidStack> fluidNet = gridProxy.getStorage().getFluidInventory();
IEnergySource energy = gridProxy.getEnergy();
for (int x = 0; x < 6; x++)
{
ItemStack is = cells.getStackInSlot( x );
if ( is != null )
{
if ( ItemsToMove > 0 )
{
IMEInventory<IAEItemStack> itemInv = getInv( is, StorageChannel.ITEMS );
IMEInventory<IAEFluidStack> fluidInv = getInv( is, StorageChannel.FLUIDS );
if ( cm.getSetting( Settings.OPERATION_MODE ) == OperationMode.EMPTY )
{
if ( itemInv != null )
ItemsToMove = transferContents( energy, itemInv, itemNet, ItemsToMove, StorageChannel.ITEMS );
if ( fluidInv != null )
ItemsToMove = transferContents( energy, fluidInv, fluidNet, ItemsToMove, StorageChannel.FLUIDS );
}
else
{
if ( itemInv != null )
ItemsToMove = transferContents( energy, itemNet, itemInv, ItemsToMove, StorageChannel.ITEMS );
if ( fluidInv != null )
ItemsToMove = transferContents( energy, fluidNet, fluidInv, ItemsToMove, StorageChannel.FLUIDS );
}
if ( ItemsToMove > 0 && shouldMove( itemInv, fluidInv ) && !moveSlot( x ) )
return TickRateModulation.IDLE;
return TickRateModulation.URGENT;
}
else
return TickRateModulation.URGENT;
}
}
}
catch (GridAccessException e)
{
return TickRateModulation.IDLE;
}
// nothing left to do...
return TickRateModulation.SLEEP;
}
private boolean shouldMove(IMEInventory<IAEItemStack> itemInv, IMEInventory<IAEFluidStack> fluidInv)
{
FullnessMode fm = (FullnessMode) cm.getSetting( Settings.FULLNESS_MODE );
if ( itemInv != null && fluidInv != null )
return matches( fm, itemInv ) && matches( fm, fluidInv );
else if ( itemInv != null )
return matches( fm, itemInv );
else if ( fluidInv != null )
return matches( fm, fluidInv );
return true;
}
private boolean matches(FullnessMode fm, IMEInventory src)
{
if ( fm == FullnessMode.HALF )
return true;
IItemList<? extends IAEStack> myList;
if ( src instanceof IMEMonitor )
myList = ((IMEMonitor) src).getStorageList();
else
myList = src.getAvailableItems( src.getChannel().createList() );
if ( fm == FullnessMode.EMPTY )
return myList.isEmpty();
IAEStack test = myList.getFirstItem();
if ( test != null )
{
test.setStackSize( 1 );
return src.injectItems( test, Actionable.SIMULATE, mySrc ) != null;
}
return false;
}
ItemStack currentCell;
IMEInventory<IAEFluidStack> cachedFluid;
IMEInventory<IAEItemStack> cachedItem;
private IMEInventory getInv(ItemStack is, StorageChannel chan)
{
if ( currentCell != is )
{
currentCell = is;
cachedFluid = AEApi.instance().registries().cell().getCellInventory( is, null, StorageChannel.FLUIDS );
cachedItem = AEApi.instance().registries().cell().getCellInventory( is, null, StorageChannel.ITEMS );
}
if ( StorageChannel.ITEMS == chan )
return cachedItem;
return cachedFluid;
}
private long transferContents(IEnergySource energy, IMEInventory src, IMEInventory dest, long itemsToMove, StorageChannel chan)
{
IItemList<? extends IAEStack> myList;
if ( src instanceof IMEMonitor )
myList = ((IMEMonitor) src).getStorageList();
else
myList = src.getAvailableItems( src.getChannel().createList() );
boolean didStuff;
do
{
didStuff = false;
for (IAEStack s : myList)
{
long totalStackSize = s.getStackSize();
if ( totalStackSize > 0 )
{
IAEStack stack = dest.injectItems( s, Actionable.SIMULATE, mySrc );
long possible = 0;
if ( stack == null )
possible = totalStackSize;
else
possible = totalStackSize - stack.getStackSize();
if ( possible > 0 )
{
possible = Math.min( possible, itemsToMove );
s.setStackSize( possible );
IAEStack extracted = src.extractItems( s, Actionable.MODULATE, mySrc );
if ( extracted != null )
{
possible = extracted.getStackSize();
IAEStack failed = Platform.poweredInsert( energy, dest, extracted, mySrc );
if ( failed != null )
{
possible -= failed.getStackSize();
src.injectItems( failed, Actionable.MODULATE, mySrc );
}
if ( possible > 0 )
{
itemsToMove -= possible;
didStuff = true;
}
break;
}
}
}
}
}
while (itemsToMove > 0 && didStuff);
return itemsToMove;
}
private boolean moveSlot(int x)
{
WrapperInventoryRange wir = new WrapperInventoryRange( this, outputSlots, true );
ItemStack result = InventoryAdaptor.getAdaptor( wir, ForgeDirection.UNKNOWN ).addItems( getStackInSlot( x ) );
if ( result == null )
{
setInventorySlotContents( x, null );
return true;
}
return false;
}
}
@@ -0,0 +1,106 @@
package appeng.tile.storage;
import io.netty.buffer.ByteBuf;
import java.io.IOException;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.tile.AEBaseInvTile;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.Platform;
public class TileSkyChest extends AEBaseInvTile
{
final int sides[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 };
final AppEngInternalInventory inv = new AppEngInternalInventory( this, 9 * 4 );
@TileEvent(TileEventType.NETWORK_WRITE)
public void writeToStream_TileSkyChest(ByteBuf data) throws IOException
{
data.writeBoolean( playerOpen > 0 );
}
@TileEvent(TileEventType.NETWORK_READ)
public boolean readFromStream_TileSkyChest(ByteBuf data) throws IOException
{
int wasOpen = playerOpen;
playerOpen = data.readBoolean() ? 1 : 0;
if ( wasOpen != playerOpen )
lastEvent = System.currentTimeMillis();
return false; // TESR yo!
}
// server
public int playerOpen;
// client..
public long lastEvent;
public float lidAngle;
@Override
public boolean requiresTESR()
{
return true;
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removed, ItemStack added)
{
}
@Override
public IInventory getInternalInventory()
{
return inv;
}
@Override
public int[] getAccessibleSlotsBySide(ForgeDirection side)
{
return sides;
}
@Override
public void openInventory()
{
if ( Platform.isClient() )
return;
playerOpen++;
if ( playerOpen == 1 )
{
getWorldObj().playSoundEffect( xCoord + 0.5D, yCoord + 0.5D, zCoord + 0.5D, "random.chestopen", 0.5F, getWorldObj().rand.nextFloat() * 0.1F + 0.9F );
markForUpdate();
}
}
@Override
public void closeInventory()
{
if ( Platform.isClient() )
return;
playerOpen--;
if ( playerOpen < 0 )
playerOpen = 0;
if ( playerOpen == 0 )
{
getWorldObj().playSoundEffect( xCoord + 0.5D, yCoord + 0.5D, zCoord + 0.5D, "random.chestclosed", 0.5F,
getWorldObj().rand.nextFloat() * 0.1F + 0.9F );
markForUpdate();
}
}
}