324 lines
8.6 KiB
Java
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() );
|
|
}
|
|
}
|