Files
Applied-Energistics-2/src/main/java/appeng/fluids/parts/PartFluidAnnihilationPlane.java
T

324 lines
8.6 KiB
Java

package appeng.fluids.parts;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.BlockLiquid;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fluids.IFluidBlock;
import net.minecraftforge.fluids.capability.IFluidHandler;
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.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.parts.IPart;
import appeng.api.parts.IPartCollisionHelper;
import appeng.api.parts.IPartHost;
import appeng.api.parts.IPartModel;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.channels.IFluidStorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.util.AECableType;
import appeng.api.util.AEPartLocation;
import appeng.core.AppEng;
import appeng.core.settings.TickRates;
import appeng.core.sync.packets.PacketTransitionEffect;
import appeng.fluids.util.AEFluidStack;
import appeng.items.parts.PartModels;
import appeng.me.GridAccessException;
import appeng.me.helpers.MachineSource;
import appeng.parts.PartBasicState;
import appeng.parts.automation.PlaneConnections;
import appeng.parts.automation.PlaneModels;
import appeng.util.Platform;
public class PartFluidAnnihilationPlane extends PartBasicState implements IGridTickable
{
private static final PlaneModels MODELS = new PlaneModels( "part/fluid_annihilation_plane_", "part/fluid_annihilation_plane_on_" );
@PartModels
public static List<IPartModel> getModels()
{
return MODELS.getModels();
}
private final IActionSource mySrc = new MachineSource( this );
public PartFluidAnnihilationPlane( final ItemStack is )
{
super( is );
}
@Override
public void getBoxes( final IPartCollisionHelper bch )
{
int minX = 1;
int minY = 1;
int maxX = 15;
int maxY = 15;
final IPartHost host = this.getHost();
if( host != null )
{
final TileEntity te = host.getTile();
final BlockPos pos = te.getPos();
final EnumFacing e = bch.getWorldX();
final EnumFacing u = bch.getWorldY();
if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( e.getOpposite() ) ), this.getSide() ) )
{
minX = 0;
}
if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( e ) ), this.getSide() ) )
{
maxX = 16;
}
if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( u.getOpposite() ) ), this.getSide() ) )
{
minY = 0;
}
if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( e ) ), this.getSide() ) )
{
maxY = 16;
}
}
bch.addBox( 5, 5, 14, 11, 11, 15 );
bch.addBox( minX, minY, 15, maxX, maxY, 16 );
}
public PlaneConnections getConnections()
{
final EnumFacing facingRight, facingUp;
AEPartLocation location = this.getSide();
switch( location )
{
case UP:
facingRight = EnumFacing.EAST;
facingUp = EnumFacing.NORTH;
break;
case DOWN:
facingRight = EnumFacing.WEST;
facingUp = EnumFacing.NORTH;
break;
case NORTH:
facingRight = EnumFacing.WEST;
facingUp = EnumFacing.UP;
break;
case SOUTH:
facingRight = EnumFacing.EAST;
facingUp = EnumFacing.UP;
break;
case WEST:
facingRight = EnumFacing.SOUTH;
facingUp = EnumFacing.UP;
break;
case EAST:
facingRight = EnumFacing.NORTH;
facingUp = EnumFacing.UP;
break;
default:
case INTERNAL:
return PlaneConnections.of( false, false, false, false );
}
boolean left = false, right = false, down = false, up = false;
final IPartHost host = this.getHost();
if( host != null )
{
final TileEntity te = host.getTile();
final BlockPos pos = te.getPos();
if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( facingRight.getOpposite() ) ), this.getSide() ) )
{
left = true;
}
if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( facingRight ) ), this.getSide() ) )
{
right = true;
}
if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( facingUp.getOpposite() ) ), this.getSide() ) )
{
down = true;
}
if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( facingUp ) ), this.getSide() ) )
{
up = true;
}
}
return PlaneConnections.of( up, right, down, left );
}
@Override
public void onNeighborChanged( IBlockAccess w, BlockPos pos, BlockPos neighbor )
{
if( pos.offset( this.getSide().getFacing() ).equals( neighbor ) )
{
this.refresh();
}
}
@Override
public float getCableConnectionLength( AECableType cable )
{
return 1;
}
private boolean isAnnihilationPlane( final TileEntity blockTileEntity, final AEPartLocation side )
{
if( blockTileEntity instanceof IPartHost )
{
final IPart p = ( (IPartHost) blockTileEntity ).getPart( side );
return p != null && p.getClass() == this.getClass();
}
return false;
}
private void refresh()
{
try
{
this.getProxy().getTick().alertDevice( this.getProxy().getNode() );
}
catch( final GridAccessException e )
{
// :P
}
}
@Override
@MENetworkEventSubscribe
public void chanRender( final MENetworkChannelsChanged c )
{
this.refresh();
this.getHost().markForUpdate();
}
@Override
@MENetworkEventSubscribe
public void powerRender( final MENetworkPowerStatusChange c )
{
this.refresh();
this.getHost().markForUpdate();
}
private TickRateModulation pickupFluid()
{
if( !this.getProxy().isActive() )
{
return TickRateModulation.SLEEP;
}
final TileEntity te = this.getTile();
final World w = te.getWorld();
final BlockPos pos = te.getPos().offset( this.getSide().getFacing() );
final IBlockState state = w.getBlockState( pos );
final Block block = state.getBlock();
if( block instanceof IFluidBlock || block instanceof BlockLiquid )
{
final IFluidHandler fh = FluidUtil.getFluidHandler( w, pos, null );
final IAEFluidStack blockFluid = AEFluidStack.fromFluidStack( fh.drain( Integer.MAX_VALUE, false ) );
if( blockFluid != null )
{
if( this.storeFluid( blockFluid, false ) )
{
this.storeFluid( AEFluidStack.fromFluidStack( fh.drain( Integer.MAX_VALUE, true ) ), true );
AppEng.proxy.sendToAllNearExcept( null, pos.getX(), pos.getY(), pos.getZ(), 64, w,
new PacketTransitionEffect( pos.getX(), pos.getY(), pos.getZ(), this.getSide(), true ) );
return TickRateModulation.URGENT;
}
return TickRateModulation.IDLE;
}
}
// nothing to do here :)
return TickRateModulation.SLEEP;
}
@Override
public TickingRequest getTickingRequest( final IGridNode node )
{
return new TickingRequest( TickRates.AnnihilationPlane.getMin(), TickRates.AnnihilationPlane.getMax(), false, true );
}
@Override
public TickRateModulation tickingRequest( final IGridNode node, final int ticksSinceLastCall )
{
return this.pickupFluid();
}
private boolean storeFluid( IAEFluidStack stack, boolean modulate )
{
try
{
final IStorageGrid storage = this.getProxy().getStorage();
final IMEInventory<IAEFluidStack> inv = storage.getInventory( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) );
if( modulate )
{
final IEnergyGrid energy = this.getProxy().getEnergy();
return Platform.poweredInsert( energy, inv, stack, this.mySrc ) == null;
}
else
{
final float requiredPower = stack.getStackSize() / Math.min( 1.0f, stack.getChannel().transferFactor() );
final IEnergyGrid energy = this.getProxy().getEnergy();
if( energy.extractAEPower( requiredPower, Actionable.SIMULATE, PowerMultiplier.CONFIG ) < requiredPower )
{
return false;
}
final IAEFluidStack leftOver = inv.injectItems( stack, Actionable.SIMULATE, this.mySrc );
return leftOver == null || leftOver.getStackSize() == 0;
}
}
catch( final GridAccessException e )
{
// :P
}
return false;
}
@Override
public IPartModel getStaticModels()
{
return MODELS.getModel( this.getConnections(), this.isPowered(), this.isActive() );
}
}