1e20086799
* Extracts item comparison from Platform into their own helper. Renamed methods to be more more fitting for the actual comparison. Added documentation about each methods behaviour.
386 lines
10 KiB
Java
386 lines
10 KiB
Java
/*
|
|
* This file is part of Applied Energistics 2.
|
|
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
|
*
|
|
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
|
*/
|
|
|
|
package appeng.block;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import javax.annotation.Nonnull;
|
|
import javax.annotation.Nullable;
|
|
|
|
import com.google.common.collect.Lists;
|
|
|
|
import net.minecraft.block.Block;
|
|
import net.minecraft.block.ITileEntityProvider;
|
|
import net.minecraft.block.material.Material;
|
|
import net.minecraft.block.state.BlockStateContainer;
|
|
import net.minecraft.block.state.IBlockState;
|
|
import net.minecraft.entity.EntityLivingBase;
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
import net.minecraft.inventory.Container;
|
|
import net.minecraft.inventory.IInventory;
|
|
import net.minecraft.item.EnumDyeColor;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.tileentity.TileEntity;
|
|
import net.minecraft.util.EnumFacing;
|
|
import net.minecraft.util.EnumHand;
|
|
import net.minecraft.util.math.BlockPos;
|
|
import net.minecraft.world.IBlockAccess;
|
|
import net.minecraft.world.World;
|
|
import net.minecraftforge.common.property.ExtendedBlockState;
|
|
import net.minecraftforge.common.property.IExtendedBlockState;
|
|
import net.minecraftforge.common.property.IUnlistedProperty;
|
|
|
|
import appeng.api.implementations.items.IMemoryCard;
|
|
import appeng.api.implementations.items.MemoryCardMessages;
|
|
import appeng.api.implementations.tiles.IColorableTile;
|
|
import appeng.api.util.AEColor;
|
|
import appeng.api.util.IOrientable;
|
|
import appeng.block.networking.BlockCableBus;
|
|
import appeng.helpers.ICustomCollision;
|
|
import appeng.tile.AEBaseTile;
|
|
import appeng.tile.networking.TileCableBus;
|
|
import appeng.tile.storage.TileSkyChest;
|
|
import appeng.util.Platform;
|
|
import appeng.util.SettingsFrom;
|
|
|
|
|
|
public abstract class AEBaseTileBlock extends AEBaseBlock implements ITileEntityProvider
|
|
{
|
|
|
|
@Nonnull
|
|
private Class<? extends AEBaseTile> tileEntityType;
|
|
|
|
public AEBaseTileBlock( final Material mat )
|
|
{
|
|
super( mat );
|
|
}
|
|
|
|
public static final UnlistedDirection FORWARD = new UnlistedDirection( "forward" );
|
|
public static final UnlistedDirection UP = new UnlistedDirection( "up" );
|
|
|
|
@Override
|
|
public IBlockState getExtendedState( IBlockState state, IBlockAccess world, BlockPos pos )
|
|
{
|
|
// A subclass may decide it doesn't want extended block state for whatever reason
|
|
if( !( state instanceof IExtendedBlockState ) )
|
|
{
|
|
return state;
|
|
}
|
|
|
|
AEBaseTile tile = getTileEntity( world, pos );
|
|
if( tile == null )
|
|
{
|
|
return state; // No info available
|
|
}
|
|
|
|
IExtendedBlockState extState = (IExtendedBlockState) state;
|
|
return extState.withProperty( FORWARD, tile.getForward() ).withProperty( UP, tile.getUp() );
|
|
}
|
|
|
|
@Override
|
|
protected BlockStateContainer createBlockState()
|
|
{
|
|
return new ExtendedBlockState( this, getAEStates(), new IUnlistedProperty[] {
|
|
FORWARD,
|
|
UP
|
|
} );
|
|
}
|
|
|
|
@Override
|
|
public int getMetaFromState( IBlockState state )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
protected void setTileEntity( final Class<? extends AEBaseTile> c )
|
|
{
|
|
this.tileEntityType = c;
|
|
this.setInventory( IInventory.class.isAssignableFrom( c ) );
|
|
}
|
|
|
|
@Override
|
|
public boolean hasTileEntity( IBlockState state )
|
|
{
|
|
return hasBlockTileEntity();
|
|
}
|
|
|
|
private boolean hasBlockTileEntity()
|
|
{
|
|
return this.tileEntityType != null;
|
|
}
|
|
|
|
public Class<? extends AEBaseTile> getTileEntityClass()
|
|
{
|
|
return this.tileEntityType;
|
|
}
|
|
|
|
@Nullable
|
|
public <T extends AEBaseTile> T getTileEntity( final IBlockAccess w, final int x, final int y, final int z )
|
|
{
|
|
return this.getTileEntity( w, new BlockPos( x, y, z ) );
|
|
}
|
|
|
|
@Nullable
|
|
public <T extends AEBaseTile> T getTileEntity( final IBlockAccess w, final BlockPos pos )
|
|
{
|
|
if( !this.hasBlockTileEntity() )
|
|
{
|
|
return null;
|
|
}
|
|
|
|
final TileEntity te = w.getTileEntity( pos );
|
|
if( this.tileEntityType.isInstance( te ) )
|
|
{
|
|
return (T) te;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public final TileEntity createNewTileEntity( final World var1, final int var2 )
|
|
{
|
|
if( this.hasBlockTileEntity() )
|
|
{
|
|
try
|
|
{
|
|
return this.tileEntityType.newInstance();
|
|
}
|
|
catch( final InstantiationException e )
|
|
{
|
|
throw new IllegalStateException( "Failed to create a new instance of an illegal class " + this.tileEntityType, e );
|
|
}
|
|
catch( final IllegalAccessException e )
|
|
{
|
|
throw new IllegalStateException( "Failed to create a new instance of " + this.tileEntityType + ", because lack of permissions", e );
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public void breakBlock( final World w, final BlockPos pos, final IBlockState state )
|
|
{
|
|
final AEBaseTile te = this.getTileEntity( w, pos );
|
|
if( te != null )
|
|
{
|
|
final ArrayList<ItemStack> drops = new ArrayList<ItemStack>();
|
|
if( te.dropItems() )
|
|
{
|
|
te.getDrops( w, pos, drops );
|
|
}
|
|
else
|
|
{
|
|
te.getNoDrops( w, pos, drops );
|
|
}
|
|
|
|
// Cry ;_; ...
|
|
Platform.spawnDrops( w, pos, drops );
|
|
}
|
|
|
|
// super will remove the TE, as it is not an instance of BlockContainer
|
|
super.breakBlock( w, pos, state );
|
|
}
|
|
|
|
@Override
|
|
public final EnumFacing[] getValidRotations( final World w, final BlockPos pos )
|
|
{
|
|
final AEBaseTile obj = this.getTileEntity( w, pos );
|
|
if( obj != null && obj.canBeRotated() )
|
|
{
|
|
return EnumFacing.VALUES;
|
|
}
|
|
|
|
return super.getValidRotations( w, pos );
|
|
}
|
|
|
|
@Override
|
|
public boolean recolorBlock( final World world, final BlockPos pos, final EnumFacing side, final EnumDyeColor color )
|
|
{
|
|
final TileEntity te = this.getTileEntity( world, pos );
|
|
|
|
if( te instanceof IColorableTile )
|
|
{
|
|
final IColorableTile ct = (IColorableTile) te;
|
|
final AEColor c = ct.getColor();
|
|
final AEColor newColor = AEColor.values()[color.getMetadata()];
|
|
|
|
if( c != newColor )
|
|
{
|
|
ct.recolourBlock( side, newColor, null );
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
return super.recolorBlock( world, pos, side, color );
|
|
}
|
|
|
|
@Override
|
|
public int getComparatorInputOverride( IBlockState state, final World w, final BlockPos pos )
|
|
{
|
|
final TileEntity te = this.getTileEntity( w, pos );
|
|
if( te instanceof IInventory )
|
|
{
|
|
return Container.calcRedstoneFromInventory( (IInventory) te );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public boolean eventReceived( final IBlockState state, final World worldIn, final BlockPos pos, final int eventID, final int eventParam )
|
|
{
|
|
super.eventReceived( state, worldIn, pos, eventID, eventParam );
|
|
final TileEntity tileentity = worldIn.getTileEntity( pos );
|
|
return tileentity != null ? tileentity.receiveClientEvent( eventID, eventParam ) : false;
|
|
}
|
|
|
|
@Override
|
|
public void onBlockPlacedBy( final World w, final BlockPos pos, final IBlockState state, final EntityLivingBase placer, final ItemStack is )
|
|
{
|
|
if( is.hasDisplayName() )
|
|
{
|
|
final TileEntity te = this.getTileEntity( w, pos );
|
|
if( te instanceof AEBaseTile )
|
|
{
|
|
( (AEBaseTile) w.getTileEntity( pos ) ).setName( is.getDisplayName() );
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean onBlockActivated( final World w, final BlockPos pos, final IBlockState state, final EntityPlayer player, final EnumHand hand, final @Nullable ItemStack heldItem, final EnumFacing side, final float hitX, final float hitY, final float hitZ )
|
|
{
|
|
if( player != null && heldItem != null )
|
|
{
|
|
if( Platform.isWrench( player, heldItem, pos ) && player.isSneaking() )
|
|
{
|
|
final IBlockState blockState = w.getBlockState( pos );
|
|
final Block block = blockState.getBlock();
|
|
|
|
if( block == null )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
final AEBaseTile tile = this.getTileEntity( w, pos );
|
|
|
|
if( tile == null )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( tile instanceof TileCableBus || tile instanceof TileSkyChest )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
final ItemStack[] itemDropCandidates = Platform.getBlockDrops( w, pos );
|
|
final ItemStack op = new ItemStack( this );
|
|
|
|
for( final ItemStack ol : itemDropCandidates )
|
|
{
|
|
if( Platform.itemComparisons().isEqualItemType( ol, op ) )
|
|
{
|
|
final NBTTagCompound tag = tile.downloadSettings( SettingsFrom.DISMANTLE_ITEM );
|
|
if( tag != null )
|
|
{
|
|
ol.setTagCompound( tag );
|
|
}
|
|
}
|
|
}
|
|
|
|
if( block.removedByPlayer( blockState, w, pos, player, false ) )
|
|
{
|
|
final List<ItemStack> itemsToDrop = Lists.newArrayList( itemDropCandidates );
|
|
Platform.spawnDrops( w, pos, itemsToDrop );
|
|
w.setBlockToAir( pos );
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
if( heldItem.getItem() instanceof IMemoryCard && !( this instanceof BlockCableBus ) )
|
|
{
|
|
final IMemoryCard memoryCard = (IMemoryCard) heldItem.getItem();
|
|
final AEBaseTile tileEntity = this.getTileEntity( w, pos );
|
|
|
|
if( tileEntity == null )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
final String name = this.getUnlocalizedName();
|
|
|
|
if( player.isSneaking() )
|
|
{
|
|
final NBTTagCompound data = tileEntity.downloadSettings( SettingsFrom.MEMORY_CARD );
|
|
if( data != null )
|
|
{
|
|
memoryCard.setMemoryCardContents( heldItem, name, data );
|
|
memoryCard.notifyUser( player, MemoryCardMessages.SETTINGS_SAVED );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
final String savedName = memoryCard.getSettingsName( heldItem );
|
|
final NBTTagCompound data = memoryCard.getData( heldItem );
|
|
|
|
if( this.getUnlocalizedName().equals( savedName ) )
|
|
{
|
|
tileEntity.uploadSettings( SettingsFrom.MEMORY_CARD, data );
|
|
memoryCard.notifyUser( player, MemoryCardMessages.SETTINGS_LOADED );
|
|
}
|
|
else
|
|
{
|
|
memoryCard.notifyUser( player, MemoryCardMessages.INVALID_MACHINE );
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return this.onActivated( w, pos, player, hand, heldItem, side, hitX, hitY, hitZ );
|
|
}
|
|
|
|
@Override
|
|
public IOrientable getOrientable( final IBlockAccess w, final BlockPos pos )
|
|
{
|
|
return this.getTileEntity( w, pos );
|
|
}
|
|
|
|
@Override
|
|
public ICustomCollision getCustomCollision( final World w, final BlockPos pos )
|
|
{
|
|
final AEBaseTile te = this.getTileEntity( w, pos );
|
|
if( te instanceof ICustomCollision )
|
|
{
|
|
return (ICustomCollision) te;
|
|
}
|
|
|
|
return super.getCustomCollision( w, pos );
|
|
}
|
|
|
|
}
|