mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-11-20 23:34:48 +00:00
ComputerCraft 1.79 initial upload
Added the complete source code to ComputerCraft 1.79 for Minecraft 1.8.9, plus newly written README and LICENSE files for the open source release.
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.common;
|
||||
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public abstract class BlockDirectional extends BlockGeneric
|
||||
{
|
||||
protected BlockDirectional( Material material )
|
||||
{
|
||||
super( material );
|
||||
}
|
||||
|
||||
public EnumFacing getDirection( IBlockAccess world, BlockPos pos )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof IDirectionalTile )
|
||||
{
|
||||
IDirectionalTile directional = (IDirectionalTile)tile;
|
||||
return directional.getDirection();
|
||||
}
|
||||
return EnumFacing.NORTH;
|
||||
}
|
||||
|
||||
public void setDirection( World world, BlockPos pos, EnumFacing dir )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof IDirectionalTile )
|
||||
{
|
||||
IDirectionalTile directional = (IDirectionalTile)tile;
|
||||
directional.setDirection( dir );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,340 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.common;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.ITileEntityProvider;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BlockGeneric extends Block implements
|
||||
ITileEntityProvider
|
||||
{
|
||||
protected BlockGeneric( Material material )
|
||||
{
|
||||
super( material );
|
||||
this.isBlockContainer = true;
|
||||
}
|
||||
|
||||
protected abstract IBlockState getDefaultBlockState( int damage, EnumFacing placedSide );
|
||||
protected abstract TileGeneric createTile( IBlockState state );
|
||||
protected abstract TileGeneric createTile( int damage );
|
||||
|
||||
@Override
|
||||
public final void dropBlockAsItemWithChance( World world, BlockPos pos, IBlockState state, float chance, int fortune )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<ItemStack> getDrops( IBlockAccess world, BlockPos pos, IBlockState state, int fortune )
|
||||
{
|
||||
ArrayList<ItemStack> drops = new ArrayList<ItemStack>( 1 );
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileGeneric )
|
||||
{
|
||||
TileGeneric generic = (TileGeneric)tile;
|
||||
generic.getDroppedItems( drops, fortune, false, false );
|
||||
}
|
||||
return drops;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final IBlockState onBlockPlaced( World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ, int damage, EntityLivingBase placer )
|
||||
{
|
||||
return getDefaultBlockState( damage, side );
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean removedByPlayer( World world, BlockPos pos, EntityPlayer player, boolean willHarvest )
|
||||
{
|
||||
if( !world.isRemote )
|
||||
{
|
||||
// Drop items
|
||||
int fortune = EnchantmentHelper.getFortuneModifier( player );
|
||||
boolean creative = player.capabilities.isCreativeMode;
|
||||
boolean silkTouch = EnchantmentHelper.getSilkTouchModifier( player );
|
||||
dropAllItems( world, pos, fortune, creative, silkTouch );
|
||||
}
|
||||
|
||||
// Remove block
|
||||
return super.removedByPlayer( world, pos, player, willHarvest );
|
||||
}
|
||||
|
||||
public final void dropAllItems( World world, BlockPos pos, int fortune, boolean creative, boolean silkTouch )
|
||||
{
|
||||
// Get items to drop
|
||||
List<ItemStack> drops = new ArrayList<ItemStack>( 1 );
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileGeneric )
|
||||
{
|
||||
TileGeneric generic = (TileGeneric)tile;
|
||||
generic.getDroppedItems( drops, fortune, creative, silkTouch );
|
||||
}
|
||||
|
||||
// Drop items
|
||||
if( drops.size() > 0 )
|
||||
{
|
||||
Iterator<ItemStack> it = drops.iterator();
|
||||
while( it.hasNext() )
|
||||
{
|
||||
ItemStack item = it.next();
|
||||
dropItem( world, pos, item );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final void dropItem( World world, BlockPos pos, ItemStack stack )
|
||||
{
|
||||
Block.spawnAsEntity( world, pos, stack );
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void breakBlock( World world, BlockPos pos, IBlockState newState )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileGeneric )
|
||||
{
|
||||
TileGeneric generic = (TileGeneric)tile;
|
||||
generic.destroy();
|
||||
}
|
||||
super.breakBlock( world, pos, newState );
|
||||
world.removeTileEntity( pos );
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ItemStack getPickBlock( MovingObjectPosition target, World world, BlockPos pos, EntityPlayer player )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileGeneric )
|
||||
{
|
||||
TileGeneric generic = (TileGeneric)tile;
|
||||
return generic.getPickedItem();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final ItemStack createStackedBlock( IBlockState state )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean onBlockActivated( World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumFacing side, float hitX, float hitY, float hitZ )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileGeneric )
|
||||
{
|
||||
TileGeneric generic = (TileGeneric)tile;
|
||||
return generic.onActivate( player, side, hitX, hitY, hitZ );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onNeighborBlockChange( World world, BlockPos pos, IBlockState state, Block neighbour )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileGeneric )
|
||||
{
|
||||
TileGeneric generic = (TileGeneric)tile;
|
||||
generic.onNeighbourChange();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isSideSolid( IBlockAccess world, BlockPos pos, EnumFacing side )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileGeneric )
|
||||
{
|
||||
TileGeneric generic = (TileGeneric)tile;
|
||||
return generic.isSolidOnSide( side.ordinal() );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean canBeReplacedByLeaves( IBlockAccess world, BlockPos pos )
|
||||
{
|
||||
return false; // Generify me if anyone ever feels the need to change this
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getExplosionResistance( World world, BlockPos pos, Entity exploder, Explosion explosion )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileGeneric && tile.hasWorldObj() )
|
||||
{
|
||||
TileGeneric generic = (TileGeneric)tile;
|
||||
if( generic.isImmuneToExplosion( exploder ) )
|
||||
{
|
||||
return 2000.0f;
|
||||
}
|
||||
}
|
||||
return super.getExplosionResistance( exploder );
|
||||
}
|
||||
|
||||
private void setBlockBounds( AxisAlignedBB bounds )
|
||||
{
|
||||
setBlockBounds(
|
||||
(float)bounds.minX, (float)bounds.minY, (float)bounds.minZ,
|
||||
(float)bounds.maxX, (float)bounds.maxY, (float)bounds.maxZ
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setBlockBoundsBasedOnState( IBlockAccess world, BlockPos pos )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileGeneric && tile.hasWorldObj() )
|
||||
{
|
||||
TileGeneric generic = (TileGeneric)tile;
|
||||
setBlockBounds( generic.getBounds() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final AxisAlignedBB getCollisionBoundingBox( World world, BlockPos pos, IBlockState state )
|
||||
{
|
||||
setBlockBoundsBasedOnState( world, pos );
|
||||
return super.getCollisionBoundingBox( world, pos, state );
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void addCollisionBoxesToList( World world, BlockPos pos, IBlockState state, AxisAlignedBB bigBox, List list, Entity entity )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileGeneric )
|
||||
{
|
||||
TileGeneric generic = (TileGeneric)tile;
|
||||
|
||||
// Get collision bounds
|
||||
List<AxisAlignedBB> collision = new ArrayList<AxisAlignedBB>( 1 );
|
||||
generic.getCollisionBounds( collision );
|
||||
|
||||
// Add collision bounds to list
|
||||
if( collision.size() > 0 )
|
||||
{
|
||||
Iterator<AxisAlignedBB> it = collision.iterator();
|
||||
while( it.hasNext() )
|
||||
{
|
||||
AxisAlignedBB localBounds = it.next();
|
||||
setBlockBounds( localBounds );
|
||||
|
||||
AxisAlignedBB bounds = super.getCollisionBoundingBox( world, pos, state );
|
||||
if( bounds != null && bigBox.intersectsWith(bounds) )
|
||||
{
|
||||
list.add( bounds );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean canProvidePower()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean canConnectRedstone( IBlockAccess world, BlockPos pos, EnumFacing side )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileGeneric )
|
||||
{
|
||||
TileGeneric generic = (TileGeneric)tile;
|
||||
return generic.getRedstoneConnectivity( side );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getStrongPower( IBlockAccess world, BlockPos pos, IBlockState state, EnumFacing oppositeSide )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileGeneric && tile.hasWorldObj() )
|
||||
{
|
||||
TileGeneric generic = (TileGeneric)tile;
|
||||
return generic.getRedstoneOutput( oppositeSide.getOpposite() );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getWeakPower( IBlockAccess world, BlockPos pos, IBlockState state, EnumFacing oppositeSide )
|
||||
{
|
||||
return getStrongPower( world, pos, state, oppositeSide );
|
||||
}
|
||||
|
||||
public boolean getBundledRedstoneConnectivity( World world, BlockPos pos, EnumFacing side )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileGeneric )
|
||||
{
|
||||
TileGeneric generic = (TileGeneric)tile;
|
||||
return generic.getBundledRedstoneConnectivity( side );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getBundledRedstoneOutput( World world, BlockPos pos, EnumFacing side )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileGeneric && tile.hasWorldObj() )
|
||||
{
|
||||
TileGeneric generic = (TileGeneric)tile;
|
||||
return generic.getBundledRedstoneOutput( side );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockEventReceived( World world, BlockPos pos, IBlockState state, int eventID, int eventParameter )
|
||||
{
|
||||
if( world.isRemote )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileGeneric )
|
||||
{
|
||||
TileGeneric generic = (TileGeneric)tile;
|
||||
generic.onBlockEvent( eventID, eventParameter );
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final TileEntity createTileEntity( World world, IBlockState state )
|
||||
{
|
||||
return createTile( state );
|
||||
}
|
||||
|
||||
@Override
|
||||
public final TileEntity createNewTileEntity( World world, int damage )
|
||||
{
|
||||
return createTile( damage );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.common;
|
||||
|
||||
import dan200.computercraft.core.terminal.Terminal;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
public class ClientTerminal implements ITerminal
|
||||
{
|
||||
private boolean m_colour;
|
||||
private Terminal m_terminal;
|
||||
private boolean m_terminalChanged;
|
||||
private boolean m_terminalChangedLastFrame;
|
||||
|
||||
public ClientTerminal( boolean colour )
|
||||
{
|
||||
m_colour = colour;
|
||||
m_terminal = null;
|
||||
m_terminalChanged = false;
|
||||
m_terminalChangedLastFrame = false;
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
m_terminalChangedLastFrame = m_terminalChanged || (m_terminal != null && m_terminal.getChanged());
|
||||
if( m_terminal != null )
|
||||
{
|
||||
m_terminal.clearChanged();
|
||||
}
|
||||
m_terminalChanged = false;
|
||||
}
|
||||
|
||||
public boolean hasTerminalChanged()
|
||||
{
|
||||
return m_terminalChangedLastFrame;
|
||||
}
|
||||
|
||||
// ITerminal implementation
|
||||
|
||||
@Override
|
||||
public Terminal getTerminal()
|
||||
{
|
||||
return m_terminal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isColour()
|
||||
{
|
||||
return m_colour;
|
||||
}
|
||||
|
||||
public void readDescription( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
m_colour = nbttagcompound.getBoolean( "colour" );
|
||||
if( nbttagcompound.hasKey( "terminal" ) )
|
||||
{
|
||||
NBTTagCompound terminal = nbttagcompound.getCompoundTag( "terminal" );
|
||||
resizeTerminal( terminal.getInteger( "term_width" ), terminal.getInteger( "term_height" ) );
|
||||
m_terminal.readFromNBT( terminal );
|
||||
}
|
||||
else
|
||||
{
|
||||
deleteTerminal();
|
||||
}
|
||||
}
|
||||
|
||||
private void resizeTerminal( int width, int height )
|
||||
{
|
||||
if( m_terminal == null )
|
||||
{
|
||||
m_terminal = new Terminal( width, height );
|
||||
m_terminalChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_terminal.resize( width, height );
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteTerminal()
|
||||
{
|
||||
if( m_terminal != null )
|
||||
{
|
||||
m_terminal = null;
|
||||
m_terminalChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.common;
|
||||
|
||||
import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class DefaultBundledRedstoneProvider implements IBundledRedstoneProvider
|
||||
{
|
||||
public DefaultBundledRedstoneProvider()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBundledRedstoneOutput( World world, BlockPos pos, EnumFacing side )
|
||||
{
|
||||
return getDefaultBundledRedstoneOutput( world, pos, side );
|
||||
}
|
||||
|
||||
public static int getDefaultBundledRedstoneOutput( World world, BlockPos pos, EnumFacing side )
|
||||
{
|
||||
Block block = world.getBlockState( pos ).getBlock();
|
||||
if( block != null && block instanceof BlockGeneric )
|
||||
{
|
||||
BlockGeneric generic = (BlockGeneric)block;
|
||||
if( generic.getBundledRedstoneConnectivity( world, pos, side ) )
|
||||
{
|
||||
return generic.getBundledRedstoneOutput( world, pos, side );
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.common;
|
||||
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
public interface IDirectionalTile
|
||||
{
|
||||
public EnumFacing getDirection();
|
||||
public void setDirection( EnumFacing dir );
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.common;
|
||||
|
||||
import dan200.computercraft.core.terminal.Terminal;
|
||||
|
||||
public interface ITerminal
|
||||
{
|
||||
public Terminal getTerminal();
|
||||
public boolean isColour();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.common;
|
||||
|
||||
public interface ITerminalTile
|
||||
{
|
||||
public ITerminal getTerminal();
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.common;
|
||||
|
||||
import dan200.computercraft.core.terminal.Terminal;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
public class ServerTerminal implements ITerminal
|
||||
{
|
||||
private final boolean m_colour;
|
||||
private Terminal m_terminal;
|
||||
private boolean m_terminalChanged;
|
||||
private boolean m_terminalChangedLastFrame;
|
||||
|
||||
public ServerTerminal( boolean colour )
|
||||
{
|
||||
m_colour = colour;
|
||||
m_terminal = null;
|
||||
m_terminalChanged = false;
|
||||
m_terminalChangedLastFrame = false;
|
||||
}
|
||||
|
||||
public ServerTerminal( boolean colour, int terminalWidth, int terminalHeight )
|
||||
{
|
||||
m_colour = colour;
|
||||
m_terminal = new Terminal( terminalWidth, terminalHeight );
|
||||
m_terminalChanged = false;
|
||||
m_terminalChangedLastFrame = false;
|
||||
}
|
||||
|
||||
public void resize( int width, int height )
|
||||
{
|
||||
if( m_terminal == null )
|
||||
{
|
||||
m_terminal = new Terminal( width, height );
|
||||
m_terminalChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_terminal.resize( width, height );
|
||||
}
|
||||
}
|
||||
|
||||
public void delete()
|
||||
{
|
||||
if( m_terminal != null )
|
||||
{
|
||||
m_terminal = null;
|
||||
m_terminalChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
m_terminalChangedLastFrame = m_terminalChanged || (m_terminal != null && m_terminal.getChanged());
|
||||
if( m_terminal != null )
|
||||
{
|
||||
m_terminal.clearChanged();
|
||||
}
|
||||
m_terminalChanged = false;
|
||||
}
|
||||
|
||||
public boolean hasTerminalChanged()
|
||||
{
|
||||
return m_terminalChangedLastFrame;
|
||||
}
|
||||
|
||||
// ITerminal implementation
|
||||
|
||||
@Override
|
||||
public Terminal getTerminal()
|
||||
{
|
||||
return m_terminal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isColour()
|
||||
{
|
||||
return m_colour;
|
||||
}
|
||||
|
||||
// Networking stuff
|
||||
|
||||
public void writeDescription( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
nbttagcompound.setBoolean( "colour", m_colour );
|
||||
if( m_terminal != null )
|
||||
{
|
||||
NBTTagCompound terminal = new NBTTagCompound();
|
||||
terminal.setInteger( "term_width", m_terminal.getWidth() );
|
||||
terminal.setInteger( "term_height", m_terminal.getHeight() );
|
||||
m_terminal.writeToNBT( terminal );
|
||||
nbttagcompound.setTag( "terminal", terminal );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.common;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.network.ComputerCraftPacket;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
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.util.AxisAlignedBB;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class TileGeneric extends TileEntity
|
||||
{
|
||||
public TileGeneric()
|
||||
{
|
||||
}
|
||||
|
||||
public void requestTileEntityUpdate()
|
||||
{
|
||||
if( worldObj.isRemote )
|
||||
{
|
||||
ComputerCraftPacket packet = new ComputerCraftPacket();
|
||||
packet.m_packetType = ComputerCraftPacket.RequestTileEntityUpdate;
|
||||
|
||||
BlockPos pos = getPos();
|
||||
packet.m_dataInt = new int[]{ pos.getX(), pos.getY(), pos.getZ() };
|
||||
ComputerCraft.sendToServer( packet );
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy()
|
||||
{
|
||||
}
|
||||
|
||||
public BlockGeneric getBlock()
|
||||
{
|
||||
Block block = worldObj.getBlockState( getPos() ).getBlock();
|
||||
if( block != null && block instanceof BlockGeneric )
|
||||
{
|
||||
return (BlockGeneric)block;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected final IBlockState getBlockState()
|
||||
{
|
||||
return worldObj.getBlockState( getPos() );
|
||||
}
|
||||
|
||||
public final void updateBlock()
|
||||
{
|
||||
worldObj.markBlockForUpdate( getPos() );
|
||||
worldObj.markChunkDirty( getPos(), this );
|
||||
}
|
||||
|
||||
protected final void setBlockState( IBlockState newState )
|
||||
{
|
||||
worldObj.setBlockState( getPos(), newState, 3 );
|
||||
}
|
||||
|
||||
public void getDroppedItems( List<ItemStack> drops, int fortune, boolean creative, boolean silkTouch )
|
||||
{
|
||||
}
|
||||
|
||||
public ItemStack getPickedItem()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean onActivate( EntityPlayer player, EnumFacing side, float hitX, float hitY, float hitZ )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void onNeighbourChange()
|
||||
{
|
||||
}
|
||||
|
||||
public boolean isSolidOnSide( int side )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isImmuneToExplosion( Entity exploder )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public AxisAlignedBB getBounds()
|
||||
{
|
||||
return new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, 1.0, 1.0 );
|
||||
}
|
||||
|
||||
public void getCollisionBounds( List<AxisAlignedBB> bounds )
|
||||
{
|
||||
bounds.add( getBounds() );
|
||||
}
|
||||
|
||||
public boolean getRedstoneConnectivity( EnumFacing side )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getRedstoneOutput( EnumFacing side )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean getBundledRedstoneConnectivity( EnumFacing side )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getBundledRedstoneOutput( EnumFacing side )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected double getInteractRange( EntityPlayer player )
|
||||
{
|
||||
return 8.0;
|
||||
}
|
||||
|
||||
public boolean isUsable( EntityPlayer player, boolean ignoreRange )
|
||||
{
|
||||
if( player != null && player.isEntityAlive() )
|
||||
{
|
||||
if( worldObj.getTileEntity( getPos() ) == this )
|
||||
{
|
||||
if( !ignoreRange )
|
||||
{
|
||||
double range = getInteractRange( player );
|
||||
BlockPos pos = getPos();
|
||||
return player.getEntityWorld() == worldObj &&
|
||||
player.getDistanceSq( (double)pos.getX() + 0.5, (double)pos.getY() + 0.5, (double)pos.getZ() + 0.5 ) <= ( range * range );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void writeDescription( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
}
|
||||
|
||||
protected void readDescription( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
}
|
||||
|
||||
public final void sendBlockEvent( int eventID )
|
||||
{
|
||||
sendBlockEvent( eventID, 0 );
|
||||
}
|
||||
|
||||
public final void sendBlockEvent( int eventID, int eventParameter )
|
||||
{
|
||||
worldObj.addBlockEvent( getPos(), worldObj.getBlockState( getPos() ).getBlock(), eventID, eventParameter );
|
||||
}
|
||||
|
||||
public void onBlockEvent( int eventID, int eventParameter )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRefresh( World world, BlockPos pos, IBlockState oldState, IBlockState newState )
|
||||
{
|
||||
return newState.getBlock() != oldState.getBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Packet getDescriptionPacket()
|
||||
{
|
||||
// Communicate properties
|
||||
NBTTagCompound nbttagcompound = new NBTTagCompound();
|
||||
writeDescription( nbttagcompound );
|
||||
return new S35PacketUpdateTileEntity( getPos(), 0, nbttagcompound );
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onDataPacket( NetworkManager net, S35PacketUpdateTileEntity packet )
|
||||
{
|
||||
switch( packet.getTileEntityType() )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// Receive properties
|
||||
NBTTagCompound nbttagcompound = packet.getNbtCompound();
|
||||
readDescription( nbttagcompound );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,325 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.apis;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.ILuaTask;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.core.apis.ILuaAPI;
|
||||
import dan200.computercraft.shared.computer.blocks.TileCommandComputer;
|
||||
import dan200.computercraft.shared.util.WorldUtil;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.properties.IProperty;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.command.ICommand;
|
||||
import net.minecraft.command.ICommandManager;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class CommandAPI implements ILuaAPI
|
||||
{
|
||||
private TileCommandComputer m_computer;
|
||||
|
||||
public CommandAPI( TileCommandComputer computer )
|
||||
{
|
||||
m_computer = computer;
|
||||
}
|
||||
|
||||
// ILuaAPI implementation
|
||||
|
||||
@Override
|
||||
public String[] getNames()
|
||||
{
|
||||
return new String[] {
|
||||
"commands"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startup()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void advance( double dt )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getMethodNames()
|
||||
{
|
||||
return new String[] {
|
||||
"exec",
|
||||
"execAsync",
|
||||
"list",
|
||||
"getBlockPosition",
|
||||
"getBlockInfos",
|
||||
"getBlockInfo"
|
||||
};
|
||||
}
|
||||
|
||||
private Map<Object, Object> createOutput( String output )
|
||||
{
|
||||
Map<Object, Object> result = new HashMap<Object, Object>( 1 );
|
||||
result.put( 1, output );
|
||||
return result;
|
||||
}
|
||||
|
||||
private Object[] doCommand( String command )
|
||||
{
|
||||
MinecraftServer server = MinecraftServer.getServer();
|
||||
if( server != null && server.isCommandBlockEnabled() )
|
||||
{
|
||||
ICommandManager commandManager = server.getCommandManager();
|
||||
try
|
||||
{
|
||||
TileCommandComputer.CommandSender sender = m_computer.getCommandSender();
|
||||
sender.clearOutput();
|
||||
|
||||
int result = commandManager.executeCommand( sender, command );
|
||||
return new Object[]{ (result > 0), sender.copyOutput() };
|
||||
}
|
||||
catch( Throwable t )
|
||||
{
|
||||
return new Object[]{ false, createOutput( "Java Exception Thrown: " + t.toString() ) };
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Object[] { false, createOutput( "Command blocks disabled by server" ) };
|
||||
}
|
||||
}
|
||||
|
||||
private Object getBlockInfo( World world, BlockPos pos )
|
||||
{
|
||||
// Get the details of the block
|
||||
IBlockState state = world.getBlockState( pos );
|
||||
Block block = state.getBlock();
|
||||
String name = ((ResourceLocation)Block.blockRegistry.getNameForObject( block )).toString();
|
||||
int metadata = block.getMetaFromState( state );
|
||||
|
||||
Map<Object, Object> table = new HashMap<Object, Object>();
|
||||
table.put( "name", name );
|
||||
table.put( "metadata", metadata );
|
||||
|
||||
Map<Object, Object> stateTable = new HashMap<Object, Object>();
|
||||
for( Object o : block.getActualState( state, world, pos ).getProperties().entrySet() )
|
||||
{
|
||||
ImmutableMap.Entry<IProperty, Object> entry = (ImmutableMap.Entry<IProperty, Object>)o;
|
||||
String propertyName = entry.getKey().getName();
|
||||
Object value = entry.getValue();
|
||||
if( value instanceof String || value instanceof Number || value instanceof Boolean )
|
||||
{
|
||||
stateTable.put( propertyName, value );
|
||||
}
|
||||
else
|
||||
{
|
||||
stateTable.put( propertyName, value.toString() );
|
||||
}
|
||||
}
|
||||
table.put( "state", stateTable );
|
||||
// TODO: NBT data?
|
||||
return table;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( ILuaContext context, int method, Object[] arguments ) throws LuaException, InterruptedException
|
||||
{
|
||||
switch( method )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// exec
|
||||
if( arguments.length < 1 || !(arguments[0] instanceof String) )
|
||||
{
|
||||
throw new LuaException( "Expected string" );
|
||||
}
|
||||
final String command = (String)arguments[0];
|
||||
return context.executeMainThreadTask( new ILuaTask()
|
||||
{
|
||||
@Override
|
||||
public Object[] execute() throws LuaException
|
||||
{
|
||||
return doCommand( command );
|
||||
}
|
||||
} );
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
// execAsync
|
||||
if( arguments.length < 1 || !(arguments[0] instanceof String) )
|
||||
{
|
||||
throw new LuaException( "Expected string" );
|
||||
}
|
||||
final String command = (String)arguments[0];
|
||||
long taskID = context.issueMainThreadTask( new ILuaTask()
|
||||
{
|
||||
@Override
|
||||
public Object[] execute() throws LuaException
|
||||
{
|
||||
return doCommand( command );
|
||||
}
|
||||
} );
|
||||
return new Object[] { taskID };
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
// list
|
||||
return context.executeMainThreadTask( new ILuaTask()
|
||||
{
|
||||
@Override
|
||||
public Object[] execute() throws LuaException
|
||||
{
|
||||
int i = 1;
|
||||
Map<Object, Object> result = new HashMap<Object, Object>();
|
||||
MinecraftServer server = MinecraftServer.getServer();
|
||||
if( server != null )
|
||||
{
|
||||
ICommandManager commandManager = server.getCommandManager();
|
||||
ICommandSender commmandSender = m_computer.getCommandSender();
|
||||
Map commands = commandManager.getCommands();
|
||||
for( Object entryObject : commands.entrySet() )
|
||||
{
|
||||
Map.Entry entry = (Map.Entry)entryObject;
|
||||
String name = (String)entry.getKey();
|
||||
ICommand command = (ICommand)entry.getValue();
|
||||
try
|
||||
{
|
||||
if( command.canCommandSenderUseCommand( commmandSender ) )
|
||||
{
|
||||
result.put( i++, name );
|
||||
}
|
||||
}
|
||||
catch( Throwable t )
|
||||
{
|
||||
// Ignore buggy command
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Object[]{ result };
|
||||
}
|
||||
} );
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
// getBlockPosition
|
||||
// This is probably safe to do on the Lua thread. Probably.
|
||||
BlockPos pos = m_computer.getPos();
|
||||
return new Object[] { pos.getX(), pos.getY(), pos.getZ() };
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
// getBlockInfos
|
||||
if( arguments.length < 6 ||
|
||||
!(arguments[0] instanceof Number) ||
|
||||
!(arguments[1] instanceof Number) ||
|
||||
!(arguments[2] instanceof Number) ||
|
||||
!(arguments[3] instanceof Number) ||
|
||||
!(arguments[4] instanceof Number) ||
|
||||
!(arguments[5] instanceof Number) )
|
||||
{
|
||||
throw new LuaException( "Expected number, number, number, number, number, number" );
|
||||
}
|
||||
final int minx = ((Number)arguments[0]).intValue();
|
||||
final int miny = ((Number)arguments[1]).intValue();
|
||||
final int minz = ((Number)arguments[2]).intValue();
|
||||
final int maxx = ((Number)arguments[3]).intValue();
|
||||
final int maxy = ((Number)arguments[4]).intValue();
|
||||
final int maxz = ((Number)arguments[5]).intValue();
|
||||
return context.executeMainThreadTask( new ILuaTask()
|
||||
{
|
||||
@Override
|
||||
public Object[] execute() throws LuaException
|
||||
{
|
||||
// Get the details of the block
|
||||
World world = m_computer.getWorld();
|
||||
BlockPos min = new BlockPos(
|
||||
Math.min( minx, maxx ),
|
||||
Math.min( miny, maxy ),
|
||||
Math.min( minz, maxz )
|
||||
);
|
||||
BlockPos max = new BlockPos(
|
||||
Math.max( minx, maxx ),
|
||||
Math.max( miny, maxy ),
|
||||
Math.max( minz, maxz )
|
||||
);
|
||||
if( !WorldUtil.isBlockInWorld( world, min ) || !WorldUtil.isBlockInWorld( world, max ) )
|
||||
{
|
||||
throw new LuaException( "Co-ordinates out or range" );
|
||||
}
|
||||
if( ( max.getX() - min.getX() + 1 ) * ( max.getY() - min.getY() + 1 ) * ( max.getZ() - min.getZ() + 1 ) > 4096 )
|
||||
{
|
||||
throw new LuaException( "Too many blocks" );
|
||||
}
|
||||
int i=1;
|
||||
Map<Object, Object> results = new HashMap<Object, Object>();
|
||||
for( int y=min.getY(); y<= max.getY(); ++y )
|
||||
{
|
||||
for( int z = min.getZ(); z <= max.getZ(); ++z )
|
||||
{
|
||||
for( int x = min.getX(); x <= max.getX(); ++x )
|
||||
{
|
||||
BlockPos pos = new BlockPos( x, y, z );
|
||||
results.put( i++, getBlockInfo( world, pos ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Object[]{ results };
|
||||
}
|
||||
} );
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
// getBlockInfo
|
||||
if( arguments.length < 3 ||
|
||||
!(arguments[0] instanceof Number) ||
|
||||
!(arguments[1] instanceof Number) ||
|
||||
!(arguments[2] instanceof Number) )
|
||||
{
|
||||
throw new LuaException( "Expected number, number, number" );
|
||||
}
|
||||
final int x = ((Number)arguments[0]).intValue();
|
||||
final int y = ((Number)arguments[1]).intValue();
|
||||
final int z = ((Number)arguments[2]).intValue();
|
||||
return context.executeMainThreadTask( new ILuaTask()
|
||||
{
|
||||
@Override
|
||||
public Object[] execute() throws LuaException
|
||||
{
|
||||
// Get the details of the block
|
||||
World world = m_computer.getWorld();
|
||||
BlockPos position = new BlockPos( x, y, z );
|
||||
if( WorldUtil.isBlockInWorld( world, position ) )
|
||||
{
|
||||
return new Object[]{ getBlockInfo( world, position ) };
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new LuaException( "co-ordinates out or range" );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
default:
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.blocks;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.IComputer;
|
||||
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
|
||||
import dan200.computercraft.shared.util.DirectionUtil;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.properties.IProperty;
|
||||
import net.minecraft.block.properties.PropertyDirection;
|
||||
import net.minecraft.block.properties.PropertyEnum;
|
||||
import net.minecraft.block.state.BlockState;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BlockCommandComputer extends BlockComputerBase
|
||||
{
|
||||
// Statics
|
||||
|
||||
public static class Properties
|
||||
{
|
||||
public static final PropertyDirection FACING = PropertyDirection.create("facing", EnumFacing.Plane.HORIZONTAL);
|
||||
public static final PropertyEnum STATE = PropertyEnum.create("state", ComputerState.class);
|
||||
}
|
||||
|
||||
// Members
|
||||
|
||||
public BlockCommandComputer()
|
||||
{
|
||||
super( Material.iron );
|
||||
setBlockUnbreakable();
|
||||
setResistance( 6000000.0F );
|
||||
setUnlocalizedName( "computercraft:command_computer" );
|
||||
setCreativeTab( ComputerCraft.mainCreativeTab );
|
||||
setDefaultState( this.blockState.getBaseState()
|
||||
.withProperty( Properties.FACING, EnumFacing.NORTH )
|
||||
.withProperty( Properties.STATE, ComputerState.Off )
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockState createBlockState()
|
||||
{
|
||||
return new BlockState(this, new IProperty[] {
|
||||
Properties.FACING,
|
||||
Properties.STATE
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getStateFromMeta( int meta )
|
||||
{
|
||||
EnumFacing dir = EnumFacing.getFront( meta & 0x7 );
|
||||
if( dir.getAxis() == EnumFacing.Axis.Y )
|
||||
{
|
||||
dir = EnumFacing.NORTH;
|
||||
}
|
||||
return getDefaultState().withProperty( Properties.FACING, dir );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetaFromState( IBlockState state )
|
||||
{
|
||||
return ((EnumFacing)state.getValue( Properties.FACING )).getIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getActualState( IBlockState state, IBlockAccess world, BlockPos pos )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof IComputerTile )
|
||||
{
|
||||
IComputer computer = ((IComputerTile)tile).getComputer();
|
||||
if( computer != null && computer.isOn() )
|
||||
{
|
||||
if( computer.isCursorDisplayed() )
|
||||
{
|
||||
return state.withProperty( Properties.STATE, ComputerState.Blinking );
|
||||
}
|
||||
else
|
||||
{
|
||||
return state.withProperty( Properties.STATE, ComputerState.On );
|
||||
}
|
||||
}
|
||||
}
|
||||
return state.withProperty( Properties.STATE, ComputerState.Off );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IBlockState getDefaultBlockState( ComputerFamily family, EnumFacing placedSide )
|
||||
{
|
||||
if( placedSide.getAxis() != EnumFacing.Axis.Y )
|
||||
{
|
||||
return getDefaultState().withProperty( Properties.FACING, placedSide );
|
||||
}
|
||||
else
|
||||
{
|
||||
return getDefaultState();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComputerFamily getFamily( int damage )
|
||||
{
|
||||
return ComputerFamily.Command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComputerFamily getFamily( IBlockState state )
|
||||
{
|
||||
return ComputerFamily.Command;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TileComputer createTile( ComputerFamily family )
|
||||
{
|
||||
return new TileCommandComputer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockPlacedBy( World world, BlockPos pos, IBlockState state, EntityLivingBase player, ItemStack itemstack )
|
||||
{
|
||||
// Not sure why this is necessary
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileCommandComputer )
|
||||
{
|
||||
tile.setWorldObj( world ); // Not sure why this is necessary
|
||||
tile.setPos( pos ); // Not sure why this is necessary
|
||||
}
|
||||
|
||||
// Set direction
|
||||
EnumFacing dir = DirectionUtil.fromEntityRot( player );
|
||||
setDirection( world, pos, dir );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.blocks;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.IComputer;
|
||||
import dan200.computercraft.shared.computer.items.ItemComputer;
|
||||
import dan200.computercraft.shared.util.DirectionUtil;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.properties.IProperty;
|
||||
import net.minecraft.block.properties.PropertyBool;
|
||||
import net.minecraft.block.properties.PropertyDirection;
|
||||
import net.minecraft.block.properties.PropertyEnum;
|
||||
import net.minecraft.block.state.BlockState;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BlockComputer extends BlockComputerBase
|
||||
{
|
||||
// Statics
|
||||
public static class Properties
|
||||
{
|
||||
public static final PropertyDirection FACING = PropertyDirection.create("facing", EnumFacing.Plane.HORIZONTAL);
|
||||
public static final PropertyBool ADVANCED = PropertyBool.create("advanced");
|
||||
public static final PropertyEnum STATE = PropertyEnum.create("state", ComputerState.class);
|
||||
}
|
||||
|
||||
// Members
|
||||
|
||||
public BlockComputer()
|
||||
{
|
||||
super( Material.rock );
|
||||
setHardness( 2.0f );
|
||||
setUnlocalizedName( "computercraft:computer" );
|
||||
setCreativeTab( ComputerCraft.mainCreativeTab );
|
||||
setDefaultState( this.blockState.getBaseState()
|
||||
.withProperty( Properties.FACING, EnumFacing.NORTH )
|
||||
.withProperty( Properties.ADVANCED, false )
|
||||
.withProperty( Properties.STATE, ComputerState.Off )
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockState createBlockState()
|
||||
{
|
||||
return new BlockState(this, new IProperty[] {
|
||||
Properties.FACING,
|
||||
Properties.ADVANCED,
|
||||
Properties.STATE
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getStateFromMeta( int meta )
|
||||
{
|
||||
EnumFacing dir = EnumFacing.getFront( meta & 0x7 );
|
||||
if( dir.getAxis() == EnumFacing.Axis.Y )
|
||||
{
|
||||
dir = EnumFacing.NORTH;
|
||||
}
|
||||
|
||||
IBlockState state = getDefaultState().withProperty( Properties.FACING, dir );
|
||||
if( meta > 8 )
|
||||
{
|
||||
state = state.withProperty( Properties.ADVANCED, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
state = state.withProperty( Properties.ADVANCED, false );
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetaFromState( IBlockState state )
|
||||
{
|
||||
int meta = ((EnumFacing)state.getValue( Properties.FACING )).getIndex();
|
||||
if( (Boolean)state.getValue( Properties.ADVANCED ) )
|
||||
{
|
||||
meta += 8;
|
||||
}
|
||||
return meta;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IBlockState getDefaultBlockState( ComputerFamily family, EnumFacing placedSide )
|
||||
{
|
||||
IBlockState state = getDefaultState();
|
||||
if( placedSide.getAxis() != EnumFacing.Axis.Y )
|
||||
{
|
||||
state = state.withProperty( Properties.FACING, placedSide );
|
||||
}
|
||||
|
||||
switch( family )
|
||||
{
|
||||
case Normal:
|
||||
default:
|
||||
{
|
||||
return state.withProperty( Properties.ADVANCED, false );
|
||||
}
|
||||
case Advanced:
|
||||
{
|
||||
return state.withProperty( Properties.ADVANCED, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getActualState( IBlockState state, IBlockAccess world, BlockPos pos )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof IComputerTile )
|
||||
{
|
||||
IComputer computer = ((IComputerTile)tile).getComputer();
|
||||
if( computer != null && computer.isOn() )
|
||||
{
|
||||
if( computer.isCursorDisplayed() )
|
||||
{
|
||||
return state.withProperty( Properties.STATE, ComputerState.Blinking );
|
||||
}
|
||||
else
|
||||
{
|
||||
return state.withProperty( Properties.STATE, ComputerState.On );
|
||||
}
|
||||
}
|
||||
}
|
||||
return state.withProperty( Properties.STATE, ComputerState.Off );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComputerFamily getFamily( int damage )
|
||||
{
|
||||
return ((ItemComputer) Item.getItemFromBlock(this)).getFamily( damage );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComputerFamily getFamily( IBlockState state )
|
||||
{
|
||||
if( (Boolean)state.getValue( Properties.ADVANCED ) ) {
|
||||
return ComputerFamily.Advanced;
|
||||
} else {
|
||||
return ComputerFamily.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TileComputer createTile( ComputerFamily family )
|
||||
{
|
||||
return new TileComputer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockPlacedBy( World world, BlockPos pos, IBlockState state, EntityLivingBase player, ItemStack stack )
|
||||
{
|
||||
// Not sure why this is necessary
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileComputer )
|
||||
{
|
||||
tile.setWorldObj( world ); // Not sure why this is necessary
|
||||
tile.setPos( pos ); // Not sure why this is necessary
|
||||
}
|
||||
|
||||
// Set direction
|
||||
EnumFacing dir = DirectionUtil.fromEntityRot( player );
|
||||
setDirection( world, pos, dir );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.blocks;
|
||||
|
||||
import dan200.computercraft.shared.common.BlockDirectional;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.items.ItemComputerBase;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public abstract class BlockComputerBase extends BlockDirectional
|
||||
{
|
||||
public BlockComputerBase( Material material )
|
||||
{
|
||||
super( material );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockAdded( World world, BlockPos pos, IBlockState state )
|
||||
{
|
||||
super.onBlockAdded( world, pos, state );
|
||||
updateInput( world, pos );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirection( World world, BlockPos pos, EnumFacing dir )
|
||||
{
|
||||
super.setDirection( world, pos, dir );
|
||||
updateInput( world, pos );
|
||||
}
|
||||
|
||||
protected abstract IBlockState getDefaultBlockState( ComputerFamily family, EnumFacing placedSide );
|
||||
protected abstract ComputerFamily getFamily( int damage );
|
||||
protected abstract ComputerFamily getFamily( IBlockState state );
|
||||
protected abstract TileComputerBase createTile( ComputerFamily family );
|
||||
|
||||
@Override
|
||||
protected final IBlockState getDefaultBlockState( int damage, EnumFacing placedSide )
|
||||
{
|
||||
ItemComputerBase item = (ItemComputerBase)Item.getItemFromBlock( this );
|
||||
return getDefaultBlockState( item.getFamily( damage ), placedSide );
|
||||
}
|
||||
|
||||
@Override
|
||||
public final TileComputerBase createTile( IBlockState state )
|
||||
{
|
||||
return createTile( getFamily( state ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public final TileComputerBase createTile( int damage )
|
||||
{
|
||||
return createTile( getFamily( damage ) );
|
||||
}
|
||||
|
||||
public final ComputerFamily getFamily( IBlockAccess world, BlockPos pos )
|
||||
{
|
||||
return getFamily( world.getBlockState( pos ) );
|
||||
}
|
||||
|
||||
protected void updateInput( IBlockAccess world, BlockPos pos )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileComputerBase )
|
||||
{
|
||||
TileComputerBase computer = (TileComputerBase)tile;
|
||||
computer.updateInput();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.blocks;
|
||||
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||
|
||||
public class ComputerPeripheral
|
||||
implements IPeripheral
|
||||
{
|
||||
private final String m_type;
|
||||
private final ServerComputer m_computer;
|
||||
|
||||
public ComputerPeripheral( String type, ServerComputer computer )
|
||||
{
|
||||
m_type = type;
|
||||
m_computer = computer;
|
||||
}
|
||||
|
||||
// IPeripheral implementation
|
||||
|
||||
@Override
|
||||
public String getType()
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getMethodNames()
|
||||
{
|
||||
return new String[] {
|
||||
"turnOn",
|
||||
"shutdown",
|
||||
"reboot",
|
||||
"getID",
|
||||
"isOn",
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( IComputerAccess computer, ILuaContext context, int method, Object[] arguments ) throws LuaException
|
||||
{
|
||||
switch( method )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// turnOn
|
||||
m_computer.turnOn();
|
||||
return null;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
// shutdown
|
||||
m_computer.shutdown();
|
||||
return null;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
// reboot
|
||||
m_computer.reboot();
|
||||
return null;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
// getID
|
||||
return new Object[] {
|
||||
m_computer.assignID()
|
||||
};
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
// isOn
|
||||
return new Object[] { m_computer.isOn() };
|
||||
}
|
||||
default:
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attach( IComputerAccess computer )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detach( IComputerAccess computer )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( IPeripheral other )
|
||||
{
|
||||
return (other != null && other.getClass() == this.getClass());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.blocks;
|
||||
|
||||
import net.minecraft.util.IStringSerializable;
|
||||
|
||||
public enum ComputerState implements IStringSerializable
|
||||
{
|
||||
Off( "off" ),
|
||||
On( "on" ),
|
||||
Blinking( "blinking" );
|
||||
|
||||
private String m_name;
|
||||
|
||||
private ComputerState( String name )
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.blocks;
|
||||
|
||||
import dan200.computercraft.shared.common.ITerminalTile;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.IComputer;
|
||||
|
||||
public interface IComputerTile extends ITerminalTile
|
||||
{
|
||||
public void setComputerID( int id );
|
||||
public void setLabel( String label );
|
||||
public IComputer getComputer();
|
||||
public IComputer createComputer();
|
||||
public ComputerFamily getFamily();
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.blocks;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.computer.apis.CommandAPI;
|
||||
import dan200.computercraft.shared.computer.core.IComputer;
|
||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.command.server.CommandBlockLogic;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class TileCommandComputer extends TileComputer
|
||||
{
|
||||
public class CommandSender extends CommandBlockLogic
|
||||
{
|
||||
private Map<Integer, String> m_outputTable;
|
||||
|
||||
public CommandSender()
|
||||
{
|
||||
m_outputTable = new HashMap<Integer, String>();
|
||||
}
|
||||
|
||||
public void clearOutput()
|
||||
{
|
||||
m_outputTable.clear();
|
||||
}
|
||||
|
||||
public Map<Integer, String> getOutput()
|
||||
{
|
||||
return m_outputTable;
|
||||
}
|
||||
|
||||
public Map<Integer, String> copyOutput()
|
||||
{
|
||||
return new HashMap<Integer, String>( m_outputTable );
|
||||
}
|
||||
|
||||
// ICommandSender
|
||||
|
||||
@Override
|
||||
public IChatComponent getDisplayName()
|
||||
{
|
||||
IComputer computer = TileCommandComputer.this.getComputer();
|
||||
if( computer != null )
|
||||
{
|
||||
String label = computer.getLabel();
|
||||
if( label != null )
|
||||
{
|
||||
return new ChatComponentText( computer.getLabel() );
|
||||
}
|
||||
}
|
||||
return new ChatComponentText( "@" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChatMessage( IChatComponent chatComponent )
|
||||
{
|
||||
m_outputTable.put( m_outputTable.size() + 1, chatComponent.getUnformattedText() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCommandSenderUseCommand( int level, String command )
|
||||
{
|
||||
return level <= 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getPosition()
|
||||
{
|
||||
return TileCommandComputer.this.getPos();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3 getPositionVector()
|
||||
{
|
||||
BlockPos pos = getPosition();
|
||||
return new Vec3( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getEntityWorld()
|
||||
{
|
||||
return TileCommandComputer.this.worldObj;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity getCommandSenderEntity()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// CommandBlockLogic members intentionally left empty
|
||||
// The only reason we extend it at all is so that "gameRule commandBlockOutput" applies to us
|
||||
|
||||
@Override
|
||||
public void updateCommand()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public int func_145751_f()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void func_145757_a( ByteBuf p_145757_1_ )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private CommandSender m_commandSender;
|
||||
|
||||
public TileCommandComputer()
|
||||
{
|
||||
m_commandSender = new CommandSender();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumFacing getDirection()
|
||||
{
|
||||
IBlockState state = getBlockState();
|
||||
return (EnumFacing)state.getValue( BlockCommandComputer.Properties.FACING );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirection( EnumFacing dir )
|
||||
{
|
||||
if( dir.getAxis() == EnumFacing.Axis.Y )
|
||||
{
|
||||
dir = EnumFacing.NORTH;
|
||||
}
|
||||
setBlockState( getBlockState().withProperty( BlockCommandComputer.Properties.FACING, dir ) );
|
||||
updateInput();
|
||||
}
|
||||
|
||||
public CommandSender getCommandSender()
|
||||
{
|
||||
return m_commandSender;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServerComputer createComputer( int instanceID, int id )
|
||||
{
|
||||
ServerComputer computer = super.createComputer( instanceID, id );
|
||||
computer.addAPI( new CommandAPI( this ) );
|
||||
return computer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUsable( EntityPlayer player, boolean ignoreRange )
|
||||
{
|
||||
MinecraftServer server = MinecraftServer.getServer();
|
||||
if( server == null || !server.isCommandBlockEnabled() )
|
||||
{
|
||||
player.addChatMessage( new ChatComponentTranslation( "advMode.notEnabled" ) );
|
||||
return false;
|
||||
}
|
||||
else if( ComputerCraft.canPlayerUseCommands( player ) && player.capabilities.isCreativeMode )
|
||||
{
|
||||
return super.isUsable( player, ignoreRange );
|
||||
}
|
||||
else
|
||||
{
|
||||
player.addChatMessage( new ChatComponentTranslation( "advMode.notAllowed" ) );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.blocks;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.IComputer;
|
||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||
import dan200.computercraft.shared.computer.items.ComputerItemFactory;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TileComputer extends TileComputerBase
|
||||
{
|
||||
// Statics
|
||||
|
||||
// Members
|
||||
|
||||
public TileComputer()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServerComputer createComputer( int instanceID, int id )
|
||||
{
|
||||
ComputerFamily family = getFamily();
|
||||
ServerComputer computer = new ServerComputer(
|
||||
worldObj,
|
||||
id,
|
||||
m_label,
|
||||
instanceID,
|
||||
family,
|
||||
ComputerCraft.terminalWidth_computer,
|
||||
ComputerCraft.terminalHeight_computer
|
||||
);
|
||||
computer.setPosition( getPos() );
|
||||
return computer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDroppedItems( List<ItemStack> drops, int fortune, boolean creative, boolean silkTouch )
|
||||
{
|
||||
IComputer computer = getComputer();
|
||||
if( !creative || (computer != null && computer.getLabel() != null) )
|
||||
{
|
||||
drops.add( ComputerItemFactory.create( this ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickedItem()
|
||||
{
|
||||
return ComputerItemFactory.create( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openGUI( EntityPlayer player )
|
||||
{
|
||||
ComputerCraft.openComputerGUI( player, this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readDescription( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.readDescription( nbttagcompound );
|
||||
updateBlock();
|
||||
}
|
||||
|
||||
public boolean isUseableByPlayer( EntityPlayer player )
|
||||
{
|
||||
return isUsable( player, false );
|
||||
}
|
||||
|
||||
// IDirectionalTile
|
||||
|
||||
@Override
|
||||
public EnumFacing getDirection()
|
||||
{
|
||||
IBlockState state = getBlockState();
|
||||
return (EnumFacing)state.getValue( BlockComputer.Properties.FACING );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirection( EnumFacing dir )
|
||||
{
|
||||
if( dir.getAxis() == EnumFacing.Axis.Y )
|
||||
{
|
||||
dir = EnumFacing.NORTH;
|
||||
}
|
||||
setBlockState( getBlockState().withProperty( BlockComputer.Properties.FACING, dir ) );
|
||||
updateInput();
|
||||
}
|
||||
|
||||
// For legacy reasons, computers invert the meaning of "left" and "right"
|
||||
private static final int[] s_remapSide = { 0, 1, 2, 3, 5, 4 };
|
||||
|
||||
@Override
|
||||
protected int remapLocalSide( int localSide )
|
||||
{
|
||||
return s_remapSide[ localSide ];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,511 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.blocks;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.common.IDirectionalTile;
|
||||
import dan200.computercraft.shared.common.ITerminal;
|
||||
import dan200.computercraft.shared.common.TileGeneric;
|
||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.IComputer;
|
||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||
import dan200.computercraft.shared.util.DirectionUtil;
|
||||
import dan200.computercraft.shared.util.PeripheralUtil;
|
||||
import dan200.computercraft.shared.util.RedstoneUtil;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.ITickable;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
public abstract class TileComputerBase extends TileGeneric
|
||||
implements IComputerTile, IDirectionalTile, ITickable
|
||||
{
|
||||
protected int m_instanceID;
|
||||
protected int m_computerID;
|
||||
protected String m_label;
|
||||
protected boolean m_on;
|
||||
protected boolean m_startOn;
|
||||
|
||||
protected TileComputerBase()
|
||||
{
|
||||
m_instanceID = -1;
|
||||
m_computerID = -1;
|
||||
m_label = null;
|
||||
m_on = false;
|
||||
m_startOn = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockComputerBase getBlock()
|
||||
{
|
||||
Block block = super.getBlock();
|
||||
if( block != null && block instanceof BlockComputerBase )
|
||||
{
|
||||
return (BlockComputerBase)block;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void unload()
|
||||
{
|
||||
if( m_instanceID >= 0 )
|
||||
{
|
||||
if( !worldObj.isRemote )
|
||||
{
|
||||
ComputerCraft.serverComputerRegistry.remove( m_instanceID );
|
||||
}
|
||||
m_instanceID = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
unload();
|
||||
for( EnumFacing dir : EnumFacing.VALUES )
|
||||
{
|
||||
RedstoneUtil.propogateRedstoneOutput( worldObj, getPos(), dir );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChunkUnload()
|
||||
{
|
||||
unload();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate()
|
||||
{
|
||||
unload();
|
||||
super.invalidate();
|
||||
}
|
||||
|
||||
public abstract void openGUI( EntityPlayer player );
|
||||
|
||||
protected boolean canNameWithTag( EntityPlayer player )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean onDefaultComputerInteract( EntityPlayer player )
|
||||
{
|
||||
if( !worldObj.isRemote )
|
||||
{
|
||||
if( isUsable( player, false ) )
|
||||
{
|
||||
createServerComputer().turnOn();
|
||||
openGUI( player );
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActivate( EntityPlayer player, EnumFacing side, float hitX, float hitY, float hitZ )
|
||||
{
|
||||
ItemStack currentItem = player.getCurrentEquippedItem();
|
||||
if( currentItem != null && currentItem.getItem() == Items.name_tag && canNameWithTag( player ) )
|
||||
{
|
||||
// Label to rename computer
|
||||
if( !worldObj.isRemote )
|
||||
{
|
||||
if( currentItem.hasDisplayName() )
|
||||
{
|
||||
setLabel( currentItem.getDisplayName() );
|
||||
}
|
||||
else
|
||||
{
|
||||
setLabel( null );
|
||||
}
|
||||
currentItem.stackSize--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if( !player.isSneaking() )
|
||||
{
|
||||
// Regular right click to activate computer
|
||||
return onDefaultComputerInteract( player );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getRedstoneConnectivity( EnumFacing side )
|
||||
{
|
||||
int localDir = remapLocalSide( DirectionUtil.toLocal( this, side ) );
|
||||
return !isRedstoneBlockedOnSide( localDir );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRedstoneOutput( EnumFacing side )
|
||||
{
|
||||
int localDir = remapLocalSide( DirectionUtil.toLocal( this, side ) );
|
||||
if( !isRedstoneBlockedOnSide( localDir ) )
|
||||
{
|
||||
if( worldObj != null && !worldObj.isRemote )
|
||||
{
|
||||
ServerComputer computer = getServerComputer();
|
||||
if( computer != null )
|
||||
{
|
||||
return computer.getRedstoneOutput( localDir );
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBundledRedstoneConnectivity( EnumFacing side )
|
||||
{
|
||||
int localDir = remapLocalSide( DirectionUtil.toLocal( this, side ) );
|
||||
return !isRedstoneBlockedOnSide( localDir );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBundledRedstoneOutput( EnumFacing side )
|
||||
{
|
||||
int localDir = remapLocalSide( DirectionUtil.toLocal( this, side ) );
|
||||
if( !isRedstoneBlockedOnSide( localDir ) )
|
||||
{
|
||||
if( !worldObj.isRemote )
|
||||
{
|
||||
ServerComputer computer = getServerComputer();
|
||||
if( computer != null )
|
||||
{
|
||||
return computer.getBundledRedstoneOutput( localDir );
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighbourChange()
|
||||
{
|
||||
updateInput();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
if( !worldObj.isRemote )
|
||||
{
|
||||
ServerComputer computer = createServerComputer();
|
||||
if( computer != null )
|
||||
{
|
||||
if( m_startOn )
|
||||
{
|
||||
computer.turnOn();
|
||||
m_startOn = false;
|
||||
}
|
||||
computer.keepAlive();
|
||||
if( computer.hasOutputChanged() )
|
||||
{
|
||||
updateOutput();
|
||||
}
|
||||
m_computerID = computer.getID();
|
||||
m_label = computer.getLabel();
|
||||
m_on = computer.isOn();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ClientComputer computer = createClientComputer();
|
||||
if( computer != null )
|
||||
{
|
||||
if( computer.hasOutputChanged() )
|
||||
{
|
||||
updateBlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.writeToNBT( nbttagcompound );
|
||||
|
||||
// Save ID, label and power state
|
||||
if( m_computerID >= 0 )
|
||||
{
|
||||
nbttagcompound.setInteger( "computerID", m_computerID );
|
||||
}
|
||||
if( m_label != null )
|
||||
{
|
||||
nbttagcompound.setString( "label", m_label );
|
||||
}
|
||||
nbttagcompound.setBoolean( "on", m_on );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.readFromNBT( nbttagcompound );
|
||||
|
||||
// Load ID
|
||||
int id = -1;
|
||||
if( nbttagcompound.hasKey( "computerID" ) )
|
||||
{
|
||||
// Post-1.6 computers
|
||||
id = nbttagcompound.getInteger( "computerID" );
|
||||
}
|
||||
else if( nbttagcompound.hasKey( "userDir" ) )
|
||||
{
|
||||
// Pre-1.6 computers
|
||||
String userDir = nbttagcompound.getString( "userDir" );
|
||||
try
|
||||
{
|
||||
id = Integer.parseInt( userDir );
|
||||
}
|
||||
catch( NumberFormatException e )
|
||||
{
|
||||
// Ignore badly formatted data
|
||||
}
|
||||
}
|
||||
m_computerID = id;
|
||||
|
||||
// Load label
|
||||
if( nbttagcompound.hasKey( "label" ) )
|
||||
{
|
||||
m_label = nbttagcompound.getString( "label" );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_label = null;
|
||||
}
|
||||
|
||||
// Load power state
|
||||
m_startOn = nbttagcompound.getBoolean( "on" );
|
||||
m_on = m_startOn;
|
||||
}
|
||||
|
||||
protected boolean isPeripheralBlockedOnSide( int localSide )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean isRedstoneBlockedOnSide( int localSide )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected int remapLocalSide( int localSide )
|
||||
{
|
||||
return localSide;
|
||||
}
|
||||
|
||||
public void updateInput()
|
||||
{
|
||||
if( worldObj == null || worldObj.isRemote )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Update redstone and peripherals
|
||||
ServerComputer computer = getServerComputer();
|
||||
if( computer != null )
|
||||
{
|
||||
BlockPos pos = computer.getPosition();
|
||||
for( EnumFacing dir : EnumFacing.VALUES )
|
||||
{
|
||||
BlockPos offset = pos.offset( dir );
|
||||
EnumFacing offsetSide = dir.getOpposite();
|
||||
int localDir = remapLocalSide( DirectionUtil.toLocal( this, dir ) );
|
||||
if( !isRedstoneBlockedOnSide( localDir ) )
|
||||
{
|
||||
computer.setRedstoneInput( localDir, RedstoneUtil.getRedstoneOutput( worldObj, offset, offsetSide ) );
|
||||
computer.setBundledRedstoneInput( localDir, RedstoneUtil.getBundledRedstoneOutput( worldObj, offset, offsetSide ) );
|
||||
}
|
||||
if( !isPeripheralBlockedOnSide( localDir ) )
|
||||
{
|
||||
computer.setPeripheral( localDir, PeripheralUtil.getPeripheral( worldObj, offset, offsetSide ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateOutput()
|
||||
{
|
||||
// Update redstone
|
||||
updateBlock();
|
||||
for( EnumFacing dir : EnumFacing.VALUES )
|
||||
{
|
||||
RedstoneUtil.propogateRedstoneOutput( worldObj, getPos(), dir );
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract ServerComputer createComputer( int instanceID, int id );
|
||||
|
||||
// ITerminalTile
|
||||
|
||||
@Override
|
||||
public ITerminal getTerminal()
|
||||
{
|
||||
return getComputer();
|
||||
}
|
||||
|
||||
// IComputerTile
|
||||
|
||||
@Override
|
||||
public void setComputerID( int id )
|
||||
{
|
||||
if( !worldObj.isRemote && m_computerID != id )
|
||||
{
|
||||
m_computerID = id;
|
||||
ServerComputer computer = getServerComputer();
|
||||
if( computer != null )
|
||||
{
|
||||
computer.setID( m_computerID );
|
||||
}
|
||||
markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLabel( String label )
|
||||
{
|
||||
if( !worldObj.isRemote )
|
||||
{
|
||||
createServerComputer().setLabel( label );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IComputer createComputer()
|
||||
{
|
||||
if( worldObj.isRemote )
|
||||
{
|
||||
return createClientComputer();
|
||||
}
|
||||
else
|
||||
{
|
||||
return createServerComputer();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IComputer getComputer()
|
||||
{
|
||||
if( worldObj.isRemote )
|
||||
{
|
||||
return getClientComputer();
|
||||
}
|
||||
else
|
||||
{
|
||||
return getServerComputer();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComputerFamily getFamily()
|
||||
{
|
||||
BlockComputerBase block = getBlock();
|
||||
if( block != null )
|
||||
{
|
||||
return block.getFamily( worldObj, getPos() );
|
||||
}
|
||||
return ComputerFamily.Normal;
|
||||
}
|
||||
|
||||
public ServerComputer createServerComputer()
|
||||
{
|
||||
if( !worldObj.isRemote )
|
||||
{
|
||||
boolean changed = false;
|
||||
if( m_instanceID < 0 )
|
||||
{
|
||||
m_instanceID = ComputerCraft.serverComputerRegistry.getUnusedInstanceID();
|
||||
changed = true;
|
||||
}
|
||||
if( !ComputerCraft.serverComputerRegistry.contains( m_instanceID ) )
|
||||
{
|
||||
ServerComputer computer = createComputer( m_instanceID, m_computerID );
|
||||
ComputerCraft.serverComputerRegistry.add( m_instanceID, computer );
|
||||
changed = true;
|
||||
}
|
||||
if( changed )
|
||||
{
|
||||
updateBlock();
|
||||
updateInput();
|
||||
}
|
||||
return ComputerCraft.serverComputerRegistry.get( m_instanceID );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ServerComputer getServerComputer()
|
||||
{
|
||||
if( !worldObj.isRemote )
|
||||
{
|
||||
return ComputerCraft.serverComputerRegistry.get( m_instanceID );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ClientComputer createClientComputer()
|
||||
{
|
||||
if( worldObj.isRemote )
|
||||
{
|
||||
if( m_instanceID >= 0 )
|
||||
{
|
||||
if( !ComputerCraft.clientComputerRegistry.contains( m_instanceID ) )
|
||||
{
|
||||
ComputerCraft.clientComputerRegistry.add( m_instanceID, new ClientComputer( m_instanceID ) );
|
||||
}
|
||||
return ComputerCraft.clientComputerRegistry.get( m_instanceID );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ClientComputer getClientComputer()
|
||||
{
|
||||
if( worldObj.isRemote )
|
||||
{
|
||||
return ComputerCraft.clientComputerRegistry.get( m_instanceID );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Networking stuff
|
||||
|
||||
@Override
|
||||
public void writeDescription( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.writeDescription( nbttagcompound );
|
||||
nbttagcompound.setInteger( "instanceID", createServerComputer().getInstanceID() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readDescription( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.readDescription( nbttagcompound );
|
||||
m_instanceID = nbttagcompound.getInteger( "instanceID" );
|
||||
}
|
||||
|
||||
protected void transferStateFrom( TileComputerBase copy )
|
||||
{
|
||||
if( copy.m_computerID != m_computerID || copy.m_instanceID != m_instanceID )
|
||||
{
|
||||
unload();
|
||||
m_instanceID = copy.m_instanceID;
|
||||
m_computerID = copy.m_computerID;
|
||||
m_label = copy.m_label;
|
||||
m_on = copy.m_on;
|
||||
m_startOn = copy.m_startOn;
|
||||
updateBlock();
|
||||
}
|
||||
copy.m_instanceID = -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.core;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.common.ClientTerminal;
|
||||
import dan200.computercraft.shared.network.ComputerCraftPacket;
|
||||
import dan200.computercraft.shared.network.INetworkedThing;
|
||||
import dan200.computercraft.shared.util.NBTUtil;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
public class ClientComputer extends ClientTerminal
|
||||
implements IComputer, INetworkedThing
|
||||
{
|
||||
private final int m_instanceID;
|
||||
|
||||
private int m_computerID;
|
||||
private String m_label;
|
||||
private boolean m_on;
|
||||
private boolean m_blinking;
|
||||
private boolean m_changed;
|
||||
private NBTTagCompound m_userData;
|
||||
|
||||
private boolean m_changedLastFrame;
|
||||
|
||||
public ClientComputer( int instanceID )
|
||||
{
|
||||
super( false );
|
||||
m_instanceID = instanceID;
|
||||
|
||||
m_computerID = -1;
|
||||
m_label = null;
|
||||
m_on = false;
|
||||
m_blinking = false;
|
||||
m_changed = true;
|
||||
m_userData = null;
|
||||
m_changedLastFrame = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
super.update();
|
||||
m_changedLastFrame = m_changed;
|
||||
m_changed = false;
|
||||
}
|
||||
|
||||
public boolean hasOutputChanged()
|
||||
{
|
||||
return m_changedLastFrame;
|
||||
}
|
||||
|
||||
public NBTTagCompound getUserData()
|
||||
{
|
||||
return m_userData;
|
||||
}
|
||||
|
||||
public void requestState()
|
||||
{
|
||||
// Request state from server
|
||||
ComputerCraftPacket packet = new ComputerCraftPacket();
|
||||
packet.m_packetType = ComputerCraftPacket.RequestComputerUpdate;
|
||||
packet.m_dataInt = new int[] { getInstanceID() };
|
||||
ComputerCraft.sendToServer( packet );
|
||||
}
|
||||
|
||||
// IComputer
|
||||
|
||||
@Override
|
||||
public int getInstanceID()
|
||||
{
|
||||
return m_instanceID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getID()
|
||||
{
|
||||
return m_computerID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel()
|
||||
{
|
||||
return m_label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOn()
|
||||
{
|
||||
return m_on;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCursorDisplayed()
|
||||
{
|
||||
return m_on && m_blinking;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void turnOn()
|
||||
{
|
||||
// Send turnOn to server
|
||||
ComputerCraftPacket packet = new ComputerCraftPacket();
|
||||
packet.m_packetType = ComputerCraftPacket.TurnOn;
|
||||
packet.m_dataInt = new int[] { m_instanceID };
|
||||
ComputerCraft.sendToServer( packet );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown()
|
||||
{
|
||||
// Send shutdown to server
|
||||
ComputerCraftPacket packet = new ComputerCraftPacket();
|
||||
packet.m_packetType = ComputerCraftPacket.Shutdown;
|
||||
packet.m_dataInt = new int[] { m_instanceID };
|
||||
ComputerCraft.sendToServer( packet );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reboot()
|
||||
{
|
||||
// Send reboot to server
|
||||
ComputerCraftPacket packet = new ComputerCraftPacket();
|
||||
packet.m_packetType = ComputerCraftPacket.Reboot;
|
||||
packet.m_dataInt = new int[] { m_instanceID };
|
||||
ComputerCraft.sendToServer( packet );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queueEvent( String event )
|
||||
{
|
||||
queueEvent( event, null );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queueEvent( String event, Object[] arguments )
|
||||
{
|
||||
// Send event to server
|
||||
ComputerCraftPacket packet = new ComputerCraftPacket();
|
||||
packet.m_packetType = ComputerCraftPacket.QueueEvent;
|
||||
packet.m_dataInt = new int[] { m_instanceID };
|
||||
packet.m_dataString = new String[] { event };
|
||||
if( arguments != null )
|
||||
{
|
||||
packet.m_dataNBT = NBTUtil.encodeObjects( arguments );
|
||||
}
|
||||
ComputerCraft.sendToServer( packet );
|
||||
}
|
||||
|
||||
public void readDescription( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.readDescription( nbttagcompound );
|
||||
|
||||
int oldID = m_computerID;
|
||||
String oldLabel = m_label;
|
||||
boolean oldOn = m_on;
|
||||
boolean oldBlinking = m_blinking;
|
||||
NBTTagCompound oldUserData = m_userData;
|
||||
|
||||
m_computerID = nbttagcompound.getInteger( "id" );
|
||||
m_label = nbttagcompound.hasKey( "label" ) ? nbttagcompound.getString( "label" ) : null;
|
||||
m_on = nbttagcompound.getBoolean( "on" );
|
||||
m_blinking = nbttagcompound.getBoolean( "blinking" );
|
||||
if( nbttagcompound.hasKey( "userData" ) )
|
||||
{
|
||||
m_userData = (NBTTagCompound)(nbttagcompound.getCompoundTag( "userData" )).copy();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_userData = null;
|
||||
}
|
||||
|
||||
if( m_computerID != oldID || m_on != oldOn || m_blinking != oldBlinking || !Objects.equal( m_label, oldLabel ) || !Objects.equal( m_userData, oldUserData ) )
|
||||
{
|
||||
m_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePacket( ComputerCraftPacket packet, EntityPlayer sender )
|
||||
{
|
||||
switch( packet.m_packetType )
|
||||
{
|
||||
case ComputerCraftPacket.ComputerChanged:
|
||||
{
|
||||
readDescription( packet.m_dataNBT );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.core;
|
||||
|
||||
public class ClientComputerRegistry extends ComputerRegistry<ClientComputer>
|
||||
{
|
||||
public ClientComputerRegistry()
|
||||
{
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
for( ClientComputer computer : getComputers() )
|
||||
{
|
||||
computer.update();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add( int instanceID, ClientComputer computer )
|
||||
{
|
||||
//System.out.println( "ADD CLIENT COMPUTER " + instanceID );
|
||||
super.add( instanceID, computer );
|
||||
computer.requestState();
|
||||
//System.out.println( getComputers().size() + " CLIENT COMPUTERS" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove( int instanceID )
|
||||
{
|
||||
//System.out.println( "REMOVE CLIENT COMPUTER " + instanceID );
|
||||
super.remove( instanceID );
|
||||
//System.out.println( getComputers().size() + " CLIENT COMPUTERS" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
//System.out.println( "RESET CLIENT COMPUTERS" );
|
||||
super.reset();
|
||||
//System.out.println( getComputers().size() + " CLIENT COMPUTERS" );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.core;
|
||||
|
||||
public enum ComputerFamily
|
||||
{
|
||||
Normal,
|
||||
Advanced,
|
||||
Beginners,
|
||||
Command
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.core;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
public class ComputerRegistry<TComputer extends IComputer>
|
||||
{
|
||||
private Map<Integer, TComputer> m_computers;
|
||||
private int m_nextUnusedInstanceID;
|
||||
private int m_sessionID;
|
||||
|
||||
protected ComputerRegistry()
|
||||
{
|
||||
m_computers = new HashMap<Integer, TComputer>();
|
||||
reset();
|
||||
}
|
||||
|
||||
public int getSessionID()
|
||||
{
|
||||
return m_sessionID;
|
||||
}
|
||||
|
||||
public int getUnusedInstanceID()
|
||||
{
|
||||
return m_nextUnusedInstanceID++;
|
||||
}
|
||||
|
||||
public Collection<TComputer> getComputers()
|
||||
{
|
||||
return m_computers.values();
|
||||
}
|
||||
|
||||
public TComputer get( int instanceID )
|
||||
{
|
||||
if( instanceID >= 0 )
|
||||
{
|
||||
if( m_computers.containsKey( instanceID ) )
|
||||
{
|
||||
return m_computers.get( instanceID );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public TComputer lookup( int computerID )
|
||||
{
|
||||
if( computerID >= 0 )
|
||||
{
|
||||
for( TComputer computer : getComputers() )
|
||||
{
|
||||
if( computer.getID() == computerID )
|
||||
{
|
||||
return computer;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean contains( int instanceID )
|
||||
{
|
||||
return m_computers.containsKey( instanceID );
|
||||
}
|
||||
|
||||
public void add( int instanceID, TComputer computer )
|
||||
{
|
||||
if( m_computers.containsKey( instanceID ) )
|
||||
{
|
||||
remove( instanceID );
|
||||
}
|
||||
m_computers.put( instanceID, computer );
|
||||
m_nextUnusedInstanceID = Math.max( m_nextUnusedInstanceID, instanceID + 1 );
|
||||
}
|
||||
|
||||
public void remove( int instanceID )
|
||||
{
|
||||
if( m_computers.containsKey( instanceID ) )
|
||||
{
|
||||
m_computers.remove( instanceID );
|
||||
}
|
||||
}
|
||||
|
||||
public void reset()
|
||||
{
|
||||
m_computers.clear();
|
||||
m_nextUnusedInstanceID = 0;
|
||||
m_sessionID = (new Random().nextInt());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.core;
|
||||
|
||||
import dan200.computercraft.shared.common.ITerminal;
|
||||
|
||||
public interface IComputer extends ITerminal
|
||||
{
|
||||
public int getInstanceID();
|
||||
public int getID();
|
||||
public String getLabel();
|
||||
|
||||
public boolean isOn();
|
||||
public boolean isCursorDisplayed();
|
||||
public void turnOn();
|
||||
public void shutdown();
|
||||
public void reboot();
|
||||
|
||||
public void queueEvent( String event );
|
||||
public void queueEvent( String event, Object[] arguments );
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.core;
|
||||
|
||||
public interface IComputerContainer
|
||||
{
|
||||
public IComputer getComputer();
|
||||
}
|
||||
@@ -0,0 +1,402 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.core;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.filesystem.IMount;
|
||||
import dan200.computercraft.api.filesystem.IWritableMount;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.core.apis.IAPIEnvironment;
|
||||
import dan200.computercraft.core.apis.ILuaAPI;
|
||||
import dan200.computercraft.core.computer.Computer;
|
||||
import dan200.computercraft.core.computer.IComputerEnvironment;
|
||||
import dan200.computercraft.shared.common.ServerTerminal;
|
||||
import dan200.computercraft.shared.network.ComputerCraftPacket;
|
||||
import dan200.computercraft.shared.network.INetworkedThing;
|
||||
import dan200.computercraft.shared.util.NBTUtil;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
|
||||
public class ServerComputer extends ServerTerminal
|
||||
implements IComputer, IComputerEnvironment, INetworkedThing
|
||||
{
|
||||
private final int m_instanceID;
|
||||
|
||||
private World m_world;
|
||||
private BlockPos m_position;
|
||||
|
||||
private final Computer m_computer;
|
||||
private NBTTagCompound m_userData;
|
||||
private boolean m_changed;
|
||||
|
||||
private boolean m_changedLastFrame;
|
||||
private int m_ticksSincePing;
|
||||
|
||||
public ServerComputer( World world, int computerID, String label, int instanceID, ComputerFamily family, int terminalWidth, int terminalHeight )
|
||||
{
|
||||
super( family != ComputerFamily.Normal, terminalWidth, terminalHeight );
|
||||
m_instanceID = instanceID;
|
||||
|
||||
m_world = world;
|
||||
m_position = null;
|
||||
|
||||
m_computer = new Computer( this, getTerminal(), computerID );
|
||||
m_computer.setLabel( label );
|
||||
m_userData = null;
|
||||
m_changed = false;
|
||||
|
||||
m_changedLastFrame = false;
|
||||
m_ticksSincePing = 0;
|
||||
}
|
||||
|
||||
public World getWorld()
|
||||
{
|
||||
return m_world;
|
||||
}
|
||||
|
||||
public void setWorld( World world )
|
||||
{
|
||||
m_world = world;
|
||||
}
|
||||
|
||||
public BlockPos getPosition()
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
public void setPosition( BlockPos pos )
|
||||
{
|
||||
m_position = new BlockPos( pos );
|
||||
}
|
||||
|
||||
public IAPIEnvironment getAPIEnvironment()
|
||||
{
|
||||
return m_computer.getAPIEnvironment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
super.update();
|
||||
m_computer.advance( 0.05 );
|
||||
|
||||
m_changedLastFrame = m_changed || m_computer.pollChanged();
|
||||
m_computer.clearChanged();
|
||||
m_changed = false;
|
||||
|
||||
m_ticksSincePing++;
|
||||
}
|
||||
|
||||
public void keepAlive()
|
||||
{
|
||||
m_ticksSincePing = 0;
|
||||
}
|
||||
|
||||
public boolean hasTimedOut()
|
||||
{
|
||||
return m_ticksSincePing > 100;
|
||||
}
|
||||
|
||||
public boolean hasOutputChanged()
|
||||
{
|
||||
return m_changedLastFrame;
|
||||
}
|
||||
|
||||
public void unload()
|
||||
{
|
||||
m_computer.unload();
|
||||
}
|
||||
|
||||
public NBTTagCompound getUserData()
|
||||
{
|
||||
if( m_userData == null )
|
||||
{
|
||||
m_userData = new NBTTagCompound();
|
||||
}
|
||||
return m_userData;
|
||||
}
|
||||
|
||||
public void updateUserData()
|
||||
{
|
||||
m_changed = true;
|
||||
}
|
||||
|
||||
public void broadcastState()
|
||||
{
|
||||
// Send state to client
|
||||
ComputerCraftPacket packet = new ComputerCraftPacket();
|
||||
packet.m_packetType = ComputerCraftPacket.ComputerChanged;
|
||||
packet.m_dataInt = new int[] { getInstanceID() };
|
||||
packet.m_dataNBT = new NBTTagCompound();
|
||||
writeDescription( packet.m_dataNBT );
|
||||
ComputerCraft.sendToAllPlayers( packet );
|
||||
}
|
||||
|
||||
public void sendState( EntityPlayer player )
|
||||
{
|
||||
// Send state to client
|
||||
ComputerCraftPacket packet = new ComputerCraftPacket();
|
||||
packet.m_packetType = ComputerCraftPacket.ComputerChanged;
|
||||
packet.m_dataInt = new int[] { getInstanceID() };
|
||||
packet.m_dataNBT = new NBTTagCompound();
|
||||
writeDescription( packet.m_dataNBT );
|
||||
ComputerCraft.sendToPlayer( player, packet );
|
||||
}
|
||||
|
||||
public void broadcastDelete()
|
||||
{
|
||||
// Send deletion to client
|
||||
ComputerCraftPacket packet = new ComputerCraftPacket();
|
||||
packet.m_packetType = ComputerCraftPacket.ComputerDeleted;
|
||||
packet.m_dataInt = new int[] { getInstanceID() };
|
||||
ComputerCraft.sendToAllPlayers( packet );
|
||||
}
|
||||
|
||||
public IWritableMount getRootMount()
|
||||
{
|
||||
return m_computer.getRootMount();
|
||||
}
|
||||
|
||||
public int assignID()
|
||||
{
|
||||
return m_computer.assignID();
|
||||
}
|
||||
|
||||
public void setID( int id )
|
||||
{
|
||||
m_computer.setID( id );
|
||||
}
|
||||
|
||||
// IComputer
|
||||
|
||||
@Override
|
||||
public int getInstanceID()
|
||||
{
|
||||
return m_instanceID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getID()
|
||||
{
|
||||
return m_computer.getID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel()
|
||||
{
|
||||
return m_computer.getLabel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOn()
|
||||
{
|
||||
return m_computer.isOn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCursorDisplayed()
|
||||
{
|
||||
return m_computer.isOn() && m_computer.isBlinking();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void turnOn()
|
||||
{
|
||||
// Turn on
|
||||
m_computer.turnOn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown()
|
||||
{
|
||||
// Shutdown
|
||||
m_computer.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reboot()
|
||||
{
|
||||
// Reboot
|
||||
m_computer.reboot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queueEvent( String event )
|
||||
{
|
||||
// Queue event
|
||||
queueEvent( event, null );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queueEvent( String event, Object[] arguments )
|
||||
{
|
||||
// Queue event
|
||||
m_computer.queueEvent( event, arguments );
|
||||
}
|
||||
|
||||
public int getRedstoneOutput( int side )
|
||||
{
|
||||
return m_computer.getRedstoneOutput( side );
|
||||
}
|
||||
|
||||
public void setRedstoneInput( int side, int level )
|
||||
{
|
||||
m_computer.setRedstoneInput( side, level );
|
||||
}
|
||||
|
||||
public int getBundledRedstoneOutput( int side )
|
||||
{
|
||||
return m_computer.getBundledRedstoneOutput( side );
|
||||
}
|
||||
|
||||
public void setBundledRedstoneInput( int side, int combination )
|
||||
{
|
||||
m_computer.setBundledRedstoneInput( side, combination );
|
||||
}
|
||||
|
||||
public void addAPI( ILuaAPI api )
|
||||
{
|
||||
m_computer.addAPI( api );
|
||||
}
|
||||
|
||||
public void setPeripheral( int side, IPeripheral peripheral )
|
||||
{
|
||||
m_computer.setPeripheral( side, peripheral );
|
||||
}
|
||||
|
||||
public IPeripheral getPeripheral( int side )
|
||||
{
|
||||
return m_computer.getPeripheral( side );
|
||||
}
|
||||
|
||||
public void setLabel( String label )
|
||||
{
|
||||
m_computer.setLabel( label );
|
||||
}
|
||||
|
||||
// IComputerEnvironment implementation
|
||||
|
||||
@Override
|
||||
public double getTimeOfDay()
|
||||
{
|
||||
return (double)((m_world.getWorldTime() + 6000) % 24000) / 1000.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDay()
|
||||
{
|
||||
return (int)((m_world.getWorldTime() + 6000) / 24000) + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IWritableMount createSaveDirMount( String subPath, long capacity )
|
||||
{
|
||||
return ComputerCraftAPI.createSaveDirMount( m_world, subPath, capacity );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMount createResourceMount( String domain, String subPath )
|
||||
{
|
||||
return ComputerCraftAPI.createResourceMount( ComputerCraft.class, domain, subPath );
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getComputerSpaceLimit()
|
||||
{
|
||||
return ComputerCraft.computerSpaceLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHostString()
|
||||
{
|
||||
return "ComputerCraft ${version} (Minecraft " + Loader.MC_VERSION + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int assignNewID()
|
||||
{
|
||||
return ComputerCraft.createUniqueNumberedSaveDir( m_world, "computer" );
|
||||
}
|
||||
|
||||
// Networking stuff
|
||||
|
||||
public void writeDescription( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.writeDescription( nbttagcompound );
|
||||
|
||||
nbttagcompound.setInteger( "id", m_computer.getID() );
|
||||
String label = m_computer.getLabel();
|
||||
if( label != null )
|
||||
{
|
||||
nbttagcompound.setString( "label", label );
|
||||
}
|
||||
nbttagcompound.setBoolean( "on", m_computer.isOn() );
|
||||
nbttagcompound.setBoolean( "blinking", m_computer.isBlinking() );
|
||||
if( m_userData != null )
|
||||
{
|
||||
nbttagcompound.setTag( "userData", m_userData.copy() );
|
||||
}
|
||||
}
|
||||
|
||||
// INetworkedThing
|
||||
|
||||
@Override
|
||||
public void handlePacket( ComputerCraftPacket packet, EntityPlayer sender )
|
||||
{
|
||||
// Receive packets sent from the client to the server
|
||||
switch( packet.m_packetType )
|
||||
{
|
||||
case ComputerCraftPacket.TurnOn:
|
||||
{
|
||||
// A player has turned the computer on
|
||||
turnOn();
|
||||
break;
|
||||
}
|
||||
case ComputerCraftPacket.Reboot:
|
||||
{
|
||||
// A player has held down ctrl+r
|
||||
reboot();
|
||||
break;
|
||||
}
|
||||
case ComputerCraftPacket.Shutdown:
|
||||
{
|
||||
// A player has held down ctrl+s
|
||||
shutdown();
|
||||
break;
|
||||
}
|
||||
case ComputerCraftPacket.QueueEvent:
|
||||
{
|
||||
// A player has caused a UI event to be fired
|
||||
String event = packet.m_dataString[0];
|
||||
Object[] arguments = null;
|
||||
if( packet.m_dataNBT != null )
|
||||
{
|
||||
arguments = NBTUtil.decodeObjects( packet.m_dataNBT );
|
||||
}
|
||||
queueEvent( event, arguments );
|
||||
break;
|
||||
}
|
||||
case ComputerCraftPacket.SetLabel:
|
||||
{
|
||||
// A player wants to relabel a computer
|
||||
String label = (packet.m_dataString != null && packet.m_dataString.length >= 1) ? packet.m_dataString[0] : null;
|
||||
setLabel( label );
|
||||
break;
|
||||
}
|
||||
case ComputerCraftPacket.RequestComputerUpdate:
|
||||
{
|
||||
// A player asked for an update on the state of the terminal
|
||||
sendState( sender );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.core;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public class ServerComputerRegistry extends ComputerRegistry<ServerComputer>
|
||||
{
|
||||
public ServerComputerRegistry()
|
||||
{
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
Iterator<ServerComputer> it = getComputers().iterator();
|
||||
while( it.hasNext() )
|
||||
{
|
||||
ServerComputer computer = it.next();
|
||||
if( computer.hasTimedOut() )
|
||||
{
|
||||
//System.out.println( "TIMED OUT SERVER COMPUTER " + computer.getInstanceID() );
|
||||
computer.unload();
|
||||
computer.broadcastDelete();
|
||||
it.remove();
|
||||
//System.out.println( getComputers().size() + " SERVER COMPUTERS" );
|
||||
}
|
||||
else
|
||||
{
|
||||
computer.update();
|
||||
if( computer.hasTerminalChanged() || computer.hasOutputChanged() )
|
||||
{
|
||||
computer.broadcastState();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add( int instanceID, ServerComputer computer )
|
||||
{
|
||||
//System.out.println( "ADD SERVER COMPUTER " + instanceID );
|
||||
super.add( instanceID, computer );
|
||||
computer.broadcastState();
|
||||
//System.out.println( getComputers().size() + " SERVER COMPUTERS" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove( int instanceID )
|
||||
{
|
||||
//System.out.println( "REMOVE SERVER COMPUTER " + instanceID );
|
||||
ServerComputer computer = get( instanceID );
|
||||
if( computer != null )
|
||||
{
|
||||
computer.unload();
|
||||
computer.broadcastDelete();
|
||||
}
|
||||
super.remove( instanceID );
|
||||
//System.out.println( getComputers().size() + " SERVER COMPUTERS" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
//System.out.println( "RESET SERVER COMPUTERS" );
|
||||
for( ServerComputer computer : getComputers() )
|
||||
{
|
||||
computer.unload();
|
||||
}
|
||||
super.reset();
|
||||
//System.out.println( getComputers().size() + " SERVER COMPUTERS" );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.inventory;
|
||||
|
||||
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.Container;
|
||||
|
||||
public class ContainerComputer extends Container
|
||||
{
|
||||
private TileComputer m_computer;
|
||||
|
||||
public ContainerComputer( TileComputer computer )
|
||||
{
|
||||
m_computer = computer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInteractWith( EntityPlayer player )
|
||||
{
|
||||
return m_computer.isUseableByPlayer( player );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.items;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.computer.blocks.IComputerTile;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.IComputer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class ComputerItemFactory
|
||||
{
|
||||
public static ItemStack create( IComputerTile computerTile )
|
||||
{
|
||||
IComputer computer = computerTile.getComputer();
|
||||
if( computer != null )
|
||||
{
|
||||
String label = computer.getLabel();
|
||||
int id = (label != null) ? computer.getID() : -1;
|
||||
return create( id, label, computerTile.getFamily() );
|
||||
}
|
||||
else
|
||||
{
|
||||
return create( -1, null, computerTile.getFamily() );
|
||||
}
|
||||
}
|
||||
|
||||
public static ItemStack create( int id, String label, ComputerFamily family )
|
||||
{
|
||||
ItemComputer computer = ((ItemComputer)Item.getItemFromBlock( ComputerCraft.Blocks.computer ));
|
||||
ItemCommandComputer commandComputer = ((ItemCommandComputer)Item.getItemFromBlock( ComputerCraft.Blocks.commandComputer ));
|
||||
switch( family )
|
||||
{
|
||||
case Normal:
|
||||
case Advanced:
|
||||
{
|
||||
return computer.create( id, label, family );
|
||||
}
|
||||
case Command:
|
||||
{
|
||||
return commandComputer.create( id, label, family );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.items;
|
||||
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public interface IComputerItem
|
||||
{
|
||||
public int getComputerID( ItemStack stack );
|
||||
public String getLabel( ItemStack stack );
|
||||
public ComputerFamily getFamily( ItemStack stack );
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.items;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ItemCommandComputer extends ItemComputer
|
||||
{
|
||||
public ItemCommandComputer( Block block )
|
||||
{
|
||||
super( block );
|
||||
setMaxStackSize( 64 );
|
||||
setHasSubtypes( true );
|
||||
setUnlocalizedName( "computercraft:command_computer" );
|
||||
setCreativeTab( ComputerCraft.mainCreativeTab );
|
||||
}
|
||||
|
||||
public ItemStack create( int id, String label, ComputerFamily family )
|
||||
{
|
||||
// Ignore types we can't handle
|
||||
if( family != ComputerFamily.Command )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Build the stack
|
||||
ItemStack result = new ItemStack( this, 1, 0 );
|
||||
|
||||
NBTTagCompound nbt = new NBTTagCompound();
|
||||
nbt.setInteger( "computerID", id );
|
||||
result.setTagCompound( nbt );
|
||||
|
||||
if( label != null )
|
||||
{
|
||||
result.setStackDisplayName( label );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubItems( Item itemID, CreativeTabs tabs, List list )
|
||||
{
|
||||
list.add( ComputerItemFactory.create( -1, null, ComputerFamily.Command ) );
|
||||
}
|
||||
|
||||
// IComputerItem implementation
|
||||
|
||||
@Override
|
||||
public int getComputerID( ItemStack stack )
|
||||
{
|
||||
if( stack.hasTagCompound() && stack.getTagCompound().hasKey( "computerID" ) )
|
||||
{
|
||||
return stack.getTagCompound().getInteger( "computerID" );
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComputerFamily getFamily( int damage )
|
||||
{
|
||||
return ComputerFamily.Command;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.items;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.computer.blocks.IComputerTile;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ItemComputer extends ItemComputerBase
|
||||
{
|
||||
public static int HIGHEST_DAMAGE_VALUE_ID = 16382;
|
||||
|
||||
public ItemComputer( Block block )
|
||||
{
|
||||
super( block );
|
||||
setMaxStackSize( 64 );
|
||||
setHasSubtypes( true );
|
||||
setUnlocalizedName( "computercraft:computer" );
|
||||
setCreativeTab( ComputerCraft.mainCreativeTab );
|
||||
}
|
||||
|
||||
public ItemStack create( int id, String label, ComputerFamily family )
|
||||
{
|
||||
// Ignore types we can't handle
|
||||
if( family != ComputerFamily.Normal && family != ComputerFamily.Advanced )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Build the damage
|
||||
int damage = 0;
|
||||
if( id >= 0 && id <= ItemComputer.HIGHEST_DAMAGE_VALUE_ID )
|
||||
{
|
||||
damage = id + 1;
|
||||
}
|
||||
if( family == ComputerFamily.Advanced )
|
||||
{
|
||||
damage += 0x4000;
|
||||
}
|
||||
|
||||
// Return the stack
|
||||
ItemStack result = new ItemStack( this, 1, damage );
|
||||
if( id > ItemComputer.HIGHEST_DAMAGE_VALUE_ID )
|
||||
{
|
||||
NBTTagCompound nbt = new NBTTagCompound();
|
||||
nbt.setInteger( "computerID", id );
|
||||
result.setTagCompound( nbt );
|
||||
}
|
||||
if( label != null )
|
||||
{
|
||||
result.setStackDisplayName( label );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubItems( Item itemID, CreativeTabs tabs, List list )
|
||||
{
|
||||
list.add( ComputerItemFactory.create( -1, null, ComputerFamily.Normal ) );
|
||||
list.add( ComputerItemFactory.create( -1, null, ComputerFamily.Advanced ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean placeBlockAt( ItemStack stack, EntityPlayer player, World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ, IBlockState newState )
|
||||
{
|
||||
if( super.placeBlockAt( stack, player, world, pos, side, hitX, hitY, hitZ, newState ) )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof IComputerTile )
|
||||
{
|
||||
IComputerTile computer = (IComputerTile)tile;
|
||||
setupComputerAfterPlacement( stack, computer );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void setupComputerAfterPlacement( ItemStack stack, IComputerTile computer )
|
||||
{
|
||||
// Set ID
|
||||
int id = getComputerID( stack );
|
||||
if( id >= 0 )
|
||||
{
|
||||
computer.setComputerID( id );
|
||||
}
|
||||
|
||||
// Set Label
|
||||
String label = getLabel( stack );
|
||||
if( label != null )
|
||||
{
|
||||
computer.setLabel( label );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUnlocalizedName( ItemStack stack )
|
||||
{
|
||||
switch( getFamily( stack ) )
|
||||
{
|
||||
case Normal:
|
||||
default:
|
||||
{
|
||||
return "tile.computercraft:computer";
|
||||
}
|
||||
case Advanced:
|
||||
{
|
||||
return "tile.computercraft:advanced_computer";
|
||||
}
|
||||
case Command:
|
||||
{
|
||||
return "tile.computercraft:command_computer";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IComputerItem implementation
|
||||
|
||||
@Override
|
||||
public int getComputerID( ItemStack stack )
|
||||
{
|
||||
if( stack.hasTagCompound() && stack.getTagCompound().hasKey( "computerID" ) )
|
||||
{
|
||||
return stack.getTagCompound().getInteger( "computerID" );
|
||||
}
|
||||
else
|
||||
{
|
||||
int damage = stack.getItemDamage() & 0x3fff;
|
||||
return ( damage - 1 );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComputerFamily getFamily( int damage )
|
||||
{
|
||||
if( (damage & 0x4000) != 0 )
|
||||
{
|
||||
return ComputerFamily.Advanced;
|
||||
}
|
||||
return ComputerFamily.Normal;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.items;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.filesystem.IMount;
|
||||
import dan200.computercraft.api.media.IMedia;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class ItemComputerBase extends ItemBlock implements IComputerItem, IMedia
|
||||
{
|
||||
protected ItemComputerBase( Block block )
|
||||
{
|
||||
super( block );
|
||||
}
|
||||
|
||||
public abstract ComputerFamily getFamily( int damage );
|
||||
|
||||
@Override
|
||||
public final int getMetadata( int damage )
|
||||
{
|
||||
return damage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInformation( ItemStack stack, EntityPlayer player, List list, boolean debug )
|
||||
{
|
||||
if( debug )
|
||||
{
|
||||
int id = getComputerID( stack );
|
||||
if( id >= 0 )
|
||||
{
|
||||
list.add( "(Computer ID: " + id + ")" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IComputerItem implementation
|
||||
|
||||
@Override
|
||||
public abstract int getComputerID( ItemStack stack );
|
||||
|
||||
@Override
|
||||
public String getLabel( ItemStack stack )
|
||||
{
|
||||
if( stack.hasDisplayName() )
|
||||
{
|
||||
return stack.getDisplayName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ComputerFamily getFamily( ItemStack stack )
|
||||
{
|
||||
int damage = stack.getItemDamage();
|
||||
return getFamily( damage );
|
||||
}
|
||||
|
||||
// IMedia implementation
|
||||
|
||||
@Override
|
||||
public boolean setLabel( ItemStack stack, String label )
|
||||
{
|
||||
if( label != null )
|
||||
{
|
||||
stack.setStackDisplayName( label );
|
||||
}
|
||||
else
|
||||
{
|
||||
stack.clearCustomName();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAudioTitle( ItemStack stack )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAudioRecordName( ItemStack stack )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMount createDataMount( ItemStack stack, World world )
|
||||
{
|
||||
ComputerFamily family = getFamily( stack );
|
||||
if( family != ComputerFamily.Command )
|
||||
{
|
||||
int id = getComputerID( stack );
|
||||
if( id >= 0 )
|
||||
{
|
||||
return ComputerCraft.createSaveDirMount( world, "computer/" + id, ComputerCraft.computerSpaceLimit );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package dan200.computercraft.shared.media.common;
|
||||
|
||||
import dan200.computercraft.api.media.IMedia;
|
||||
import dan200.computercraft.api.media.IMediaProvider;
|
||||
import dan200.computercraft.shared.media.items.RecordMedia;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemRecord;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class DefaultMediaProvider implements IMediaProvider
|
||||
{
|
||||
public DefaultMediaProvider()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMedia getMedia( ItemStack stack )
|
||||
{
|
||||
Item item = stack.getItem();
|
||||
if( item instanceof IMedia )
|
||||
{
|
||||
return (IMedia)item;
|
||||
}
|
||||
else if( item instanceof ItemRecord )
|
||||
{
|
||||
return new RecordMedia();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.media.inventory;
|
||||
|
||||
import dan200.computercraft.shared.util.InventoryUtil;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class ContainerHeldItem extends Container
|
||||
{
|
||||
private final ItemStack m_stack;
|
||||
private final int m_slot;
|
||||
|
||||
public ContainerHeldItem( InventoryPlayer player )
|
||||
{
|
||||
m_slot = player.currentItem;
|
||||
m_stack = InventoryUtil.copyItem( player.getStackInSlot( m_slot ) );
|
||||
}
|
||||
|
||||
public ItemStack getStack()
|
||||
{
|
||||
return m_stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInteractWith( EntityPlayer player )
|
||||
{
|
||||
if( player != null && player.isEntityAlive() )
|
||||
{
|
||||
ItemStack stack = player.inventory.getStackInSlot( m_slot );
|
||||
if( (stack == m_stack) || (stack != null && m_stack != null && stack.getItem() == m_stack.getItem()) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.media.items;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
public class ItemDiskExpanded extends ItemDiskLegacy
|
||||
{
|
||||
public ItemDiskExpanded()
|
||||
{
|
||||
}
|
||||
|
||||
public static ItemStack createFromIDAndColour( int id, String label, int colour )
|
||||
{
|
||||
ItemStack stack = new ItemStack( ComputerCraft.Items.diskExpanded, 1, 0 );
|
||||
|
||||
NBTTagCompound nbt = stack.getTagCompound();
|
||||
if( nbt == null )
|
||||
{
|
||||
nbt = new NBTTagCompound();
|
||||
stack.setTagCompound(nbt);
|
||||
}
|
||||
nbt.setInteger( "color", colour );
|
||||
ComputerCraft.Items.diskExpanded.setDiskID( stack, id );
|
||||
ComputerCraft.Items.diskExpanded.setLabel( stack, label );
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDiskID( ItemStack stack )
|
||||
{
|
||||
NBTTagCompound nbt = stack.getTagCompound();
|
||||
if( nbt != null && nbt.hasKey( "diskID" ) )
|
||||
{
|
||||
return nbt.getInteger( "diskID" );
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDiskID( ItemStack stack, int id )
|
||||
{
|
||||
if( id >= 0 )
|
||||
{
|
||||
NBTTagCompound nbt = stack.getTagCompound();
|
||||
if( nbt == null )
|
||||
{
|
||||
nbt = new NBTTagCompound();
|
||||
stack.setTagCompound( nbt );
|
||||
}
|
||||
nbt.setInteger( "diskID", id );
|
||||
}
|
||||
}
|
||||
|
||||
public int getColor( ItemStack stack )
|
||||
{
|
||||
NBTTagCompound nbt = stack.getTagCompound();
|
||||
return nbt != null && nbt.hasKey("color") ? nbt.getInteger("color") : Colour.values()[ Math.min(15, stack.getItemDamage()) ].getHex();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.media.items;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.api.filesystem.IMount;
|
||||
import dan200.computercraft.api.media.IMedia;
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ItemDiskLegacy extends Item
|
||||
implements IMedia
|
||||
{
|
||||
public ItemDiskLegacy()
|
||||
{
|
||||
setMaxStackSize( 1 );
|
||||
setHasSubtypes( true );
|
||||
setUnlocalizedName( "computercraft:disk" );
|
||||
setCreativeTab( ComputerCraft.mainCreativeTab );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubItems( Item itemID, CreativeTabs tabs, List list )
|
||||
{
|
||||
for( int colour=0; colour<16; ++colour )
|
||||
{
|
||||
ItemStack stack = createFromIDAndColour( -1, null, Colour.values()[ colour ].getHex() );
|
||||
if( stack.getItem() == this )
|
||||
{
|
||||
list.add( stack );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ItemStack createFromIDAndColour( int id, String label, int colour )
|
||||
{
|
||||
if( colour != Colour.Blue.getHex() )
|
||||
{
|
||||
return ItemDiskExpanded.createFromIDAndColour( id, label, colour );
|
||||
}
|
||||
|
||||
ItemStack stack = new ItemStack( ComputerCraft.Items.disk, 1 );
|
||||
ComputerCraft.Items.disk.setDiskID( stack, id );
|
||||
ComputerCraft.Items.disk.setLabel( stack, label );
|
||||
return stack;
|
||||
}
|
||||
|
||||
public int getDiskID( ItemStack stack )
|
||||
{
|
||||
int damage = stack.getItemDamage();
|
||||
if( damage > 0 )
|
||||
{
|
||||
return damage;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected void setDiskID( ItemStack stack, int id )
|
||||
{
|
||||
if( id > 0 ) {
|
||||
stack.setItemDamage( id );
|
||||
} else {
|
||||
stack.setItemDamage( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInformation( ItemStack stack, EntityPlayer player, List list, boolean debug )
|
||||
{
|
||||
if( debug )
|
||||
{
|
||||
int id = getDiskID( stack );
|
||||
if( id >= 0 )
|
||||
{
|
||||
list.add( "(Disk ID: " + id + ")" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IMedia implementation
|
||||
|
||||
@Override
|
||||
public String getLabel( ItemStack stack )
|
||||
{
|
||||
if( stack.hasDisplayName() )
|
||||
{
|
||||
return stack.getDisplayName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLabel( ItemStack stack, String label )
|
||||
{
|
||||
if( label != null )
|
||||
{
|
||||
stack.setStackDisplayName( label );
|
||||
}
|
||||
else
|
||||
{
|
||||
stack.clearCustomName();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAudioTitle( ItemStack stack )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAudioRecordName( ItemStack stack )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMount createDataMount( ItemStack stack, World world )
|
||||
{
|
||||
int diskID = getDiskID( stack );
|
||||
if( diskID < 0 )
|
||||
{
|
||||
diskID = ComputerCraft.createUniqueNumberedSaveDir( world, "computer/disk" );
|
||||
setDiskID( stack, diskID );
|
||||
}
|
||||
return ComputerCraftAPI.createSaveDirMount( world, "computer/disk/" + diskID, ComputerCraft.floppySpaceLimit );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColorFromItemStack( ItemStack stack, int layer )
|
||||
{
|
||||
return layer == 0 ? 0xffffff : getColor(stack);
|
||||
}
|
||||
|
||||
public int getColor( ItemStack stack )
|
||||
{
|
||||
return Colour.Blue.getHex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesSneakBypassUse( World world, BlockPos pos, EntityPlayer player )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.media.items;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ItemPrintout extends Item
|
||||
{
|
||||
public static final int LINES_PER_PAGE = 21;
|
||||
public static final int LINE_MAX_LENGTH = 25;
|
||||
public static final int MAX_PAGES = 16;
|
||||
|
||||
public enum Type
|
||||
{
|
||||
Single,
|
||||
Multiple,
|
||||
Book
|
||||
}
|
||||
|
||||
public ItemPrintout()
|
||||
{
|
||||
setMaxStackSize( 1 );
|
||||
setHasSubtypes( true );
|
||||
setUnlocalizedName( "computercraft:page" );
|
||||
setCreativeTab( ComputerCraft.mainCreativeTab );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubItems( Item itemID, CreativeTabs tabs, List list )
|
||||
{
|
||||
list.add( createSingleFromTitleAndText( null, new String[ LINES_PER_PAGE ], new String[ LINES_PER_PAGE ] ) );
|
||||
list.add( createMultipleFromTitleAndText( null, new String[ 2*LINES_PER_PAGE ], new String[ 2*LINES_PER_PAGE ] ) );
|
||||
list.add( createBookFromTitleAndText( null, new String[ 2*LINES_PER_PAGE ], new String[ 2*LINES_PER_PAGE ] ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInformation( ItemStack itemstack, EntityPlayer par2EntityPlayer, List list, boolean flag )
|
||||
{
|
||||
String title = getTitle( itemstack );
|
||||
if( title != null && title.length() > 0 )
|
||||
{
|
||||
list.add( title );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUnlocalizedName( ItemStack stack )
|
||||
{
|
||||
Type type = getType( stack );
|
||||
switch( type )
|
||||
{
|
||||
case Single:
|
||||
default:
|
||||
{
|
||||
return "item.computercraft:page";
|
||||
}
|
||||
case Multiple:
|
||||
{
|
||||
return "item.computercraft:pages";
|
||||
}
|
||||
case Book:
|
||||
{
|
||||
return "item.computercraft:book";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack onItemRightClick( ItemStack stack, World world, EntityPlayer player )
|
||||
{
|
||||
if( !world.isRemote )
|
||||
{
|
||||
ComputerCraft.openPrintoutGUI( player );
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
private static ItemStack createFromTitleAndText( Type type, String title, String[] text, String[] colours )
|
||||
{
|
||||
// Calculate damage
|
||||
int damage;
|
||||
switch( type )
|
||||
{
|
||||
case Single:
|
||||
default:
|
||||
{
|
||||
damage = 0;
|
||||
break;
|
||||
}
|
||||
case Multiple:
|
||||
{
|
||||
damage = 1;
|
||||
break;
|
||||
}
|
||||
case Book:
|
||||
{
|
||||
damage = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Create stack
|
||||
ItemStack stack = new ItemStack( ComputerCraft.Items.printout, 1, damage );
|
||||
|
||||
// Build NBT
|
||||
NBTTagCompound nbt = new NBTTagCompound();
|
||||
if( title != null )
|
||||
{
|
||||
nbt.setString( "title", title );
|
||||
}
|
||||
if( text != null )
|
||||
{
|
||||
nbt.setInteger( "pages", text.length / LINES_PER_PAGE );
|
||||
for(int i=0; i<text.length; ++i)
|
||||
{
|
||||
if( text[i] != null )
|
||||
{
|
||||
nbt.setString( "line"+i, text[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
if( colours != null )
|
||||
{
|
||||
for(int i=0; i<colours.length; ++i)
|
||||
{
|
||||
if( colours[i] != null )
|
||||
{
|
||||
nbt.setString( "colour"+i, colours[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
stack.setTagCompound( nbt );
|
||||
|
||||
// Return stack
|
||||
return stack;
|
||||
}
|
||||
|
||||
public static ItemStack createSingleFromTitleAndText( String title, String[] text, String[] colours )
|
||||
{
|
||||
return createFromTitleAndText( Type.Single, title, text, colours );
|
||||
}
|
||||
|
||||
public static ItemStack createMultipleFromTitleAndText( String title, String[] text, String[] colours )
|
||||
{
|
||||
return createFromTitleAndText( Type.Multiple, title, text, colours );
|
||||
}
|
||||
|
||||
public static ItemStack createBookFromTitleAndText( String title, String[] text, String[] colours )
|
||||
{
|
||||
return createFromTitleAndText( Type.Book, title, text, colours );
|
||||
}
|
||||
|
||||
public static Type getType( ItemStack stack )
|
||||
{
|
||||
int damage = stack.getItemDamage();
|
||||
switch( damage )
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
{
|
||||
return Type.Single;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
return Type.Multiple;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
return Type.Book;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String getTitle( ItemStack stack )
|
||||
{
|
||||
NBTTagCompound nbt = stack.getTagCompound();
|
||||
if( nbt != null && nbt.hasKey( "title" ) )
|
||||
{
|
||||
return nbt.getString( "title" );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int getPageCount( ItemStack stack )
|
||||
{
|
||||
NBTTagCompound nbt = stack.getTagCompound();
|
||||
if( nbt != null && nbt.hasKey( "pages" ) )
|
||||
{
|
||||
return nbt.getInteger( "pages" );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static String[] getText( ItemStack stack )
|
||||
{
|
||||
NBTTagCompound nbt = stack.getTagCompound();
|
||||
int numLines = getPageCount( stack ) * LINES_PER_PAGE;
|
||||
String[] lines = new String[numLines];
|
||||
for( int i=0; i<lines.length; ++i )
|
||||
{
|
||||
if( nbt != null )
|
||||
{
|
||||
lines[i] = nbt.getString( "line"+i );
|
||||
}
|
||||
else
|
||||
{
|
||||
lines[i] = "";
|
||||
}
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
public static String[] getColours( ItemStack stack )
|
||||
{
|
||||
NBTTagCompound nbt = stack.getTagCompound();
|
||||
int numLines = getPageCount( stack ) * LINES_PER_PAGE;
|
||||
String[] lines = new String[numLines];
|
||||
for( int i=0; i<lines.length; ++i )
|
||||
{
|
||||
if( nbt != null )
|
||||
{
|
||||
lines[i] = nbt.getString( "colour"+i );
|
||||
}
|
||||
else
|
||||
{
|
||||
lines[i] = "";
|
||||
}
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.media.items;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.filesystem.IMount;
|
||||
import dan200.computercraft.api.media.IMedia;
|
||||
import dan200.computercraft.core.filesystem.SubMount;
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.WeightedRandomChestContent;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.ChestGenHooks;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class ItemTreasureDisk extends Item
|
||||
implements IMedia
|
||||
{
|
||||
private static ItemStack[] s_treasureItems = null;
|
||||
|
||||
public ItemTreasureDisk()
|
||||
{
|
||||
setMaxStackSize( 1 );
|
||||
setHasSubtypes( true );
|
||||
setUnlocalizedName( "computercraft:treasure_disk" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubItems( Item itemID, CreativeTabs tabs, List list )
|
||||
{
|
||||
if( s_treasureItems != null )
|
||||
{
|
||||
Collections.addAll( list, s_treasureItems );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInformation( ItemStack stack, EntityPlayer player, List list, boolean bool )
|
||||
{
|
||||
String label = getTitle( stack );
|
||||
if( label != null && label.length() > 0 )
|
||||
{
|
||||
list.add( label );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColorFromItemStack( ItemStack stack, int pass )
|
||||
{
|
||||
return pass == 0 ? 0xffffff : getColour(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesSneakBypassUse( World world, BlockPos pos, EntityPlayer player )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// IMedia implementation
|
||||
|
||||
@Override
|
||||
public String getLabel( ItemStack stack )
|
||||
{
|
||||
return getTitle( stack );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLabel( ItemStack stack, String label )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAudioTitle( ItemStack stack )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAudioRecordName( ItemStack stack )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMount createDataMount( ItemStack stack, World world )
|
||||
{
|
||||
IMount rootTreasure = getTreasureMount();
|
||||
String subPath = getSubPath( stack );
|
||||
try
|
||||
{
|
||||
if( rootTreasure.exists( subPath ) )
|
||||
{
|
||||
return new SubMount( rootTreasure, subPath );
|
||||
}
|
||||
else if( rootTreasure.exists( "deprecated/" + subPath ) )
|
||||
{
|
||||
return new SubMount( rootTreasure, "deprecated/" + subPath );
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static ItemStack create( String subPath, int colourIndex )
|
||||
{
|
||||
NBTTagCompound nbt = new NBTTagCompound();
|
||||
nbt.setString( "subPath", subPath );
|
||||
|
||||
int slash = subPath.indexOf( "/" );
|
||||
if( slash >= 0 )
|
||||
{
|
||||
String author = subPath.substring( 0, slash );
|
||||
String title = subPath.substring( slash + 1 );
|
||||
nbt.setString( "title", "\"" + title + "\" by " + author );
|
||||
}
|
||||
else
|
||||
{
|
||||
nbt.setString( "title", "untitled" );
|
||||
}
|
||||
nbt.setInteger( "colour", Colour.values()[ colourIndex ].getHex() );
|
||||
|
||||
ItemStack result = new ItemStack( ComputerCraft.Items.treasureDisk, 1, 0 );
|
||||
result.setTagCompound( nbt );
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void registerDungeonLoot()
|
||||
{
|
||||
if( s_treasureItems == null )
|
||||
{
|
||||
// Get the list of all programs
|
||||
List<String> paths = new ArrayList<String>();
|
||||
try
|
||||
{
|
||||
IMount treasure = getTreasureMount();
|
||||
if( treasure != null )
|
||||
{
|
||||
List<String> authors = new ArrayList<String>();
|
||||
treasure.list( "", authors );
|
||||
for( String author : authors )
|
||||
{
|
||||
if( treasure.isDirectory( author ) && !author.equals( "deprecated" ) )
|
||||
{
|
||||
List<String> titles = new ArrayList<String>();
|
||||
treasure.list( author, titles );
|
||||
for( String title : titles )
|
||||
{
|
||||
String path = author + "/" + title;
|
||||
if( treasure.isDirectory( path ) )
|
||||
{
|
||||
paths.add( path );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( java.io.IOException e )
|
||||
{
|
||||
// no items for us
|
||||
}
|
||||
|
||||
// Build creative tab
|
||||
List<ItemStack> allTreasure = new ArrayList<ItemStack>();
|
||||
for( String path : paths )
|
||||
{
|
||||
ItemStack stack = create( path, 4 );
|
||||
allTreasure.add( stack );
|
||||
}
|
||||
s_treasureItems = allTreasure.toArray( new ItemStack[ allTreasure.size() ] );
|
||||
|
||||
// Register the loot
|
||||
int n=0;
|
||||
Random random = new Random();
|
||||
WeightedRandomChestContent[] content = new WeightedRandomChestContent[ paths.size() * ComputerCraft.treasureDiskLootFrequency ];
|
||||
WeightedRandomChestContent[] commonContent = new WeightedRandomChestContent[ paths.size() * ComputerCraft.treasureDiskLootFrequency ];
|
||||
for( String path : paths )
|
||||
{
|
||||
// Don't use all the random colours
|
||||
// We don't want to overload the probability matrix
|
||||
for( int i=0; i<ComputerCraft.treasureDiskLootFrequency; ++i )
|
||||
{
|
||||
ItemStack stack = create( path, random.nextInt( 16 ) );
|
||||
content[ n ] = new WeightedRandomChestContent( stack, 1, 1, 1 );
|
||||
commonContent[ n ] = new WeightedRandomChestContent( stack, 1, 1, 2 );
|
||||
n++;
|
||||
}
|
||||
}
|
||||
registerLoot( ChestGenHooks.DUNGEON_CHEST, content );
|
||||
registerLoot( ChestGenHooks.MINESHAFT_CORRIDOR, content );
|
||||
registerLoot( ChestGenHooks.STRONGHOLD_CORRIDOR, content );
|
||||
registerLoot( ChestGenHooks.STRONGHOLD_CROSSING, content );
|
||||
registerLoot( ChestGenHooks.STRONGHOLD_LIBRARY, commonContent );
|
||||
registerLoot( ChestGenHooks.PYRAMID_DESERT_CHEST, content );
|
||||
registerLoot( ChestGenHooks.PYRAMID_JUNGLE_CHEST, content );
|
||||
}
|
||||
}
|
||||
|
||||
private static void registerLoot( String category, WeightedRandomChestContent[] content )
|
||||
{
|
||||
for( int i=0; i<content.length; ++i )
|
||||
{
|
||||
ChestGenHooks.getInfo( category ).addItem( content[i] );
|
||||
}
|
||||
}
|
||||
|
||||
private static IMount getTreasureMount()
|
||||
{
|
||||
return ComputerCraft.createResourceMount( ComputerCraft.class, "computercraft", "lua/treasure" );
|
||||
}
|
||||
|
||||
// private stuff
|
||||
|
||||
public String getTitle( ItemStack stack )
|
||||
{
|
||||
NBTTagCompound nbt = stack.getTagCompound();
|
||||
if( nbt != null && nbt.hasKey( "title" ) )
|
||||
{
|
||||
return nbt.getString( "title" );
|
||||
}
|
||||
return "'alongtimeago' by dan200";
|
||||
}
|
||||
|
||||
public String getSubPath( ItemStack stack )
|
||||
{
|
||||
NBTTagCompound nbt = stack.getTagCompound();
|
||||
if( nbt != null && nbt.hasKey( "subPath" ) )
|
||||
{
|
||||
return nbt.getString( "subPath" );
|
||||
}
|
||||
return "dan200/alongtimeago";
|
||||
}
|
||||
|
||||
public int getColour( ItemStack stack )
|
||||
{
|
||||
NBTTagCompound nbt = stack.getTagCompound();
|
||||
if( nbt != null && nbt.hasKey( "colour" ) )
|
||||
{
|
||||
return nbt.getInteger( "colour" );
|
||||
}
|
||||
return Colour.Blue.getHex();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.media.items;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.filesystem.IMount;
|
||||
import dan200.computercraft.api.media.IMedia;
|
||||
import net.minecraft.item.ItemRecord;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
// An implementation of IMedia for ItemRecord's
|
||||
public class RecordMedia implements IMedia
|
||||
{
|
||||
public RecordMedia()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel( ItemStack stack )
|
||||
{
|
||||
return getAudioTitle( stack );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLabel( ItemStack stack, String label )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAudioTitle( ItemStack stack )
|
||||
{
|
||||
return ComputerCraft.getRecordInfo( stack );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAudioRecordName( ItemStack stack )
|
||||
{
|
||||
ItemRecord itemRecord = (ItemRecord)stack.getItem();
|
||||
return "records." + itemRecord.recordName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMount createDataMount( ItemStack stack, World world )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.media.recipes;
|
||||
|
||||
import dan200.computercraft.shared.media.items.ItemDiskLegacy;
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class DiskRecipe implements IRecipe
|
||||
{
|
||||
public DiskRecipe()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches( InventoryCrafting inventory, World world )
|
||||
{
|
||||
boolean diskFound = false;
|
||||
boolean paperFound = false;
|
||||
boolean redstoneFound = false;
|
||||
boolean dyeFound = false;
|
||||
|
||||
for (int var5 = 0; var5 < inventory.getSizeInventory(); ++var5)
|
||||
{
|
||||
ItemStack var6 = inventory.getStackInSlot(var5);
|
||||
|
||||
if (var6 != null)
|
||||
{
|
||||
if (var6.getItem() instanceof ItemDiskLegacy )
|
||||
{
|
||||
if (diskFound || redstoneFound || paperFound) // make sure no redstone or paper already accepted if disk there
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
diskFound = true;
|
||||
}
|
||||
else if( var6.getItem() == Items.dye )
|
||||
{
|
||||
dyeFound = true;
|
||||
}
|
||||
else if( var6.getItem() == Items.paper )
|
||||
{
|
||||
if(paperFound || diskFound)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
paperFound = true;
|
||||
}
|
||||
else if (var6.getItem() == Items.redstone)
|
||||
{
|
||||
if (redstoneFound || diskFound)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
redstoneFound = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (redstoneFound && paperFound) || (diskFound && dyeFound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getCraftingResult(InventoryCrafting par1InventoryCrafting)
|
||||
{
|
||||
int diskID = -1;
|
||||
String diskLabel = null;
|
||||
|
||||
int[] var3 = new int[3];
|
||||
int var4 = 0;
|
||||
int var5 = 0;
|
||||
ItemDiskLegacy var6 = null;
|
||||
int var7;
|
||||
int var9;
|
||||
float var10;
|
||||
float var11;
|
||||
int var17;
|
||||
boolean dyeFound = false;
|
||||
|
||||
for (var7 = 0; var7 < par1InventoryCrafting.getSizeInventory(); ++var7)
|
||||
{
|
||||
ItemStack var8 = par1InventoryCrafting.getStackInSlot(var7);
|
||||
|
||||
if (var8 != null)
|
||||
{
|
||||
if (var8.getItem() instanceof ItemDiskLegacy )
|
||||
{
|
||||
var6 = (ItemDiskLegacy)var8.getItem();
|
||||
diskID = var6.getDiskID( var8 );
|
||||
diskLabel = var6.getLabel( var8 );
|
||||
}
|
||||
else if (var8.getItem() == Items.dye)
|
||||
{
|
||||
dyeFound = true;
|
||||
float[] var14 = Colour.values()[ var8.getItemDamage() & 0xf ].getRGB();
|
||||
int var16 = (int)(var14[0] * 255.0F);
|
||||
int var15 = (int)(var14[1] * 255.0F);
|
||||
var17 = (int)(var14[2] * 255.0F);
|
||||
var4 += Math.max(var16, Math.max(var15, var17));
|
||||
var3[0] += var16;
|
||||
var3[1] += var15;
|
||||
var3[2] += var17;
|
||||
++var5;
|
||||
}
|
||||
else if (!(var8.getItem() != Items.paper || var8.getItem() != Items.redstone))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !dyeFound )
|
||||
{
|
||||
return ItemDiskLegacy.createFromIDAndColour( diskID, diskLabel, Colour.Blue.getHex() );
|
||||
}
|
||||
|
||||
var7 = var3[0] / var5;
|
||||
int var13 = var3[1] / var5;
|
||||
var9 = var3[2] / var5;
|
||||
var10 = (float)var4 / (float)var5;
|
||||
var11 = (float)Math.max(var7, Math.max(var13, var9));
|
||||
var7 = (int)((float)var7 * var10 / var11);
|
||||
var13 = (int)((float)var13 * var10 / var11);
|
||||
var9 = (int)((float)var9 * var10 / var11);
|
||||
var17 = (var7 << 8) + var13;
|
||||
var17 = (var17 << 8) + var9;
|
||||
return ItemDiskLegacy.createFromIDAndColour( diskID, diskLabel, var17 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRecipeSize()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getRecipeOutput()
|
||||
{
|
||||
return ItemDiskLegacy.createFromIDAndColour( -1, null, Colour.Blue.getHex() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack[] getRemainingItems( InventoryCrafting inventoryCrafting )
|
||||
{
|
||||
ItemStack[] results = new ItemStack[ inventoryCrafting.getSizeInventory() ];
|
||||
for (int i = 0; i < results.length; ++i)
|
||||
{
|
||||
ItemStack stack = inventoryCrafting.getStackInSlot(i);
|
||||
results[i] = net.minecraftforge.common.ForgeHooks.getContainerItem(stack);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.media.recipes;
|
||||
|
||||
import dan200.computercraft.shared.media.items.ItemPrintout;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class PrintoutRecipe implements IRecipe
|
||||
{
|
||||
public PrintoutRecipe( )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRecipeSize()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getRecipeOutput()
|
||||
{
|
||||
return ItemPrintout.createMultipleFromTitleAndText( null, null, null );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches( InventoryCrafting _inventory, World world )
|
||||
{
|
||||
return (getCraftingResult( _inventory ) != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getCraftingResult( InventoryCrafting inventory )
|
||||
{
|
||||
// See if we match the recipe, and extract the input disk ID and dye colour
|
||||
int numPages = 0;
|
||||
int numPrintouts = 0;
|
||||
ItemStack[] printouts = null;
|
||||
boolean stringFound = false;
|
||||
boolean leatherFound = false;
|
||||
boolean printoutFound = false;
|
||||
for( int y=0; y<inventory.getHeight(); ++y )
|
||||
{
|
||||
for( int x=0; x<inventory.getWidth(); ++x )
|
||||
{
|
||||
ItemStack stack = inventory.getStackInRowAndColumn(x, y);
|
||||
if( stack != null )
|
||||
{
|
||||
Item item = stack.getItem();
|
||||
if( item instanceof ItemPrintout && ItemPrintout.getType( stack ) != ItemPrintout.Type.Book )
|
||||
{
|
||||
if( printouts == null )
|
||||
{
|
||||
printouts = new ItemStack[9];
|
||||
}
|
||||
printouts[ numPrintouts ] = stack;
|
||||
numPages = numPages + ItemPrintout.getPageCount( stack );
|
||||
numPrintouts++;
|
||||
printoutFound = true;
|
||||
}
|
||||
else if( item == Items.paper )
|
||||
{
|
||||
if( printouts == null )
|
||||
{
|
||||
printouts = new ItemStack[9];
|
||||
}
|
||||
printouts[ numPrintouts ] = stack;
|
||||
numPages++;
|
||||
numPrintouts++;
|
||||
}
|
||||
else if( item == Items.string && !stringFound )
|
||||
{
|
||||
stringFound = true;
|
||||
}
|
||||
else if( item == Items.leather && !leatherFound )
|
||||
{
|
||||
leatherFound = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build some pages with what was passed in
|
||||
if( numPages <= ItemPrintout.MAX_PAGES && stringFound && printoutFound && numPrintouts >= (leatherFound ? 1 : 2) )
|
||||
{
|
||||
String[] text = new String[ numPages * ItemPrintout.LINES_PER_PAGE ];
|
||||
String[] colours = new String[ numPages * ItemPrintout.LINES_PER_PAGE ];
|
||||
int line = 0;
|
||||
|
||||
for( int printout=0; printout<numPrintouts; ++printout )
|
||||
{
|
||||
ItemStack stack = printouts[printout];
|
||||
if( stack.getItem() instanceof ItemPrintout )
|
||||
{
|
||||
// Add a printout
|
||||
String[] pageText = ItemPrintout.getText( printouts[printout] );
|
||||
String[] pageColours = ItemPrintout.getColours( printouts[printout] );
|
||||
for( int pageLine=0; pageLine<pageText.length; ++pageLine )
|
||||
{
|
||||
text[ line ] = pageText[ pageLine ];
|
||||
colours[ line ] = pageColours[ pageLine ];
|
||||
line++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add a blank page
|
||||
for( int pageLine=0; pageLine<ItemPrintout.LINES_PER_PAGE; ++pageLine )
|
||||
{
|
||||
text[ line ] = "";
|
||||
colours[ line ] = "";
|
||||
line++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String title = null;
|
||||
if( printouts[0].getItem() instanceof ItemPrintout )
|
||||
{
|
||||
title = ItemPrintout.getTitle( printouts[0] );
|
||||
}
|
||||
|
||||
if( leatherFound )
|
||||
{
|
||||
return ItemPrintout.createBookFromTitleAndText( title, text, colours );
|
||||
}
|
||||
else
|
||||
{
|
||||
return ItemPrintout.createMultipleFromTitleAndText( title, text, colours );
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack[] getRemainingItems( InventoryCrafting inventoryCrafting )
|
||||
{
|
||||
ItemStack[] results = new ItemStack[ inventoryCrafting.getSizeInventory() ];
|
||||
for (int i = 0; i < results.length; ++i)
|
||||
{
|
||||
ItemStack stack = inventoryCrafting.getStackInSlot(i);
|
||||
results[i] = net.minecraftforge.common.ForgeHooks.getContainerItem(stack);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.network;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.nbt.CompressedStreamTools;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
public class ComputerCraftPacket
|
||||
{
|
||||
// Packet types
|
||||
// To server
|
||||
public static final byte TurnOn = 1;
|
||||
public static final byte Reboot = 2;
|
||||
public static final byte Shutdown = 3;
|
||||
public static final byte QueueEvent = 4;
|
||||
public static final byte RequestComputerUpdate = 5;
|
||||
public static final byte SetLabel = 6;
|
||||
public static final byte RequestTileEntityUpdate = 9;
|
||||
|
||||
// To client
|
||||
public static final byte ComputerChanged = 7;
|
||||
public static final byte ComputerDeleted = 8;
|
||||
|
||||
// Packet class
|
||||
public byte m_packetType;
|
||||
public String[] m_dataString;
|
||||
public int[] m_dataInt;
|
||||
public byte[][] m_dataByte;
|
||||
public NBTTagCompound m_dataNBT;
|
||||
|
||||
public ComputerCraftPacket()
|
||||
{
|
||||
m_packetType = 0;
|
||||
m_dataString = null;
|
||||
m_dataInt = null;
|
||||
m_dataByte = null;
|
||||
m_dataNBT = null;
|
||||
}
|
||||
|
||||
public void toBytes( PacketBuffer buffer )
|
||||
{
|
||||
buffer.writeByte( m_packetType );
|
||||
if( m_dataString != null )
|
||||
{
|
||||
buffer.writeByte( m_dataString.length );
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.writeByte( 0 );
|
||||
}
|
||||
if( m_dataInt != null )
|
||||
{
|
||||
buffer.writeByte( m_dataInt.length );
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.writeByte( 0 );
|
||||
}
|
||||
if( m_dataByte != null )
|
||||
{
|
||||
buffer.writeInt( m_dataByte.length );
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.writeInt( 0 );
|
||||
}
|
||||
if( m_dataString != null )
|
||||
{
|
||||
for( String s : m_dataString )
|
||||
{
|
||||
if( s != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] b = s.getBytes( "UTF-8" );
|
||||
buffer.writeBoolean( true );
|
||||
buffer.writeInt( b.length );
|
||||
buffer.writeBytes( b );
|
||||
}
|
||||
catch( UnsupportedEncodingException e )
|
||||
{
|
||||
buffer.writeBoolean( false );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.writeBoolean( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
if( m_dataInt != null )
|
||||
{
|
||||
for( int i : m_dataInt )
|
||||
{
|
||||
buffer.writeInt( i );
|
||||
}
|
||||
}
|
||||
if( m_dataByte != null )
|
||||
{
|
||||
for( byte[] bytes : m_dataByte )
|
||||
{
|
||||
if( bytes != null )
|
||||
{
|
||||
buffer.writeInt( bytes.length );
|
||||
buffer.writeBytes( bytes );
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.writeInt( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
if( m_dataNBT != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
CompressedStreamTools.writeCompressed( m_dataNBT, bos );
|
||||
byte[] bytes = bos.toByteArray();
|
||||
buffer.writeBoolean( true );
|
||||
buffer.writeInt( bytes.length );
|
||||
buffer.writeBytes( bytes );
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
buffer.writeBoolean( false );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.writeBoolean( false );
|
||||
}
|
||||
}
|
||||
|
||||
public void fromBytes( ByteBuf buffer )
|
||||
{
|
||||
m_packetType = buffer.readByte();
|
||||
byte nString = buffer.readByte();
|
||||
byte nInt = buffer.readByte();
|
||||
int nByte = buffer.readInt();
|
||||
if( nString == 0 )
|
||||
{
|
||||
m_dataString = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dataString = new String[ nString ];
|
||||
for( int k = 0; k < nString; k++ )
|
||||
{
|
||||
if( buffer.readBoolean() )
|
||||
{
|
||||
int len = buffer.readInt();
|
||||
byte[] b = new byte[len];
|
||||
buffer.readBytes( b );
|
||||
try
|
||||
{
|
||||
m_dataString[ k ] = new String( b, "UTF-8" );
|
||||
}
|
||||
catch( UnsupportedEncodingException e )
|
||||
{
|
||||
m_dataString[ k ] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( nInt == 0 )
|
||||
{
|
||||
m_dataInt = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dataInt = new int[ nInt ];
|
||||
for( int k = 0; k < nInt; k++ )
|
||||
{
|
||||
m_dataInt[ k ] = buffer.readInt();
|
||||
}
|
||||
}
|
||||
if( nByte == 0 )
|
||||
{
|
||||
m_dataByte = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dataByte = new byte[ nByte ][];
|
||||
for( int k = 0; k < nByte; k++ )
|
||||
{
|
||||
int length = buffer.readInt();
|
||||
if( length > 0 )
|
||||
{
|
||||
m_dataByte[ k ] = new byte[ length ];
|
||||
buffer.getBytes( buffer.readerIndex(), m_dataByte[ k ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean bNBT = buffer.readBoolean();
|
||||
if( !bNBT )
|
||||
{
|
||||
m_dataNBT = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
int byteLength = buffer.readInt();
|
||||
byte[] bytes = new byte[ byteLength ];
|
||||
buffer.getBytes( buffer.readerIndex(), bytes );
|
||||
try
|
||||
{
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream( bytes );
|
||||
m_dataNBT = CompressedStreamTools.readCompressed( bis );
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
m_dataNBT = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.network;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
public interface INetworkedThing
|
||||
{
|
||||
public void handlePacket( ComputerCraftPacket packet, EntityPlayer sender );
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.network;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import net.minecraft.network.NetHandlerPlayServer;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.network.FMLNetworkEvent;
|
||||
|
||||
public class PacketHandler
|
||||
{
|
||||
@SubscribeEvent
|
||||
public void onClientPacket( FMLNetworkEvent.ClientCustomPacketEvent event )
|
||||
{
|
||||
try
|
||||
{
|
||||
ComputerCraftPacket packet = new ComputerCraftPacket();
|
||||
packet.fromBytes( event.packet.payload() );
|
||||
ComputerCraft.handlePacket( packet, null );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onServerPacket( FMLNetworkEvent.ServerCustomPacketEvent event )
|
||||
{
|
||||
try
|
||||
{
|
||||
ComputerCraftPacket packet = new ComputerCraftPacket();
|
||||
packet.fromBytes( event.packet.payload() );
|
||||
ComputerCraft.handlePacket( packet, ((NetHandlerPlayServer)event.handler).playerEntity );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral;
|
||||
|
||||
import net.minecraft.util.IStringSerializable;
|
||||
|
||||
public enum PeripheralType implements IStringSerializable
|
||||
{
|
||||
DiskDrive( "disk_drive" ),
|
||||
Printer( "printer" ),
|
||||
Monitor( "monitor" ),
|
||||
AdvancedMonitor( "advanced_monitor" ),
|
||||
WirelessModem( "wireless_modem" ),
|
||||
WiredModem( "wired_modem" ),
|
||||
Cable( "cable" ),
|
||||
WiredModemWithCable( "wired_modem_with_cable" ),
|
||||
AdvancedModem( "advanced_modem" );
|
||||
|
||||
private String m_name;
|
||||
|
||||
private PeripheralType( String name )
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() { return getName(); }
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.commandblock;
|
||||
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.ILuaTask;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import net.minecraft.tileentity.TileEntityCommandBlock;
|
||||
|
||||
public class CommandBlockPeripheral implements IPeripheral
|
||||
{
|
||||
private final TileEntityCommandBlock m_commandBlock;
|
||||
|
||||
public CommandBlockPeripheral( TileEntityCommandBlock commandBlock )
|
||||
{
|
||||
m_commandBlock = commandBlock;
|
||||
}
|
||||
|
||||
// IPeripheral methods
|
||||
|
||||
@Override
|
||||
public String getType()
|
||||
{
|
||||
return "command";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getMethodNames()
|
||||
{
|
||||
return new String[] {
|
||||
"getCommand",
|
||||
"setCommand",
|
||||
"runCommand",
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( IComputerAccess computer, ILuaContext context, int method, final Object[] arguments ) throws LuaException, InterruptedException
|
||||
{
|
||||
switch (method)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// getCommand
|
||||
return context.executeMainThreadTask( new ILuaTask()
|
||||
{
|
||||
@Override
|
||||
public Object[] execute() throws LuaException
|
||||
{
|
||||
return new Object[] {
|
||||
m_commandBlock.getCommandBlockLogic().getCommand()
|
||||
};
|
||||
}
|
||||
} );
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
// setCommand
|
||||
if( arguments.length < 1 || !(arguments[0] instanceof String) )
|
||||
{
|
||||
throw new LuaException( "Expected string" );
|
||||
}
|
||||
|
||||
final String command = (String) arguments[ 0 ];
|
||||
context.issueMainThreadTask( new ILuaTask()
|
||||
{
|
||||
@Override
|
||||
public Object[] execute() throws LuaException
|
||||
{
|
||||
m_commandBlock.getCommandBlockLogic().setCommand( command );
|
||||
m_commandBlock.getWorld().markBlockForUpdate( m_commandBlock.getPos() );
|
||||
return null;
|
||||
}
|
||||
} );
|
||||
return null;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
// runCommand
|
||||
return context.executeMainThreadTask( new ILuaTask()
|
||||
{
|
||||
@Override
|
||||
public Object[] execute() throws LuaException
|
||||
{
|
||||
m_commandBlock.getCommandBlockLogic().trigger( m_commandBlock.getWorld() );
|
||||
int result = m_commandBlock.getCommandBlockLogic().getSuccessCount();
|
||||
if( result > 0 )
|
||||
{
|
||||
return new Object[] { true };
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Object[] { false, "Command failed" };
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attach( IComputerAccess computer )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detach( IComputerAccess computer )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( IPeripheral other )
|
||||
{
|
||||
return (other != null && other.getClass() == this.getClass());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.commandblock;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.api.peripheral.IPeripheralProvider;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityCommandBlock;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class CommandBlockPeripheralProvider implements IPeripheralProvider
|
||||
{
|
||||
@Override
|
||||
public IPeripheral getPeripheral( World world, BlockPos pos, EnumFacing side )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileEntityCommandBlock )
|
||||
{
|
||||
TileEntityCommandBlock commandBlock = (TileEntityCommandBlock)tile;
|
||||
return new CommandBlockPeripheral( commandBlock );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.common;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import dan200.computercraft.shared.peripheral.modem.TileCable;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.properties.IProperty;
|
||||
import net.minecraft.block.properties.PropertyBool;
|
||||
import net.minecraft.block.properties.PropertyEnum;
|
||||
import net.minecraft.block.state.BlockState;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
|
||||
public class BlockCable extends BlockPeripheralBase
|
||||
{
|
||||
// Statics
|
||||
|
||||
public static class Properties
|
||||
{
|
||||
public static final PropertyEnum MODEM = PropertyEnum.create( "modem", BlockCableModemVariant.class );
|
||||
public static final PropertyBool CABLE = PropertyBool.create( "cable" );
|
||||
public static final PropertyBool NORTH = PropertyBool.create( "north" );
|
||||
public static final PropertyBool SOUTH = PropertyBool.create( "south" );
|
||||
public static final PropertyBool EAST = PropertyBool.create( "east" );
|
||||
public static final PropertyBool WEST = PropertyBool.create( "west" );
|
||||
public static final PropertyBool UP = PropertyBool.create( "up" );
|
||||
public static final PropertyBool DOWN = PropertyBool.create( "down" );
|
||||
}
|
||||
|
||||
public static boolean isCable( IBlockAccess world, BlockPos pos )
|
||||
{
|
||||
Block block = world.getBlockState( pos ).getBlock();
|
||||
if( block == ComputerCraft.Blocks.cable )
|
||||
{
|
||||
switch( ComputerCraft.Blocks.cable.getPeripheralType( world, pos ) )
|
||||
{
|
||||
case Cable:
|
||||
case WiredModemWithCable:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Members
|
||||
|
||||
public BlockCable()
|
||||
{
|
||||
setHardness( 1.5f );
|
||||
setUnlocalizedName( "computercraft:cable" );
|
||||
setCreativeTab( ComputerCraft.mainCreativeTab );
|
||||
setDefaultState( this.blockState.getBaseState()
|
||||
.withProperty( Properties.MODEM, BlockCableModemVariant.None )
|
||||
.withProperty( Properties.CABLE, true )
|
||||
.withProperty( Properties.NORTH, false )
|
||||
.withProperty( Properties.SOUTH, false )
|
||||
.withProperty( Properties.EAST, false )
|
||||
.withProperty( Properties.WEST, false )
|
||||
.withProperty( Properties.UP, false )
|
||||
.withProperty( Properties.DOWN, false )
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockState createBlockState()
|
||||
{
|
||||
return new BlockState(this, new IProperty[] {
|
||||
Properties.MODEM,
|
||||
Properties.CABLE,
|
||||
Properties.NORTH,
|
||||
Properties.SOUTH,
|
||||
Properties.EAST,
|
||||
Properties.WEST,
|
||||
Properties.UP,
|
||||
Properties.DOWN,
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getStateFromMeta( int meta )
|
||||
{
|
||||
IBlockState state = getDefaultState();
|
||||
if( meta < 6 )
|
||||
{
|
||||
state = state.withProperty( Properties.CABLE, false );
|
||||
state = state.withProperty( Properties.MODEM, BlockCableModemVariant.fromFacing( EnumFacing.getFront( meta ) ) );
|
||||
}
|
||||
else if( meta < 12 )
|
||||
{
|
||||
state = state.withProperty( Properties.CABLE, true );
|
||||
state = state.withProperty( Properties.MODEM, BlockCableModemVariant.fromFacing( EnumFacing.getFront( meta - 6 ) ) );
|
||||
}
|
||||
else if( meta == 13 )
|
||||
{
|
||||
state = state.withProperty( Properties.CABLE, true );
|
||||
state = state.withProperty( Properties.MODEM, BlockCableModemVariant.None );
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetaFromState( IBlockState state )
|
||||
{
|
||||
int meta = 0;
|
||||
boolean cable = (Boolean)state.getValue( Properties.CABLE );
|
||||
BlockCableModemVariant modem = (BlockCableModemVariant)state.getValue( Properties.MODEM );
|
||||
if( cable && modem != BlockCableModemVariant.None )
|
||||
{
|
||||
meta = 6 + modem.getFacing().getIndex();
|
||||
}
|
||||
else if( modem != BlockCableModemVariant.None )
|
||||
{
|
||||
meta = modem.getFacing().getIndex();
|
||||
}
|
||||
else if( cable )
|
||||
{
|
||||
meta = 13;
|
||||
}
|
||||
return meta;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getDefaultBlockState( PeripheralType type, EnumFacing placedSide )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case Cable:
|
||||
{
|
||||
return getDefaultState()
|
||||
.withProperty( Properties.CABLE, true )
|
||||
.withProperty( Properties.MODEM, BlockCableModemVariant.None );
|
||||
}
|
||||
case WiredModem:
|
||||
default:
|
||||
{
|
||||
return getDefaultState()
|
||||
.withProperty( Properties.CABLE, false )
|
||||
.withProperty( Properties.MODEM, BlockCableModemVariant.fromFacing( placedSide.getOpposite() ) );
|
||||
}
|
||||
case WiredModemWithCable:
|
||||
{
|
||||
return getDefaultState()
|
||||
.withProperty( Properties.CABLE, true )
|
||||
.withProperty( Properties.MODEM, BlockCableModemVariant.fromFacing( placedSide.getOpposite() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean doesConnect( IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing dir )
|
||||
{
|
||||
if( !((Boolean)state.getValue( Properties.CABLE )) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if( ((BlockCableModemVariant)state.getValue( Properties.MODEM )).getFacing() == dir )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return isCable( world, pos.offset( dir ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getActualState( IBlockState state, IBlockAccess world, BlockPos pos )
|
||||
{
|
||||
state = state.withProperty( Properties.NORTH, doesConnect( state, world, pos, EnumFacing.NORTH ) );
|
||||
state = state.withProperty( Properties.SOUTH, doesConnect( state, world, pos, EnumFacing.SOUTH ) );
|
||||
state = state.withProperty( Properties.EAST, doesConnect( state, world, pos, EnumFacing.EAST ) );
|
||||
state = state.withProperty( Properties.WEST, doesConnect( state, world, pos, EnumFacing.WEST ) );
|
||||
state = state.withProperty( Properties.UP, doesConnect( state, world, pos, EnumFacing.UP ) );
|
||||
state = state.withProperty( Properties.DOWN, doesConnect( state, world, pos, EnumFacing.DOWN ) );
|
||||
|
||||
int anim;
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TilePeripheralBase )
|
||||
{
|
||||
TilePeripheralBase peripheral = (TilePeripheralBase)tile;
|
||||
anim = peripheral.getAnim();
|
||||
}
|
||||
else
|
||||
{
|
||||
anim = 0;
|
||||
}
|
||||
|
||||
BlockCableModemVariant modem = ((BlockCableModemVariant)state.getValue( Properties.MODEM ));
|
||||
if( modem != BlockCableModemVariant.None )
|
||||
{
|
||||
modem = BlockCableModemVariant.values()[
|
||||
1 + 6 * anim + modem.getFacing().getIndex()
|
||||
];
|
||||
}
|
||||
state = state.withProperty( Properties.MODEM, modem );
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldSideBeRendered( IBlockAccess world, BlockPos pos, EnumFacing side )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeripheralType getPeripheralType( int damage )
|
||||
{
|
||||
return ((ItemCable) Item.getItemFromBlock( this )).getPeripheralType( damage );
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeripheralType getPeripheralType( IBlockState state )
|
||||
{
|
||||
boolean cable = (Boolean)state.getValue( Properties.CABLE );
|
||||
BlockCableModemVariant modem = (BlockCableModemVariant)state.getValue( Properties.MODEM );
|
||||
if( cable && modem != BlockCableModemVariant.None )
|
||||
{
|
||||
return PeripheralType.WiredModemWithCable;
|
||||
}
|
||||
else if( modem != BlockCableModemVariant.None )
|
||||
{
|
||||
return PeripheralType.WiredModem;
|
||||
}
|
||||
else
|
||||
{
|
||||
return PeripheralType.Cable;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TilePeripheralBase createTile( PeripheralType type )
|
||||
{
|
||||
return new TileCable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.common;
|
||||
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.IStringSerializable;
|
||||
|
||||
public enum BlockCableModemVariant implements IStringSerializable
|
||||
{
|
||||
None( "none", null ),
|
||||
DownOff( "down_off", EnumFacing.DOWN ),
|
||||
UpOff( "up_off", EnumFacing.UP ),
|
||||
NorthOff( "north_off", EnumFacing.NORTH ),
|
||||
SouthOff( "south_off", EnumFacing.SOUTH ),
|
||||
WestOff( "west_off", EnumFacing.WEST ),
|
||||
EastOff( "east_off", EnumFacing.EAST ),
|
||||
DownOn( "down_on", EnumFacing.DOWN ),
|
||||
UpOn( "up_on", EnumFacing.UP ),
|
||||
NorthOn( "north_on", EnumFacing.NORTH ),
|
||||
SouthOn( "south_on", EnumFacing.SOUTH ),
|
||||
WestOn( "west_on", EnumFacing.WEST ),
|
||||
EastOn( "east_on", EnumFacing.EAST ),
|
||||
DownOffPeripheral( "down_off_peripheral", EnumFacing.DOWN ),
|
||||
UpOffPeripheral( "up_off_peripheral", EnumFacing.UP ),
|
||||
NorthOffPeripheral( "north_off_peripheral", EnumFacing.NORTH ),
|
||||
SouthOffPeripheral( "south_off_peripheral", EnumFacing.SOUTH ),
|
||||
WestOffPeripheral( "west_off_peripheral", EnumFacing.WEST ),
|
||||
EastOffPeripheral( "east_off_peripheral", EnumFacing.EAST ),
|
||||
DownOnPeripheral( "down_on_peripheral", EnumFacing.DOWN ),
|
||||
UpOnPeripheral( "up_on_peripheral", EnumFacing.UP ),
|
||||
NorthOnPeripheral( "north_on_peripheral", EnumFacing.NORTH ),
|
||||
SouthOnPeripheral( "south_on_peripheral", EnumFacing.SOUTH ),
|
||||
WestOnPeripheral( "west_on_peripheral", EnumFacing.WEST ),
|
||||
EastOnPeripheral( "east_on_peripheral", EnumFacing.EAST );
|
||||
|
||||
public static BlockCableModemVariant fromFacing( EnumFacing facing )
|
||||
{
|
||||
switch( facing )
|
||||
{
|
||||
case DOWN: return DownOff;
|
||||
case UP: return UpOff;
|
||||
case NORTH: return NorthOff;
|
||||
case SOUTH: return SouthOff;
|
||||
case WEST: return WestOff;
|
||||
case EAST: return EastOff;
|
||||
}
|
||||
return NorthOff;
|
||||
}
|
||||
|
||||
private String m_name;
|
||||
private EnumFacing m_facing;
|
||||
|
||||
private BlockCableModemVariant( String name, EnumFacing facing )
|
||||
{
|
||||
m_name = name;
|
||||
m_facing = facing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
public EnumFacing getFacing()
|
||||
{
|
||||
return m_facing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,586 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.common;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
|
||||
import dan200.computercraft.shared.peripheral.modem.TileWirelessModem;
|
||||
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
|
||||
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
|
||||
import dan200.computercraft.shared.util.DirectionUtil;
|
||||
import net.minecraft.block.properties.IProperty;
|
||||
import net.minecraft.block.properties.PropertyDirection;
|
||||
import net.minecraft.block.properties.PropertyEnum;
|
||||
import net.minecraft.block.state.BlockState;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumWorldBlockLayer;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
public class BlockPeripheral extends BlockPeripheralBase
|
||||
{
|
||||
public static class Properties
|
||||
{
|
||||
public static final PropertyDirection FACING = PropertyDirection.create( "facing",EnumFacing.Plane.HORIZONTAL );
|
||||
public static final PropertyEnum VARIANT = PropertyEnum.create( "variant", BlockPeripheralVariant.class );
|
||||
}
|
||||
|
||||
public BlockPeripheral()
|
||||
{
|
||||
setHardness( 2.0f );
|
||||
setUnlocalizedName( "computercraft:peripheral" );
|
||||
setCreativeTab( ComputerCraft.mainCreativeTab );
|
||||
setDefaultState( this.blockState.getBaseState()
|
||||
.withProperty( Properties.FACING, EnumFacing.NORTH )
|
||||
.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveEmpty )
|
||||
);
|
||||
}
|
||||
|
||||
@SideOnly( Side.CLIENT)
|
||||
public EnumWorldBlockLayer getBlockLayer()
|
||||
{
|
||||
return EnumWorldBlockLayer.CUTOUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockState createBlockState()
|
||||
{
|
||||
return new BlockState(this, new IProperty[] {
|
||||
Properties.FACING,
|
||||
Properties.VARIANT
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getStateFromMeta( int meta )
|
||||
{
|
||||
IBlockState state = getDefaultState();
|
||||
if( meta >= 2 && meta <= 5 )
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveEmpty );
|
||||
state = state.withProperty( Properties.FACING, EnumFacing.getFront( meta ) );
|
||||
}
|
||||
else if( meta <= 9 )
|
||||
{
|
||||
if( meta == 0 )
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemDownOff );
|
||||
state = state.withProperty( Properties.FACING, EnumFacing.NORTH );
|
||||
}
|
||||
else if( meta == 1 )
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemUpOff );
|
||||
state = state.withProperty( Properties.FACING, EnumFacing.NORTH );
|
||||
}
|
||||
else
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemOff );
|
||||
state = state.withProperty( Properties.FACING, EnumFacing.getFront( meta - 4 ) );
|
||||
}
|
||||
}
|
||||
else if( meta == 10 )
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.Monitor );
|
||||
}
|
||||
else if( meta == 11 )
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterEmpty );
|
||||
}
|
||||
else if( meta == 12 )
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.AdvancedMonitor );
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetaFromState( IBlockState state )
|
||||
{
|
||||
int meta = 0;
|
||||
BlockPeripheralVariant variant = (BlockPeripheralVariant)state.getValue( Properties.VARIANT );
|
||||
switch( variant.getPeripheralType() )
|
||||
{
|
||||
case DiskDrive:
|
||||
{
|
||||
EnumFacing dir = (EnumFacing)state.getValue( Properties.FACING );
|
||||
if( dir.getAxis() == EnumFacing.Axis.Y ) {
|
||||
dir = EnumFacing.NORTH;
|
||||
}
|
||||
meta = dir.getIndex();
|
||||
break;
|
||||
}
|
||||
case WirelessModem:
|
||||
{
|
||||
switch( variant )
|
||||
{
|
||||
case WirelessModemDownOff:
|
||||
case WirelessModemDownOn:
|
||||
{
|
||||
meta = 0;
|
||||
break;
|
||||
}
|
||||
case WirelessModemUpOff:
|
||||
case WirelessModemUpOn:
|
||||
{
|
||||
meta = 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
EnumFacing dir = (EnumFacing)state.getValue( Properties.FACING );
|
||||
meta = dir.getIndex() + 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Monitor:
|
||||
{
|
||||
meta = 10;
|
||||
break;
|
||||
}
|
||||
case Printer:
|
||||
{
|
||||
meta = 11;
|
||||
break;
|
||||
}
|
||||
case AdvancedMonitor:
|
||||
{
|
||||
meta = 12;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return meta;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getActualState( IBlockState state, IBlockAccess world, BlockPos pos )
|
||||
{
|
||||
int anim;
|
||||
EnumFacing dir;
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TilePeripheralBase )
|
||||
{
|
||||
TilePeripheralBase peripheral = (TilePeripheralBase)tile;
|
||||
anim = peripheral.getAnim();
|
||||
dir = peripheral.getDirection();
|
||||
}
|
||||
else
|
||||
{
|
||||
anim = 0;
|
||||
dir = (EnumFacing)state.getValue( Properties.FACING );
|
||||
switch( (BlockPeripheralVariant)state.getValue( BlockPeripheral.Properties.VARIANT ) )
|
||||
{
|
||||
case WirelessModemDownOff:
|
||||
case WirelessModemDownOn:
|
||||
{
|
||||
dir = EnumFacing.DOWN;
|
||||
break;
|
||||
}
|
||||
case WirelessModemUpOff:
|
||||
case WirelessModemUpOn:
|
||||
{
|
||||
dir = EnumFacing.UP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PeripheralType type = getPeripheralType( state );
|
||||
switch( type )
|
||||
{
|
||||
case DiskDrive:
|
||||
{
|
||||
state = state.withProperty( Properties.FACING, dir );
|
||||
switch( anim )
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveEmpty );
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveInvalid );
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveFull );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Printer:
|
||||
{
|
||||
state = state.withProperty( Properties.FACING, dir );
|
||||
switch( anim )
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterEmpty );
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterTopFull );
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterBottomFull );
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterBothFull );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WirelessModem:
|
||||
{
|
||||
switch( dir )
|
||||
{
|
||||
case UP:
|
||||
{
|
||||
state = state.withProperty( Properties.FACING, EnumFacing.NORTH );
|
||||
switch( anim )
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemUpOff );
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemUpOn );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DOWN:
|
||||
{
|
||||
state = state.withProperty( Properties.FACING, EnumFacing.NORTH );
|
||||
switch( anim )
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemDownOff );
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemDownOn );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
state = state.withProperty( Properties.FACING, dir );
|
||||
switch( anim )
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemOff );
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemOn );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Monitor:
|
||||
case AdvancedMonitor:
|
||||
{
|
||||
EnumFacing front;
|
||||
int xIndex, yIndex, width, height;
|
||||
if( tile != null && tile instanceof TileMonitor )
|
||||
{
|
||||
TileMonitor monitor = (TileMonitor)tile;
|
||||
dir = monitor.getDirection();
|
||||
front = monitor.getFront();
|
||||
xIndex = monitor.getXIndex();
|
||||
yIndex = monitor.getYIndex();
|
||||
width = monitor.getWidth();
|
||||
height = monitor.getHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
dir = EnumFacing.NORTH;
|
||||
front = EnumFacing.NORTH;
|
||||
xIndex = 0;
|
||||
yIndex = 0;
|
||||
width = 1;
|
||||
height = 1;
|
||||
}
|
||||
|
||||
BlockPeripheralVariant baseVariant;
|
||||
if( front == EnumFacing.UP )
|
||||
{
|
||||
baseVariant = (type == PeripheralType.AdvancedMonitor) ?
|
||||
BlockPeripheralVariant.AdvancedMonitorUp :
|
||||
BlockPeripheralVariant.MonitorUp;
|
||||
}
|
||||
else if( front == EnumFacing.DOWN )
|
||||
{
|
||||
baseVariant = (type == PeripheralType.AdvancedMonitor) ?
|
||||
BlockPeripheralVariant.AdvancedMonitorDown :
|
||||
BlockPeripheralVariant.MonitorDown;
|
||||
}
|
||||
else
|
||||
{
|
||||
baseVariant = (type == PeripheralType.AdvancedMonitor) ?
|
||||
BlockPeripheralVariant.AdvancedMonitor :
|
||||
BlockPeripheralVariant.Monitor;
|
||||
}
|
||||
|
||||
int subType;
|
||||
if( width == 1 && height == 1 )
|
||||
{
|
||||
subType = 0;
|
||||
}
|
||||
else if( height == 1 )
|
||||
{
|
||||
if( xIndex == 0 )
|
||||
{
|
||||
subType = 1;
|
||||
}
|
||||
else if( xIndex == width - 1 )
|
||||
{
|
||||
subType = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
subType = 2;
|
||||
}
|
||||
}
|
||||
else if( width == 1 )
|
||||
{
|
||||
if( yIndex == 0 )
|
||||
{
|
||||
subType = 6;
|
||||
}
|
||||
else if( yIndex == height - 1 )
|
||||
{
|
||||
subType = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
subType = 5;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( xIndex == 0 )
|
||||
{
|
||||
subType = 7;
|
||||
}
|
||||
else if( xIndex == width - 1 )
|
||||
{
|
||||
subType = 9;
|
||||
}
|
||||
else
|
||||
{
|
||||
subType = 8;
|
||||
}
|
||||
if( yIndex == 0 )
|
||||
{
|
||||
subType += 6;
|
||||
}
|
||||
else if( yIndex < height - 1 )
|
||||
{
|
||||
subType += 3;
|
||||
}
|
||||
}
|
||||
|
||||
state = state.withProperty( Properties.FACING, dir );
|
||||
state = state.withProperty( Properties.VARIANT,
|
||||
BlockPeripheralVariant.values()[ baseVariant.ordinal() + subType ]
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getDefaultBlockState( PeripheralType type, EnumFacing placedSide )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case DiskDrive:
|
||||
default:
|
||||
{
|
||||
IBlockState state = getDefaultState().withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveEmpty );
|
||||
if( placedSide.getAxis() != EnumFacing.Axis.Y )
|
||||
{
|
||||
return state.withProperty( Properties.FACING, placedSide );
|
||||
}
|
||||
else
|
||||
{
|
||||
return state.withProperty( Properties.FACING, EnumFacing.NORTH );
|
||||
}
|
||||
}
|
||||
case WirelessModem:
|
||||
{
|
||||
EnumFacing dir = placedSide.getOpposite();
|
||||
if( dir == EnumFacing.DOWN )
|
||||
{
|
||||
return getDefaultState()
|
||||
.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemDownOff )
|
||||
.withProperty( Properties.FACING, EnumFacing.NORTH );
|
||||
}
|
||||
else if( dir == EnumFacing.UP )
|
||||
{
|
||||
return getDefaultState()
|
||||
.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemUpOff )
|
||||
.withProperty( Properties.FACING, EnumFacing.NORTH );
|
||||
}
|
||||
else
|
||||
{
|
||||
return getDefaultState()
|
||||
.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemOff )
|
||||
.withProperty( Properties.FACING, dir );
|
||||
}
|
||||
}
|
||||
case Monitor:
|
||||
{
|
||||
return getDefaultState().withProperty( Properties.VARIANT, BlockPeripheralVariant.Monitor );
|
||||
}
|
||||
case Printer:
|
||||
{
|
||||
return getDefaultState().withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterEmpty );
|
||||
}
|
||||
case AdvancedMonitor:
|
||||
{
|
||||
return getDefaultState().withProperty( Properties.VARIANT, BlockPeripheralVariant.AdvancedMonitor );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeripheralType getPeripheralType( int damage )
|
||||
{
|
||||
return ((ItemPeripheral)Item.getItemFromBlock(this)).getPeripheralType( damage );
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeripheralType getPeripheralType( IBlockState state )
|
||||
{
|
||||
return ((BlockPeripheralVariant)state.getValue( Properties.VARIANT )).getPeripheralType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TilePeripheralBase createTile( PeripheralType type )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case DiskDrive:
|
||||
default:
|
||||
{
|
||||
return new TileDiskDrive();
|
||||
}
|
||||
case WirelessModem:
|
||||
{
|
||||
return new TileWirelessModem();
|
||||
}
|
||||
case Monitor:
|
||||
case AdvancedMonitor:
|
||||
{
|
||||
return new TileMonitor();
|
||||
}
|
||||
case Printer:
|
||||
{
|
||||
return new TilePrinter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockPlacedBy( World world, BlockPos pos, IBlockState state, EntityLivingBase player, ItemStack stack )
|
||||
{
|
||||
// Not sure why this is necessary
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TilePeripheralBase )
|
||||
{
|
||||
tile.setWorldObj( world ); // Not sure why this is necessary
|
||||
tile.setPos( pos ); // Not sure why this is necessary
|
||||
}
|
||||
|
||||
switch( getPeripheralType( state ) )
|
||||
{
|
||||
case DiskDrive:
|
||||
case Printer:
|
||||
{
|
||||
EnumFacing dir = DirectionUtil.fromEntityRot( player );
|
||||
setDirection( world, pos, dir );
|
||||
if( stack.hasDisplayName() && tile != null && tile instanceof TilePeripheralBase )
|
||||
{
|
||||
TilePeripheralBase peripheral = (TilePeripheralBase)tile;
|
||||
peripheral.setLabel( stack.getDisplayName() );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Monitor:
|
||||
case AdvancedMonitor:
|
||||
{
|
||||
if( tile != null && tile instanceof TileMonitor )
|
||||
{
|
||||
int direction = DirectionUtil.fromEntityRot( player ).getIndex();
|
||||
if( player.rotationPitch > 66.5F )
|
||||
{
|
||||
direction += 12;
|
||||
}
|
||||
else if( player.rotationPitch < -66.5F )
|
||||
{
|
||||
direction += 6;
|
||||
}
|
||||
|
||||
TileMonitor monitor = (TileMonitor)tile;
|
||||
if( world.isRemote )
|
||||
{
|
||||
monitor.setDir( direction );
|
||||
}
|
||||
else
|
||||
{
|
||||
monitor.contractNeighbours();
|
||||
monitor.setDir( direction );
|
||||
monitor.contract();
|
||||
monitor.expand();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.common;
|
||||
|
||||
import dan200.computercraft.shared.common.BlockDirectional;
|
||||
import dan200.computercraft.shared.common.TileGeneric;
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public abstract class BlockPeripheralBase extends BlockDirectional
|
||||
{
|
||||
public BlockPeripheralBase()
|
||||
{
|
||||
super( Material.rock );
|
||||
}
|
||||
|
||||
protected abstract IBlockState getDefaultBlockState( PeripheralType type, EnumFacing placedSide );
|
||||
protected abstract PeripheralType getPeripheralType( int damage );
|
||||
protected abstract PeripheralType getPeripheralType( IBlockState state );
|
||||
protected abstract TilePeripheralBase createTile( PeripheralType type );
|
||||
|
||||
@Override
|
||||
public final boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isFullCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean canPlaceBlockOnSide( World world, BlockPos pos, EnumFacing side )
|
||||
{
|
||||
return true; // ItemPeripheralBase handles this
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final IBlockState getDefaultBlockState( int damage, EnumFacing placedSide )
|
||||
{
|
||||
ItemPeripheralBase item = (ItemPeripheralBase)Item.getItemFromBlock( this );
|
||||
return getDefaultBlockState( item.getPeripheralType( damage ), placedSide );
|
||||
}
|
||||
|
||||
@Override
|
||||
public final TileGeneric createTile( IBlockState state )
|
||||
{
|
||||
return createTile( getPeripheralType( state ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public final TileGeneric createTile( int damage )
|
||||
{
|
||||
return createTile( getPeripheralType( damage ) );
|
||||
}
|
||||
|
||||
public final PeripheralType getPeripheralType( IBlockAccess world, BlockPos pos )
|
||||
{
|
||||
return getPeripheralType( world.getBlockState( pos ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.common;
|
||||
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import net.minecraft.util.IStringSerializable;
|
||||
|
||||
public enum BlockPeripheralVariant implements IStringSerializable
|
||||
{
|
||||
DiskDriveEmpty( "disk_drive_empty", PeripheralType.DiskDrive ),
|
||||
DiskDriveFull( "disk_drive_full", PeripheralType.DiskDrive ),
|
||||
DiskDriveInvalid( "disk_drive_invalid", PeripheralType.DiskDrive ),
|
||||
PrinterEmpty( "printer_empty", PeripheralType.Printer ),
|
||||
PrinterTopFull( "printer_top_full", PeripheralType.Printer ),
|
||||
PrinterBottomFull( "printer_bottom_full", PeripheralType.Printer ),
|
||||
PrinterBothFull( "printer_both_full", PeripheralType.Printer ),
|
||||
WirelessModemOff( "wireless_modem_off", PeripheralType.WirelessModem ),
|
||||
WirelessModemOn( "wireless_modem_on", PeripheralType.WirelessModem ),
|
||||
WirelessModemUpOff( "wireless_modem_up_off", PeripheralType.WirelessModem ),
|
||||
WirelessModemUpOn( "wireless_modem_up_on", PeripheralType.WirelessModem ),
|
||||
WirelessModemDownOff( "wireless_modem_down_off", PeripheralType.WirelessModem ),
|
||||
WirelessModemDownOn( "wireless_modem_down_on", PeripheralType.WirelessModem ),
|
||||
Monitor( "monitor", PeripheralType.Monitor ),
|
||||
MonitorR( "monitor_r", PeripheralType.Monitor ),
|
||||
MonitorLR( "monitor_lr", PeripheralType.Monitor ),
|
||||
MonitorL( "monitor_l", PeripheralType.Monitor ),
|
||||
MonitorD( "monitor_d", PeripheralType.Monitor ),
|
||||
MonitorUD( "monitor_ud", PeripheralType.Monitor ),
|
||||
MonitorU( "monitor_u", PeripheralType.Monitor ),
|
||||
MonitorRD( "monitor_rd", PeripheralType.Monitor ),
|
||||
MonitorLRD( "monitor_lrd", PeripheralType.Monitor ),
|
||||
MonitorLD( "monitor_ld", PeripheralType.Monitor ),
|
||||
MonitorRUD( "monitor_rud", PeripheralType.Monitor ),
|
||||
MonitorLRUD( "monitor_lrud", PeripheralType.Monitor ),
|
||||
MonitorLUD( "monitor_lud", PeripheralType.Monitor ),
|
||||
MonitorRU( "monitor_ru", PeripheralType.Monitor ),
|
||||
MonitorLRU( "monitor_lru", PeripheralType.Monitor ),
|
||||
MonitorLU( "monitor_lu", PeripheralType.Monitor ),
|
||||
MonitorUp( "monitor_up", PeripheralType.Monitor ),
|
||||
MonitorUpR( "monitor_up_r", PeripheralType.Monitor ),
|
||||
MonitorUpLR( "monitor_up_lr", PeripheralType.Monitor ),
|
||||
MonitorUpL( "monitor_up_l", PeripheralType.Monitor ),
|
||||
MonitorUpD( "monitor_up_d", PeripheralType.Monitor ),
|
||||
MonitorUpUD( "monitor_up_ud", PeripheralType.Monitor ),
|
||||
MonitorUpU( "monitor_up_u", PeripheralType.Monitor ),
|
||||
MonitorUpRD( "monitor_up_rd", PeripheralType.Monitor ),
|
||||
MonitorUpLRD( "monitor_up_lrd", PeripheralType.Monitor ),
|
||||
MonitorUpLD( "monitor_up_ld", PeripheralType.Monitor ),
|
||||
MonitorUpRUD( "monitor_up_rud", PeripheralType.Monitor ),
|
||||
MonitorUpLRUD( "monitor_up_lrud", PeripheralType.Monitor ),
|
||||
MonitorUpLUD( "monitor_up_lud", PeripheralType.Monitor ),
|
||||
MonitorUpRU( "monitor_up_ru", PeripheralType.Monitor ),
|
||||
MonitorUpLRU( "monitor_up_lru", PeripheralType.Monitor ),
|
||||
MonitorUpLU( "monitor_up_lu", PeripheralType.Monitor ),
|
||||
MonitorDown( "monitor_down", PeripheralType.Monitor ),
|
||||
MonitorDownR( "monitor_down_r", PeripheralType.Monitor ),
|
||||
MonitorDownLR( "monitor_down_lr", PeripheralType.Monitor ),
|
||||
MonitorDownL( "monitor_down_l", PeripheralType.Monitor ),
|
||||
MonitorDownD( "monitor_down_d", PeripheralType.Monitor ),
|
||||
MonitorDownUD( "monitor_down_ud", PeripheralType.Monitor ),
|
||||
MonitorDownU( "monitor_down_u", PeripheralType.Monitor ),
|
||||
MonitorDownRD( "monitor_down_rd", PeripheralType.Monitor ),
|
||||
MonitorDownLRD( "monitor_down_lrd", PeripheralType.Monitor ),
|
||||
MonitorDownLD( "monitor_down_ld", PeripheralType.Monitor ),
|
||||
MonitorDownRUD( "monitor_down_rud", PeripheralType.Monitor ),
|
||||
MonitorDownLRUD( "monitor_down_lrud", PeripheralType.Monitor ),
|
||||
MonitorDownLUD( "monitor_down_lud", PeripheralType.Monitor ),
|
||||
MonitorDownRU( "monitor_down_ru", PeripheralType.Monitor ),
|
||||
MonitorDownLRU( "monitor_down_lru", PeripheralType.Monitor ),
|
||||
MonitorDownLU( "monitor_down_lu", PeripheralType.Monitor ),
|
||||
AdvancedMonitor( "advanced_monitor", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorR( "advanced_monitor_r", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorLR( "advanced_monitor_lr", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorL( "advanced_monitor_l", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorD( "advanced_monitor_d", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorUD( "advanced_monitor_ud", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorU( "advanced_monitor_u", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorRD( "advanced_monitor_rd", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorLRD( "advanced_monitor_lrd", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorLD( "advanced_monitor_ld", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorRUD( "advanced_monitor_rud", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorLRUD( "advanced_monitor_lrud", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorLUD( "advanced_monitor_lud", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorRU( "advanced_monitor_ru", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorLRU( "advanced_monitor_lru", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorLU( "advanced_monitor_lu", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorUp( "advanced_monitor_up", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorUpR( "advanced_monitor_up_r", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorUpLR( "advanced_monitor_up_lr", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorUpL( "advanced_monitor_up_l", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorUpD( "advanced_monitor_up_d", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorUpUD( "advanced_monitor_up_ud", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorUpU( "advanced_monitor_up_u", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorUpRD( "advanced_monitor_up_rd", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorUpLRD( "advanced_monitor_up_lrd", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorUpLD( "advanced_monitor_up_ld", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorUpRUD( "advanced_monitor_up_rud", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorUpLRUD( "advanced_monitor_up_lrud", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorUpLUD( "advanced_monitor_up_lud", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorUpRU( "advanced_monitor_up_ru", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorUpLRU( "advanced_monitor_up_lru", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorUpLU( "advanced_monitor_up_lu", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorDown( "advanced_monitor_down", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorDownR( "advanced_monitor_down_r", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorDownLR( "advanced_monitor_down_lr", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorDownL( "advanced_monitor_down_l", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorDownD( "advanced_monitor_down_d", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorDownUD( "advanced_monitor_down_ud", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorDownU( "advanced_monitor_down_u", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorDownRD( "advanced_monitor_down_rd", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorDownLRD( "advanced_monitor_down_lrd", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorDownLD( "advanced_monitor_down_ld", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorDownRUD( "advanced_monitor_down_rud", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorDownLRUD( "advanced_monitor_down_lrud", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorDownLUD( "advanced_monitor_down_lud", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorDownRU( "advanced_monitor_down_ru", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorDownLRU( "advanced_monitor_down_lru", PeripheralType.AdvancedMonitor ),
|
||||
AdvancedMonitorDownLU( "advanced_monitor_down_lu", PeripheralType.AdvancedMonitor );
|
||||
|
||||
private String m_name;
|
||||
private PeripheralType m_peripheralType;
|
||||
|
||||
private BlockPeripheralVariant( String name, PeripheralType peripheralType )
|
||||
{
|
||||
m_name = name;
|
||||
m_peripheralType = peripheralType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
public PeripheralType getPeripheralType()
|
||||
{
|
||||
return m_peripheralType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.common;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.api.peripheral.IPeripheralProvider;
|
||||
import dan200.computercraft.shared.computer.blocks.ComputerPeripheral;
|
||||
import dan200.computercraft.shared.computer.blocks.TileComputerBase;
|
||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class DefaultPeripheralProvider implements IPeripheralProvider
|
||||
{
|
||||
public DefaultPeripheralProvider()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPeripheral getPeripheral( World world, BlockPos pos, EnumFacing side )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null )
|
||||
{
|
||||
// Handle our peripherals
|
||||
if( tile instanceof IPeripheralTile )
|
||||
{
|
||||
IPeripheralTile peripheralTile = (IPeripheralTile)tile;
|
||||
return peripheralTile.getPeripheral( side );
|
||||
}
|
||||
|
||||
// Handle our computers
|
||||
if( tile instanceof TileComputerBase )
|
||||
{
|
||||
TileComputerBase computerTile = (TileComputerBase)tile;
|
||||
if( tile instanceof TileTurtle )
|
||||
{
|
||||
if( !((TileTurtle)tile).hasMoved() )
|
||||
{
|
||||
return new ComputerPeripheral( "turtle", computerTile.createServerComputer() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ComputerPeripheral( "computer", computerTile.createServerComputer() );
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.common;
|
||||
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public interface IPeripheralItem
|
||||
{
|
||||
public PeripheralType getPeripheralType( ItemStack stack );
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.common;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.shared.common.IDirectionalTile;
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
public interface IPeripheralTile extends IDirectionalTile
|
||||
{
|
||||
public PeripheralType getPeripheralType();
|
||||
public IPeripheral getPeripheral( EnumFacing side );
|
||||
public String getLabel();
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.common;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ItemAdvancedModem extends ItemPeripheralBase
|
||||
{
|
||||
public ItemAdvancedModem( Block block )
|
||||
{
|
||||
super( block );
|
||||
setUnlocalizedName( "computercraft:advanced_modem" );
|
||||
setCreativeTab( ComputerCraft.mainCreativeTab );
|
||||
}
|
||||
|
||||
public ItemStack create( PeripheralType type, String label, int quantity )
|
||||
{
|
||||
ItemStack stack;
|
||||
switch( type )
|
||||
{
|
||||
case AdvancedModem:
|
||||
{
|
||||
stack = new ItemStack( this, quantity, 0 );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
// Ignore types we can't handle
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if( label != null )
|
||||
{
|
||||
stack.setStackDisplayName( label );
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubItems( Item itemID, CreativeTabs tabs, List list )
|
||||
{
|
||||
list.add( PeripheralItemFactory.create( PeripheralType.AdvancedModem, null, 1 ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeripheralType getPeripheralType( int damage )
|
||||
{
|
||||
return PeripheralType.AdvancedModem;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.common;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import dan200.computercraft.shared.peripheral.modem.TileCable;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ItemCable extends ItemPeripheralBase
|
||||
{
|
||||
public ItemCable( Block block )
|
||||
{
|
||||
super( block );
|
||||
setUnlocalizedName( "computercraft:cable" );
|
||||
setCreativeTab( ComputerCraft.mainCreativeTab );
|
||||
}
|
||||
|
||||
public ItemStack create( PeripheralType type, String label, int quantity )
|
||||
{
|
||||
ItemStack stack;
|
||||
switch( type )
|
||||
{
|
||||
case Cable:
|
||||
{
|
||||
stack = new ItemStack( this, quantity, 0 );
|
||||
break;
|
||||
}
|
||||
case WiredModem:
|
||||
{
|
||||
stack = new ItemStack( this, quantity, 1 );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if( label != null )
|
||||
{
|
||||
stack.setStackDisplayName( label );
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubItems( Item itemID, CreativeTabs tabs, List list )
|
||||
{
|
||||
list.add( PeripheralItemFactory.create( PeripheralType.WiredModem, null, 1 ) );
|
||||
list.add( PeripheralItemFactory.create( PeripheralType.Cable, null, 1 ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onItemUse( ItemStack stack, EntityPlayer player, World world, BlockPos pos, EnumFacing side, float fx, float fy, float fz )
|
||||
{
|
||||
if( !canPlaceBlockOnSide( world, pos, side, player, stack ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try to add a cable to a modem
|
||||
PeripheralType type = getPeripheralType( stack );
|
||||
Block existing = world.getBlockState( pos ).getBlock();
|
||||
IBlockState existingState = world.getBlockState( pos );
|
||||
if( existing == ComputerCraft.Blocks.cable )
|
||||
{
|
||||
PeripheralType existingType = ComputerCraft.Blocks.cable.getPeripheralType( world, pos );
|
||||
if( existingType == PeripheralType.WiredModem && type == PeripheralType.Cable )
|
||||
{
|
||||
if( stack.stackSize > 0 )
|
||||
{
|
||||
world.setBlockState( pos, existingState.withProperty( BlockCable.Properties.CABLE, true ), 3 );
|
||||
world.playSoundEffect( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, ComputerCraft.Blocks.cable.stepSound.getBreakSound(), (ComputerCraft.Blocks.cable.stepSound.getVolume() + 1.0F) / 2.0F, ComputerCraft.Blocks.cable.stepSound.getFrequency() * 0.8F);
|
||||
stack.stackSize--;
|
||||
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileCable )
|
||||
{
|
||||
TileCable cable = (TileCable)tile;
|
||||
cable.networkChanged();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to add on the side of something
|
||||
if( existing != Blocks.air && (type == PeripheralType.Cable || existing.isSideSolid( world, pos, side )) )
|
||||
{
|
||||
BlockPos offset = pos.offset( side );
|
||||
Block offsetExisting = world.getBlockState( offset ).getBlock();
|
||||
IBlockState offsetExistingState = world.getBlockState( offset );
|
||||
if( offsetExisting == ComputerCraft.Blocks.cable )
|
||||
{
|
||||
// Try to add a modem to a cable
|
||||
PeripheralType offsetExistingType = ComputerCraft.Blocks.cable.getPeripheralType( world, offset );
|
||||
if( offsetExistingType == PeripheralType.Cable && type == PeripheralType.WiredModem )
|
||||
{
|
||||
if( stack.stackSize > 0 )
|
||||
{
|
||||
world.setBlockState( offset, offsetExistingState.withProperty( BlockCable.Properties.MODEM, BlockCableModemVariant.fromFacing( side.getOpposite() ) ), 3 );
|
||||
world.playSoundEffect( offset.getX() + 0.5, offset.getY() + 0.5, offset.getZ() + 0.5, ComputerCraft.Blocks.cable.stepSound.getBreakSound(), (ComputerCraft.Blocks.cable.stepSound.getVolume() + 1.0F) / 2.0F, ComputerCraft.Blocks.cable.stepSound.getFrequency() * 0.8F);
|
||||
stack.stackSize--;
|
||||
|
||||
TileEntity tile = world.getTileEntity( offset );
|
||||
if( tile != null && tile instanceof TileCable )
|
||||
{
|
||||
TileCable cable = (TileCable)tile;
|
||||
cable.networkChanged();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try to add a cable to a modem
|
||||
if( offsetExistingType == PeripheralType.WiredModem && type == PeripheralType.Cable )
|
||||
{
|
||||
if( stack.stackSize > 0 )
|
||||
{
|
||||
world.setBlockState( offset, offsetExistingState.withProperty( BlockCable.Properties.CABLE, true ), 3 );
|
||||
world.playSoundEffect( offset.getX() + 0.5, offset.getY() + 0.5, offset.getZ() + 0.5, ComputerCraft.Blocks.cable.stepSound.getBreakSound(), (ComputerCraft.Blocks.cable.stepSound.getVolume() + 1.0F) / 2.0F, ComputerCraft.Blocks.cable.stepSound.getFrequency() * 0.8F);
|
||||
stack.stackSize--;
|
||||
|
||||
TileEntity tile = world.getTileEntity( offset );
|
||||
if( tile != null && tile instanceof TileCable )
|
||||
{
|
||||
TileCable cable = (TileCable)tile;
|
||||
cable.networkChanged();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return super.onItemUse( stack, player, world, pos, side, fx, fy, fz );
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeripheralType getPeripheralType( int damage )
|
||||
{
|
||||
switch( damage )
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
{
|
||||
return PeripheralType.Cable;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
return PeripheralType.WiredModem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.common;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ItemPeripheral extends ItemPeripheralBase
|
||||
{
|
||||
public ItemPeripheral( Block block )
|
||||
{
|
||||
super( block );
|
||||
setUnlocalizedName( "computercraft:peripheral" );
|
||||
setCreativeTab( ComputerCraft.mainCreativeTab );
|
||||
}
|
||||
|
||||
public ItemStack create( PeripheralType type, String label, int quantity )
|
||||
{
|
||||
ItemStack stack;
|
||||
switch( type )
|
||||
{
|
||||
case DiskDrive:
|
||||
{
|
||||
stack = new ItemStack( this, quantity, 0 );
|
||||
break;
|
||||
}
|
||||
case WirelessModem:
|
||||
{
|
||||
stack = new ItemStack( this, quantity, 1 );
|
||||
break;
|
||||
}
|
||||
case Monitor:
|
||||
{
|
||||
stack = new ItemStack( this, quantity, 2 );
|
||||
break;
|
||||
}
|
||||
case Printer:
|
||||
{
|
||||
stack = new ItemStack( this, quantity, 3 );
|
||||
break;
|
||||
}
|
||||
case AdvancedMonitor:
|
||||
{
|
||||
stack = new ItemStack( this, quantity, 4 );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
// Ignore types we can't handle
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if( label != null )
|
||||
{
|
||||
stack.setStackDisplayName( label );
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubItems( Item itemID, CreativeTabs tabs, List list )
|
||||
{
|
||||
list.add( PeripheralItemFactory.create( PeripheralType.DiskDrive, null, 1 ) );
|
||||
list.add( PeripheralItemFactory.create( PeripheralType.Printer, null, 1 ) );
|
||||
list.add( PeripheralItemFactory.create( PeripheralType.Monitor, null, 1 ) );
|
||||
list.add( PeripheralItemFactory.create( PeripheralType.AdvancedMonitor, null, 1 ) );
|
||||
list.add( PeripheralItemFactory.create( PeripheralType.WirelessModem, null, 1 ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeripheralType getPeripheralType( int damage )
|
||||
{
|
||||
switch( damage )
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
{
|
||||
return PeripheralType.DiskDrive;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
return PeripheralType.WirelessModem;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
return PeripheralType.Monitor;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
return PeripheralType.Printer;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
return PeripheralType.AdvancedMonitor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.common;
|
||||
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public abstract class ItemPeripheralBase extends ItemBlock implements IPeripheralItem
|
||||
{
|
||||
protected ItemPeripheralBase( Block block )
|
||||
{
|
||||
super( block );
|
||||
setMaxStackSize( 64 );
|
||||
setHasSubtypes( true );
|
||||
}
|
||||
|
||||
public abstract PeripheralType getPeripheralType( int damage );
|
||||
|
||||
@Override
|
||||
public final int getMetadata( int damage )
|
||||
{
|
||||
return damage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceBlockOnSide( World world, BlockPos pos, EnumFacing side, EntityPlayer player, ItemStack stack ) // canPlaceItemBlockOnSide
|
||||
{
|
||||
PeripheralType type = getPeripheralType( stack );
|
||||
switch( type )
|
||||
{
|
||||
case WirelessModem:
|
||||
case WiredModem:
|
||||
case AdvancedModem:
|
||||
{
|
||||
return world.isSideSolid( pos, side );
|
||||
}
|
||||
case Cable:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return super.canPlaceBlockOnSide( world, pos, side, player, stack );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUnlocalizedName( ItemStack stack )
|
||||
{
|
||||
PeripheralType type = getPeripheralType( stack );
|
||||
switch( type )
|
||||
{
|
||||
case DiskDrive:
|
||||
default:
|
||||
{
|
||||
return "tile.computercraft:drive";
|
||||
}
|
||||
case Printer:
|
||||
{
|
||||
return "tile.computercraft:printer";
|
||||
}
|
||||
case Monitor:
|
||||
{
|
||||
return "tile.computercraft:monitor";
|
||||
}
|
||||
case AdvancedMonitor:
|
||||
{
|
||||
return "tile.computercraft:advanced_monitor";
|
||||
}
|
||||
case WirelessModem:
|
||||
{
|
||||
return "tile.computercraft:wireless_modem";
|
||||
}
|
||||
case WiredModem:
|
||||
case WiredModemWithCable:
|
||||
{
|
||||
return "tile.computercraft:wired_modem";
|
||||
}
|
||||
case Cable:
|
||||
{
|
||||
return "tile.computercraft:cable";
|
||||
}
|
||||
case AdvancedModem:
|
||||
{
|
||||
return "tile.computercraft:advanced_modem";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IPeripheralItem implementation
|
||||
|
||||
@Override
|
||||
public final PeripheralType getPeripheralType( ItemStack stack )
|
||||
{
|
||||
return getPeripheralType( stack.getItemDamage() );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.common;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class PeripheralItemFactory
|
||||
{
|
||||
public static ItemStack create( IPeripheralTile tile )
|
||||
{
|
||||
return create( tile.getPeripheralType(), tile.getLabel(), 1 );
|
||||
}
|
||||
|
||||
public static ItemStack create( PeripheralType type, String label, int quantity )
|
||||
{
|
||||
ItemPeripheral peripheral = ((ItemPeripheral)Item.getItemFromBlock( ComputerCraft.Blocks.peripheral ));
|
||||
ItemCable cable = ((ItemCable)Item.getItemFromBlock( ComputerCraft.Blocks.cable ));
|
||||
ItemAdvancedModem advancedModem = ((ItemAdvancedModem)Item.getItemFromBlock( ComputerCraft.Blocks.advancedModem ));
|
||||
switch( type )
|
||||
{
|
||||
case DiskDrive:
|
||||
case Printer:
|
||||
case Monitor:
|
||||
case AdvancedMonitor:
|
||||
case WirelessModem:
|
||||
{
|
||||
return peripheral.create( type, label, quantity );
|
||||
}
|
||||
case WiredModem:
|
||||
case Cable:
|
||||
{
|
||||
return cable.create( type, label, quantity );
|
||||
}
|
||||
case AdvancedModem:
|
||||
{
|
||||
return advancedModem.create( type, label, quantity );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.common;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.shared.common.IDirectionalTile;
|
||||
import dan200.computercraft.shared.common.TileGeneric;
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.ITickable;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class TilePeripheralBase extends TileGeneric
|
||||
implements IPeripheralTile, IDirectionalTile, ITickable
|
||||
{
|
||||
// Statics
|
||||
|
||||
private EnumFacing m_dir;
|
||||
private int m_anim;
|
||||
private boolean m_changed;
|
||||
|
||||
private String m_label;
|
||||
|
||||
public TilePeripheralBase()
|
||||
{
|
||||
m_dir = EnumFacing.NORTH;
|
||||
m_anim = 0;
|
||||
m_changed = false;
|
||||
|
||||
m_label = null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockPeripheralBase getBlock()
|
||||
{
|
||||
return (BlockPeripheralBase)super.getBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDroppedItems( List<ItemStack> drops, int fortune, boolean creative, boolean silkTouch )
|
||||
{
|
||||
if( !creative )
|
||||
{
|
||||
drops.add( PeripheralItemFactory.create( this ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickedItem()
|
||||
{
|
||||
return PeripheralItemFactory.create( this );
|
||||
}
|
||||
|
||||
// IPeripheralTile implementation
|
||||
|
||||
@Override
|
||||
public final PeripheralType getPeripheralType()
|
||||
{
|
||||
return getBlock().getPeripheralType( getBlockState() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPeripheral getPeripheral( EnumFacing side )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel()
|
||||
{
|
||||
if( m_label != null && m_label.length() > 0 )
|
||||
{
|
||||
return m_label;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setLabel( String label )
|
||||
{
|
||||
m_label = label;
|
||||
}
|
||||
|
||||
// IDirectionalTile implementation
|
||||
|
||||
@Override
|
||||
public EnumFacing getDirection()
|
||||
{
|
||||
return m_dir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirection( EnumFacing dir )
|
||||
{
|
||||
if( dir != m_dir )
|
||||
{
|
||||
m_dir = dir;
|
||||
m_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized int getAnim()
|
||||
{
|
||||
return m_anim;
|
||||
}
|
||||
|
||||
public synchronized void setAnim( int anim )
|
||||
{
|
||||
if( anim != m_anim )
|
||||
{
|
||||
m_anim = anim;
|
||||
m_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void update()
|
||||
{
|
||||
if( m_changed )
|
||||
{
|
||||
updateBlock();
|
||||
m_changed = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
// Read properties
|
||||
super.readFromNBT(nbttagcompound);
|
||||
if( nbttagcompound.hasKey( "dir" ) )
|
||||
{
|
||||
m_dir = EnumFacing.getFront( nbttagcompound.getInteger( "dir" ) );
|
||||
}
|
||||
if( nbttagcompound.hasKey( "anim" ) )
|
||||
{
|
||||
m_anim = nbttagcompound.getInteger( "anim" );
|
||||
}
|
||||
if( nbttagcompound.hasKey( "label" ) )
|
||||
{
|
||||
m_label = nbttagcompound.getString( "label" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
// Write properties
|
||||
super.writeToNBT( nbttagcompound );
|
||||
nbttagcompound.setInteger( "dir", m_dir.getIndex() );
|
||||
nbttagcompound.setInteger( "anim", m_anim );
|
||||
if( m_label != null )
|
||||
{
|
||||
nbttagcompound.setString( "label", m_label );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readDescription( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.readDescription( nbttagcompound );
|
||||
m_dir = EnumFacing.getFront( nbttagcompound.getInteger( "dir" ) );
|
||||
m_anim = nbttagcompound.getInteger( "anim" );
|
||||
if( nbttagcompound.hasKey( "label" ) )
|
||||
{
|
||||
m_label = nbttagcompound.getString( "label" );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_label = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDescription( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.writeDescription( nbttagcompound );
|
||||
nbttagcompound.setInteger( "dir", m_dir.getIndex() );
|
||||
nbttagcompound.setInteger( "anim", m_anim );
|
||||
if( m_label != null )
|
||||
{
|
||||
nbttagcompound.setString( "label", m_label );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.diskdrive;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class ContainerDiskDrive extends Container
|
||||
{
|
||||
private final TileDiskDrive m_diskDrive;
|
||||
|
||||
public ContainerDiskDrive( IInventory playerInventory, TileDiskDrive diskDrive )
|
||||
{
|
||||
m_diskDrive = diskDrive;
|
||||
addSlotToContainer(new Slot( m_diskDrive, 0, 8 + 4 * 18, 35));
|
||||
|
||||
for(int j = 0; j < 3; j++)
|
||||
{
|
||||
for(int i1 = 0; i1 < 9; i1++)
|
||||
{
|
||||
addSlotToContainer(new Slot(playerInventory, i1 + j * 9 + 9, 8 + i1 * 18, 84 + j * 18));
|
||||
}
|
||||
}
|
||||
|
||||
for(int k = 0; k < 9; k++)
|
||||
{
|
||||
addSlotToContainer(new Slot(playerInventory, k, 8 + k * 18, 142));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInteractWith( EntityPlayer player )
|
||||
{
|
||||
return m_diskDrive.isUseableByPlayer( player );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack transferStackInSlot( EntityPlayer player, int i )
|
||||
{
|
||||
ItemStack itemstack = null;
|
||||
Slot slot = (Slot)inventorySlots.get(i);
|
||||
if(slot != null && slot.getHasStack())
|
||||
{
|
||||
ItemStack itemstack1 = slot.getStack();
|
||||
itemstack = itemstack1.copy();
|
||||
if(i == 0 )
|
||||
{
|
||||
if(!mergeItemStack(itemstack1, 1, 37, true))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else if( !mergeItemStack(itemstack1, 0, 1, false) )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if(itemstack1.stackSize == 0)
|
||||
{
|
||||
slot.putStack(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
slot.onSlotChanged();
|
||||
}
|
||||
|
||||
if(itemstack1.stackSize != itemstack.stackSize)
|
||||
{
|
||||
slot.onPickupFromSlot(player, itemstack1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return itemstack;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.diskdrive;
|
||||
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.media.IMedia;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.shared.media.items.ItemDiskLegacy;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class DiskDrivePeripheral implements IPeripheral
|
||||
{
|
||||
private final TileDiskDrive m_diskDrive;
|
||||
|
||||
public DiskDrivePeripheral( TileDiskDrive diskDrive )
|
||||
{
|
||||
m_diskDrive = diskDrive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType()
|
||||
{
|
||||
return "drive";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getMethodNames()
|
||||
{
|
||||
return new String[] {
|
||||
"isDiskPresent",
|
||||
"getDiskLabel",
|
||||
"setDiskLabel",
|
||||
"hasData",
|
||||
"getMountPath",
|
||||
"hasAudio",
|
||||
"getAudioTitle",
|
||||
"playAudio",
|
||||
"stopAudio",
|
||||
"ejectDisk",
|
||||
"getDiskID"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( IComputerAccess computer, ILuaContext context, int method, Object[] arguments ) throws LuaException
|
||||
{
|
||||
switch( method )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// isPresent
|
||||
return new Object[] {
|
||||
m_diskDrive.getDiskStack() != null
|
||||
};
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
// getDiskLabel
|
||||
IMedia media = m_diskDrive.getDiskMedia();
|
||||
if( media != null )
|
||||
{
|
||||
return new Object[] { media.getLabel( m_diskDrive.getDiskStack() ) };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
// setDiskLabel
|
||||
String label = null;
|
||||
if( arguments.length > 0 )
|
||||
{
|
||||
if( arguments[0] != null && !(arguments[0] instanceof String) )
|
||||
{
|
||||
throw new LuaException( "Expected string" );
|
||||
}
|
||||
label = (String)arguments[0];
|
||||
}
|
||||
|
||||
IMedia media = m_diskDrive.getDiskMedia();
|
||||
if( media != null )
|
||||
{
|
||||
ItemStack disk = m_diskDrive.getDiskStack();
|
||||
if( media.setLabel( disk, label ) )
|
||||
{
|
||||
m_diskDrive.setDiskStack( disk );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new LuaException( "Disk label cannot be changed" );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
// hasData
|
||||
return new Object[] {
|
||||
m_diskDrive.getDiskMountPath( computer ) != null
|
||||
};
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
// getMountPath
|
||||
return new Object[] {
|
||||
m_diskDrive.getDiskMountPath( computer )
|
||||
};
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
// hasAudio
|
||||
IMedia media = m_diskDrive.getDiskMedia();
|
||||
if( media != null )
|
||||
{
|
||||
return new Object[] { media.getAudioRecordName( m_diskDrive.getDiskStack() ) != null };
|
||||
}
|
||||
return new Object[] { false };
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
// getAudioTitle
|
||||
IMedia media = m_diskDrive.getDiskMedia();
|
||||
if( media != null )
|
||||
{
|
||||
return new Object[] { media.getAudioTitle( m_diskDrive.getDiskStack() ) };
|
||||
}
|
||||
return new Object[] { false };
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
// playAudio
|
||||
m_diskDrive.playDiskAudio();
|
||||
return null;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
// stopAudio
|
||||
m_diskDrive.stopDiskAudio();
|
||||
return null;
|
||||
}
|
||||
case 9:
|
||||
{
|
||||
// eject
|
||||
m_diskDrive.ejectDisk();
|
||||
return null;
|
||||
}
|
||||
case 10:
|
||||
{
|
||||
// getDiskID
|
||||
ItemStack disk = m_diskDrive.getDiskStack();
|
||||
if( disk != null )
|
||||
{
|
||||
Item item = disk.getItem();
|
||||
if( item instanceof ItemDiskLegacy )
|
||||
{
|
||||
return new Object[] { ((ItemDiskLegacy)item).getDiskID( disk ) };
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attach( IComputerAccess computer )
|
||||
{
|
||||
m_diskDrive.mount( computer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detach( IComputerAccess computer )
|
||||
{
|
||||
m_diskDrive.unmount( computer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( IPeripheral other )
|
||||
{
|
||||
if( other instanceof DiskDrivePeripheral )
|
||||
{
|
||||
DiskDrivePeripheral otherDiskDrive = (DiskDrivePeripheral)other;
|
||||
if( otherDiskDrive.m_diskDrive == this.m_diskDrive )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,683 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.diskdrive;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.filesystem.IMount;
|
||||
import dan200.computercraft.api.filesystem.IWritableMount;
|
||||
import dan200.computercraft.api.media.IMedia;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
|
||||
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
|
||||
import dan200.computercraft.shared.util.InventoryUtil;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.ITickable;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class TileDiskDrive extends TilePeripheralBase
|
||||
implements IInventory, ITickable
|
||||
{
|
||||
// Statics
|
||||
|
||||
private static final int BLOCKEVENT_PLAY_RECORD = 0;
|
||||
private static final int BLOCKEVENT_STOP_RECORD = 1;
|
||||
|
||||
private static class MountInfo
|
||||
{
|
||||
public String mountPath;
|
||||
}
|
||||
|
||||
// Members
|
||||
|
||||
private final Map<IComputerAccess, MountInfo> m_computers;
|
||||
|
||||
private ItemStack m_diskStack;
|
||||
private IMount m_diskMount;
|
||||
|
||||
private boolean m_recordQueued;
|
||||
private boolean m_recordPlaying;
|
||||
private boolean m_restartRecord;
|
||||
private boolean m_ejectQueued;
|
||||
|
||||
public TileDiskDrive()
|
||||
{
|
||||
m_computers = new HashMap<IComputerAccess, MountInfo>();
|
||||
|
||||
m_diskStack = null;
|
||||
m_diskMount = null;
|
||||
|
||||
m_recordQueued = false;
|
||||
m_recordPlaying = false;
|
||||
m_restartRecord = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
ejectContents( true );
|
||||
synchronized( this )
|
||||
{
|
||||
if( m_recordPlaying )
|
||||
{
|
||||
sendBlockEvent( BLOCKEVENT_STOP_RECORD );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActivate( EntityPlayer player, EnumFacing side, float hitX, float hitY, float hitZ )
|
||||
{
|
||||
if( player.isSneaking() )
|
||||
{
|
||||
// Try to put a disk into the drive
|
||||
if( !worldObj.isRemote )
|
||||
{
|
||||
ItemStack disk = player.getCurrentEquippedItem();
|
||||
if( disk != null && getStackInSlot(0) == null )
|
||||
{
|
||||
if( ComputerCraft.getMedia( disk ) != null )
|
||||
{
|
||||
setInventorySlotContents( 0, disk );
|
||||
player.destroyCurrentEquippedItem();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Open the GUI
|
||||
if( !worldObj.isRemote )
|
||||
{
|
||||
ComputerCraft.openDiskDriveGUI( player, this );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumFacing getDirection()
|
||||
{
|
||||
IBlockState state = getBlockState();
|
||||
return (EnumFacing)state.getValue( BlockPeripheral.Properties.FACING );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirection( EnumFacing dir )
|
||||
{
|
||||
if( dir.getAxis() == EnumFacing.Axis.Y )
|
||||
{
|
||||
dir = EnumFacing.NORTH;
|
||||
}
|
||||
setBlockState( getBlockState().withProperty( BlockPeripheral.Properties.FACING, dir ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound nbttagcompound)
|
||||
{
|
||||
super.readFromNBT(nbttagcompound);
|
||||
if( nbttagcompound.hasKey( "item" ) )
|
||||
{
|
||||
NBTTagCompound item = nbttagcompound.getCompoundTag( "item" );
|
||||
m_diskStack = ItemStack.loadItemStackFromNBT( item );
|
||||
m_diskMount = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT(NBTTagCompound nbttagcompound)
|
||||
{
|
||||
super.writeToNBT(nbttagcompound);
|
||||
if( m_diskStack != null )
|
||||
{
|
||||
NBTTagCompound item = new NBTTagCompound();
|
||||
m_diskStack.writeToNBT( item );
|
||||
nbttagcompound.setTag( "item", item );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
super.update();
|
||||
|
||||
// Ejection
|
||||
synchronized( this )
|
||||
{
|
||||
if( m_ejectQueued )
|
||||
{
|
||||
ejectContents( false );
|
||||
m_ejectQueued = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Music
|
||||
synchronized( this )
|
||||
{
|
||||
if( m_recordPlaying != m_recordQueued || m_restartRecord )
|
||||
{
|
||||
m_restartRecord = false;
|
||||
if( m_recordQueued )
|
||||
{
|
||||
IMedia contents = getDiskMedia();
|
||||
String record = (contents != null) ? contents.getAudioRecordName( m_diskStack ) : null;
|
||||
if( record != null )
|
||||
{
|
||||
m_recordPlaying = true;
|
||||
sendBlockEvent( BLOCKEVENT_PLAY_RECORD );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_recordQueued = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sendBlockEvent( BLOCKEVENT_STOP_RECORD );
|
||||
m_recordPlaying = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IInventory implementation
|
||||
|
||||
@Override
|
||||
public int getSizeInventory()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int i)
|
||||
{
|
||||
return m_diskStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeStackFromSlot(int i)
|
||||
{
|
||||
ItemStack result = m_diskStack;
|
||||
m_diskStack = null;
|
||||
m_diskMount = null;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack decrStackSize(int i, int j)
|
||||
{
|
||||
if (m_diskStack == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (m_diskStack.stackSize <= j)
|
||||
{
|
||||
ItemStack disk = m_diskStack;
|
||||
setInventorySlotContents( 0, null );
|
||||
return disk;
|
||||
}
|
||||
|
||||
ItemStack part = m_diskStack.splitStack(j);
|
||||
if (m_diskStack.stackSize == 0)
|
||||
{
|
||||
setInventorySlotContents( 0, null );
|
||||
}
|
||||
else
|
||||
{
|
||||
setInventorySlotContents( 0, m_diskStack );
|
||||
}
|
||||
return part;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInventorySlotContents( int i, ItemStack itemStack )
|
||||
{
|
||||
if( worldObj.isRemote )
|
||||
{
|
||||
m_diskStack = itemStack;
|
||||
m_diskMount = null;
|
||||
markDirty();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized( this )
|
||||
{
|
||||
if( InventoryUtil.areItemsStackable( itemStack, m_diskStack ) )
|
||||
{
|
||||
m_diskStack = itemStack;
|
||||
return;
|
||||
}
|
||||
|
||||
// Unmount old disk
|
||||
if( m_diskStack != null )
|
||||
{
|
||||
Set<IComputerAccess> computers = m_computers.keySet();
|
||||
Iterator<IComputerAccess> it = computers.iterator();
|
||||
while( it.hasNext() )
|
||||
{
|
||||
IComputerAccess computer = it.next();
|
||||
unmountDisk( computer );
|
||||
}
|
||||
}
|
||||
|
||||
// Stop music
|
||||
if( m_recordPlaying )
|
||||
{
|
||||
sendBlockEvent( BLOCKEVENT_STOP_RECORD );
|
||||
m_recordPlaying = false;
|
||||
m_recordQueued = false;
|
||||
}
|
||||
|
||||
// Swap disk over
|
||||
m_diskStack = itemStack;
|
||||
m_diskMount = null;
|
||||
markDirty();
|
||||
|
||||
// Update contents
|
||||
updateAnim();
|
||||
|
||||
// Mount new disk
|
||||
if( m_diskStack != null )
|
||||
{
|
||||
Set<IComputerAccess> computers = m_computers.keySet();
|
||||
Iterator<IComputerAccess> it = computers.iterator();
|
||||
while( it.hasNext() )
|
||||
{
|
||||
IComputerAccess computer = it.next();
|
||||
mountDisk( computer );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCustomName()
|
||||
{
|
||||
return getLabel() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
String label = getLabel();
|
||||
if( label != null )
|
||||
{
|
||||
return label;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "tile.computercraft:drive.name";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IChatComponent getDisplayName()
|
||||
{
|
||||
if( hasCustomName() )
|
||||
{
|
||||
return new ChatComponentText( getName() );
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ChatComponentTranslation( getName() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInventoryStackLimit()
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openInventory( EntityPlayer player )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeInventory( EntityPlayer player )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValidForSlot(int i, ItemStack itemstack)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseableByPlayer( EntityPlayer player )
|
||||
{
|
||||
return isUsable( player, false );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear()
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
setInventorySlotContents( 0, null );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFieldCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getField(int id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setField(int id, int value)
|
||||
{
|
||||
}
|
||||
|
||||
// IPeripheralTile implementation
|
||||
|
||||
@Override
|
||||
public IPeripheral getPeripheral( EnumFacing side )
|
||||
{
|
||||
return new DiskDrivePeripheral( this );
|
||||
}
|
||||
|
||||
public ItemStack getDiskStack()
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
return getStackInSlot( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
public void setDiskStack( ItemStack stack )
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
setInventorySlotContents( 0, stack );
|
||||
}
|
||||
}
|
||||
|
||||
public IMedia getDiskMedia()
|
||||
{
|
||||
return ComputerCraft.getMedia( getDiskStack() );
|
||||
}
|
||||
|
||||
public String getDiskMountPath( IComputerAccess computer )
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
if( m_computers.containsKey( computer ) )
|
||||
{
|
||||
MountInfo info = m_computers.get( computer );
|
||||
return info.mountPath;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void mount( IComputerAccess computer )
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
m_computers.put( computer, new MountInfo() );
|
||||
mountDisk( computer );
|
||||
}
|
||||
}
|
||||
|
||||
public void unmount( IComputerAccess computer )
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
unmountDisk( computer );
|
||||
m_computers.remove( computer );
|
||||
}
|
||||
}
|
||||
|
||||
public void playDiskAudio()
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
IMedia media = getDiskMedia();
|
||||
if( media != null && media.getAudioTitle( m_diskStack ) != null )
|
||||
{
|
||||
m_recordQueued = true;
|
||||
m_restartRecord = m_recordPlaying;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void stopDiskAudio()
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
m_recordQueued = false;
|
||||
m_restartRecord = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void ejectDisk()
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
if( !m_ejectQueued )
|
||||
{
|
||||
m_ejectQueued = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// private methods
|
||||
|
||||
private synchronized void mountDisk( IComputerAccess computer )
|
||||
{
|
||||
if( m_diskStack != null )
|
||||
{
|
||||
MountInfo info = m_computers.get( computer );
|
||||
IMedia contents = getDiskMedia();
|
||||
if( contents != null )
|
||||
{
|
||||
if( m_diskMount == null )
|
||||
{
|
||||
m_diskMount = contents.createDataMount( m_diskStack, worldObj );
|
||||
}
|
||||
if( m_diskMount != null )
|
||||
{
|
||||
if( m_diskMount instanceof IWritableMount)
|
||||
{
|
||||
// Try mounting at the lowest numbered "disk" name we can
|
||||
int n = 1;
|
||||
while( info.mountPath == null )
|
||||
{
|
||||
info.mountPath = computer.mountWritable( (n==1) ? "disk" : ("disk" + n), (IWritableMount)m_diskMount );
|
||||
n++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try mounting at the lowest numbered "disk" name we can
|
||||
int n = 1;
|
||||
while( info.mountPath == null )
|
||||
{
|
||||
info.mountPath = computer.mount( (n==1) ? "disk" : ("disk" + n), m_diskMount );
|
||||
n++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
info.mountPath = null;
|
||||
}
|
||||
}
|
||||
computer.queueEvent( "disk", new Object[] { computer.getAttachmentName() } );
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void unmountDisk( IComputerAccess computer )
|
||||
{
|
||||
if( m_diskStack != null )
|
||||
{
|
||||
MountInfo info = m_computers.get( computer );
|
||||
assert( info != null );
|
||||
if( info.mountPath != null )
|
||||
{
|
||||
computer.unmount( info.mountPath );
|
||||
info.mountPath = null;
|
||||
}
|
||||
computer.queueEvent( "disk_eject", new Object[] { computer.getAttachmentName() } );
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void updateAnim()
|
||||
{
|
||||
if( m_diskStack != null )
|
||||
{
|
||||
IMedia contents = getDiskMedia();
|
||||
if( contents != null ) {
|
||||
setAnim( 2 );
|
||||
} else {
|
||||
setAnim( 1 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setAnim( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void ejectContents( boolean destroyed )
|
||||
{
|
||||
if( worldObj.isRemote )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_diskStack != null )
|
||||
{
|
||||
// Remove the disks from the inventory
|
||||
ItemStack disks = m_diskStack;
|
||||
setInventorySlotContents( 0, null );
|
||||
|
||||
// Spawn the item in the world
|
||||
int xOff = 0;
|
||||
int zOff = 0;
|
||||
if( !destroyed )
|
||||
{
|
||||
EnumFacing dir = getDirection();
|
||||
xOff = dir.getFrontOffsetX();
|
||||
zOff = dir.getFrontOffsetZ();
|
||||
}
|
||||
|
||||
BlockPos pos = getPos();
|
||||
double x = (double)pos.getX() + 0.5 + ((double)xOff * 0.5);
|
||||
double y = (double)pos.getY() + 0.75;
|
||||
double z = (double)pos.getZ() + 0.5 + ((double)zOff * 0.5);
|
||||
EntityItem entityitem = new EntityItem( worldObj, x, y, z, disks );
|
||||
entityitem.motionX = (double)xOff * 0.15;
|
||||
entityitem.motionY = 0.0;
|
||||
entityitem.motionZ = (double)zOff * 0.15;
|
||||
|
||||
worldObj.spawnEntityInWorld(entityitem);
|
||||
if( !destroyed )
|
||||
{
|
||||
worldObj.playAuxSFX(1000, getPos(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readDescription( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.readDescription( nbttagcompound );
|
||||
if( nbttagcompound.hasKey( "item" ) )
|
||||
{
|
||||
m_diskStack = ItemStack.loadItemStackFromNBT( nbttagcompound.getCompoundTag( "item" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_diskStack = null;
|
||||
}
|
||||
updateBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDescription( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.writeDescription( nbttagcompound );
|
||||
if( m_diskStack != null )
|
||||
{
|
||||
NBTTagCompound item = new NBTTagCompound();
|
||||
m_diskStack.writeToNBT( item );
|
||||
nbttagcompound.setTag( "item", item );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockEvent( int eventID, int eventParameter )
|
||||
{
|
||||
super.onBlockEvent( eventID, eventParameter );
|
||||
switch( eventID )
|
||||
{
|
||||
case BLOCKEVENT_PLAY_RECORD:
|
||||
{
|
||||
playRecord();
|
||||
break;
|
||||
}
|
||||
case BLOCKEVENT_STOP_RECORD:
|
||||
{
|
||||
stopRecord();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRefresh( World world, BlockPos pos, IBlockState oldState, IBlockState newState )
|
||||
{
|
||||
return super.shouldRefresh( world, pos, oldState, newState ) || ComputerCraft.Blocks.peripheral.getPeripheralType( newState ) != PeripheralType.DiskDrive;
|
||||
}
|
||||
|
||||
// Private methods
|
||||
|
||||
private void playRecord()
|
||||
{
|
||||
IMedia contents = getDiskMedia();
|
||||
String record = (contents != null) ? contents.getAudioRecordName( m_diskStack ) : null;
|
||||
if( record != null )
|
||||
{
|
||||
ComputerCraft.playRecord( record, contents.getAudioTitle( m_diskStack ), worldObj, getPos() );
|
||||
}
|
||||
else
|
||||
{
|
||||
ComputerCraft.playRecord( null, null, worldObj, getPos() );
|
||||
}
|
||||
}
|
||||
|
||||
private void stopRecord()
|
||||
{
|
||||
ComputerCraft.playRecord( null, null, worldObj, getPos() );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.modem;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import dan200.computercraft.shared.peripheral.common.BlockPeripheralBase;
|
||||
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
|
||||
import net.minecraft.block.properties.IProperty;
|
||||
import net.minecraft.block.properties.PropertyBool;
|
||||
import net.minecraft.block.properties.PropertyDirection;
|
||||
import net.minecraft.block.state.BlockState;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BlockAdvancedModem extends BlockPeripheralBase
|
||||
{
|
||||
public static class Properties
|
||||
{
|
||||
public static final PropertyDirection FACING = PropertyDirection.create( "facing" );
|
||||
public static final PropertyBool ON = PropertyBool.create( "on" );
|
||||
}
|
||||
|
||||
public BlockAdvancedModem()
|
||||
{
|
||||
setHardness( 2.0f );
|
||||
setUnlocalizedName( "computercraft:advanced_modem" );
|
||||
setCreativeTab( ComputerCraft.mainCreativeTab );
|
||||
setDefaultState( this.blockState.getBaseState()
|
||||
.withProperty( Properties.FACING, EnumFacing.NORTH )
|
||||
.withProperty( Properties.ON, false )
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockState createBlockState()
|
||||
{
|
||||
return new BlockState(this, new IProperty[] {
|
||||
Properties.FACING,
|
||||
Properties.ON
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getStateFromMeta( int meta )
|
||||
{
|
||||
IBlockState state = getDefaultState();
|
||||
state = state.withProperty( Properties.FACING, EnumFacing.getFront( meta ) );
|
||||
state = state.withProperty( Properties.ON, false );
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetaFromState( IBlockState state )
|
||||
{
|
||||
EnumFacing dir = (EnumFacing) state.getValue( Properties.FACING );
|
||||
return dir.getIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getActualState( IBlockState state, IBlockAccess world, BlockPos pos )
|
||||
{
|
||||
int anim;
|
||||
EnumFacing dir;
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TilePeripheralBase )
|
||||
{
|
||||
TilePeripheralBase peripheral = (TilePeripheralBase) tile;
|
||||
anim = peripheral.getAnim();
|
||||
dir = peripheral.getDirection();
|
||||
}
|
||||
else
|
||||
{
|
||||
anim = 0;
|
||||
dir = (EnumFacing)state.getValue( Properties.FACING );
|
||||
}
|
||||
|
||||
state = state.withProperty( Properties.FACING, dir );
|
||||
state = state.withProperty( Properties.ON, anim > 0 );
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getDefaultBlockState( PeripheralType type, EnumFacing placedSide )
|
||||
{
|
||||
EnumFacing dir = placedSide.getOpposite();
|
||||
return getDefaultState().withProperty( Properties.FACING, dir );
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeripheralType getPeripheralType( int damage )
|
||||
{
|
||||
return PeripheralType.AdvancedModem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeripheralType getPeripheralType( IBlockState state )
|
||||
{
|
||||
return PeripheralType.AdvancedModem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TilePeripheralBase createTile( PeripheralType type )
|
||||
{
|
||||
return new TileAdvancedModem();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.modem;
|
||||
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface INetwork
|
||||
{
|
||||
public void addReceiver( IReceiver receiver );
|
||||
public void removeReceiver( IReceiver receiver );
|
||||
public void transmit( int channel, int replyChannel, Object payload, World world, Vec3 pos, double range, boolean interdimensional, Object senderObject );
|
||||
public boolean isWireless();
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.modem;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface IReceiver
|
||||
{
|
||||
public int getChannel();
|
||||
public World getWorld();
|
||||
public Vec3 getWorldPosition();
|
||||
public boolean isInterdimensional();
|
||||
public double getReceiveRange();
|
||||
public void receiveSameDimension( int replyChannel, Object payload, double distance, Object senderObject );
|
||||
public void receiveDifferentDimension( int replyChannel, Object payload, Object senderObject );
|
||||
}
|
||||
@@ -0,0 +1,406 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.modem;
|
||||
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class ModemPeripheral
|
||||
implements IPeripheral
|
||||
{
|
||||
private static class SingleChannelReceiver implements IReceiver
|
||||
{
|
||||
private ModemPeripheral m_owner;
|
||||
private int m_channel;
|
||||
|
||||
public SingleChannelReceiver( ModemPeripheral owner, int channel )
|
||||
{
|
||||
m_owner = owner;
|
||||
m_channel = channel;
|
||||
}
|
||||
|
||||
// IReceiver implementation
|
||||
|
||||
@Override
|
||||
public int getChannel()
|
||||
{
|
||||
return m_channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld()
|
||||
{
|
||||
return m_owner.getWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3 getWorldPosition()
|
||||
{
|
||||
return m_owner.getWorldPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInterdimensional()
|
||||
{
|
||||
return m_owner.isInterdimensional();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getReceiveRange()
|
||||
{
|
||||
return m_owner.getReceiveRange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveSameDimension( int replyChannel, Object payload, double distance, Object senderObject )
|
||||
{
|
||||
if( senderObject != m_owner )
|
||||
{
|
||||
m_owner.receiveSameDimension( m_channel, replyChannel, payload, distance );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveDifferentDimension( int replyChannel, Object payload, Object senderObject )
|
||||
{
|
||||
if( senderObject != m_owner )
|
||||
{
|
||||
m_owner.receiveDifferentDimension( m_channel, replyChannel, payload );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private INetwork m_network;
|
||||
private IComputerAccess m_computer;
|
||||
private Map<Integer, IReceiver> m_channels;
|
||||
|
||||
private boolean m_open;
|
||||
private boolean m_changed;
|
||||
|
||||
public ModemPeripheral()
|
||||
{
|
||||
m_network = null;
|
||||
m_computer = null;
|
||||
|
||||
m_channels = new HashMap<Integer, IReceiver>();
|
||||
m_open = false;
|
||||
m_changed = true;
|
||||
}
|
||||
|
||||
private synchronized void setNetwork( INetwork network )
|
||||
{
|
||||
if( m_network != network )
|
||||
{
|
||||
// Leave old network
|
||||
if( m_network != null )
|
||||
{
|
||||
Iterator<IReceiver> it = m_channels.values().iterator();
|
||||
while( it.hasNext() )
|
||||
{
|
||||
m_network.removeReceiver( it.next() );
|
||||
}
|
||||
}
|
||||
|
||||
// Set new network
|
||||
m_network = network;
|
||||
|
||||
// Join new network
|
||||
if( m_network != null )
|
||||
{
|
||||
Iterator<IReceiver> it = m_channels.values().iterator();
|
||||
while( it.hasNext() )
|
||||
{
|
||||
m_network.addReceiver( it.next() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void switchNetwork()
|
||||
{
|
||||
setNetwork( getNetwork() );
|
||||
}
|
||||
|
||||
protected abstract World getWorld();
|
||||
|
||||
protected abstract Vec3 getPosition();
|
||||
|
||||
public synchronized void destroy()
|
||||
{
|
||||
setNetwork( null );
|
||||
m_channels.clear();
|
||||
m_open = false;
|
||||
}
|
||||
|
||||
public synchronized boolean pollChanged()
|
||||
{
|
||||
if( m_changed )
|
||||
{
|
||||
m_changed = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract double getTransmitRange();
|
||||
|
||||
protected abstract boolean isInterdimensional();
|
||||
|
||||
public synchronized boolean isActive()
|
||||
{
|
||||
return (m_computer != null) && m_open;
|
||||
}
|
||||
|
||||
public synchronized Vec3 getWorldPosition()
|
||||
{
|
||||
return getPosition();
|
||||
}
|
||||
|
||||
public synchronized double getReceiveRange()
|
||||
{
|
||||
return getTransmitRange();
|
||||
}
|
||||
|
||||
public void receiveSameDimension( int channel, int replyChannel, Object payload, double distance )
|
||||
{
|
||||
synchronized (m_channels)
|
||||
{
|
||||
if( m_computer != null && m_channels.containsKey( channel ) )
|
||||
{
|
||||
m_computer.queueEvent( "modem_message", new Object[] {
|
||||
m_computer.getAttachmentName(), channel, replyChannel, payload, distance
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void receiveDifferentDimension( int channel, int replyChannel, Object payload )
|
||||
{
|
||||
synchronized (m_channels)
|
||||
{
|
||||
if( m_computer != null && m_channels.containsKey( channel ) )
|
||||
{
|
||||
m_computer.queueEvent( "modem_message", new Object[] {
|
||||
m_computer.getAttachmentName(), channel, replyChannel, payload
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract INetwork getNetwork();
|
||||
|
||||
// IPeripheral implementation
|
||||
|
||||
@Override
|
||||
public String getType()
|
||||
{
|
||||
return "modem";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getMethodNames()
|
||||
{
|
||||
return new String[] {
|
||||
"open",
|
||||
"isOpen",
|
||||
"close",
|
||||
"closeAll",
|
||||
"transmit",
|
||||
"isWireless",
|
||||
};
|
||||
}
|
||||
|
||||
private static int parseChannel( Object[] arguments, int index ) throws LuaException
|
||||
{
|
||||
if( arguments.length <= index || !(arguments[index] instanceof Double) )
|
||||
{
|
||||
throw new LuaException( "Expected number" );
|
||||
}
|
||||
int channel = (int)((Double)arguments[index]).doubleValue();
|
||||
if( channel < 0 || channel > 65535 )
|
||||
{
|
||||
throw new LuaException( "Expected number in range 0-65535" );
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( IComputerAccess computer, ILuaContext context, int method, Object[] arguments ) throws LuaException, InterruptedException
|
||||
{
|
||||
switch( method )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// open
|
||||
int channel = parseChannel( arguments, 0 );
|
||||
synchronized( this )
|
||||
{
|
||||
if( !m_channels.containsKey( channel ) )
|
||||
{
|
||||
if( m_channels.size() >= 128 )
|
||||
{
|
||||
throw new LuaException( "Too many open channels" );
|
||||
}
|
||||
|
||||
IReceiver receiver = new SingleChannelReceiver( this, channel );
|
||||
m_channels.put( channel, receiver );
|
||||
if( m_network != null )
|
||||
{
|
||||
m_network.addReceiver( receiver );
|
||||
}
|
||||
if( !m_open )
|
||||
{
|
||||
m_open = true;
|
||||
m_changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
// isOpen
|
||||
int channel = parseChannel( arguments, 0 );
|
||||
synchronized( this )
|
||||
{
|
||||
boolean open = m_channels.containsKey( channel );
|
||||
return new Object[] { open };
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
// close
|
||||
int channel = parseChannel( arguments, 0 );
|
||||
synchronized( this )
|
||||
{
|
||||
if( m_channels.containsKey( channel ) )
|
||||
{
|
||||
IReceiver receiver = m_channels.get( channel );
|
||||
if( m_network != null )
|
||||
{
|
||||
m_network.removeReceiver( receiver );
|
||||
}
|
||||
m_channels.remove( channel );
|
||||
|
||||
if( m_channels.size() == 0 )
|
||||
{
|
||||
m_open = false;
|
||||
m_changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
// closeAll
|
||||
synchronized( this )
|
||||
{
|
||||
if( m_channels.size() > 0 )
|
||||
{
|
||||
if( m_network != null )
|
||||
{
|
||||
Iterator<IReceiver> it = m_channels.values().iterator();
|
||||
while( it.hasNext() )
|
||||
{
|
||||
m_network.removeReceiver( it.next() );
|
||||
}
|
||||
}
|
||||
m_channels.clear();
|
||||
|
||||
if( m_open )
|
||||
{
|
||||
m_open = false;
|
||||
m_changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
// transmit
|
||||
int channel = parseChannel( arguments, 0 );
|
||||
int replyChannel = parseChannel( arguments, 1 );
|
||||
Object payload = (arguments.length >= 3) ? arguments[2] : null;
|
||||
synchronized( this )
|
||||
{
|
||||
World world = getWorld();
|
||||
Vec3 position = getPosition();
|
||||
if( world != null && position != null && m_network != null)
|
||||
{
|
||||
m_network.transmit( channel, replyChannel, payload, world, position, getTransmitRange(), isInterdimensional(), this );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
// isWireless
|
||||
synchronized( this )
|
||||
{
|
||||
if( m_network != null )
|
||||
{
|
||||
return new Object[] { m_network.isWireless() };
|
||||
}
|
||||
}
|
||||
return new Object[] { false };
|
||||
}
|
||||
default:
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void attach( IComputerAccess computer )
|
||||
{
|
||||
m_computer = computer;
|
||||
setNetwork( getNetwork() );
|
||||
m_open = !m_channels.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void detach( IComputerAccess computer )
|
||||
{
|
||||
if( m_network != null )
|
||||
{
|
||||
Iterator<IReceiver> it = m_channels.values().iterator();
|
||||
while( it.hasNext() )
|
||||
{
|
||||
m_network.removeReceiver( it.next() );
|
||||
}
|
||||
m_channels.clear();
|
||||
m_network = null;
|
||||
}
|
||||
|
||||
m_computer = null;
|
||||
|
||||
if( m_open )
|
||||
{
|
||||
m_open = false;
|
||||
m_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract boolean equals( IPeripheral other );
|
||||
|
||||
public IComputerAccess getComputer()
|
||||
{
|
||||
return m_computer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.modem;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class TileAdvancedModem extends TileModemBase
|
||||
{
|
||||
// Statics
|
||||
|
||||
private static class Peripheral extends WirelessModemPeripheral
|
||||
{
|
||||
private TileModemBase m_entity;
|
||||
|
||||
public Peripheral( TileModemBase entity )
|
||||
{
|
||||
super( true );
|
||||
m_entity = entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld()
|
||||
{
|
||||
return m_entity.getWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Vec3 getPosition()
|
||||
{
|
||||
BlockPos pos = m_entity.getPos().offset( m_entity.getDirection() );
|
||||
return new Vec3( (double)pos.getX(), (double)pos.getY(), (double)pos.getZ() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( IPeripheral other )
|
||||
{
|
||||
if( other instanceof Peripheral )
|
||||
{
|
||||
Peripheral otherModem = (Peripheral)other;
|
||||
return otherModem.m_entity == m_entity;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Members
|
||||
|
||||
public TileAdvancedModem()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumFacing getDirection()
|
||||
{
|
||||
// Wireless Modem
|
||||
IBlockState state = getBlockState();
|
||||
return (EnumFacing)state.getValue( BlockPeripheral.Properties.FACING );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirection( EnumFacing dir )
|
||||
{
|
||||
// Wireless Modem
|
||||
setBlockState( getBlockState()
|
||||
.withProperty( BlockPeripheral.Properties.FACING, dir )
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ModemPeripheral createPeripheral()
|
||||
{
|
||||
return new Peripheral( this );
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.modem;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.shared.common.BlockGeneric;
|
||||
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
public abstract class TileModemBase extends TilePeripheralBase
|
||||
{
|
||||
protected ModemPeripheral m_modem;
|
||||
|
||||
protected TileModemBase()
|
||||
{
|
||||
m_modem = createPeripheral();
|
||||
}
|
||||
|
||||
protected abstract ModemPeripheral createPeripheral();
|
||||
|
||||
@Override
|
||||
public synchronized void destroy()
|
||||
{
|
||||
if( m_modem != null )
|
||||
{
|
||||
m_modem.destroy();
|
||||
m_modem = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSolidOnSide( int side )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighbourChange()
|
||||
{
|
||||
EnumFacing dir = getDirection();
|
||||
if( !worldObj.isSideSolid(
|
||||
getPos().offset( dir ),
|
||||
dir.getOpposite()
|
||||
) )
|
||||
{
|
||||
// Drop everything and remove block
|
||||
((BlockGeneric)getBlockType()).dropAllItems( worldObj, getPos(), 0, false, false );
|
||||
worldObj.setBlockToAir( getPos() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB getBounds()
|
||||
{
|
||||
switch( getDirection() )
|
||||
{
|
||||
case UP:
|
||||
default:
|
||||
{
|
||||
return new AxisAlignedBB( 0.125, 0.8125, 0.125, 0.875, 1.0, 0.875 );
|
||||
}
|
||||
case DOWN:
|
||||
{
|
||||
return new AxisAlignedBB( 0.125, 0.0, 0.125, 0.875, 0.1875, 0.875 );
|
||||
}
|
||||
case NORTH:
|
||||
{
|
||||
return new AxisAlignedBB( 0.125, 0.125, 0.0, 0.875, 0.875, 0.1875 );
|
||||
}
|
||||
case SOUTH:
|
||||
{
|
||||
return new AxisAlignedBB( 0.125, 0.125, 0.8125, 0.875, 0.875, 1.0 );
|
||||
}
|
||||
case WEST:
|
||||
{
|
||||
return new AxisAlignedBB( 0.0, 0.125, 0.125, 0.1875, 0.875, 0.875 );
|
||||
}
|
||||
case EAST:
|
||||
{
|
||||
return new AxisAlignedBB( 0.8125, 0.125, 0.125, 1.0, 0.875, 0.875 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
super.update();
|
||||
if( !worldObj.isRemote && m_modem.pollChanged() )
|
||||
{
|
||||
updateAnim();
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateAnim()
|
||||
{
|
||||
if( m_modem.isActive() )
|
||||
{
|
||||
setAnim(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
setAnim(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readDescription( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.readDescription( nbttagcompound );
|
||||
updateBlock();
|
||||
}
|
||||
|
||||
// IPeripheralTile implementation
|
||||
|
||||
@Override
|
||||
public IPeripheral getPeripheral( EnumFacing side )
|
||||
{
|
||||
if( side == getDirection() )
|
||||
{
|
||||
return m_modem;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean isAttached()
|
||||
{
|
||||
return (m_modem != null) && (m_modem.getComputer() != null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.modem;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
|
||||
import dan200.computercraft.shared.peripheral.common.BlockPeripheralVariant;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class TileWirelessModem extends TileModemBase
|
||||
{
|
||||
// Statics
|
||||
|
||||
private static class Peripheral extends WirelessModemPeripheral
|
||||
{
|
||||
private TileModemBase m_entity;
|
||||
|
||||
public Peripheral( TileModemBase entity )
|
||||
{
|
||||
super( false );
|
||||
m_entity = entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected World getWorld()
|
||||
{
|
||||
return m_entity.getWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Vec3 getPosition()
|
||||
{
|
||||
BlockPos pos = m_entity.getPos().offset( m_entity.getDirection() );
|
||||
return new Vec3( (double)pos.getX(), (double)pos.getY(), (double)pos.getZ() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( IPeripheral other )
|
||||
{
|
||||
if( other instanceof Peripheral )
|
||||
{
|
||||
Peripheral otherModem = (Peripheral)other;
|
||||
return otherModem.m_entity == m_entity;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Members
|
||||
|
||||
public TileWirelessModem()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumFacing getDirection()
|
||||
{
|
||||
// Wireless Modem
|
||||
IBlockState state = getBlockState();
|
||||
switch( (BlockPeripheralVariant)state.getValue( BlockPeripheral.Properties.VARIANT ) )
|
||||
{
|
||||
case WirelessModemDownOff:
|
||||
case WirelessModemDownOn:
|
||||
{
|
||||
return EnumFacing.DOWN;
|
||||
}
|
||||
case WirelessModemUpOff:
|
||||
case WirelessModemUpOn:
|
||||
{
|
||||
return EnumFacing.UP;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return (EnumFacing)state.getValue( BlockPeripheral.Properties.FACING );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirection( EnumFacing dir )
|
||||
{
|
||||
// Wireless Modem
|
||||
if( dir == EnumFacing.UP )
|
||||
{
|
||||
setBlockState( getBlockState()
|
||||
.withProperty( BlockPeripheral.Properties.VARIANT, BlockPeripheralVariant.WirelessModemUpOff )
|
||||
.withProperty( BlockPeripheral.Properties.FACING, EnumFacing.NORTH )
|
||||
);
|
||||
}
|
||||
else if( dir == EnumFacing.DOWN )
|
||||
{
|
||||
setBlockState( getBlockState()
|
||||
.withProperty( BlockPeripheral.Properties.VARIANT, BlockPeripheralVariant.WirelessModemDownOff )
|
||||
.withProperty( BlockPeripheral.Properties.FACING, EnumFacing.NORTH )
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
setBlockState( getBlockState()
|
||||
.withProperty( BlockPeripheral.Properties.VARIANT, BlockPeripheralVariant.WirelessModemOff )
|
||||
.withProperty( BlockPeripheral.Properties.FACING, dir )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ModemPeripheral createPeripheral()
|
||||
{
|
||||
return new Peripheral( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRefresh( World world, BlockPos pos, IBlockState oldState, IBlockState newState )
|
||||
{
|
||||
return super.shouldRefresh( world, pos, oldState, newState ) || ComputerCraft.Blocks.peripheral.getPeripheralType( newState ) != PeripheralType.WirelessModem;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.modem;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public abstract class WirelessModemPeripheral extends ModemPeripheral
|
||||
{
|
||||
private boolean m_advanced;
|
||||
|
||||
public WirelessModemPeripheral( boolean advanced )
|
||||
{
|
||||
m_advanced = advanced;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInterdimensional()
|
||||
{
|
||||
return m_advanced;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double getTransmitRange()
|
||||
{
|
||||
if( m_advanced )
|
||||
{
|
||||
return (double)Integer.MAX_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
World world = getWorld();
|
||||
if( world != null )
|
||||
{
|
||||
Vec3 position = getPosition();
|
||||
double minRange = (double) ComputerCraft.modem_range;
|
||||
double maxRange = (double) ComputerCraft.modem_highAltitudeRange;
|
||||
if( world.isRaining() && world.isThundering() )
|
||||
{
|
||||
minRange = (double) ComputerCraft.modem_rangeDuringStorm;
|
||||
maxRange = (double) ComputerCraft.modem_highAltitudeRangeDuringStorm;
|
||||
}
|
||||
if( position.yCoord > 96.0 && maxRange > minRange )
|
||||
{
|
||||
return minRange + ( position.yCoord - 96.0 ) * ( ( maxRange - minRange ) / ( ( world.getHeight() - 1 ) - 96.0 ) );
|
||||
}
|
||||
return minRange;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected INetwork getNetwork()
|
||||
{
|
||||
return WirelessNetwork.getUniversal();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.modem;
|
||||
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class WirelessNetwork implements INetwork
|
||||
{
|
||||
private static WirelessNetwork s_universalNetwork = null;
|
||||
|
||||
public static WirelessNetwork getUniversal()
|
||||
{
|
||||
if( s_universalNetwork == null )
|
||||
{
|
||||
s_universalNetwork = new WirelessNetwork();
|
||||
}
|
||||
return s_universalNetwork;
|
||||
}
|
||||
|
||||
public static void resetNetworks()
|
||||
{
|
||||
s_universalNetwork = null;
|
||||
}
|
||||
|
||||
private Map<Integer, Set<IReceiver>> m_receivers;
|
||||
|
||||
private WirelessNetwork()
|
||||
{
|
||||
m_receivers = new HashMap<Integer, Set<IReceiver>>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void addReceiver( IReceiver receiver )
|
||||
{
|
||||
int channel = receiver.getChannel();
|
||||
Set<IReceiver> receivers = m_receivers.get( channel );
|
||||
if( receivers == null )
|
||||
{
|
||||
receivers = new HashSet<IReceiver>();
|
||||
m_receivers.put( channel, receivers );
|
||||
}
|
||||
receivers.add( receiver );
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void removeReceiver( IReceiver receiver )
|
||||
{
|
||||
int channel = receiver.getChannel();
|
||||
Set<IReceiver> receivers = m_receivers.get( channel );
|
||||
if( receivers != null )
|
||||
{
|
||||
receivers.remove( receiver );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void transmit( int channel, int replyChannel, Object payload, World world, Vec3 pos, double range, boolean interdimensional, Object senderObject )
|
||||
{
|
||||
Set<IReceiver> receivers = m_receivers.get( channel );
|
||||
if( receivers != null )
|
||||
{
|
||||
Iterator<IReceiver> it = receivers.iterator();
|
||||
while( it.hasNext() )
|
||||
{
|
||||
IReceiver receiver = it.next();
|
||||
tryTransmit( receiver, replyChannel, payload, world, pos, range, interdimensional, senderObject );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void tryTransmit( IReceiver receiver, int replyChannel, Object payload, World world, Vec3 pos, double range, boolean interdimensional, Object senderObject )
|
||||
{
|
||||
if( receiver.getWorld() == world )
|
||||
{
|
||||
Vec3 position = receiver.getWorldPosition();
|
||||
double receiveRange = Math.max( range, receiver.getReceiveRange() ); // Ensure range is symmetrical
|
||||
double distanceSq = position.squareDistanceTo( pos );
|
||||
if( interdimensional || receiver.isInterdimensional() || distanceSq <= ( receiveRange * receiveRange ) )
|
||||
{
|
||||
receiver.receiveSameDimension( replyChannel, payload, Math.sqrt( distanceSq ), senderObject );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( interdimensional || receiver.isInterdimensional() )
|
||||
{
|
||||
receiver.receiveDifferentDimension( replyChannel, payload, senderObject );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWireless()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.monitor;
|
||||
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.core.terminal.Terminal;
|
||||
|
||||
public class MonitorPeripheral implements IPeripheral
|
||||
{
|
||||
private final TileMonitor m_monitor;
|
||||
|
||||
public MonitorPeripheral( TileMonitor monitor )
|
||||
{
|
||||
m_monitor = monitor;
|
||||
}
|
||||
|
||||
// IPeripheral implementation
|
||||
|
||||
@Override
|
||||
public String getType()
|
||||
{
|
||||
return "monitor";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getMethodNames()
|
||||
{
|
||||
return new String[] {
|
||||
"write",
|
||||
"scroll",
|
||||
"setCursorPos",
|
||||
"setCursorBlink",
|
||||
"getCursorPos",
|
||||
"getSize",
|
||||
"clear",
|
||||
"clearLine",
|
||||
"setTextScale",
|
||||
"setTextColour",
|
||||
"setTextColor",
|
||||
"setBackgroundColour",
|
||||
"setBackgroundColor",
|
||||
"isColour",
|
||||
"isColor",
|
||||
"getTextColour",
|
||||
"getTextColor",
|
||||
"getBackgroundColour",
|
||||
"getBackgroundColor",
|
||||
"blit"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( IComputerAccess computer, ILuaContext context, int method, Object args[] ) throws LuaException
|
||||
{
|
||||
switch( method )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// write
|
||||
String text;
|
||||
if( args.length > 0 && args[0] != null ) {
|
||||
text = args[0].toString();
|
||||
} else {
|
||||
text = "";
|
||||
}
|
||||
Terminal terminal = m_monitor.getTerminal().getTerminal();
|
||||
terminal.write( text );
|
||||
terminal.setCursorPos( terminal.getCursorX() + text.length(), terminal.getCursorY() );
|
||||
return null;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
// scroll
|
||||
if( args.length < 1 || !(args[0] instanceof Number) )
|
||||
{
|
||||
throw new LuaException( "Expected number" );
|
||||
}
|
||||
Terminal terminal = m_monitor.getTerminal().getTerminal();
|
||||
terminal.scroll( ((Number)(args[0])).intValue() );
|
||||
return null;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
// setCursorPos
|
||||
if( args.length < 2 || !(args[0] instanceof Number) || !(args[1] instanceof Number) )
|
||||
{
|
||||
throw new LuaException( "Expected number, number" );
|
||||
}
|
||||
int x = ((Number)args[0]).intValue() - 1;
|
||||
int y = ((Number)args[1]).intValue() - 1;
|
||||
Terminal terminal = m_monitor.getTerminal().getTerminal();
|
||||
terminal.setCursorPos( x, y );
|
||||
return null;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
// setCursorBlink
|
||||
if( args.length < 1 || !(args[0] instanceof Boolean) )
|
||||
{
|
||||
throw new LuaException( "Expected boolean" );
|
||||
}
|
||||
Terminal terminal = m_monitor.getTerminal().getTerminal();
|
||||
terminal.setCursorBlink( ((Boolean)args[0]).booleanValue() );
|
||||
return null;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
// getCursorPos
|
||||
Terminal terminal = m_monitor.getTerminal().getTerminal();
|
||||
return new Object[] {
|
||||
terminal.getCursorX() + 1,
|
||||
terminal.getCursorY() + 1
|
||||
};
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
// getSize
|
||||
Terminal terminal = m_monitor.getTerminal().getTerminal();
|
||||
return new Object[] {
|
||||
terminal.getWidth(),
|
||||
terminal.getHeight()
|
||||
};
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
// clear
|
||||
Terminal terminal = m_monitor.getTerminal().getTerminal();
|
||||
terminal.clear();
|
||||
return null;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
// clearLine
|
||||
Terminal terminal = m_monitor.getTerminal().getTerminal();
|
||||
terminal.clearLine();
|
||||
return null;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
// setTextScale
|
||||
if( args.length < 1 || !(args[0] instanceof Number) )
|
||||
{
|
||||
throw new LuaException( "Expected number" );
|
||||
}
|
||||
int scale = (int)(((Number)args[0]).doubleValue() * 2.0);
|
||||
if( scale < 1 || scale > 10 )
|
||||
{
|
||||
throw new LuaException( "Expected number in range 0.5-5" );
|
||||
}
|
||||
m_monitor.setTextScale( scale );
|
||||
return null;
|
||||
}
|
||||
case 9:
|
||||
case 10:
|
||||
{
|
||||
// setTextColour/setTextColor
|
||||
int colour = dan200.computercraft.core.apis.TermAPI.parseColour( args, m_monitor.getTerminal().isColour() );
|
||||
Terminal terminal = m_monitor.getTerminal().getTerminal();
|
||||
terminal.setTextColour( colour );
|
||||
return null;
|
||||
}
|
||||
case 11:
|
||||
case 12:
|
||||
{
|
||||
// setBackgroundColour/setBackgroundColor
|
||||
int colour = dan200.computercraft.core.apis.TermAPI.parseColour( args, m_monitor.getTerminal().isColour() );
|
||||
Terminal terminal = m_monitor.getTerminal().getTerminal();
|
||||
terminal.setBackgroundColour( colour );
|
||||
return null;
|
||||
}
|
||||
case 13:
|
||||
case 14:
|
||||
{
|
||||
// isColour/isColor
|
||||
return new Object[] {
|
||||
m_monitor.getTerminal().isColour()
|
||||
};
|
||||
}
|
||||
case 15:
|
||||
case 16:
|
||||
{
|
||||
// getTextColour/getTextColor
|
||||
Terminal terminal = m_monitor.getTerminal().getTerminal();
|
||||
return dan200.computercraft.core.apis.TermAPI.encodeColour( terminal.getTextColour() );
|
||||
}
|
||||
case 17:
|
||||
case 18:
|
||||
{
|
||||
// getBackgroundColour/getBackgroundColor
|
||||
Terminal terminal = m_monitor.getTerminal().getTerminal();
|
||||
return dan200.computercraft.core.apis.TermAPI.encodeColour( terminal.getBackgroundColour() );
|
||||
}
|
||||
case 19:
|
||||
{
|
||||
// blit
|
||||
if( args.length < 3 || !(args[0] instanceof String) || !(args[1] instanceof String) || !(args[2] instanceof String) )
|
||||
{
|
||||
throw new LuaException( "Expected string, string, string" );
|
||||
}
|
||||
|
||||
String text = (String)args[0];
|
||||
String textColour = (String)args[1];
|
||||
String backgroundColour = (String)args[2];
|
||||
if( textColour.length() != text.length() || backgroundColour.length() != text.length() )
|
||||
{
|
||||
throw new LuaException( "Arguments must be the same length" );
|
||||
}
|
||||
|
||||
Terminal terminal = m_monitor.getTerminal().getTerminal();
|
||||
terminal.blit( text, textColour, backgroundColour );
|
||||
terminal.setCursorPos( terminal.getCursorX() + text.length(), terminal.getCursorY() );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attach( IComputerAccess computer )
|
||||
{
|
||||
m_monitor.addComputer( computer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detach( IComputerAccess computer )
|
||||
{
|
||||
m_monitor.removeComputer( computer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( IPeripheral other )
|
||||
{
|
||||
if( other != null && other instanceof MonitorPeripheral )
|
||||
{
|
||||
MonitorPeripheral otherMonitor = (MonitorPeripheral)other;
|
||||
if( otherMonitor.m_monitor == this.m_monitor )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,865 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.monitor;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.core.terminal.Terminal;
|
||||
import dan200.computercraft.shared.common.ClientTerminal;
|
||||
import dan200.computercraft.shared.common.ITerminal;
|
||||
import dan200.computercraft.shared.common.ITerminalTile;
|
||||
import dan200.computercraft.shared.common.ServerTerminal;
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class TileMonitor extends TilePeripheralBase
|
||||
implements ITerminalTile
|
||||
{
|
||||
// Statics
|
||||
|
||||
public static final double RENDER_BORDER = (2.0 / 16.0);
|
||||
public static final double RENDER_MARGIN = (0.5 / 16.0);
|
||||
public static final double RENDER_PIXEL_SCALE = (1.0 / 64.0);
|
||||
|
||||
private static final int MAX_WIDTH = 8;
|
||||
private static final int MAX_HEIGHT = 6;
|
||||
|
||||
// Members
|
||||
|
||||
private ServerTerminal m_serverTerminal;
|
||||
private ClientTerminal m_clientTerminal;
|
||||
private final Set<IComputerAccess> m_computers;
|
||||
|
||||
public long m_lastRenderFrame = -1; // For rendering use only
|
||||
public int m_renderDisplayList = -1; // For rendering use only
|
||||
|
||||
private boolean m_destroyed;
|
||||
private boolean m_ignoreMe;
|
||||
private boolean m_changed;
|
||||
|
||||
private int m_textScale;
|
||||
private int m_width;
|
||||
private int m_height;
|
||||
private int m_xIndex;
|
||||
private int m_yIndex;
|
||||
|
||||
private int m_dir;
|
||||
private boolean m_sizeChangedQueued;
|
||||
|
||||
public TileMonitor()
|
||||
{
|
||||
m_computers = new HashSet<IComputerAccess>();
|
||||
|
||||
m_destroyed = false;
|
||||
m_ignoreMe = false;
|
||||
m_textScale = 2;
|
||||
|
||||
m_width = 1;
|
||||
m_height = 1;
|
||||
m_xIndex = 0;
|
||||
m_yIndex = 0;
|
||||
m_changed = false;
|
||||
|
||||
m_dir = 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
if( !m_destroyed )
|
||||
{
|
||||
m_destroyed = true;
|
||||
if( !worldObj.isRemote )
|
||||
{
|
||||
contractNeighbours();
|
||||
}
|
||||
}
|
||||
if( m_renderDisplayList >= 0 )
|
||||
{
|
||||
ComputerCraft.deleteDisplayLists( m_renderDisplayList, 3 );
|
||||
m_renderDisplayList = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActivate( EntityPlayer player, EnumFacing side, float hitX, float hitY, float hitZ )
|
||||
{
|
||||
if( !player.isSneaking() && getFront() == side )
|
||||
{
|
||||
if( !worldObj.isRemote )
|
||||
{
|
||||
monitorTouched( hitX, hitY, hitZ );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.writeToNBT(nbttagcompound);
|
||||
nbttagcompound.setInteger( "xIndex", m_xIndex );
|
||||
nbttagcompound.setInteger( "yIndex", m_yIndex );
|
||||
nbttagcompound.setInteger( "width", m_width );
|
||||
nbttagcompound.setInteger( "height", m_height );
|
||||
nbttagcompound.setInteger( "dir", m_dir );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.readFromNBT(nbttagcompound);
|
||||
m_xIndex = nbttagcompound.getInteger("xIndex");
|
||||
m_yIndex = nbttagcompound.getInteger("yIndex");
|
||||
m_width = nbttagcompound.getInteger("width");
|
||||
m_height = nbttagcompound.getInteger("height");
|
||||
m_dir = nbttagcompound.getInteger("dir");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
super.update();
|
||||
|
||||
if( !worldObj.isRemote )
|
||||
{
|
||||
if( m_sizeChangedQueued )
|
||||
{
|
||||
for( IComputerAccess computer : m_computers )
|
||||
{
|
||||
computer.queueEvent( "monitor_resize", new Object[] {
|
||||
computer.getAttachmentName()
|
||||
} );
|
||||
}
|
||||
m_sizeChangedQueued = false;
|
||||
}
|
||||
|
||||
if( m_serverTerminal != null )
|
||||
{
|
||||
m_serverTerminal.update();
|
||||
if( m_serverTerminal.hasTerminalChanged() )
|
||||
{
|
||||
updateBlock();
|
||||
}
|
||||
}
|
||||
|
||||
if( m_clientTerminal != null )
|
||||
{
|
||||
m_clientTerminal.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean pollChanged()
|
||||
{
|
||||
if( m_changed )
|
||||
{
|
||||
m_changed = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// IPeripheralTile implementation
|
||||
|
||||
@Override
|
||||
public IPeripheral getPeripheral( EnumFacing side )
|
||||
{
|
||||
return new MonitorPeripheral( this );
|
||||
}
|
||||
|
||||
public void setTextScale( int scale )
|
||||
{
|
||||
TileMonitor origin = getOrigin();
|
||||
if( origin != null )
|
||||
{
|
||||
synchronized( origin )
|
||||
{
|
||||
if( origin.m_textScale != scale )
|
||||
{
|
||||
origin.m_textScale = scale;
|
||||
origin.rebuildTerminal();
|
||||
origin.updateBlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Networking stuff
|
||||
|
||||
@Override
|
||||
public void writeDescription( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.writeDescription( nbttagcompound );
|
||||
nbttagcompound.setInteger( "xIndex", m_xIndex );
|
||||
nbttagcompound.setInteger( "yIndex", m_yIndex );
|
||||
nbttagcompound.setInteger( "width", m_width );
|
||||
nbttagcompound.setInteger( "height", m_height );
|
||||
nbttagcompound.setInteger( "textScale", m_textScale );
|
||||
nbttagcompound.setInteger( "monitorDir", m_dir );
|
||||
((ServerTerminal)getLocalTerminal()).writeDescription( nbttagcompound );
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readDescription( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.readDescription( nbttagcompound );
|
||||
|
||||
int oldXIndex = m_xIndex;
|
||||
int oldYIndex = m_yIndex;
|
||||
int oldWidth = m_width;
|
||||
int oldHeight = m_height;
|
||||
int oldTextScale = m_textScale;
|
||||
int oldDir = m_dir;
|
||||
|
||||
m_xIndex = nbttagcompound.getInteger( "xIndex" );
|
||||
m_yIndex = nbttagcompound.getInteger( "yIndex" );
|
||||
m_width = nbttagcompound.getInteger( "width" );
|
||||
m_height = nbttagcompound.getInteger( "height" );
|
||||
m_textScale = nbttagcompound.getInteger( "textScale" );
|
||||
m_dir = nbttagcompound.getInteger( "monitorDir" );
|
||||
((ClientTerminal)getLocalTerminal()).readDescription( nbttagcompound );
|
||||
m_changed = true;
|
||||
|
||||
if( oldXIndex != m_xIndex || oldYIndex != m_yIndex ||
|
||||
oldWidth != m_width || oldHeight != m_height ||
|
||||
oldTextScale != m_textScale || oldDir != m_dir )
|
||||
{
|
||||
updateBlock();
|
||||
}
|
||||
}
|
||||
|
||||
// ITerminalTile implementation
|
||||
|
||||
@Override
|
||||
public ITerminal getTerminal()
|
||||
{
|
||||
TileMonitor origin = getOrigin();
|
||||
if( origin != null )
|
||||
{
|
||||
return origin.getLocalTerminal();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ITerminal getLocalTerminal()
|
||||
{
|
||||
if( !worldObj.isRemote )
|
||||
{
|
||||
if( m_serverTerminal == null )
|
||||
{
|
||||
m_serverTerminal = new ServerTerminal(
|
||||
getPeripheralType() == PeripheralType.AdvancedMonitor
|
||||
);
|
||||
}
|
||||
return m_serverTerminal;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_clientTerminal == null )
|
||||
{
|
||||
m_clientTerminal = new ClientTerminal(
|
||||
getPeripheralType() == PeripheralType.AdvancedMonitor
|
||||
);
|
||||
}
|
||||
return m_clientTerminal;
|
||||
}
|
||||
}
|
||||
|
||||
// Sizing and placement stuff
|
||||
|
||||
public double getTextScale()
|
||||
{
|
||||
return (double)m_textScale * 0.5;
|
||||
}
|
||||
|
||||
private void rebuildTerminal()
|
||||
{
|
||||
Terminal oldTerm = getTerminal().getTerminal();
|
||||
int oldWidth = (oldTerm != null) ? oldTerm.getWidth() : -1;
|
||||
int oldHeight = (oldTerm != null) ? oldTerm.getHeight() : -1;
|
||||
|
||||
double textScale = getTextScale();
|
||||
int termWidth = (int)Math.max(
|
||||
Math.round( ((double)m_width - 2.0 * ( TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN )) / (textScale * 6.0 * TileMonitor.RENDER_PIXEL_SCALE) ),
|
||||
1.0
|
||||
);
|
||||
int termHeight = (int)Math.max(
|
||||
Math.round( ((double)m_height - 2.0 * ( TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN )) / (textScale * 9.0 * TileMonitor.RENDER_PIXEL_SCALE) ),
|
||||
1.0
|
||||
);
|
||||
((ServerTerminal)getLocalTerminal()).resize( termWidth, termHeight );
|
||||
|
||||
if( oldWidth != termWidth || oldHeight != termHeight )
|
||||
{
|
||||
getLocalTerminal().getTerminal().clear();
|
||||
for( int y=0; y<m_height; ++y )
|
||||
{
|
||||
for( int x=0; x<m_width; ++x )
|
||||
{
|
||||
TileMonitor monitor = getNeighbour( x, y );
|
||||
if( monitor != null )
|
||||
{
|
||||
monitor.queueSizeChangedEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void destroyTerminal()
|
||||
{
|
||||
((ServerTerminal)getLocalTerminal()).delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumFacing getDirection()
|
||||
{
|
||||
int dir = getDir() % 6;
|
||||
switch( dir ) {
|
||||
case 2: return EnumFacing.NORTH;
|
||||
case 3: return EnumFacing.SOUTH;
|
||||
case 4: return EnumFacing.WEST;
|
||||
case 5: return EnumFacing.EAST;
|
||||
}
|
||||
return EnumFacing.NORTH;
|
||||
}
|
||||
|
||||
public int getDir()
|
||||
{
|
||||
return m_dir;
|
||||
}
|
||||
|
||||
public void setDir( int dir )
|
||||
{
|
||||
m_dir = dir;
|
||||
m_changed = true;
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public EnumFacing getFront()
|
||||
{
|
||||
return m_dir <= 5 ? EnumFacing.getFront( m_dir ) : (m_dir <= 11 ? EnumFacing.DOWN : EnumFacing.UP);
|
||||
}
|
||||
|
||||
public EnumFacing getRight()
|
||||
{
|
||||
int dir = getDir() % 6;
|
||||
switch( dir ) {
|
||||
case 2: return EnumFacing.WEST;
|
||||
case 3: return EnumFacing.EAST;
|
||||
case 4: return EnumFacing.SOUTH;
|
||||
case 5: return EnumFacing.NORTH;
|
||||
}
|
||||
return EnumFacing.WEST;
|
||||
}
|
||||
|
||||
private EnumFacing getDown()
|
||||
{
|
||||
int dir = getDir();
|
||||
if (dir <= 5) return EnumFacing.UP;
|
||||
|
||||
switch( dir ) {
|
||||
// up facing
|
||||
case 8: return EnumFacing.NORTH;
|
||||
case 9: return EnumFacing.SOUTH;
|
||||
case 10: return EnumFacing.WEST;
|
||||
case 11: return EnumFacing.EAST;
|
||||
// down facing
|
||||
case 14: return EnumFacing.SOUTH;
|
||||
case 15: return EnumFacing.NORTH;
|
||||
case 16: return EnumFacing.EAST;
|
||||
case 17: return EnumFacing.WEST;
|
||||
}
|
||||
return EnumFacing.NORTH;
|
||||
}
|
||||
|
||||
public int getWidth()
|
||||
{
|
||||
return m_width;
|
||||
}
|
||||
|
||||
public int getHeight()
|
||||
{
|
||||
return m_height;
|
||||
}
|
||||
|
||||
public int getXIndex()
|
||||
{
|
||||
return m_xIndex;
|
||||
}
|
||||
|
||||
public int getYIndex()
|
||||
{
|
||||
return m_yIndex;
|
||||
}
|
||||
|
||||
private TileMonitor getSimilarMonitorAt( BlockPos pos )
|
||||
{
|
||||
if( pos.equals( getPos() ) )
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
int y = pos.getY();
|
||||
if( worldObj != null && y >= 0 && y < worldObj.getHeight() )
|
||||
{
|
||||
if( worldObj.isBlockLoaded( pos ) )
|
||||
{
|
||||
TileEntity tile = worldObj.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileMonitor )
|
||||
{
|
||||
TileMonitor monitor = (TileMonitor)tile;
|
||||
if( monitor.getDir() == getDir() &&
|
||||
monitor.getLocalTerminal().isColour() == getLocalTerminal().isColour() &&
|
||||
!monitor.m_destroyed && !monitor.m_ignoreMe )
|
||||
{
|
||||
return monitor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private TileMonitor getNeighbour( int x, int y )
|
||||
{
|
||||
BlockPos pos = getPos();
|
||||
EnumFacing right = getRight();
|
||||
EnumFacing down = getDown();
|
||||
int xOffset = -m_xIndex + x;
|
||||
int yOffset = -m_yIndex + y;
|
||||
return getSimilarMonitorAt(
|
||||
pos.offset( right, xOffset ).offset( down, yOffset )
|
||||
);
|
||||
}
|
||||
|
||||
public TileMonitor getOrigin()
|
||||
{
|
||||
return getNeighbour( 0, 0 );
|
||||
}
|
||||
|
||||
private void resize( int width, int height )
|
||||
{
|
||||
// Update the positions and indexes of the other monitors
|
||||
BlockPos pos = getPos();
|
||||
EnumFacing right = getRight();
|
||||
EnumFacing down = getDown();
|
||||
for( int y=0; y<height; ++y )
|
||||
{
|
||||
for( int x=0; x<width; ++x )
|
||||
{
|
||||
TileMonitor monitor = getSimilarMonitorAt(
|
||||
pos.offset( right, x ).offset( down, y )
|
||||
);
|
||||
if( monitor != null )
|
||||
{
|
||||
monitor.m_xIndex = x;
|
||||
monitor.m_yIndex = y;
|
||||
monitor.m_width = width;
|
||||
monitor.m_height = height;
|
||||
monitor.updateBlock();
|
||||
if( x != 0 || y != 0 )
|
||||
{
|
||||
monitor.destroyTerminal();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Rebuild this terminal (will invoke resize events)
|
||||
rebuildTerminal();
|
||||
}
|
||||
|
||||
private boolean mergeLeft()
|
||||
{
|
||||
TileMonitor left = getNeighbour( -1,0 );
|
||||
if( left != null && left.m_yIndex == 0 && left.m_height == m_height )
|
||||
{
|
||||
int width = left.m_width + m_width;
|
||||
if( width <= MAX_WIDTH )
|
||||
{
|
||||
TileMonitor origin = left.getOrigin();
|
||||
if( origin != null )
|
||||
{
|
||||
origin.resize( width, m_height );
|
||||
}
|
||||
left.expand();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean mergeRight()
|
||||
{
|
||||
TileMonitor right = getNeighbour( m_width,0 );
|
||||
if( right != null && right.m_yIndex == 0 && right.m_height == m_height )
|
||||
{
|
||||
int width = m_width + right.m_width;
|
||||
if( width <= MAX_WIDTH )
|
||||
{
|
||||
TileMonitor origin = getOrigin();
|
||||
if( origin != null )
|
||||
{
|
||||
origin.resize( width, m_height );
|
||||
}
|
||||
expand();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean mergeUp()
|
||||
{
|
||||
TileMonitor above = getNeighbour( 0,m_height );
|
||||
if( above != null && above.m_xIndex == 0 && above.m_width == m_width )
|
||||
{
|
||||
int height = above.m_height + m_height;
|
||||
if( height <= MAX_HEIGHT)
|
||||
{
|
||||
TileMonitor origin = getOrigin();
|
||||
if( origin != null )
|
||||
{
|
||||
origin.resize( m_width, height );
|
||||
}
|
||||
expand();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean mergeDown()
|
||||
{
|
||||
TileMonitor below = getNeighbour( 0,-1 );
|
||||
if( below != null && below.m_xIndex == 0 && below.m_width == m_width )
|
||||
{
|
||||
int height = m_height + below.m_height;
|
||||
if( height <= MAX_HEIGHT )
|
||||
{
|
||||
TileMonitor origin = below.getOrigin();
|
||||
if( origin != null )
|
||||
{
|
||||
origin.resize( m_width, height );
|
||||
}
|
||||
below.expand();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void expand()
|
||||
{
|
||||
while( mergeLeft() || mergeRight() || mergeUp() || mergeDown() ) {}
|
||||
}
|
||||
|
||||
public void contractNeighbours()
|
||||
{
|
||||
m_ignoreMe = true;
|
||||
if( m_xIndex > 0 ) {
|
||||
TileMonitor left = getNeighbour( m_xIndex - 1, m_yIndex );
|
||||
if( left != null ) {
|
||||
left.contract( );
|
||||
}
|
||||
}
|
||||
if( m_xIndex + 1 < m_width ) {
|
||||
TileMonitor right = getNeighbour( m_xIndex + 1, m_yIndex );
|
||||
if( right != null ) {
|
||||
right.contract();
|
||||
}
|
||||
}
|
||||
if( m_yIndex > 0 ) {
|
||||
TileMonitor below = getNeighbour( m_xIndex, m_yIndex - 1 );
|
||||
if( below != null ) {
|
||||
below.contract();
|
||||
}
|
||||
}
|
||||
if( m_yIndex + 1 < m_height ) {
|
||||
TileMonitor above = getNeighbour( m_xIndex, m_yIndex + 1 );
|
||||
if( above != null ) {
|
||||
above.contract();
|
||||
}
|
||||
}
|
||||
m_ignoreMe = false;
|
||||
}
|
||||
|
||||
public void contract()
|
||||
{
|
||||
int height = m_height;
|
||||
int width = m_width;
|
||||
|
||||
TileMonitor origin = getOrigin();
|
||||
if( origin == null )
|
||||
{
|
||||
TileMonitor right = null;
|
||||
TileMonitor below = null;
|
||||
if( width > 1 ) {
|
||||
right = getNeighbour( 1, 0 );
|
||||
}
|
||||
if( height > 1 ) {
|
||||
below = getNeighbour( 0, 1 );
|
||||
}
|
||||
if( right != null ) {
|
||||
right.resize( width - 1, 1 );
|
||||
}
|
||||
if( below != null ) {
|
||||
below.resize( width, height - 1 );
|
||||
}
|
||||
if( right != null ) {
|
||||
right.expand();
|
||||
}
|
||||
if( below != null ) {
|
||||
below.expand();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for( int y=0; y<height; ++y )
|
||||
{
|
||||
for( int x=0; x<width; ++x )
|
||||
{
|
||||
TileMonitor monitor = origin.getNeighbour( x, y );
|
||||
if( monitor == null )
|
||||
{
|
||||
// Decompose
|
||||
TileMonitor above = null;
|
||||
TileMonitor left = null;
|
||||
TileMonitor right = null;
|
||||
TileMonitor below = null;
|
||||
|
||||
if( y > 0 ) {
|
||||
above = origin;
|
||||
above.resize( width, y );
|
||||
}
|
||||
if( x > 0 ) {
|
||||
left = origin.getNeighbour( 0, y );
|
||||
left.resize( x, 1 );
|
||||
}
|
||||
if( x + 1 < width ) {
|
||||
right = origin.getNeighbour( x + 1, y );
|
||||
right.resize( width - (x + 1), 1 );
|
||||
}
|
||||
if( y + 1 < height ) {
|
||||
below = origin.getNeighbour( 0, y + 1 );
|
||||
below.resize( width, height - (y + 1) );
|
||||
}
|
||||
|
||||
// Re-expand
|
||||
if( above != null ) {
|
||||
above.expand();
|
||||
}
|
||||
if( left != null ) {
|
||||
left.expand();
|
||||
}
|
||||
if( right != null ) {
|
||||
right.expand();
|
||||
}
|
||||
if( below != null ) {
|
||||
below.expand();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void monitorTouched( float xPos, float yPos, float zPos )
|
||||
{
|
||||
int side = getDir();
|
||||
XYPair pair = convertToXY( xPos, yPos, zPos, side );
|
||||
pair = new XYPair( pair.x + m_xIndex, pair.y + m_height - m_yIndex - 1 );
|
||||
|
||||
if (pair.x > (m_width - RENDER_BORDER) || pair.y > (m_height - RENDER_BORDER) || pair.x < (RENDER_BORDER) || pair.y < (RENDER_BORDER))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Terminal originTerminal = getTerminal().getTerminal();
|
||||
if( originTerminal == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if( !getTerminal().isColour() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
double xCharWidth = ((double)m_width - ((RENDER_BORDER + RENDER_MARGIN) * 2.0)) / ((double)originTerminal.getWidth());
|
||||
double yCharHeight = ((double)m_height - ((RENDER_BORDER + RENDER_MARGIN) * 2.0)) / ((double)originTerminal.getHeight());
|
||||
|
||||
int xCharPos = (int)Math.min((double)originTerminal.getWidth(), Math.max(((pair.x - RENDER_BORDER - RENDER_MARGIN) / xCharWidth) + 1.0, 1.0));
|
||||
int yCharPos = (int)Math.min((double)originTerminal.getHeight(), Math.max(((pair.y - RENDER_BORDER - RENDER_MARGIN) / yCharHeight) + 1.0, 1.0));
|
||||
|
||||
for( int y=0; y<m_height; ++y )
|
||||
{
|
||||
for( int x=0; x<m_width; ++x )
|
||||
{
|
||||
TileMonitor monitor = getNeighbour( x, y );
|
||||
if( monitor != null )
|
||||
{
|
||||
monitor.queueTouchEvent(xCharPos, yCharPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void queueTouchEvent( int xCharPos, int yCharPos )
|
||||
{
|
||||
for( IComputerAccess computer : m_computers )
|
||||
{
|
||||
computer.queueEvent( "monitor_touch", new Object[] {
|
||||
computer.getAttachmentName(), xCharPos, yCharPos
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
private void queueSizeChangedEvent()
|
||||
{
|
||||
m_sizeChangedQueued = true;
|
||||
}
|
||||
|
||||
private XYPair convertToXY( float xPos, float yPos, float zPos, int side )
|
||||
{
|
||||
switch (side)
|
||||
{
|
||||
case 2:
|
||||
return new XYPair( 1 - xPos, 1 - yPos );
|
||||
case 3:
|
||||
return new XYPair( xPos, 1 - yPos );
|
||||
case 4:
|
||||
return new XYPair( zPos, 1 - yPos );
|
||||
case 5:
|
||||
return new XYPair( 1 - zPos, 1 - yPos );
|
||||
case 8:
|
||||
return new XYPair( 1 - xPos, zPos );
|
||||
case 9:
|
||||
return new XYPair( xPos, 1 - zPos );
|
||||
case 10:
|
||||
return new XYPair( zPos, xPos );
|
||||
case 11:
|
||||
return new XYPair( 1 - zPos, 1 - xPos );
|
||||
case 14:
|
||||
return new XYPair( 1 - xPos, 1 - zPos );
|
||||
case 15:
|
||||
return new XYPair( xPos, zPos );
|
||||
case 16:
|
||||
return new XYPair( zPos, 1 - xPos );
|
||||
case 17:
|
||||
return new XYPair( 1 - zPos, xPos );
|
||||
default:
|
||||
return new XYPair( xPos, zPos );
|
||||
}
|
||||
}
|
||||
|
||||
public void addComputer( IComputerAccess computer )
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
if( m_computers.size() == 0 )
|
||||
{
|
||||
TileMonitor origin = getOrigin();
|
||||
if( origin != null )
|
||||
{
|
||||
origin.rebuildTerminal();
|
||||
}
|
||||
}
|
||||
if( !m_computers.contains(computer) )
|
||||
{
|
||||
m_computers.add(computer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeComputer( IComputerAccess computer )
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
if( m_computers.contains(computer) )
|
||||
{
|
||||
m_computers.remove(computer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class XYPair
|
||||
{
|
||||
public final float x;
|
||||
public final float y;
|
||||
|
||||
private XYPair( float x, float y )
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB getRenderBoundingBox()
|
||||
{
|
||||
TileMonitor start = getNeighbour(0, 0);
|
||||
TileMonitor end = getNeighbour(m_width - 1, m_height - 1);
|
||||
if( start != null && end != null )
|
||||
{
|
||||
BlockPos startPos = start.getPos();
|
||||
BlockPos endPos = end.getPos();
|
||||
int minX = Math.min( startPos.getX(), endPos.getX() );
|
||||
int minY = Math.min( startPos.getY(), endPos.getY() );
|
||||
int minZ = Math.min( startPos.getZ(), endPos.getZ() );
|
||||
int maxX = Math.max( startPos.getX(), endPos.getX() ) + 1;
|
||||
int maxY = Math.max( startPos.getY(), endPos.getY() ) + 1;
|
||||
int maxZ = Math.max( startPos.getZ(), endPos.getZ() ) + 1;
|
||||
return new AxisAlignedBB( minX, minY, minZ, maxX, maxY, maxZ );
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockPos pos = this.getPos();
|
||||
return new AxisAlignedBB( pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRefresh( World world, BlockPos pos, IBlockState oldState, IBlockState newState )
|
||||
{
|
||||
if( super.shouldRefresh( world, pos, oldState, newState ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( ComputerCraft.Blocks.peripheral.getPeripheralType( newState ) )
|
||||
{
|
||||
case Monitor:
|
||||
case AdvancedMonitor:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.printer;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.ICrafting;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class ContainerPrinter extends Container
|
||||
{
|
||||
private TilePrinter m_printer;
|
||||
private boolean m_lastPrinting;
|
||||
|
||||
public ContainerPrinter( IInventory playerInventory, TilePrinter printer )
|
||||
{
|
||||
m_printer = printer;
|
||||
m_lastPrinting = false;
|
||||
|
||||
// Ink slot
|
||||
addSlotToContainer(new Slot( m_printer, 0, 13, 35));
|
||||
|
||||
// In-tray
|
||||
for( int i = 0; i < 6; ++i )
|
||||
{
|
||||
addSlotToContainer(new Slot( m_printer, i + 1, 61 + i * 18, 22));
|
||||
}
|
||||
|
||||
// Out-tray
|
||||
for( int i = 0; i < 6; ++i )
|
||||
{
|
||||
addSlotToContainer(new Slot( m_printer, i + 7, 61 + i * 18, 49));
|
||||
}
|
||||
|
||||
// Player inv
|
||||
for(int j = 0; j < 3; j++)
|
||||
{
|
||||
for(int i1 = 0; i1 < 9; i1++)
|
||||
{
|
||||
addSlotToContainer(new Slot(playerInventory, i1 + j * 9 + 9, 8 + i1 * 18, 84 + j * 18));
|
||||
}
|
||||
}
|
||||
|
||||
// Player hotbar
|
||||
for(int k = 0; k < 9; k++)
|
||||
{
|
||||
addSlotToContainer(new Slot(playerInventory, k, 8 + k * 18, 142));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPrinting()
|
||||
{
|
||||
return m_lastPrinting;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCraftGuiOpened( ICrafting crafting )
|
||||
{
|
||||
super.onCraftGuiOpened( crafting );
|
||||
crafting.sendProgressBarUpdate( this, 0, m_printer.isPrinting() ? 1 : 0 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detectAndSendChanges()
|
||||
{
|
||||
super.detectAndSendChanges();
|
||||
|
||||
if( !m_printer.getWorld().isRemote )
|
||||
{
|
||||
boolean printing = m_printer.isPrinting();
|
||||
for (int i=0; i<crafters.size(); ++i)
|
||||
{
|
||||
ICrafting icrafting = (ICrafting)crafters.get(i);
|
||||
if( printing != m_lastPrinting )
|
||||
{
|
||||
icrafting.sendProgressBarUpdate( this, 0, printing ? 1 : 0 );
|
||||
}
|
||||
}
|
||||
m_lastPrinting = printing;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProgressBar(int i, int j)
|
||||
{
|
||||
if( m_printer.getWorld().isRemote )
|
||||
{
|
||||
m_lastPrinting = (j > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInteractWith( EntityPlayer player )
|
||||
{
|
||||
return m_printer.isUseableByPlayer( player );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int i)
|
||||
{
|
||||
ItemStack itemstack = null;
|
||||
Slot slot = (Slot)inventorySlots.get(i);
|
||||
if( slot != null && slot.getHasStack() )
|
||||
{
|
||||
ItemStack itemstack1 = slot.getStack();
|
||||
itemstack = itemstack1.copy();
|
||||
if( i < 13 )
|
||||
{
|
||||
// Transfer from printer to inventory
|
||||
if(!mergeItemStack(itemstack1, 13, 49, true))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Transfer from inventory to printer
|
||||
if( itemstack1.getItem() == Items.dye )
|
||||
{
|
||||
if( !mergeItemStack(itemstack1, 0, 1, false) )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else //if is paper
|
||||
{
|
||||
if( !mergeItemStack(itemstack1, 1, 13, false) )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(itemstack1.stackSize == 0)
|
||||
{
|
||||
slot.putStack(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
slot.onSlotChanged();
|
||||
}
|
||||
|
||||
if(itemstack1.stackSize != itemstack.stackSize)
|
||||
{
|
||||
slot.onPickupFromSlot(par1EntityPlayer, itemstack1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return itemstack;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.printer;
|
||||
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.core.terminal.Terminal;
|
||||
|
||||
public class PrinterPeripheral implements IPeripheral
|
||||
{
|
||||
private final TilePrinter m_printer;
|
||||
|
||||
public PrinterPeripheral( TilePrinter printer )
|
||||
{
|
||||
m_printer = printer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType()
|
||||
{
|
||||
return "printer";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getMethodNames()
|
||||
{
|
||||
return new String[] {
|
||||
"write",
|
||||
"setCursorPos",
|
||||
"getCursorPos",
|
||||
"getPageSize",
|
||||
"newPage",
|
||||
"endPage",
|
||||
"getInkLevel",
|
||||
"setPageTitle",
|
||||
"getPaperLevel",
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( IComputerAccess computer, ILuaContext context, int method, Object[] args ) throws LuaException
|
||||
{
|
||||
switch( method )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// write
|
||||
String text;
|
||||
if( args.length > 0 && args[0] != null ) {
|
||||
text = args[0].toString();
|
||||
} else {
|
||||
text = "";
|
||||
}
|
||||
|
||||
Terminal page = getCurrentPage();
|
||||
page.write( text );
|
||||
page.setCursorPos( page.getCursorX() + text.length(), page.getCursorY() );
|
||||
return null;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
// setCursorPos
|
||||
if( args.length != 2 || args[0] == null || !(args[0] instanceof Number) || args[1] == null || !(args[1] instanceof Number) )
|
||||
{
|
||||
throw new LuaException( "Expected number, number" );
|
||||
}
|
||||
|
||||
int x = ((Number)args[0]).intValue() - 1;
|
||||
int y = ((Number)args[1]).intValue() - 1;
|
||||
Terminal page = getCurrentPage();
|
||||
page.setCursorPos( x, y );
|
||||
return null;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
// getCursorPos
|
||||
Terminal page = getCurrentPage();
|
||||
int x = page.getCursorX();
|
||||
int y = page.getCursorY();
|
||||
return new Object[] { x + 1, y + 1 };
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
// getPageSize
|
||||
Terminal page = getCurrentPage();
|
||||
int width = page.getWidth();
|
||||
int height = page.getHeight();
|
||||
return new Object[] { width, height };
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
// newPage
|
||||
return new Object[] { m_printer.startNewPage() };
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
// endPage
|
||||
getCurrentPage();
|
||||
return new Object[] { m_printer.endCurrentPage() };
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
// getInkLevel
|
||||
return new Object[] { m_printer.getInkLevel() };
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
// setPageTitle
|
||||
String title = "";
|
||||
if( args.length > 0 && args[0] != null )
|
||||
{
|
||||
if( !(args[0] instanceof String) )
|
||||
{
|
||||
throw new LuaException( "Expected string" );
|
||||
}
|
||||
title = (String)args[0];
|
||||
}
|
||||
|
||||
getCurrentPage();
|
||||
m_printer.setPageTitle( title );
|
||||
return null;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
// getPaperLevel
|
||||
return new Object[] { m_printer.getPaperLevel() };
|
||||
}
|
||||
default:
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attach( IComputerAccess computer )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detach( IComputerAccess computer )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( IPeripheral other )
|
||||
{
|
||||
if( other instanceof PrinterPeripheral )
|
||||
{
|
||||
PrinterPeripheral otherPrinter = (PrinterPeripheral)other;
|
||||
if( otherPrinter.m_printer == this.m_printer )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Terminal getCurrentPage() throws LuaException
|
||||
{
|
||||
Terminal currentPage = m_printer.getCurrentPage();
|
||||
if( currentPage == null )
|
||||
{
|
||||
throw new LuaException( "Page not started" );
|
||||
}
|
||||
return currentPage;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,597 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.printer;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.core.terminal.Terminal;
|
||||
import dan200.computercraft.shared.media.items.ItemPrintout;
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
|
||||
import dan200.computercraft.shared.util.InventoryUtil;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.ISidedInventory;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
|
||||
public class TilePrinter extends TilePeripheralBase
|
||||
implements IInventory, ISidedInventory
|
||||
{
|
||||
// Statics
|
||||
|
||||
private static final int[] bottomSlots = { 7, 8, 9, 10, 11, 12 };
|
||||
private static final int[] topSlots = { 1, 2, 3, 4, 5, 6 };
|
||||
private static final int[] sideSlots = { 0 };
|
||||
|
||||
// Members
|
||||
|
||||
private final ItemStack[] m_inventory;
|
||||
private final Terminal m_page;
|
||||
private String m_pageTitle;
|
||||
private boolean m_printing;
|
||||
|
||||
public TilePrinter()
|
||||
{
|
||||
m_inventory = new ItemStack[13];
|
||||
m_page = new Terminal( ItemPrintout.LINE_MAX_LENGTH, ItemPrintout.LINES_PER_PAGE );
|
||||
m_pageTitle = "";
|
||||
m_printing = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
ejectContents();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActivate( EntityPlayer player, EnumFacing side, float hitX, float hitY, float hitZ )
|
||||
{
|
||||
if( !player.isSneaking() )
|
||||
{
|
||||
if( !worldObj.isRemote )
|
||||
{
|
||||
ComputerCraft.openPrinterGUI( player, this );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound nbttagcompound)
|
||||
{
|
||||
super.readFromNBT(nbttagcompound);
|
||||
|
||||
// Read page
|
||||
synchronized( m_page )
|
||||
{
|
||||
m_printing = nbttagcompound.getBoolean( "printing" );
|
||||
m_pageTitle = nbttagcompound.getString( "pageTitle" );
|
||||
m_page.readFromNBT( nbttagcompound );
|
||||
}
|
||||
|
||||
// Read inventory
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
NBTTagList nbttaglist = nbttagcompound.getTagList( "Items", Constants.NBT.TAG_COMPOUND );
|
||||
for( int i=0; i<nbttaglist.tagCount(); ++i )
|
||||
{
|
||||
NBTTagCompound itemTag = nbttaglist.getCompoundTagAt( i );
|
||||
int j = itemTag.getByte("Slot") & 0xff;
|
||||
if (j >= 0 && j < m_inventory.length)
|
||||
{
|
||||
m_inventory[j] = ItemStack.loadItemStackFromNBT(itemTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT(NBTTagCompound nbttagcompound)
|
||||
{
|
||||
super.writeToNBT(nbttagcompound);
|
||||
|
||||
// Write page
|
||||
synchronized( m_page )
|
||||
{
|
||||
nbttagcompound.setBoolean( "printing", m_printing );
|
||||
nbttagcompound.setString( "pageTitle", m_pageTitle );
|
||||
m_page.writeToNBT( nbttagcompound );
|
||||
}
|
||||
|
||||
// Write inventory
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
NBTTagList nbttaglist = new NBTTagList();
|
||||
for(int i=0; i<m_inventory.length; ++i)
|
||||
{
|
||||
if (m_inventory[i] != null)
|
||||
{
|
||||
NBTTagCompound itemtag = new NBTTagCompound();
|
||||
itemtag.setByte("Slot", (byte)i);
|
||||
m_inventory[i].writeToNBT(itemtag);
|
||||
nbttaglist.appendTag(itemtag);
|
||||
}
|
||||
}
|
||||
nbttagcompound.setTag("Items", nbttaglist);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readDescription( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.readDescription( nbttagcompound );
|
||||
updateBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRefresh( World world, BlockPos pos, IBlockState oldState, IBlockState newState )
|
||||
{
|
||||
return super.shouldRefresh( world, pos, oldState, newState ) || ComputerCraft.Blocks.peripheral.getPeripheralType( newState ) != PeripheralType.Printer;
|
||||
}
|
||||
|
||||
public boolean isPrinting()
|
||||
{
|
||||
return m_printing;
|
||||
}
|
||||
|
||||
// IInventory implementation
|
||||
|
||||
@Override
|
||||
public int getSizeInventory()
|
||||
{
|
||||
return m_inventory.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int i)
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
return m_inventory[i];
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeStackFromSlot(int i)
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
ItemStack result = m_inventory[i];
|
||||
m_inventory[i] = null;
|
||||
updateAnim();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack decrStackSize(int i, int j)
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
if( m_inventory[i] == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if( m_inventory[i].stackSize <= j )
|
||||
{
|
||||
ItemStack itemstack = m_inventory[i];
|
||||
m_inventory[i] = null;
|
||||
markDirty();
|
||||
updateAnim();
|
||||
return itemstack;
|
||||
}
|
||||
|
||||
ItemStack part = m_inventory[i].splitStack(j);
|
||||
if( m_inventory[i].stackSize == 0 )
|
||||
{
|
||||
m_inventory[i] = null;
|
||||
updateAnim();
|
||||
}
|
||||
markDirty();
|
||||
return part;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInventorySlotContents( int i, ItemStack stack )
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
m_inventory[i] = stack;
|
||||
markDirty();
|
||||
updateAnim();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear()
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
for( int i=0; i<m_inventory.length; ++i )
|
||||
{
|
||||
m_inventory[i] = null;
|
||||
}
|
||||
markDirty();
|
||||
updateAnim();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCustomName()
|
||||
{
|
||||
return getLabel() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
String label = getLabel();
|
||||
if( label != null )
|
||||
{
|
||||
return label;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "tile.computercraft:printer.name";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IChatComponent getDisplayName()
|
||||
{
|
||||
if( hasCustomName() )
|
||||
{
|
||||
return new ChatComponentText( getName() );
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ChatComponentTranslation( getName() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInventoryStackLimit()
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openInventory( EntityPlayer player )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeInventory( EntityPlayer player )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValidForSlot( int slot, ItemStack itemstack )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseableByPlayer( EntityPlayer player )
|
||||
{
|
||||
return isUsable( player, false );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFieldCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getField(int id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setField(int id, int value)
|
||||
{
|
||||
}
|
||||
|
||||
// ISidedInventory implementation
|
||||
|
||||
@Override
|
||||
public int[] getSlotsForFace( EnumFacing side )
|
||||
{
|
||||
switch( side )
|
||||
{
|
||||
case DOWN: return bottomSlots; // Bottom (Out tray)
|
||||
case UP: return topSlots; // Top (In tray)
|
||||
default: return sideSlots; // Sides (Ink)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInsertItem( int slot, ItemStack itemstack, EnumFacing face )
|
||||
{
|
||||
return isItemValidForSlot( slot, itemstack );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExtractItem( int slot, ItemStack itemstack, EnumFacing face )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// IPeripheralTile implementation
|
||||
|
||||
@Override
|
||||
public IPeripheral getPeripheral( EnumFacing side )
|
||||
{
|
||||
return new PrinterPeripheral( this );
|
||||
}
|
||||
|
||||
public Terminal getCurrentPage()
|
||||
{
|
||||
if( m_printing )
|
||||
{
|
||||
return m_page;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean startNewPage()
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
if( canInputPage() )
|
||||
{
|
||||
if( m_printing && !outputPage() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if( inputPage() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean endCurrentPage()
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
if( m_printing && outputPage() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getInkLevel()
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
ItemStack inkStack = m_inventory[0];
|
||||
if( inkStack != null && isInk(inkStack) )
|
||||
{
|
||||
return inkStack.stackSize;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getPaperLevel()
|
||||
{
|
||||
int count = 0;
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
for( int i=1; i<7; ++i )
|
||||
{
|
||||
ItemStack paperStack = m_inventory[i];
|
||||
if( paperStack != null && isPaper(paperStack) )
|
||||
{
|
||||
count += paperStack.stackSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setPageTitle( String title )
|
||||
{
|
||||
if( m_printing )
|
||||
{
|
||||
m_pageTitle = title;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInk( ItemStack stack )
|
||||
{
|
||||
return (stack.getItem() == Items.dye);
|
||||
}
|
||||
|
||||
private boolean isPaper( ItemStack stack )
|
||||
{
|
||||
Item item = stack.getItem();
|
||||
return ( item == Items.paper || (item instanceof ItemPrintout && ItemPrintout.getType( stack ) == ItemPrintout.Type.Single) );
|
||||
}
|
||||
|
||||
private boolean canInputPage()
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
ItemStack inkStack = m_inventory[0];
|
||||
if( inkStack == null || !isInk(inkStack) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if( getPaperLevel() > 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean inputPage()
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
ItemStack inkStack = m_inventory[0];
|
||||
if( inkStack == null || !isInk(inkStack) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for( int i=1; i<7; ++i )
|
||||
{
|
||||
ItemStack paperStack = m_inventory[i];
|
||||
if( paperStack != null && isPaper(paperStack) )
|
||||
{
|
||||
// Decrement ink
|
||||
inkStack.stackSize--;
|
||||
if( inkStack.stackSize <= 0 )
|
||||
{
|
||||
m_inventory[0] = null;
|
||||
}
|
||||
|
||||
// Decrement paper
|
||||
paperStack.stackSize--;
|
||||
if( paperStack.stackSize <= 0 )
|
||||
{
|
||||
m_inventory[i] = null;
|
||||
updateAnim();
|
||||
}
|
||||
|
||||
// Setup the new page
|
||||
int colour = inkStack.getItemDamage();
|
||||
if( colour >= 0 && colour < 16 ) {
|
||||
m_page.setTextColour( 15 - colour );
|
||||
} else {
|
||||
m_page.setTextColour( 15 );
|
||||
}
|
||||
|
||||
m_page.clear();
|
||||
if( paperStack.getItem() instanceof ItemPrintout )
|
||||
{
|
||||
m_pageTitle = ItemPrintout.getTitle( paperStack );
|
||||
String[] text = ItemPrintout.getText( paperStack );
|
||||
String[] textColour = ItemPrintout.getColours( paperStack );
|
||||
for( int y=0; y<m_page.getHeight(); ++y )
|
||||
{
|
||||
m_page.setLine( y, text[y], textColour[y], "" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pageTitle = "";
|
||||
}
|
||||
m_page.setCursorPos( 0, 0 );
|
||||
|
||||
markDirty();
|
||||
m_printing = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean outputPage()
|
||||
{
|
||||
synchronized( m_page )
|
||||
{
|
||||
int height = m_page.getHeight();
|
||||
String[] lines = new String[height];
|
||||
String[] colours = new String[height];
|
||||
for( int i=0; i<height; ++i )
|
||||
{
|
||||
lines[i] = m_page.getLine(i).toString();
|
||||
colours[i] = m_page.getTextColourLine(i).toString();
|
||||
}
|
||||
|
||||
ItemStack stack = ItemPrintout.createSingleFromTitleAndText( m_pageTitle, lines, colours );
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
ItemStack remainder = InventoryUtil.storeItems( stack, this, 7, 6, 7 );
|
||||
if( remainder == null )
|
||||
{
|
||||
m_printing = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void ejectContents()
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
for( int i=0; i<13; ++i )
|
||||
{
|
||||
ItemStack stack = m_inventory[i];
|
||||
if( stack != null )
|
||||
{
|
||||
// Remove the stack from the inventory
|
||||
setInventorySlotContents( i, null );
|
||||
|
||||
// Spawn the item in the world
|
||||
BlockPos pos = getPos();
|
||||
double x = (double)pos.getX() + 0.5;
|
||||
double y = (double)pos.getY() + 0.75;
|
||||
double z = (double)pos.getZ() + 0.5;
|
||||
EntityItem entityitem = new EntityItem( worldObj, x, y, z, stack );
|
||||
entityitem.motionX = worldObj.rand.nextFloat() * 0.2 - 0.1;
|
||||
entityitem.motionY = worldObj.rand.nextFloat() * 0.2 - 0.1;
|
||||
entityitem.motionZ = worldObj.rand.nextFloat() * 0.2 - 0.1;
|
||||
worldObj.spawnEntityInWorld(entityitem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAnim()
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
int anim = 0;
|
||||
for( int i=1;i<7;++i )
|
||||
{
|
||||
ItemStack stack = m_inventory[i];
|
||||
if( stack != null && isPaper(stack) )
|
||||
{
|
||||
anim += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for( int i=7;i<13;++i )
|
||||
{
|
||||
ItemStack stack = m_inventory[i];
|
||||
if( stack != null && isPaper(stack) )
|
||||
{
|
||||
anim += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
setAnim( anim );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.pocket.apis;
|
||||
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.core.apis.ILuaAPI;
|
||||
|
||||
public class PocketAPI implements ILuaAPI
|
||||
{
|
||||
public PocketAPI()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getNames()
|
||||
{
|
||||
return new String[] {
|
||||
"pocket"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startup()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void advance( double dt )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getMethodNames()
|
||||
{
|
||||
return new String[] {
|
||||
// TODO: Add some methods
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( ILuaContext context, int method, Object[] arguments ) throws LuaException
|
||||
{
|
||||
// TODO: Add some methods
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,460 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.pocket.items;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.filesystem.IMount;
|
||||
import dan200.computercraft.api.media.IMedia;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.shared.computer.blocks.ComputerState;
|
||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||
import dan200.computercraft.shared.computer.items.IComputerItem;
|
||||
import dan200.computercraft.shared.pocket.apis.PocketAPI;
|
||||
import dan200.computercraft.shared.pocket.peripherals.PocketModemPeripheral;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
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.minecraft.util.StatCollector;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ItemPocketComputer extends Item implements IComputerItem, IMedia
|
||||
{
|
||||
public ItemPocketComputer()
|
||||
{
|
||||
setMaxStackSize( 1 );
|
||||
setHasSubtypes( true );
|
||||
setUnlocalizedName( "computercraft:pocket_computer" );
|
||||
setCreativeTab( ComputerCraft.mainCreativeTab );
|
||||
}
|
||||
|
||||
public ItemStack create( int id, String label, ComputerFamily family, boolean modem )
|
||||
{
|
||||
// Ignore types we can't handle
|
||||
if( family != ComputerFamily.Normal && family != ComputerFamily.Advanced )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Build the stack
|
||||
int damage = (family == ComputerFamily.Advanced) ? 1 : 0;
|
||||
ItemStack result = new ItemStack( this, 1, damage );
|
||||
if( id >= 0 || modem )
|
||||
{
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
if( id >= 0 )
|
||||
{
|
||||
compound.setInteger( "computerID", id );
|
||||
}
|
||||
if( modem )
|
||||
{
|
||||
compound.setInteger( "upgrade", 1 );
|
||||
}
|
||||
result.setTagCompound( compound );
|
||||
}
|
||||
if( label != null )
|
||||
{
|
||||
result.setStackDisplayName( label );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubItems( Item itemID, CreativeTabs tabs, List list )
|
||||
{
|
||||
list.add( PocketComputerItemFactory.create( -1, null, ComputerFamily.Normal, false ) );
|
||||
list.add( PocketComputerItemFactory.create( -1, null, ComputerFamily.Normal, true ) );
|
||||
list.add( PocketComputerItemFactory.create( -1, null, ComputerFamily.Advanced, false ) );
|
||||
list.add( PocketComputerItemFactory.create( -1, null, ComputerFamily.Advanced, true ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate( ItemStack stack, World world, Entity entity, int slotNum, boolean selected )
|
||||
{
|
||||
if( !world.isRemote )
|
||||
{
|
||||
// Server side
|
||||
IInventory inventory = (entity instanceof EntityPlayer) ? ((EntityPlayer)entity).inventory : null;
|
||||
ServerComputer computer = createServerComputer( world, inventory, stack );
|
||||
if( computer != null )
|
||||
{
|
||||
// Ping computer
|
||||
computer.keepAlive();
|
||||
computer.setWorld( world );
|
||||
|
||||
// Sync ID
|
||||
int id = computer.getID();
|
||||
if( id != getComputerID( stack ) )
|
||||
{
|
||||
setComputerID( stack, id );
|
||||
if( inventory != null )
|
||||
{
|
||||
inventory.markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
// Sync label
|
||||
String label = computer.getLabel();
|
||||
if( !Objects.equal( label, getLabel( stack ) ) )
|
||||
{
|
||||
setLabel( stack, label );
|
||||
if( inventory != null )
|
||||
{
|
||||
inventory.markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
// Update modem
|
||||
IPeripheral peripheral = computer.getPeripheral( 2 );
|
||||
if( peripheral != null && peripheral instanceof PocketModemPeripheral )
|
||||
{
|
||||
// Location
|
||||
PocketModemPeripheral modem = (PocketModemPeripheral)peripheral;
|
||||
if( entity instanceof EntityLivingBase )
|
||||
{
|
||||
EntityLivingBase player = (EntityLivingBase)entity;
|
||||
modem.setLocation( world, player.posX, player.posY + player.getEyeHeight(), player.posZ );
|
||||
}
|
||||
else
|
||||
{
|
||||
modem.setLocation( world, entity.posX, entity.posY, entity.posZ );
|
||||
}
|
||||
|
||||
// Light
|
||||
boolean modemLight = modem.isActive();
|
||||
NBTTagCompound modemNBT = computer.getUserData();
|
||||
if( modemNBT.getBoolean( "modemLight" ) != modemLight )
|
||||
{
|
||||
modemNBT.setBoolean( "modemLight", modemLight );
|
||||
computer.updateUserData();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Client side
|
||||
ClientComputer computer = createClientComputer( stack );
|
||||
if( computer != null )
|
||||
{
|
||||
// Todo: things here?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack onItemRightClick( ItemStack stack, World world, EntityPlayer player )
|
||||
{
|
||||
if( !world.isRemote )
|
||||
{
|
||||
ServerComputer computer = createServerComputer( world, player.inventory, stack );
|
||||
if( computer != null )
|
||||
{
|
||||
computer.turnOn();
|
||||
}
|
||||
ComputerCraft.openPocketComputerGUI( player );
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUnlocalizedName( ItemStack stack )
|
||||
{
|
||||
switch( getFamily( stack ) )
|
||||
{
|
||||
case Normal:
|
||||
default:
|
||||
{
|
||||
return "item.computercraft:pocket_computer";
|
||||
}
|
||||
case Advanced:
|
||||
{
|
||||
return "item.computercraft:advanced_pocket_computer";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getItemStackDisplayName( ItemStack stack )
|
||||
{
|
||||
String baseString = getUnlocalizedName( stack );
|
||||
boolean modem = getHasModem( stack );
|
||||
if( modem )
|
||||
{
|
||||
return StatCollector.translateToLocalFormatted(
|
||||
baseString + ".upgraded.name",
|
||||
StatCollector.translateToLocal( "upgrade.computercraft:wireless_modem.adjective" )
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return StatCollector.translateToLocal( baseString + ".name" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInformation( ItemStack stack, EntityPlayer player, List list, boolean debug )
|
||||
{
|
||||
if( debug )
|
||||
{
|
||||
int id = getComputerID( stack );
|
||||
if( id >= 0 )
|
||||
{
|
||||
list.add( "(Computer ID: " + id + ")" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ServerComputer createServerComputer( final World world, IInventory inventory, ItemStack stack )
|
||||
{
|
||||
if( world.isRemote )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ServerComputer computer;
|
||||
int instanceID = getInstanceID( stack );
|
||||
int sessionID = getSessionID( stack );
|
||||
int correctSessionID = ComputerCraft.serverComputerRegistry.getSessionID();
|
||||
|
||||
if( instanceID >= 0 && sessionID == correctSessionID &&
|
||||
ComputerCraft.serverComputerRegistry.contains( instanceID ) )
|
||||
{
|
||||
computer = ComputerCraft.serverComputerRegistry.get( instanceID );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( instanceID < 0 || sessionID != correctSessionID )
|
||||
{
|
||||
instanceID = ComputerCraft.serverComputerRegistry.getUnusedInstanceID();
|
||||
setInstanceID( stack, instanceID );
|
||||
setSessionID( stack, correctSessionID );
|
||||
}
|
||||
int computerID = getComputerID( stack );
|
||||
if( computerID < 0 )
|
||||
{
|
||||
computerID = ComputerCraft.createUniqueNumberedSaveDir( world, "computer" );
|
||||
setComputerID( stack, computerID );
|
||||
}
|
||||
computer = new ServerComputer(
|
||||
world,
|
||||
computerID,
|
||||
getLabel( stack ),
|
||||
instanceID,
|
||||
getFamily( stack ),
|
||||
ComputerCraft.terminalWidth_pocketComputer,
|
||||
ComputerCraft.terminalHeight_pocketComputer
|
||||
);
|
||||
computer.addAPI( new PocketAPI() );
|
||||
if( getHasModem( stack ) )
|
||||
{
|
||||
computer.setPeripheral( 2, new PocketModemPeripheral( false ) );
|
||||
}
|
||||
ComputerCraft.serverComputerRegistry.add( instanceID, computer );
|
||||
if( inventory != null )
|
||||
{
|
||||
inventory.markDirty();
|
||||
}
|
||||
}
|
||||
computer.setWorld( world );
|
||||
return computer;
|
||||
}
|
||||
|
||||
public ClientComputer createClientComputer( ItemStack stack )
|
||||
{
|
||||
int instanceID = getInstanceID( stack );
|
||||
if( instanceID >= 0 )
|
||||
{
|
||||
if( !ComputerCraft.clientComputerRegistry.contains( instanceID ) )
|
||||
{
|
||||
ComputerCraft.clientComputerRegistry.add( instanceID, new ClientComputer( instanceID ) );
|
||||
}
|
||||
return ComputerCraft.clientComputerRegistry.get( instanceID );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ClientComputer getClientComputer( ItemStack stack )
|
||||
{
|
||||
int instanceID = getInstanceID( stack );
|
||||
if( instanceID >= 0 )
|
||||
{
|
||||
return ComputerCraft.clientComputerRegistry.get( instanceID );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// IComputerItem implementation
|
||||
|
||||
@Override
|
||||
public int getComputerID( ItemStack stack )
|
||||
{
|
||||
NBTTagCompound compound = stack.getTagCompound();
|
||||
if( compound != null && compound.hasKey( "computerID" ) )
|
||||
{
|
||||
return compound.getInteger( "computerID" );
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void setComputerID( ItemStack stack, int computerID )
|
||||
{
|
||||
if( !stack.hasTagCompound() )
|
||||
{
|
||||
stack.setTagCompound( new NBTTagCompound() );
|
||||
}
|
||||
stack.getTagCompound().setInteger( "computerID", computerID );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel( ItemStack stack )
|
||||
{
|
||||
if( stack.hasDisplayName() )
|
||||
{
|
||||
return stack.getDisplayName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComputerFamily getFamily( ItemStack stack )
|
||||
{
|
||||
int damage = stack.getItemDamage();
|
||||
switch( damage )
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
{
|
||||
return ComputerFamily.Normal;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
return ComputerFamily.Advanced;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IMedia
|
||||
|
||||
@Override
|
||||
public boolean setLabel( ItemStack stack, String label )
|
||||
{
|
||||
if( label != null )
|
||||
{
|
||||
stack.setStackDisplayName( label );
|
||||
}
|
||||
else
|
||||
{
|
||||
stack.clearCustomName();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAudioTitle( ItemStack stack )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAudioRecordName( ItemStack stack )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMount createDataMount( ItemStack stack, World world )
|
||||
{
|
||||
ServerComputer computer = createServerComputer( world, null, stack );
|
||||
if( computer != null )
|
||||
{
|
||||
return computer.getRootMount();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private int getInstanceID( ItemStack stack )
|
||||
{
|
||||
NBTTagCompound compound = stack.getTagCompound();
|
||||
if( compound != null && compound.hasKey( "instanceID" ) )
|
||||
{
|
||||
return compound.getInteger( "instanceID" );
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void setInstanceID( ItemStack stack, int instanceID )
|
||||
{
|
||||
if( !stack.hasTagCompound() )
|
||||
{
|
||||
stack.setTagCompound( new NBTTagCompound() );
|
||||
}
|
||||
stack.getTagCompound().setInteger( "instanceID", instanceID );
|
||||
}
|
||||
|
||||
private int getSessionID( ItemStack stack )
|
||||
{
|
||||
NBTTagCompound compound = stack.getTagCompound();
|
||||
if( compound != null && compound.hasKey( "sessionID" ) )
|
||||
{
|
||||
return compound.getInteger( "sessionID" );
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void setSessionID( ItemStack stack, int sessionID )
|
||||
{
|
||||
if( !stack.hasTagCompound() )
|
||||
{
|
||||
stack.setTagCompound( new NBTTagCompound() );
|
||||
}
|
||||
stack.getTagCompound().setInteger( "sessionID", sessionID );
|
||||
}
|
||||
|
||||
public ComputerState getState( ItemStack stack )
|
||||
{
|
||||
ClientComputer computer = getClientComputer( stack );
|
||||
if( computer != null && computer.isOn() )
|
||||
{
|
||||
return computer.isCursorDisplayed() ? ComputerState.Blinking : ComputerState.On;
|
||||
}
|
||||
return ComputerState.Off;
|
||||
}
|
||||
|
||||
public boolean getModemState( ItemStack stack )
|
||||
{
|
||||
ClientComputer computer = getClientComputer( stack );
|
||||
if( computer != null && computer.isOn() )
|
||||
{
|
||||
NBTTagCompound computerNBT = computer.getUserData();
|
||||
if( computerNBT != null && computerNBT.getBoolean( "modemLight" ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean getHasModem( ItemStack stack )
|
||||
{
|
||||
NBTTagCompound compound = stack.getTagCompound();
|
||||
if( compound != null && compound.hasKey( "upgrade" ) )
|
||||
{
|
||||
return (compound.getInteger( "upgrade" ) == 1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.pocket.items;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class PocketComputerItemFactory
|
||||
{
|
||||
public static ItemStack create( int id, String label, ComputerFamily family, boolean modem )
|
||||
{
|
||||
ItemPocketComputer computer = ComputerCraft.Items.pocketComputer;
|
||||
switch( family )
|
||||
{
|
||||
case Normal:
|
||||
case Advanced:
|
||||
{
|
||||
return computer.create( id, label, family, modem );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package dan200.computercraft.shared.pocket.peripherals;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.shared.peripheral.modem.WirelessModemPeripheral;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
public class PocketModemPeripheral extends WirelessModemPeripheral
|
||||
{
|
||||
private World m_world;
|
||||
private Vec3 m_position;
|
||||
|
||||
public PocketModemPeripheral( boolean advanced )
|
||||
{
|
||||
super( advanced );
|
||||
m_world = null;
|
||||
m_position = new Vec3( 0.0, 0.0, 0.0 );
|
||||
}
|
||||
|
||||
public void setLocation( World world, double x, double y, double z )
|
||||
{
|
||||
m_position = new Vec3( x, y, z );
|
||||
if( m_world != world )
|
||||
{
|
||||
m_world = world;
|
||||
switchNetwork();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected World getWorld()
|
||||
{
|
||||
return m_world;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Vec3 getPosition()
|
||||
{
|
||||
if( m_world != null )
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( IPeripheral other )
|
||||
{
|
||||
if( other instanceof PocketModemPeripheral )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.pocket.recipes;
|
||||
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import dan200.computercraft.shared.peripheral.common.IPeripheralItem;
|
||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
||||
import dan200.computercraft.shared.pocket.items.PocketComputerItemFactory;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class PocketComputerUpgradeRecipe implements IRecipe
|
||||
{
|
||||
public PocketComputerUpgradeRecipe()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRecipeSize()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getRecipeOutput()
|
||||
{
|
||||
return PocketComputerItemFactory.create( -1, null, ComputerFamily.Normal, true );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches( InventoryCrafting inventory, World world )
|
||||
{
|
||||
return (getCraftingResult( inventory ) != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getCraftingResult( InventoryCrafting inventory )
|
||||
{
|
||||
// Scan the grid for a pocket computer
|
||||
ItemStack computer = null;
|
||||
int computerX = -1;
|
||||
int computerY = -1;
|
||||
for( int y=0; y<inventory.getHeight(); ++y )
|
||||
{
|
||||
for( int x=0; x<inventory.getWidth(); ++x )
|
||||
{
|
||||
ItemStack item = inventory.getStackInRowAndColumn( x, y );
|
||||
if( item != null && item.getItem() instanceof ItemPocketComputer )
|
||||
{
|
||||
computer = item;
|
||||
computerX = x;
|
||||
computerY = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( computer != null )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( computer == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check for upgrades around the item
|
||||
ItemStack upgrade = null;
|
||||
for( int y=0; y<inventory.getHeight(); ++y )
|
||||
{
|
||||
for( int x=0; x<inventory.getWidth(); ++x )
|
||||
{
|
||||
ItemStack item = inventory.getStackInRowAndColumn( x, y );
|
||||
if( x == computerX && y == computerY )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if( x == computerX && y == computerY - 1 )
|
||||
{
|
||||
if( item != null && item.getItem() instanceof IPeripheralItem &&
|
||||
((IPeripheralItem)item.getItem()).getPeripheralType( item ) == PeripheralType.WirelessModem )
|
||||
{
|
||||
upgrade = item;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( item != null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( upgrade == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// At this point we have a computer + 1 upgrade
|
||||
ItemPocketComputer itemComputer = (ItemPocketComputer)computer.getItem();
|
||||
if( itemComputer.getHasModem( computer ) )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Construct the new stack
|
||||
ComputerFamily family = itemComputer.getFamily( computer );
|
||||
int computerID = itemComputer.getComputerID( computer );
|
||||
String label = itemComputer.getLabel( computer );
|
||||
return PocketComputerItemFactory.create( computerID, label, family, true );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack[] getRemainingItems( InventoryCrafting inventoryCrafting )
|
||||
{
|
||||
ItemStack[] results = new ItemStack[ inventoryCrafting.getSizeInventory() ];
|
||||
for (int i = 0; i < results.length; ++i)
|
||||
{
|
||||
ItemStack stack = inventoryCrafting.getStackInSlot(i);
|
||||
results[i] = net.minecraftforge.common.ForgeHooks.getContainerItem(stack);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,449 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.proxy;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.api.turtle.TurtleUpgradeType;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.items.ComputerItemFactory;
|
||||
import dan200.computercraft.shared.turtle.blocks.BlockTurtle;
|
||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||
import dan200.computercraft.shared.turtle.blocks.TileTurtleAdvanced;
|
||||
import dan200.computercraft.shared.turtle.blocks.TileTurtleExpanded;
|
||||
import dan200.computercraft.shared.turtle.items.ItemTurtleAdvanced;
|
||||
import dan200.computercraft.shared.turtle.items.ItemTurtleLegacy;
|
||||
import dan200.computercraft.shared.turtle.items.ItemTurtleNormal;
|
||||
import dan200.computercraft.shared.turtle.items.TurtleItemFactory;
|
||||
import dan200.computercraft.shared.turtle.recipes.TurtleRecipe;
|
||||
import dan200.computercraft.shared.turtle.recipes.TurtleUpgradeRecipe;
|
||||
import dan200.computercraft.shared.turtle.upgrades.*;
|
||||
import dan200.computercraft.shared.util.IEntityDropConsumer;
|
||||
import dan200.computercraft.shared.util.ImpostorRecipe;
|
||||
import dan200.computercraft.shared.util.InventoryUtil;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.CraftingManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.living.LivingDropsEvent;
|
||||
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import net.minecraftforge.oredict.RecipeSorter;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public abstract class CCTurtleProxyCommon implements ICCTurtleProxy
|
||||
{
|
||||
private Map<Integer, ITurtleUpgrade> m_legacyTurtleUpgrades;
|
||||
private Map<String, ITurtleUpgrade> m_turtleUpgrades;
|
||||
private Map<Entity, IEntityDropConsumer> m_dropConsumers;
|
||||
|
||||
public CCTurtleProxyCommon()
|
||||
{
|
||||
m_legacyTurtleUpgrades = new HashMap<Integer, ITurtleUpgrade>();
|
||||
m_turtleUpgrades = new HashMap<String, ITurtleUpgrade>();
|
||||
m_dropConsumers = new WeakHashMap<Entity, IEntityDropConsumer>();
|
||||
}
|
||||
|
||||
// ICCTurtleProxy implementation
|
||||
|
||||
@Override
|
||||
public void preInit()
|
||||
{
|
||||
registerItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
registerForgeHandlers();
|
||||
registerTileEntities();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerTurtleUpgrade( ITurtleUpgrade upgrade )
|
||||
{
|
||||
// Check conditions
|
||||
int id = upgrade.getLegacyUpgradeID();
|
||||
if( id >= 0 && id < 64 )
|
||||
{
|
||||
throw new RuntimeException( "Error registering '"+upgrade.getUnlocalisedAdjective()+" Turtle'. Legacy UpgradeID '"+id+"' is reserved by ComputerCraft" );
|
||||
}
|
||||
|
||||
// Register
|
||||
registerTurtleUpgradeInternal( upgrade );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITurtleUpgrade getTurtleUpgrade( String id )
|
||||
{
|
||||
return m_turtleUpgrades.get( id );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITurtleUpgrade getTurtleUpgrade( int legacyId )
|
||||
{
|
||||
return m_legacyTurtleUpgrades.get( legacyId );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITurtleUpgrade getTurtleUpgrade( ItemStack stack )
|
||||
{
|
||||
for( ITurtleUpgrade upgrade : m_turtleUpgrades.values() )
|
||||
{
|
||||
try
|
||||
{
|
||||
ItemStack upgradeStack = upgrade.getCraftingItem();
|
||||
if( InventoryUtil.areItemsStackable( upgradeStack, stack ) )
|
||||
{
|
||||
return upgrade;
|
||||
}
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isUpgradeVanilla( ITurtleUpgrade upgrade )
|
||||
{
|
||||
return upgrade instanceof TurtleTool || upgrade instanceof TurtleModem || upgrade instanceof TurtleCraftingTable;
|
||||
}
|
||||
|
||||
public static boolean isUpgradeSuitableForFamily( ComputerFamily family, ITurtleUpgrade upgrade )
|
||||
{
|
||||
if( family == ComputerFamily.Beginners )
|
||||
{
|
||||
return upgrade.getType() == TurtleUpgradeType.Tool;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void addAllUpgradedTurtles( ComputerFamily family, List<ItemStack> list )
|
||||
{
|
||||
ItemStack basicStack = TurtleItemFactory.create( -1, null, null, family, null, null, 0, null );
|
||||
if( basicStack != null )
|
||||
{
|
||||
list.add( basicStack );
|
||||
}
|
||||
addUpgradedTurtle( family, ComputerCraft.Upgrades.diamondPickaxe, list );
|
||||
addUpgradedTurtle( family, ComputerCraft.Upgrades.diamondAxe, list );
|
||||
addUpgradedTurtle( family, ComputerCraft.Upgrades.diamondSword, list );
|
||||
addUpgradedTurtle( family, ComputerCraft.Upgrades.diamondShovel, list );
|
||||
addUpgradedTurtle( family, ComputerCraft.Upgrades.diamondHoe, list );
|
||||
addUpgradedTurtle( family, ComputerCraft.Upgrades.craftingTable, list );
|
||||
addUpgradedTurtle( family, ComputerCraft.Upgrades.wirelessModem, list );
|
||||
addUpgradedTurtle( family, ComputerCraft.Upgrades.advancedModem, list );
|
||||
}
|
||||
|
||||
private void addUpgradedTurtle( ComputerFamily family, ITurtleUpgrade upgrade, List<ItemStack> list )
|
||||
{
|
||||
if ( isUpgradeSuitableForFamily( family, upgrade ) )
|
||||
{
|
||||
ItemStack stack = TurtleItemFactory.create( -1, null, null, family, upgrade, null, 0, null );
|
||||
if( stack != null )
|
||||
{
|
||||
list.add( stack );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAllUpgradedTurtles( List<ItemStack> list )
|
||||
{
|
||||
addAllUpgradedTurtles( ComputerFamily.Normal, list );
|
||||
addAllUpgradedTurtles( ComputerFamily.Advanced, list );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEntityDropConsumer( Entity entity, IEntityDropConsumer consumer )
|
||||
{
|
||||
if( !m_dropConsumers.containsKey( entity ) )
|
||||
{
|
||||
boolean captured = ObfuscationReflectionHelper.<Boolean, Entity>getPrivateValue(
|
||||
Entity.class,
|
||||
entity,
|
||||
"captureDrops"
|
||||
).booleanValue();
|
||||
|
||||
if( !captured )
|
||||
{
|
||||
ObfuscationReflectionHelper.setPrivateValue(
|
||||
Entity.class,
|
||||
entity,
|
||||
new Boolean( true ),
|
||||
"captureDrops"
|
||||
);
|
||||
|
||||
ArrayList<EntityItem> items = ObfuscationReflectionHelper.getPrivateValue(
|
||||
Entity.class,
|
||||
entity,
|
||||
"capturedDrops"
|
||||
);
|
||||
|
||||
if( items == null || items.size() == 0 )
|
||||
{
|
||||
m_dropConsumers.put( entity, consumer );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearEntityDropConsumer( Entity entity )
|
||||
{
|
||||
if( m_dropConsumers.containsKey( entity ) )
|
||||
{
|
||||
boolean captured = ObfuscationReflectionHelper.<Boolean, Entity>getPrivateValue(
|
||||
Entity.class,
|
||||
entity,
|
||||
"captureDrops"
|
||||
);
|
||||
|
||||
if( captured )
|
||||
{
|
||||
ObfuscationReflectionHelper.setPrivateValue(
|
||||
Entity.class,
|
||||
entity,
|
||||
new Boolean( false ),
|
||||
"captureDrops"
|
||||
);
|
||||
|
||||
ArrayList<EntityItem> items = ObfuscationReflectionHelper.getPrivateValue(
|
||||
Entity.class,
|
||||
entity,
|
||||
"capturedDrops"
|
||||
);
|
||||
|
||||
if( items != null )
|
||||
{
|
||||
dispatchEntityDrops( entity, items );
|
||||
items.clear();
|
||||
}
|
||||
}
|
||||
m_dropConsumers.remove( entity );
|
||||
}
|
||||
}
|
||||
|
||||
private void registerTurtleUpgradeInternal( ITurtleUpgrade upgrade )
|
||||
{
|
||||
// Check conditions
|
||||
int legacyID = upgrade.getLegacyUpgradeID();
|
||||
if( legacyID >= 0 )
|
||||
{
|
||||
if( legacyID >= Short.MAX_VALUE )
|
||||
{
|
||||
throw new RuntimeException( "Error registering '"+upgrade.getUnlocalisedAdjective()+" Turtle'. UpgradeID '"+legacyID+"' is out of range" );
|
||||
}
|
||||
|
||||
ITurtleUpgrade existing = m_legacyTurtleUpgrades.get( legacyID );
|
||||
if( existing != null )
|
||||
{
|
||||
throw new RuntimeException( "Error registering '" + upgrade.getUnlocalisedAdjective() + " Turtle'. UpgradeID '" + legacyID + "' is already registered by '" + existing.getUnlocalisedAdjective() + " Turtle'" );
|
||||
}
|
||||
}
|
||||
|
||||
String id = upgrade.getUpgradeID().toString();
|
||||
ITurtleUpgrade existing = m_turtleUpgrades.get( id );
|
||||
if( existing != null )
|
||||
{
|
||||
throw new RuntimeException( "Error registering '" + upgrade.getUnlocalisedAdjective() + " Turtle'. UpgradeID '" + id + "' is already registered by '" + existing.getUnlocalisedAdjective() + " Turtle'" );
|
||||
}
|
||||
|
||||
// Register
|
||||
if( legacyID >= 0 )
|
||||
{
|
||||
m_legacyTurtleUpgrades.put( legacyID, upgrade );
|
||||
}
|
||||
m_turtleUpgrades.put( id, upgrade );
|
||||
|
||||
// Add a bunch of impostor recipes
|
||||
if( isUpgradeVanilla( upgrade ) )
|
||||
{
|
||||
// Add fake recipes to fool NEI
|
||||
List recipeList = CraftingManager.getInstance().getRecipeList();
|
||||
ItemStack craftingItem = upgrade.getCraftingItem();
|
||||
|
||||
// A turtle just containing this upgrade
|
||||
for( ComputerFamily family : ComputerFamily.values() )
|
||||
{
|
||||
if( !isUpgradeSuitableForFamily( family, upgrade ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ItemStack baseTurtle = TurtleItemFactory.create( -1, null, null, family, null, null, 0, null );
|
||||
if( baseTurtle != null )
|
||||
{
|
||||
ItemStack craftedTurtle = TurtleItemFactory.create( -1, null, null, family, upgrade, null, 0, null );
|
||||
ItemStack craftedTurtleFlipped = TurtleItemFactory.create( -1, null, null, family, null, upgrade, 0, null );
|
||||
recipeList.add( new ImpostorRecipe( 2, 1, new ItemStack[] { baseTurtle, craftingItem }, craftedTurtle ) );
|
||||
recipeList.add( new ImpostorRecipe( 2, 1, new ItemStack[] { craftingItem, baseTurtle }, craftedTurtleFlipped ) );
|
||||
|
||||
// A turtle containing this upgrade and another upgrade
|
||||
for( ITurtleUpgrade otherUpgrade : m_turtleUpgrades.values() )
|
||||
{
|
||||
if( isUpgradeVanilla( otherUpgrade ) && isUpgradeSuitableForFamily( family, otherUpgrade ) )
|
||||
{
|
||||
ItemStack otherCraftingItem = otherUpgrade.getCraftingItem();
|
||||
|
||||
ItemStack otherCraftedTurtle = TurtleItemFactory.create( -1, null, null, family, null, otherUpgrade, 0, null );
|
||||
ItemStack comboCraftedTurtle = TurtleItemFactory.create( -1, null, null, family, upgrade, otherUpgrade, 0, null );
|
||||
|
||||
ItemStack otherCraftedTurtleFlipped = TurtleItemFactory.create( -1, null, null, family, otherUpgrade, null, 0, null );
|
||||
ItemStack comboCraftedTurtleFlipped = TurtleItemFactory.create( -1, null, null, family, otherUpgrade, upgrade, 0, null );
|
||||
|
||||
recipeList.add( new ImpostorRecipe( 2, 1, new ItemStack[] { otherCraftingItem, craftedTurtle }, comboCraftedTurtle ) );
|
||||
recipeList.add( new ImpostorRecipe( 2, 1, new ItemStack[] { otherCraftedTurtle, craftingItem }, comboCraftedTurtle ) );
|
||||
recipeList.add( new ImpostorRecipe( 2, 1, new ItemStack[] { craftedTurtleFlipped, otherCraftingItem }, comboCraftedTurtleFlipped ) );
|
||||
recipeList.add( new ImpostorRecipe( 2, 1, new ItemStack[] { craftingItem, otherCraftedTurtleFlipped }, comboCraftedTurtleFlipped ) );
|
||||
recipeList.add( new ImpostorRecipe( 3, 1, new ItemStack[] { otherCraftingItem, baseTurtle, craftingItem, }, comboCraftedTurtle ) );
|
||||
recipeList.add( new ImpostorRecipe( 3, 1, new ItemStack[] { craftingItem, baseTurtle, otherCraftingItem }, comboCraftedTurtleFlipped ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerItems()
|
||||
{
|
||||
// Blocks
|
||||
// Turtle
|
||||
ComputerCraft.Blocks.turtle = BlockTurtle.createTurtleBlock();
|
||||
GameRegistry.registerBlock( ComputerCraft.Blocks.turtle, ItemTurtleLegacy.class, "CC-Turtle" );
|
||||
|
||||
ComputerCraft.Blocks.turtleExpanded = BlockTurtle.createTurtleBlock();
|
||||
GameRegistry.registerBlock( ComputerCraft.Blocks.turtleExpanded, ItemTurtleNormal.class, "CC-TurtleExpanded" );
|
||||
|
||||
// Advanced Turtle
|
||||
ComputerCraft.Blocks.turtleAdvanced = BlockTurtle.createTurtleBlock();
|
||||
GameRegistry.registerBlock( ComputerCraft.Blocks.turtleAdvanced, ItemTurtleAdvanced.class, "CC-TurtleAdvanced" );
|
||||
|
||||
// Recipe types
|
||||
RecipeSorter.register( "computercraft:turtle", TurtleRecipe.class, RecipeSorter.Category.SHAPED, "after:minecraft:shapeless" );
|
||||
RecipeSorter.register( "computercraft:turtle_upgrade", TurtleUpgradeRecipe.class, RecipeSorter.Category.SHAPED, "after:minecraft:shapeless" );
|
||||
|
||||
// Recipes
|
||||
// Turtle
|
||||
GameRegistry.addRecipe( new TurtleRecipe( new Item[] {
|
||||
Items.iron_ingot, Items.iron_ingot, Items.iron_ingot,
|
||||
Items.iron_ingot, Item.getItemFromBlock( ComputerCraft.Blocks.computer ), Items.iron_ingot,
|
||||
Items.iron_ingot, Item.getItemFromBlock( Blocks.chest ), Items.iron_ingot,
|
||||
}, ComputerFamily.Normal ) );
|
||||
GameRegistry.addRecipe( new TurtleUpgradeRecipe() );
|
||||
|
||||
// Impostor Turtle recipe (to fool NEI)
|
||||
ItemStack iron = new ItemStack( Items.iron_ingot, 1 );
|
||||
GameRegistry.addRecipe( new ImpostorRecipe( 3, 3,
|
||||
new ItemStack[] {
|
||||
iron, iron, iron,
|
||||
iron, ComputerItemFactory.create( -1, null, ComputerFamily.Normal ), iron,
|
||||
iron, new ItemStack( Blocks.chest, 1 ), iron,
|
||||
},
|
||||
TurtleItemFactory.create( -1, null, null, ComputerFamily.Normal, null, null, 0, null )
|
||||
) );
|
||||
|
||||
// Advanced Turtle
|
||||
GameRegistry.addRecipe( new TurtleRecipe( new Item[] {
|
||||
Items.gold_ingot, Items.gold_ingot, Items.gold_ingot,
|
||||
Items.gold_ingot, Item.getItemFromBlock( ComputerCraft.Blocks.computer ), Items.gold_ingot,
|
||||
Items.gold_ingot, Item.getItemFromBlock( Blocks.chest ), Items.gold_ingot,
|
||||
}, ComputerFamily.Advanced ) );
|
||||
|
||||
// Impostor Advanced Turtle recipe (to fool NEI)
|
||||
ItemStack gold = new ItemStack( Items.gold_ingot, 1 );
|
||||
GameRegistry.addRecipe( new ImpostorRecipe( 3, 3,
|
||||
new ItemStack[] {
|
||||
gold, gold, gold,
|
||||
gold, ComputerItemFactory.create( -1, null, ComputerFamily.Advanced ), gold,
|
||||
gold, new ItemStack( Blocks.chest, 1 ), gold,
|
||||
},
|
||||
TurtleItemFactory.create( -1, null, null, ComputerFamily.Advanced, null, null, 0, null )
|
||||
) );
|
||||
|
||||
// Upgrades
|
||||
ComputerCraft.Upgrades.wirelessModem = new TurtleModem( false, new ResourceLocation( "computercraft", "wireless_modem" ), 1 );
|
||||
registerTurtleUpgradeInternal( ComputerCraft.Upgrades.wirelessModem );
|
||||
|
||||
ComputerCraft.Upgrades.craftingTable = new TurtleCraftingTable( 2 );
|
||||
registerTurtleUpgradeInternal( ComputerCraft.Upgrades.craftingTable );
|
||||
|
||||
ComputerCraft.Upgrades.diamondSword = new TurtleSword( new ResourceLocation( "minecraft", "diamond_sword" ), 3, "upgrade.minecraft:diamond_sword.adjective", Items.diamond_sword );
|
||||
registerTurtleUpgradeInternal( ComputerCraft.Upgrades.diamondSword );
|
||||
|
||||
ComputerCraft.Upgrades.diamondShovel = new TurtleShovel( new ResourceLocation( "minecraft", "diamond_shovel" ), 4, "upgrade.minecraft:diamond_shovel.adjective", Items.diamond_shovel );
|
||||
registerTurtleUpgradeInternal( ComputerCraft.Upgrades.diamondShovel );
|
||||
|
||||
ComputerCraft.Upgrades.diamondPickaxe = new TurtleTool( new ResourceLocation( "minecraft", "diamond_pickaxe" ), 5, "upgrade.minecraft:diamond_pickaxe.adjective", Items.diamond_pickaxe );
|
||||
registerTurtleUpgradeInternal( ComputerCraft.Upgrades.diamondPickaxe );
|
||||
|
||||
ComputerCraft.Upgrades.diamondAxe = new TurtleAxe( new ResourceLocation( "minecraft", "diamond_axe" ), 6, "upgrade.minecraft:diamond_axe.adjective", Items.diamond_axe );
|
||||
registerTurtleUpgradeInternal( ComputerCraft.Upgrades.diamondAxe );
|
||||
|
||||
ComputerCraft.Upgrades.diamondHoe = new TurtleHoe( new ResourceLocation( "minecraft", "diamond_hoe" ), 7, "upgrade.minecraft:diamond_hoe.adjective", Items.diamond_hoe );
|
||||
registerTurtleUpgradeInternal( ComputerCraft.Upgrades.diamondHoe );
|
||||
|
||||
ComputerCraft.Upgrades.advancedModem = new TurtleModem( true, new ResourceLocation( "computercraft", "advanced_modem" ), -1 );
|
||||
registerTurtleUpgradeInternal( ComputerCraft.Upgrades.advancedModem );
|
||||
}
|
||||
|
||||
private void registerTileEntities()
|
||||
{
|
||||
// TileEntities
|
||||
GameRegistry.registerTileEntity( TileTurtle.class, "turtle" );
|
||||
GameRegistry.registerTileEntity( TileTurtleExpanded.class, "turtleex" );
|
||||
GameRegistry.registerTileEntity( TileTurtleAdvanced.class, "turtleadv" );
|
||||
}
|
||||
|
||||
private void registerForgeHandlers()
|
||||
{
|
||||
ForgeHandlers handlers = new ForgeHandlers();
|
||||
MinecraftForge.EVENT_BUS.register( handlers );
|
||||
}
|
||||
|
||||
public class ForgeHandlers
|
||||
{
|
||||
private ForgeHandlers()
|
||||
{
|
||||
}
|
||||
|
||||
// Forge event responses
|
||||
@SubscribeEvent
|
||||
public void onEntityLivingDrops( LivingDropsEvent event )
|
||||
{
|
||||
dispatchEntityDrops( event.entity, event.drops );
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchEntityDrops( Entity entity, java.util.List<EntityItem> drops )
|
||||
{
|
||||
IEntityDropConsumer consumer = m_dropConsumers.get( entity );
|
||||
if( consumer != null )
|
||||
{
|
||||
// All checks have passed, lets dispatch the drops
|
||||
Iterator<EntityItem> it = drops.iterator();
|
||||
while( it.hasNext() )
|
||||
{
|
||||
EntityItem entityItem = (EntityItem)it.next();
|
||||
consumer.consumeDrop( entity, entityItem.getEntityItem() );
|
||||
}
|
||||
drops.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,665 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.proxy;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
import dan200.computercraft.core.computer.MainThread;
|
||||
import dan200.computercraft.shared.common.DefaultBundledRedstoneProvider;
|
||||
import dan200.computercraft.shared.common.TileGeneric;
|
||||
import dan200.computercraft.shared.computer.blocks.BlockCommandComputer;
|
||||
import dan200.computercraft.shared.computer.blocks.BlockComputer;
|
||||
import dan200.computercraft.shared.computer.blocks.TileCommandComputer;
|
||||
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
|
||||
import dan200.computercraft.shared.computer.items.ComputerItemFactory;
|
||||
import dan200.computercraft.shared.computer.items.ItemCommandComputer;
|
||||
import dan200.computercraft.shared.computer.items.ItemComputer;
|
||||
import dan200.computercraft.shared.media.common.DefaultMediaProvider;
|
||||
import dan200.computercraft.shared.media.inventory.ContainerHeldItem;
|
||||
import dan200.computercraft.shared.media.items.ItemDiskExpanded;
|
||||
import dan200.computercraft.shared.media.items.ItemDiskLegacy;
|
||||
import dan200.computercraft.shared.media.items.ItemPrintout;
|
||||
import dan200.computercraft.shared.media.items.ItemTreasureDisk;
|
||||
import dan200.computercraft.shared.media.recipes.DiskRecipe;
|
||||
import dan200.computercraft.shared.media.recipes.PrintoutRecipe;
|
||||
import dan200.computercraft.shared.network.ComputerCraftPacket;
|
||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||
import dan200.computercraft.shared.peripheral.commandblock.CommandBlockPeripheralProvider;
|
||||
import dan200.computercraft.shared.peripheral.common.*;
|
||||
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
|
||||
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
|
||||
import dan200.computercraft.shared.peripheral.modem.BlockAdvancedModem;
|
||||
import dan200.computercraft.shared.peripheral.modem.TileAdvancedModem;
|
||||
import dan200.computercraft.shared.peripheral.modem.TileCable;
|
||||
import dan200.computercraft.shared.peripheral.modem.TileWirelessModem;
|
||||
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
|
||||
import dan200.computercraft.shared.peripheral.printer.ContainerPrinter;
|
||||
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
|
||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
||||
import dan200.computercraft.shared.pocket.items.PocketComputerItemFactory;
|
||||
import dan200.computercraft.shared.pocket.recipes.PocketComputerUpgradeRecipe;
|
||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import dan200.computercraft.shared.util.CreativeTabMain;
|
||||
import dan200.computercraft.shared.util.ImpostorRecipe;
|
||||
import dan200.computercraft.shared.util.ImpostorShapelessRecipe;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemRecord;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.IThreadListener;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||
import net.minecraftforge.fml.common.network.FMLNetworkEvent;
|
||||
import net.minecraftforge.fml.common.network.IGuiHandler;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import net.minecraftforge.oredict.RecipeSorter;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public abstract class ComputerCraftProxyCommon implements IComputerCraftProxy
|
||||
{
|
||||
public ComputerCraftProxyCommon()
|
||||
{
|
||||
}
|
||||
|
||||
// IComputerCraftProxy implementation
|
||||
|
||||
@Override
|
||||
public void preInit()
|
||||
{
|
||||
registerItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
registerTileEntities();
|
||||
registerForgeHandlers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract boolean isClient();
|
||||
|
||||
@Override
|
||||
public abstract boolean getGlobalCursorBlink();
|
||||
|
||||
@Override
|
||||
public abstract long getRenderFrame();
|
||||
|
||||
@Override
|
||||
public void deleteDisplayLists( int list, int range )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract Object getFixedWidthFontRenderer();
|
||||
|
||||
@Override
|
||||
public String getRecordInfo( ItemStack recordStack )
|
||||
{
|
||||
Item item = recordStack.getItem();
|
||||
if( item instanceof ItemRecord )
|
||||
{
|
||||
ItemRecord record = (ItemRecord)item;
|
||||
if( (( ResourceLocation)Item.itemRegistry.getNameForObject( record )).getResourceDomain().equals( "minecraft" ) )
|
||||
{
|
||||
return "C418 - " + record.recordName;
|
||||
}
|
||||
// TODO: determine descriptions for mod items (ie: Portal gun mod)
|
||||
return record.recordName;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract void playRecord( String record, String recordInfo, World world, BlockPos pos );
|
||||
|
||||
@Override
|
||||
public abstract Object getDiskDriveGUI( InventoryPlayer inventory, TileDiskDrive drive );
|
||||
|
||||
@Override
|
||||
public abstract Object getComputerGUI( TileComputer computer );
|
||||
|
||||
@Override
|
||||
public abstract Object getPrinterGUI( InventoryPlayer inventory, TilePrinter printer );
|
||||
|
||||
@Override
|
||||
public abstract Object getTurtleGUI( InventoryPlayer inventory, TileTurtle turtle );
|
||||
|
||||
@Override
|
||||
public abstract Object getPrintoutGUI( InventoryPlayer inventory );
|
||||
|
||||
@Override
|
||||
public abstract Object getPocketComputerGUI( InventoryPlayer inventory );
|
||||
|
||||
public abstract File getWorldDir( World world );
|
||||
|
||||
@Override
|
||||
public void handlePacket( final ComputerCraftPacket packet, final EntityPlayer player )
|
||||
{
|
||||
IThreadListener listener = MinecraftServer.getServer();
|
||||
if( listener != null )
|
||||
{
|
||||
if( listener.isCallingFromMinecraftThread() )
|
||||
{
|
||||
processPacket( packet, player );
|
||||
}
|
||||
else
|
||||
{
|
||||
listener.addScheduledTask( new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
processPacket( packet, player );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processPacket( ComputerCraftPacket packet, EntityPlayer player )
|
||||
{
|
||||
switch( packet.m_packetType )
|
||||
{
|
||||
///////////////////////////////////
|
||||
// Packets from Client to Server //
|
||||
///////////////////////////////////
|
||||
case ComputerCraftPacket.TurnOn:
|
||||
case ComputerCraftPacket.Shutdown:
|
||||
case ComputerCraftPacket.Reboot:
|
||||
case ComputerCraftPacket.QueueEvent:
|
||||
case ComputerCraftPacket.RequestComputerUpdate:
|
||||
case ComputerCraftPacket.SetLabel:
|
||||
{
|
||||
int instance = packet.m_dataInt[0];
|
||||
ServerComputer computer = ComputerCraft.serverComputerRegistry.get( instance );
|
||||
if( computer != null )
|
||||
{
|
||||
computer.handlePacket( packet, player );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ComputerCraftPacket.RequestTileEntityUpdate:
|
||||
{
|
||||
int x = packet.m_dataInt[0];
|
||||
int y = packet.m_dataInt[1];
|
||||
int z = packet.m_dataInt[2];
|
||||
BlockPos pos = new BlockPos( x, y, z );
|
||||
World world = player.getEntityWorld();
|
||||
TileEntity tileEntity = world.getTileEntity( pos );
|
||||
if( tileEntity != null && tileEntity instanceof TileGeneric )
|
||||
{
|
||||
TileGeneric generic = (TileGeneric)tileEntity;
|
||||
Packet description = generic.getDescriptionPacket();
|
||||
if( description != null )
|
||||
{
|
||||
((EntityPlayerMP)player).playerNetServerHandler.sendPacket( description );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerItems()
|
||||
{
|
||||
// Creative tab
|
||||
ComputerCraft.mainCreativeTab = new CreativeTabMain( CreativeTabs.getNextID() );
|
||||
|
||||
// Blocks
|
||||
// Computer
|
||||
ComputerCraft.Blocks.computer = new BlockComputer();
|
||||
GameRegistry.registerBlock( ComputerCraft.Blocks.computer, ItemComputer.class, "CC-Computer" );
|
||||
|
||||
// Peripheral
|
||||
ComputerCraft.Blocks.peripheral = new BlockPeripheral();
|
||||
GameRegistry.registerBlock( ComputerCraft.Blocks.peripheral, ItemPeripheral.class, "CC-Peripheral" );
|
||||
|
||||
// Cable
|
||||
ComputerCraft.Blocks.cable = new BlockCable();
|
||||
GameRegistry.registerBlock( ComputerCraft.Blocks.cable, ItemCable.class, "CC-Cable" );
|
||||
|
||||
// Command Computer
|
||||
ComputerCraft.Blocks.commandComputer = new BlockCommandComputer();
|
||||
GameRegistry.registerBlock( ComputerCraft.Blocks.commandComputer, ItemCommandComputer.class, "command_computer" );
|
||||
|
||||
// Command Computer
|
||||
ComputerCraft.Blocks.advancedModem = new BlockAdvancedModem();
|
||||
GameRegistry.registerBlock( ComputerCraft.Blocks.advancedModem, ItemAdvancedModem.class, "advanced_modem" );
|
||||
|
||||
// Items
|
||||
// Floppy Disk
|
||||
ComputerCraft.Items.disk = new ItemDiskLegacy();
|
||||
GameRegistry.registerItem( ComputerCraft.Items.disk, "disk" );
|
||||
|
||||
ComputerCraft.Items.diskExpanded = new ItemDiskExpanded();
|
||||
GameRegistry.registerItem( ComputerCraft.Items.diskExpanded, "diskExpanded" );
|
||||
|
||||
// Treasure Disk
|
||||
ComputerCraft.Items.treasureDisk = new ItemTreasureDisk();
|
||||
GameRegistry.registerItem( ComputerCraft.Items.treasureDisk, "treasureDisk" );
|
||||
|
||||
// Printout
|
||||
ComputerCraft.Items.printout = new ItemPrintout();
|
||||
GameRegistry.registerItem( ComputerCraft.Items.printout, "printout" );
|
||||
|
||||
// Pocket computer
|
||||
ComputerCraft.Items.pocketComputer = new ItemPocketComputer();
|
||||
GameRegistry.registerItem( ComputerCraft.Items.pocketComputer, "pocketComputer" );
|
||||
|
||||
// Recipe types
|
||||
RecipeSorter.register( "computercraft:impostor", ImpostorRecipe.class, RecipeSorter.Category.SHAPED, "after:minecraft:shapeless" );
|
||||
RecipeSorter.register( "computercraft:impostor_shapeless", ImpostorShapelessRecipe.class, RecipeSorter.Category.SHAPELESS, "after:minecraft:shapeless" );
|
||||
RecipeSorter.register( "computercraft:disk", DiskRecipe.class, RecipeSorter.Category.SHAPELESS, "after:minecraft:shapeless" );
|
||||
RecipeSorter.register( "computercraft:printout", PrintoutRecipe.class, RecipeSorter.Category.SHAPELESS, "after:minecraft:shapeless" );
|
||||
RecipeSorter.register( "computercraft:pocket_computer_upgrade", PocketComputerUpgradeRecipe.class, RecipeSorter.Category.SHAPELESS, "after:minecraft:shapeless" );
|
||||
|
||||
// Recipes
|
||||
// Computer
|
||||
ItemStack computer = ComputerItemFactory.create( -1, null, ComputerFamily.Normal );
|
||||
GameRegistry.addRecipe( computer,
|
||||
"XXX", "XYX", "XZX",
|
||||
'X', Blocks.stone,
|
||||
'Y', Items.redstone,
|
||||
'Z', Blocks.glass_pane
|
||||
);
|
||||
|
||||
// Advanced Computer
|
||||
ItemStack advancedComputer = ComputerItemFactory.create( -1, null, ComputerFamily.Advanced );
|
||||
GameRegistry.addRecipe( advancedComputer,
|
||||
"XXX", "XYX", "XZX",
|
||||
'X', Items.gold_ingot,
|
||||
'Y', Items.redstone,
|
||||
'Z', Blocks.glass_pane
|
||||
);
|
||||
|
||||
// Disk Drive
|
||||
ItemStack diskDrive = PeripheralItemFactory.create( PeripheralType.DiskDrive, null, 1 );
|
||||
GameRegistry.addRecipe( diskDrive,
|
||||
"XXX", "XYX", "XYX",
|
||||
'X', Blocks.stone,
|
||||
'Y', Items.redstone
|
||||
);
|
||||
|
||||
// Wireless Modem
|
||||
ItemStack wirelessModem = PeripheralItemFactory.create( PeripheralType.WirelessModem, null, 1 );
|
||||
GameRegistry.addRecipe( wirelessModem,
|
||||
"XXX", "XYX", "XXX",
|
||||
'X', Blocks.stone,
|
||||
'Y', Items.ender_pearl
|
||||
);
|
||||
|
||||
// Monitor
|
||||
ItemStack monitor = PeripheralItemFactory.create( PeripheralType.Monitor, null, 1 );
|
||||
GameRegistry.addRecipe( monitor,
|
||||
"XXX", "XYX", "XXX",
|
||||
'X', Blocks.stone,
|
||||
'Y', Blocks.glass_pane
|
||||
);
|
||||
|
||||
// PrinterEmpty
|
||||
ItemStack printer = PeripheralItemFactory.create( PeripheralType.Printer, null, 1 );
|
||||
GameRegistry.addRecipe( printer,
|
||||
"XXX", "XYX", "XZX",
|
||||
'X', Blocks.stone,
|
||||
'Y', Items.redstone,
|
||||
'Z', new ItemStack( Items.dye, 1, 0 ) // 0 = Black
|
||||
);
|
||||
|
||||
// Advanced Monitor
|
||||
ItemStack advancedMonitors = PeripheralItemFactory.create( PeripheralType.AdvancedMonitor, null, 4 );
|
||||
GameRegistry.addRecipe( advancedMonitors,
|
||||
"XXX", "XYX", "XXX",
|
||||
'X', Items.gold_ingot,
|
||||
'Y', Blocks.glass_pane
|
||||
);
|
||||
|
||||
// Networking Cable
|
||||
ItemStack cable = PeripheralItemFactory.create( PeripheralType.Cable, null, 6 );
|
||||
GameRegistry.addRecipe( cable,
|
||||
" X ", "XYX", " X ",
|
||||
'X', Blocks.stone,
|
||||
'Y', Items.redstone
|
||||
);
|
||||
|
||||
// Wired Modem
|
||||
ItemStack wiredModem = PeripheralItemFactory.create( PeripheralType.WiredModem, null, 1 );
|
||||
GameRegistry.addRecipe( wiredModem,
|
||||
"XXX", "XYX", "XXX",
|
||||
'X', Blocks.stone,
|
||||
'Y', Items.redstone
|
||||
);
|
||||
|
||||
// Computer
|
||||
ItemStack commandComputer = ComputerItemFactory.create( -1, null, ComputerFamily.Command );
|
||||
GameRegistry.addRecipe( commandComputer,
|
||||
"XXX", "XYX", "XZX",
|
||||
'X', Blocks.stone,
|
||||
'Y', Blocks.command_block,
|
||||
'Z', Blocks.glass_pane
|
||||
);
|
||||
|
||||
// Advanced Modem
|
||||
ItemStack advancedModem = PeripheralItemFactory.create( PeripheralType.AdvancedModem, null, 1 );
|
||||
GameRegistry.addRecipe( advancedModem,
|
||||
"XXX", "XYX", "XXX",
|
||||
'X', Items.gold_ingot,
|
||||
'Y', Items.ender_eye
|
||||
);
|
||||
|
||||
// Disk
|
||||
GameRegistry.addRecipe( new DiskRecipe() );
|
||||
|
||||
// Impostor Disk recipes (to fool NEI)
|
||||
ItemStack paper = new ItemStack( Items.paper, 1 );
|
||||
ItemStack redstone = new ItemStack( Items.redstone, 1 );
|
||||
ItemStack basicDisk = ItemDiskLegacy.createFromIDAndColour( -1, null, Colour.Blue.getHex() );
|
||||
GameRegistry.addRecipe( new ImpostorShapelessRecipe( basicDisk, new Object[] { redstone, paper } ) );
|
||||
|
||||
for( int colour=0; colour<16; ++colour )
|
||||
{
|
||||
ItemStack disk = ItemDiskLegacy.createFromIDAndColour( -1, null, Colour.values()[ colour ].getHex() );
|
||||
ItemStack dye = new ItemStack( Items.dye, 1, colour );
|
||||
for( int otherColour=0; otherColour<16; ++otherColour )
|
||||
{
|
||||
if( colour != otherColour )
|
||||
{
|
||||
ItemStack otherDisk = ItemDiskLegacy.createFromIDAndColour( -1, null, Colour.values()[ colour ].getHex() );
|
||||
GameRegistry.addRecipe( new ImpostorShapelessRecipe( disk, new Object[] {
|
||||
otherDisk, dye
|
||||
} ) );
|
||||
}
|
||||
}
|
||||
GameRegistry.addRecipe( new ImpostorShapelessRecipe( disk, new Object[] {
|
||||
redstone, paper, dye
|
||||
} ) );
|
||||
}
|
||||
|
||||
// Printout
|
||||
GameRegistry.addRecipe( new PrintoutRecipe() );
|
||||
|
||||
ItemStack singlePrintout = ItemPrintout.createSingleFromTitleAndText( null, null, null );
|
||||
ItemStack multiplePrintout = ItemPrintout.createMultipleFromTitleAndText( null, null, null );
|
||||
ItemStack bookPrintout = ItemPrintout.createBookFromTitleAndText( null, null, null );
|
||||
|
||||
// Impostor Printout recipes (to fool NEI)
|
||||
ItemStack string = new ItemStack( Items.string, 1, 0 );
|
||||
GameRegistry.addRecipe( new ImpostorShapelessRecipe( multiplePrintout, new Object[] { singlePrintout, singlePrintout, string } ) );
|
||||
|
||||
ItemStack leather = new ItemStack( Items.leather, 1, 0 );
|
||||
GameRegistry.addRecipe( new ImpostorShapelessRecipe( bookPrintout, new Object[] { leather, singlePrintout, string } ) );
|
||||
|
||||
// Pocket Computer
|
||||
ItemStack pocketComputer = PocketComputerItemFactory.create( -1, null, ComputerFamily.Normal, false );
|
||||
GameRegistry.addRecipe( pocketComputer,
|
||||
"XXX", "XYX", "XZX",
|
||||
'X', Blocks.stone,
|
||||
'Y', Items.golden_apple,
|
||||
'Z', Blocks.glass_pane
|
||||
);
|
||||
|
||||
// Advanced Pocket Computer
|
||||
ItemStack advancedPocketComputer = PocketComputerItemFactory.create( -1, null, ComputerFamily.Advanced, false );
|
||||
GameRegistry.addRecipe( advancedPocketComputer,
|
||||
"XXX", "XYX", "XZX",
|
||||
'X', Items.gold_ingot,
|
||||
'Y', Items.golden_apple,
|
||||
'Z', Blocks.glass_pane
|
||||
);
|
||||
|
||||
// Wireless Pocket Computer
|
||||
ItemStack wirelessPocketComputer = PocketComputerItemFactory.create( -1, null, ComputerFamily.Normal, true );
|
||||
GameRegistry.addRecipe( new PocketComputerUpgradeRecipe() );
|
||||
|
||||
// Advanced Wireless Pocket Computer
|
||||
ItemStack advancedWirelessPocketComputer = PocketComputerItemFactory.create( -1, null, ComputerFamily.Advanced, true );
|
||||
|
||||
// Impostor Pocket Computer recipes (to fool NEI)
|
||||
GameRegistry.addRecipe( new ImpostorRecipe( 1, 2, new ItemStack[] { wirelessModem, pocketComputer }, wirelessPocketComputer ) );
|
||||
GameRegistry.addRecipe( new ImpostorRecipe( 1, 2, new ItemStack[] { wirelessModem, advancedPocketComputer }, advancedWirelessPocketComputer ) );
|
||||
|
||||
// Skulls (Easter Egg)
|
||||
// Dan
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tag.setString( "SkullOwner", "dan200" );
|
||||
ItemStack danHead = new ItemStack( Items.skull, 1, 3 );
|
||||
danHead.setTagCompound( tag );
|
||||
GameRegistry.addShapelessRecipe( danHead, computer, new ItemStack( Items.skull, 1, 1 ) );
|
||||
|
||||
// Cloudy
|
||||
tag = new NBTTagCompound();
|
||||
tag.setString( "SkullOwner", "Cloudhunter" );
|
||||
ItemStack cloudyHead = new ItemStack( Items.skull, 1, 3 );
|
||||
cloudyHead.setTagCompound( tag );
|
||||
GameRegistry.addShapelessRecipe( cloudyHead, monitor, new ItemStack( Items.skull, 1, 1 ) );
|
||||
}
|
||||
|
||||
private void registerTileEntities()
|
||||
{
|
||||
// Tile Entities
|
||||
GameRegistry.registerTileEntity( TileComputer.class, "computer" );
|
||||
GameRegistry.registerTileEntity( TileDiskDrive.class, "diskdrive" );
|
||||
GameRegistry.registerTileEntity( TileWirelessModem.class, "wirelessmodem" );
|
||||
GameRegistry.registerTileEntity( TileMonitor.class, "monitor" );
|
||||
GameRegistry.registerTileEntity( TilePrinter.class, "ccprinter" );
|
||||
GameRegistry.registerTileEntity( TileCable.class, "wiredmodem" );
|
||||
GameRegistry.registerTileEntity( TileCommandComputer.class, "command_computer" );
|
||||
GameRegistry.registerTileEntity( TileAdvancedModem.class, "advanced_modem" );
|
||||
|
||||
// Register peripheral providers
|
||||
ComputerCraftAPI.registerPeripheralProvider( new DefaultPeripheralProvider() );
|
||||
if( ComputerCraft.enableCommandBlock )
|
||||
{
|
||||
ComputerCraftAPI.registerPeripheralProvider( new CommandBlockPeripheralProvider() );
|
||||
}
|
||||
|
||||
// Register bundled power providers
|
||||
ComputerCraftAPI.registerBundledRedstoneProvider( new DefaultBundledRedstoneProvider() );
|
||||
|
||||
// Register media providers
|
||||
ComputerCraftAPI.registerMediaProvider( new DefaultMediaProvider() );
|
||||
}
|
||||
|
||||
private void registerForgeHandlers()
|
||||
{
|
||||
ForgeHandlers handlers = new ForgeHandlers();
|
||||
MinecraftForge.EVENT_BUS.register( handlers );
|
||||
NetworkRegistry.INSTANCE.registerGuiHandler( ComputerCraft.instance, handlers );
|
||||
}
|
||||
|
||||
public class ForgeHandlers implements
|
||||
IGuiHandler
|
||||
{
|
||||
private ForgeHandlers()
|
||||
{
|
||||
}
|
||||
|
||||
// IGuiHandler implementation
|
||||
|
||||
@Override
|
||||
public Object getServerGuiElement( int id, EntityPlayer player, World world, int x, int y, int z )
|
||||
{
|
||||
BlockPos pos = new BlockPos( x, y, z );
|
||||
switch( id )
|
||||
{
|
||||
case ComputerCraft.diskDriveGUIID:
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileDiskDrive )
|
||||
{
|
||||
TileDiskDrive drive = (TileDiskDrive)tile;
|
||||
return new ContainerDiskDrive( player.inventory, drive );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ComputerCraft.computerGUIID:
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileComputer )
|
||||
{
|
||||
TileComputer computer = (TileComputer)tile;
|
||||
return new ContainerComputer( computer );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ComputerCraft.printerGUIID:
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TilePrinter )
|
||||
{
|
||||
TilePrinter printer = (TilePrinter)tile;
|
||||
return new ContainerPrinter( player.inventory, printer );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ComputerCraft.turtleGUIID:
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileTurtle )
|
||||
{
|
||||
TileTurtle turtle = (TileTurtle)tile;
|
||||
return new ContainerTurtle( player.inventory, turtle.getAccess() );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ComputerCraft.printoutGUIID:
|
||||
{
|
||||
return new ContainerHeldItem( player.inventory );
|
||||
}
|
||||
case ComputerCraft.pocketComputerGUIID:
|
||||
{
|
||||
return new ContainerHeldItem( player.inventory );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getClientGuiElement( int id, EntityPlayer player, World world, int x, int y, int z )
|
||||
{
|
||||
BlockPos pos = new BlockPos( x, y, z );
|
||||
switch( id )
|
||||
{
|
||||
case ComputerCraft.diskDriveGUIID:
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileDiskDrive )
|
||||
{
|
||||
TileDiskDrive drive = (TileDiskDrive)tile;
|
||||
return getDiskDriveGUI( player.inventory, drive );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ComputerCraft.computerGUIID:
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileComputer )
|
||||
{
|
||||
TileComputer computer = (TileComputer)tile;
|
||||
return getComputerGUI( computer );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ComputerCraft.printerGUIID:
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TilePrinter )
|
||||
{
|
||||
TilePrinter printer = (TilePrinter)tile;
|
||||
return getPrinterGUI( player.inventory, printer );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ComputerCraft.turtleGUIID:
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileTurtle )
|
||||
{
|
||||
TileTurtle turtle = (TileTurtle)tile;
|
||||
return getTurtleGUI( player.inventory, turtle );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ComputerCraft.printoutGUIID:
|
||||
{
|
||||
return getPrintoutGUI( player.inventory );
|
||||
}
|
||||
case ComputerCraft.pocketComputerGUIID:
|
||||
{
|
||||
return getPocketComputerGUI( player.inventory );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Event handlers
|
||||
|
||||
@SubscribeEvent
|
||||
public void onConnectionOpened( FMLNetworkEvent.ClientConnectedToServerEvent event )
|
||||
{
|
||||
ComputerCraft.clientComputerRegistry.reset();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onConnectionClosed( FMLNetworkEvent.ClientDisconnectionFromServerEvent event )
|
||||
{
|
||||
ComputerCraft.clientComputerRegistry.reset();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onClientTick( TickEvent.ClientTickEvent event )
|
||||
{
|
||||
if( event.phase == TickEvent.Phase.START )
|
||||
{
|
||||
ComputerCraft.clientComputerRegistry.update();
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onServerTick( TickEvent.ServerTickEvent event )
|
||||
{
|
||||
if( event.phase == TickEvent.Phase.START )
|
||||
{
|
||||
MainThread.executePendingTasks();
|
||||
ComputerCraft.serverComputerRegistry.update();
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onWorldLoad( WorldEvent.Load event )
|
||||
{
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onWorldUnload( WorldEvent.Unload event )
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.proxy;
|
||||
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.shared.util.IEntityDropConsumer;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ICCTurtleProxy
|
||||
{
|
||||
public void preInit();
|
||||
public void init();
|
||||
|
||||
public void registerTurtleUpgrade( ITurtleUpgrade upgrade );
|
||||
public ITurtleUpgrade getTurtleUpgrade( String id );
|
||||
public ITurtleUpgrade getTurtleUpgrade( int legacyId );
|
||||
public ITurtleUpgrade getTurtleUpgrade( ItemStack item );
|
||||
public void addAllUpgradedTurtles( List<ItemStack> list );
|
||||
|
||||
public void setEntityDropConsumer( Entity entity, IEntityDropConsumer consumer );
|
||||
public void clearEntityDropConsumer( Entity entity );
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.proxy;
|
||||
|
||||
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
||||
import dan200.computercraft.shared.network.ComputerCraftPacket;
|
||||
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
|
||||
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
|
||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public interface IComputerCraftProxy
|
||||
{
|
||||
public void preInit();
|
||||
public void init();
|
||||
public boolean isClient();
|
||||
|
||||
public boolean getGlobalCursorBlink();
|
||||
public long getRenderFrame();
|
||||
public void deleteDisplayLists( int list, int range );
|
||||
public Object getFixedWidthFontRenderer();
|
||||
|
||||
public String getRecordInfo( ItemStack item );
|
||||
public void playRecord( String record, String recordInfo, World world, BlockPos pos );
|
||||
|
||||
public Object getDiskDriveGUI( InventoryPlayer inventory, TileDiskDrive drive );
|
||||
public Object getComputerGUI( TileComputer computer );
|
||||
public Object getPrinterGUI( InventoryPlayer inventory, TilePrinter printer );
|
||||
public Object getTurtleGUI( InventoryPlayer inventory, TileTurtle turtle );
|
||||
public abstract Object getPrintoutGUI( InventoryPlayer inventory );
|
||||
public abstract Object getPocketComputerGUI( InventoryPlayer inventory );
|
||||
|
||||
public File getWorldDir( World world );
|
||||
public void handlePacket( ComputerCraftPacket packet, EntityPlayer player );
|
||||
}
|
||||
@@ -0,0 +1,502 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.turtle.apis;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.api.turtle.ITurtleCommand;
|
||||
import dan200.computercraft.api.turtle.TurtleSide;
|
||||
import dan200.computercraft.core.apis.IAPIEnvironment;
|
||||
import dan200.computercraft.core.apis.ILuaAPI;
|
||||
import dan200.computercraft.shared.turtle.core.*;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class TurtleAPI implements ILuaAPI
|
||||
{
|
||||
private IAPIEnvironment m_environment;
|
||||
private ITurtleAccess m_turtle;
|
||||
|
||||
public TurtleAPI( IAPIEnvironment environment, ITurtleAccess turtle )
|
||||
{
|
||||
m_environment = environment;
|
||||
m_turtle = turtle;
|
||||
}
|
||||
|
||||
// ILuaAPI implementation
|
||||
|
||||
@Override
|
||||
public String[] getNames()
|
||||
{
|
||||
return new String[] {
|
||||
"turtle"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startup( )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void advance( double _dt )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown( )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getMethodNames()
|
||||
{
|
||||
return new String[] {
|
||||
"forward",
|
||||
"back",
|
||||
"up",
|
||||
"down",
|
||||
"turnLeft",
|
||||
"turnRight",
|
||||
"dig",
|
||||
"digUp",
|
||||
"digDown",
|
||||
"place",
|
||||
"placeUp",
|
||||
"placeDown",
|
||||
"drop",
|
||||
"select",
|
||||
"getItemCount",
|
||||
"getItemSpace",
|
||||
"detect",
|
||||
"detectUp",
|
||||
"detectDown",
|
||||
"compare",
|
||||
"compareUp",
|
||||
"compareDown",
|
||||
"attack",
|
||||
"attackUp",
|
||||
"attackDown",
|
||||
"dropUp",
|
||||
"dropDown",
|
||||
"suck",
|
||||
"suckUp",
|
||||
"suckDown",
|
||||
"getFuelLevel",
|
||||
"refuel",
|
||||
"compareTo",
|
||||
"transferTo",
|
||||
"getSelectedSlot",
|
||||
"getFuelLimit",
|
||||
"equipLeft",
|
||||
"equipRight",
|
||||
"inspect",
|
||||
"inspectUp",
|
||||
"inspectDown",
|
||||
"getItemDetail",
|
||||
};
|
||||
}
|
||||
|
||||
private Object[] tryCommand( ILuaContext context, ITurtleCommand command ) throws LuaException, InterruptedException
|
||||
{
|
||||
return m_turtle.executeCommand( context, command );
|
||||
}
|
||||
|
||||
private int parseSlotNumber( Object[] arguments, int index ) throws LuaException
|
||||
{
|
||||
int slot = parseOptionalSlotNumber( arguments, index, 99 );
|
||||
if( slot == 99 )
|
||||
{
|
||||
throw new LuaException( "Expected number" );
|
||||
}
|
||||
return slot;
|
||||
}
|
||||
|
||||
private int parseOptionalSlotNumber( Object[] arguments, int index, int fallback ) throws LuaException
|
||||
{
|
||||
if( arguments.length <= index || !(arguments[index] instanceof Number) )
|
||||
{
|
||||
return fallback;
|
||||
}
|
||||
int slot = ((Number)arguments[index]).intValue();
|
||||
if( slot >= 1 && slot <= 16 )
|
||||
{
|
||||
return slot - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new LuaException( "Slot number " + slot + " out of range" );
|
||||
}
|
||||
}
|
||||
|
||||
private int parseCount( Object[] arguments, int index ) throws LuaException
|
||||
{
|
||||
if( arguments.length <= index || !(arguments[index] instanceof Number) )
|
||||
{
|
||||
throw new LuaException( "Expected number" );
|
||||
}
|
||||
int count = ((Number)arguments[index]).intValue();
|
||||
if( count >= 0 && count <= 64 )
|
||||
{
|
||||
return count;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new LuaException( "Item count " + count + " out of range" );
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<TurtleSide> parseSide( Object[] arguments, int index ) throws LuaException
|
||||
{
|
||||
if( arguments.length <= index || arguments[index] == null )
|
||||
{
|
||||
return Optional.absent();
|
||||
}
|
||||
if( !(arguments[ index ] instanceof String) )
|
||||
{
|
||||
throw new LuaException( "Expected string" );
|
||||
}
|
||||
if( arguments[ index ].equals( "left" ) )
|
||||
{
|
||||
return Optional.of( TurtleSide.Left );
|
||||
}
|
||||
else if( arguments[ index ].equals( "right" ) )
|
||||
{
|
||||
return Optional.of( TurtleSide.Right );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new LuaException( "Invalid side" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( ILuaContext context, int method, Object[] args ) throws LuaException, InterruptedException
|
||||
{
|
||||
switch( method )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// forward
|
||||
return tryCommand( context, new TurtleMoveCommand( MoveDirection.Forward ) );
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
// back
|
||||
return tryCommand( context, new TurtleMoveCommand( MoveDirection.Back ) );
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
// up
|
||||
return tryCommand( context, new TurtleMoveCommand( MoveDirection.Up ) );
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
// down
|
||||
return tryCommand( context, new TurtleMoveCommand( MoveDirection.Down ) );
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
// turnLeft
|
||||
return tryCommand( context, new TurtleTurnCommand( TurnDirection.Left ) );
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
// turnRight
|
||||
return tryCommand( context, new TurtleTurnCommand( TurnDirection.Right ) );
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
// dig
|
||||
Optional<TurtleSide> side = parseSide( args, 0 );
|
||||
return tryCommand( context, new TurtleDigCommand( InteractDirection.Forward, side ) );
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
// digUp
|
||||
Optional<TurtleSide> side = parseSide( args, 0 );
|
||||
return tryCommand( context, new TurtleDigCommand( InteractDirection.Up, side ) );
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
// digDown
|
||||
Optional<TurtleSide> side = parseSide( args, 0 );
|
||||
return tryCommand( context, new TurtleDigCommand( InteractDirection.Down, side ) );
|
||||
}
|
||||
case 9:
|
||||
{
|
||||
// place
|
||||
return tryCommand( context, new TurtlePlaceCommand( InteractDirection.Forward, args ) );
|
||||
}
|
||||
case 10:
|
||||
{
|
||||
// placeUp
|
||||
return tryCommand( context, new TurtlePlaceCommand( InteractDirection.Up, args ) );
|
||||
}
|
||||
case 11:
|
||||
{
|
||||
// placeDown
|
||||
return tryCommand( context, new TurtlePlaceCommand( InteractDirection.Down, args ) );
|
||||
}
|
||||
case 12:
|
||||
{
|
||||
// drop
|
||||
int count = 64;
|
||||
if( args.length > 0 )
|
||||
{
|
||||
count = parseCount( args, 0 );
|
||||
}
|
||||
return tryCommand( context, new TurtleDropCommand( InteractDirection.Forward, count ) );
|
||||
}
|
||||
case 13:
|
||||
{
|
||||
// select
|
||||
int slot = parseSlotNumber( args, 0 );
|
||||
return tryCommand( context, new TurtleSelectCommand( slot ) );
|
||||
}
|
||||
case 14:
|
||||
{
|
||||
// getItemCount
|
||||
int slot = parseOptionalSlotNumber( args, 0, m_turtle.getSelectedSlot() );
|
||||
ItemStack stack = m_turtle.getInventory().getStackInSlot( slot );
|
||||
if( stack != null )
|
||||
{
|
||||
return new Object[] { stack.stackSize };
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Object[] { 0 };
|
||||
}
|
||||
}
|
||||
case 15:
|
||||
{
|
||||
// getItemSpace
|
||||
int slot = parseOptionalSlotNumber( args, 0, m_turtle.getSelectedSlot() );
|
||||
ItemStack stack = m_turtle.getInventory().getStackInSlot( slot );
|
||||
if( stack != null )
|
||||
{
|
||||
return new Object[] {
|
||||
Math.min( stack.getMaxStackSize(), 64 ) - stack.stackSize
|
||||
};
|
||||
}
|
||||
return new Object[] { 64 };
|
||||
}
|
||||
case 16:
|
||||
{
|
||||
// detect
|
||||
return tryCommand( context, new TurtleDetectCommand( InteractDirection.Forward ) );
|
||||
}
|
||||
case 17:
|
||||
{
|
||||
// detectUp
|
||||
return tryCommand( context, new TurtleDetectCommand( InteractDirection.Up ) );
|
||||
}
|
||||
case 18:
|
||||
{
|
||||
// detectDown
|
||||
return tryCommand( context, new TurtleDetectCommand( InteractDirection.Down ) );
|
||||
}
|
||||
case 19:
|
||||
{
|
||||
// compare
|
||||
return tryCommand( context, new TurtleCompareCommand( InteractDirection.Forward ) );
|
||||
}
|
||||
case 20:
|
||||
{
|
||||
// compareUp
|
||||
return tryCommand( context, new TurtleCompareCommand( InteractDirection.Up ) );
|
||||
}
|
||||
case 21:
|
||||
{
|
||||
// compareDown
|
||||
return tryCommand( context, new TurtleCompareCommand( InteractDirection.Down ) );
|
||||
}
|
||||
case 22:
|
||||
{
|
||||
// attack
|
||||
Optional<TurtleSide> side = parseSide( args, 0 );
|
||||
return tryCommand( context, new TurtleAttackCommand( InteractDirection.Forward, side ) );
|
||||
}
|
||||
case 23:
|
||||
{
|
||||
// attackUp
|
||||
Optional<TurtleSide> side = parseSide( args, 0 );
|
||||
return tryCommand( context, new TurtleAttackCommand( InteractDirection.Up, side ) );
|
||||
}
|
||||
case 24:
|
||||
{
|
||||
// attackDown
|
||||
Optional<TurtleSide> side = parseSide( args, 0 );
|
||||
return tryCommand( context, new TurtleAttackCommand( InteractDirection.Down, side ) );
|
||||
}
|
||||
case 25:
|
||||
{
|
||||
// dropUp
|
||||
int count = 64;
|
||||
if( args.length > 0 )
|
||||
{
|
||||
count = parseCount( args, 0 );
|
||||
}
|
||||
return tryCommand( context, new TurtleDropCommand( InteractDirection.Up, count ) );
|
||||
}
|
||||
case 26:
|
||||
{
|
||||
// dropDown
|
||||
int count = 64;
|
||||
if( args.length > 0 )
|
||||
{
|
||||
count = parseCount( args, 0 );
|
||||
}
|
||||
return tryCommand( context, new TurtleDropCommand( InteractDirection.Down, count ) );
|
||||
}
|
||||
case 27:
|
||||
{
|
||||
// suck
|
||||
int count = 64;
|
||||
if( args.length > 0 )
|
||||
{
|
||||
count = parseCount( args, 0 );
|
||||
}
|
||||
return tryCommand( context, new TurtleSuckCommand( InteractDirection.Forward, count ) );
|
||||
}
|
||||
case 28:
|
||||
{
|
||||
// suckUp
|
||||
int count = 64;
|
||||
if( args.length > 0 )
|
||||
{
|
||||
count = parseCount( args, 0 );
|
||||
}
|
||||
return tryCommand( context, new TurtleSuckCommand( InteractDirection.Up, count ) );
|
||||
}
|
||||
case 29:
|
||||
{
|
||||
// suckDown
|
||||
int count = 64;
|
||||
if( args.length > 0 )
|
||||
{
|
||||
count = parseCount( args, 0 );
|
||||
}
|
||||
return tryCommand( context, new TurtleSuckCommand( InteractDirection.Down, count ) );
|
||||
}
|
||||
case 30:
|
||||
{
|
||||
// getFuelLevel
|
||||
if( m_turtle.isFuelNeeded() )
|
||||
{
|
||||
return new Object[] { m_turtle.getFuelLevel() };
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Object[] { "unlimited" };
|
||||
}
|
||||
}
|
||||
case 31:
|
||||
{
|
||||
// refuel
|
||||
int count = 64;
|
||||
if( args.length > 0 )
|
||||
{
|
||||
count = parseCount( args, 0 );
|
||||
}
|
||||
return tryCommand( context, new TurtleRefuelCommand( count ) );
|
||||
}
|
||||
case 32:
|
||||
{
|
||||
// compareTo
|
||||
int slot = parseSlotNumber( args, 0 );
|
||||
return tryCommand( context, new TurtleCompareToCommand( slot ) );
|
||||
}
|
||||
case 33:
|
||||
{
|
||||
// transferTo
|
||||
int slot = parseSlotNumber( args, 0 );
|
||||
int count = 64;
|
||||
if( args.length > 1 )
|
||||
{
|
||||
count = parseCount( args, 1 );
|
||||
}
|
||||
return tryCommand( context, new TurtleTransferToCommand( slot, count ) );
|
||||
}
|
||||
case 34:
|
||||
{
|
||||
// getSelectedSlot
|
||||
return new Object[] { m_turtle.getSelectedSlot() + 1 };
|
||||
}
|
||||
case 35:
|
||||
{
|
||||
// getFuelLimit
|
||||
if( m_turtle.isFuelNeeded() )
|
||||
{
|
||||
return new Object[] { m_turtle.getFuelLimit() };
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Object[] { "unlimited" };
|
||||
}
|
||||
}
|
||||
case 36:
|
||||
{
|
||||
// equipLeft
|
||||
return tryCommand( context, new TurtleEquipCommand( TurtleSide.Left ) );
|
||||
}
|
||||
case 37:
|
||||
{
|
||||
// equipRight
|
||||
return tryCommand( context, new TurtleEquipCommand( TurtleSide.Right ) );
|
||||
}
|
||||
case 38:
|
||||
{
|
||||
// inspect
|
||||
return tryCommand( context, new TurtleInspectCommand( InteractDirection.Forward ) );
|
||||
}
|
||||
case 39:
|
||||
{
|
||||
// inspectUp
|
||||
return tryCommand( context, new TurtleInspectCommand( InteractDirection.Up ) );
|
||||
}
|
||||
case 40:
|
||||
{
|
||||
// inspectDown
|
||||
return tryCommand( context, new TurtleInspectCommand( InteractDirection.Down ) );
|
||||
}
|
||||
case 41:
|
||||
{
|
||||
// getItemDetail
|
||||
int slot = parseOptionalSlotNumber( args, 0, m_turtle.getSelectedSlot() );
|
||||
ItemStack stack = m_turtle.getInventory().getStackInSlot( slot );
|
||||
if( stack != null && stack.stackSize > 0 )
|
||||
{
|
||||
Item item = stack.getItem();
|
||||
String name = ((ResourceLocation)Item.itemRegistry.getNameForObject( item )).toString();
|
||||
int damage = stack.getItemDamage();
|
||||
int count = stack.stackSize;
|
||||
|
||||
Map<Object, Object> table = new HashMap<Object, Object>();
|
||||
table.put( "name", name );
|
||||
table.put( "damage", damage );
|
||||
table.put( "count", count );
|
||||
return new Object[] { table };
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Object[] { null };
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.turtle.blocks;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.computer.blocks.BlockComputerBase;
|
||||
import dan200.computercraft.shared.computer.blocks.TileCommandComputer;
|
||||
import dan200.computercraft.shared.computer.blocks.TileComputerBase;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.util.DirectionUtil;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.properties.IProperty;
|
||||
import net.minecraft.block.properties.PropertyDirection;
|
||||
import net.minecraft.block.properties.PropertyEnum;
|
||||
import net.minecraft.block.state.BlockState;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BlockTurtle extends BlockComputerBase
|
||||
{
|
||||
// Statics
|
||||
|
||||
public static class Properties
|
||||
{
|
||||
public static final PropertyDirection FACING = PropertyDirection.create( "facing", EnumFacing.Plane.HORIZONTAL );
|
||||
public static final PropertyEnum DYE = PropertyEnum.create( "dye", BlockTurtleDyeVariant.class );
|
||||
}
|
||||
|
||||
public static BlockTurtle createTurtleBlock()
|
||||
{
|
||||
return new BlockTurtle();
|
||||
}
|
||||
|
||||
// Members
|
||||
|
||||
public BlockTurtle()
|
||||
{
|
||||
super( Material.iron );
|
||||
setHardness( 2.5f );
|
||||
setUnlocalizedName( "computercraft:turtle" );
|
||||
setCreativeTab( ComputerCraft.mainCreativeTab );
|
||||
setDefaultState( this.blockState.getBaseState()
|
||||
.withProperty( Properties.FACING, EnumFacing.NORTH )
|
||||
.withProperty( Properties.DYE, BlockTurtleDyeVariant.None )
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRenderType()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockState createBlockState()
|
||||
{
|
||||
return new BlockState(this, new IProperty[] {
|
||||
Properties.FACING,
|
||||
Properties.DYE
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getStateFromMeta( int meta )
|
||||
{
|
||||
return getDefaultState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetaFromState( IBlockState state )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getActualState( IBlockState state, IBlockAccess world, BlockPos pos )
|
||||
{
|
||||
state = state.withProperty( Properties.FACING, getDirection( world, pos ) );
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof ITurtleTile )
|
||||
{
|
||||
ITurtleTile turtle = (ITurtleTile)tile;
|
||||
state = state.withProperty( Properties.DYE, BlockTurtleDyeVariant.fromColour( turtle.getColour() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
state = state.withProperty( Properties.DYE, BlockTurtleDyeVariant.None );
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IBlockState getDefaultBlockState( ComputerFamily family, EnumFacing placedSide )
|
||||
{
|
||||
return getDefaultState();
|
||||
}
|
||||
|
||||
private ComputerFamily getFamily()
|
||||
{
|
||||
if( this == ComputerCraft.Blocks.turtleAdvanced )
|
||||
{
|
||||
return ComputerFamily.Advanced;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ComputerFamily.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComputerFamily getFamily( int damage )
|
||||
{
|
||||
return getFamily();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComputerFamily getFamily( IBlockState state )
|
||||
{
|
||||
return getFamily();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TileComputerBase createTile( ComputerFamily family )
|
||||
{
|
||||
if( this == ComputerCraft.Blocks.turtleAdvanced )
|
||||
{
|
||||
return new TileTurtleAdvanced();
|
||||
}
|
||||
else if( this == ComputerCraft.Blocks.turtleExpanded )
|
||||
{
|
||||
return new TileTurtleExpanded();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new TileTurtle();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockPlacedBy( World world, BlockPos pos, IBlockState state, EntityLivingBase player, ItemStack itemstack )
|
||||
{
|
||||
// Not sure why this is necessary
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile != null && tile instanceof TileTurtle )
|
||||
{
|
||||
tile.setWorldObj( world ); // Not sure why this is necessary
|
||||
tile.setPos( pos ); // Not sure why this is necessary
|
||||
}
|
||||
|
||||
// Set direction
|
||||
EnumFacing dir = DirectionUtil.fromEntityRot( player );
|
||||
setDirection( world, pos, dir.getOpposite() );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.turtle.blocks;
|
||||
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import net.minecraft.util.IStringSerializable;
|
||||
|
||||
public enum BlockTurtleDyeVariant implements IStringSerializable
|
||||
{
|
||||
None( "none", null ),
|
||||
Black( "black", Colour.Black ),
|
||||
Red( "red", Colour.Red ),
|
||||
Green( "green", Colour.Green ),
|
||||
Brown( "brown", Colour.Brown ),
|
||||
Blue( "blue", Colour.Blue ),
|
||||
Purple( "purple", Colour.Purple ),
|
||||
Cyan( "cyan", Colour.Cyan ),
|
||||
LightGrey( "light_grey", Colour.LightGrey ),
|
||||
Grey( "grey", Colour.Grey ),
|
||||
Pink( "pink", Colour.Pink ),
|
||||
Lime( "lime", Colour.Lime ),
|
||||
Yellow( "yellow", Colour.Yellow ),
|
||||
LightBlue( "light_blue", Colour.LightBlue ),
|
||||
Magenta( "magenta", Colour.Magenta ),
|
||||
Orange( "orange", Colour.Orange ),
|
||||
White( "white", Colour.Orange );
|
||||
|
||||
public static BlockTurtleDyeVariant fromColour( Colour colour )
|
||||
{
|
||||
if( colour != null )
|
||||
{
|
||||
switch( colour )
|
||||
{
|
||||
case Black: return Black;
|
||||
case Red: return Red;
|
||||
case Green: return Green;
|
||||
case Brown: return Brown;
|
||||
case Blue: return Blue;
|
||||
case Purple: return Purple;
|
||||
case Cyan: return Cyan;
|
||||
case LightGrey: return LightGrey;
|
||||
case Grey: return Grey;
|
||||
case Pink: return Pink;
|
||||
case Lime: return Lime;
|
||||
case Yellow: return Yellow;
|
||||
case LightBlue: return LightBlue;
|
||||
case Magenta: return Magenta;
|
||||
case Orange: return Orange;
|
||||
case White: return White;
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
private String m_name;
|
||||
private Colour m_colour;
|
||||
|
||||
private BlockTurtleDyeVariant( String name, Colour colour )
|
||||
{
|
||||
m_name = name;
|
||||
m_colour = colour;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
public Colour getColour()
|
||||
{
|
||||
return m_colour;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.turtle.blocks;
|
||||
|
||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.api.turtle.TurtleSide;
|
||||
import dan200.computercraft.shared.common.IDirectionalTile;
|
||||
import dan200.computercraft.shared.computer.blocks.IComputerTile;
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.Vec3;
|
||||
|
||||
public interface ITurtleTile extends IComputerTile, IDirectionalTile
|
||||
{
|
||||
public Colour getColour();
|
||||
public ResourceLocation getOverlay();
|
||||
public ITurtleUpgrade getUpgrade( TurtleSide side );
|
||||
public ITurtleAccess getAccess();
|
||||
|
||||
public Vec3 getRenderOffset( float f );
|
||||
public float getRenderYaw( float f );
|
||||
public float getToolRenderAngle( TurtleSide side, float f );
|
||||
}
|
||||
@@ -0,0 +1,665 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.turtle.blocks;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.api.turtle.TurtleSide;
|
||||
import dan200.computercraft.api.turtle.TurtleUpgradeType;
|
||||
import dan200.computercraft.shared.computer.blocks.TileComputerBase;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.IComputer;
|
||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||
import dan200.computercraft.shared.turtle.apis.TurtleAPI;
|
||||
import dan200.computercraft.shared.turtle.core.TurtleBrain;
|
||||
import dan200.computercraft.shared.turtle.items.TurtleItemFactory;
|
||||
import dan200.computercraft.shared.util.*;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.projectile.EntityFireball;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.util.ITickable;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TileTurtle extends TileComputerBase
|
||||
implements ITurtleTile, IInventory, ITickable
|
||||
{
|
||||
// Statics
|
||||
|
||||
public static final int INVENTORY_SIZE = 16;
|
||||
public static final int INVENTORY_WIDTH = 4;
|
||||
public static final int INVENTORY_HEIGHT = 4;
|
||||
|
||||
// Members
|
||||
|
||||
private ItemStack[] m_inventory;
|
||||
private ItemStack[] m_previousInventory;
|
||||
private boolean m_inventoryChanged;
|
||||
private TurtleBrain m_brain;
|
||||
private boolean m_moved;
|
||||
|
||||
public TileTurtle()
|
||||
{
|
||||
m_inventory = new ItemStack[ INVENTORY_SIZE ];
|
||||
m_previousInventory = new ItemStack[ getSizeInventory() ];
|
||||
m_inventoryChanged = false;
|
||||
m_brain = createBrain();
|
||||
m_moved = false;
|
||||
}
|
||||
|
||||
public boolean hasMoved()
|
||||
{
|
||||
return m_moved;
|
||||
}
|
||||
|
||||
protected TurtleBrain createBrain()
|
||||
{
|
||||
return new TurtleBrain( this );
|
||||
}
|
||||
|
||||
protected final ServerComputer createComputer( int instanceID, int id, int termWidth, int termHeight )
|
||||
{
|
||||
ServerComputer computer = new ServerComputer(
|
||||
worldObj,
|
||||
id,
|
||||
m_label,
|
||||
instanceID,
|
||||
getFamily(),
|
||||
termWidth,
|
||||
termHeight
|
||||
);
|
||||
computer.setPosition( getPos() );
|
||||
computer.addAPI( new TurtleAPI( computer.getAPIEnvironment(), getAccess() ) );
|
||||
m_brain.setupComputer( computer );
|
||||
return computer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServerComputer createComputer( int instanceID, int id )
|
||||
{
|
||||
return createComputer( instanceID, id, ComputerCraft.terminalWidth_turtle, ComputerCraft.terminalHeight_turtle );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
if( !hasMoved() )
|
||||
{
|
||||
// Stop computer
|
||||
super.destroy();
|
||||
|
||||
// Drop contents
|
||||
if( !worldObj.isRemote )
|
||||
{
|
||||
int size = getSizeInventory();
|
||||
for( int i=0; i<size; ++i )
|
||||
{
|
||||
ItemStack stack = getStackInSlot( i );
|
||||
if( stack != null )
|
||||
{
|
||||
WorldUtil.dropItemStack( stack, worldObj, getPos() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just turn off any redstone we had on
|
||||
for( EnumFacing dir : EnumFacing.VALUES )
|
||||
{
|
||||
RedstoneUtil.propogateRedstoneOutput( worldObj, getPos(), dir );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void unload()
|
||||
{
|
||||
if( !hasMoved() )
|
||||
{
|
||||
super.unload();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDroppedItems( List<ItemStack> drops, int fortune, boolean creative, boolean silkTouch )
|
||||
{
|
||||
IComputer computer = getComputer();
|
||||
if( !creative || (computer != null && computer.getLabel() != null) )
|
||||
{
|
||||
drops.add( TurtleItemFactory.create( this ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickedItem()
|
||||
{
|
||||
return TurtleItemFactory.create( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActivate( EntityPlayer player, EnumFacing side, float hitX, float hitY, float hitZ )
|
||||
{
|
||||
// Request description from server
|
||||
requestTileEntityUpdate();
|
||||
|
||||
// Apply dye
|
||||
ItemStack currentItem = player.getCurrentEquippedItem();
|
||||
if( currentItem != null )
|
||||
{
|
||||
if( currentItem.getItem() == Items.dye )
|
||||
{
|
||||
// Dye to change turtle colour
|
||||
if( !worldObj.isRemote )
|
||||
{
|
||||
int dye = (currentItem.getItemDamage() & 0xf);
|
||||
if( m_brain.getDyeColour() != dye )
|
||||
{
|
||||
m_brain.setDyeColour( dye );
|
||||
if( !player.capabilities.isCreativeMode )
|
||||
{
|
||||
currentItem.stackSize--;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if( currentItem.getItem() == Items.water_bucket && m_brain.getDyeColour() != -1 )
|
||||
{
|
||||
// Water to remove turtle colour
|
||||
if( !worldObj.isRemote )
|
||||
{
|
||||
if( m_brain.getDyeColour() != -1 )
|
||||
{
|
||||
m_brain.setDyeColour( -1 );
|
||||
if( !player.capabilities.isCreativeMode )
|
||||
{
|
||||
currentItem.setItem( Items.bucket );
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Open GUI or whatever
|
||||
return super.onActivate( player, side, hitX, hitY, hitZ );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canNameWithTag( EntityPlayer player )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openGUI( EntityPlayer player )
|
||||
{
|
||||
ComputerCraft.openTurtleGUI( player, this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSolidOnSide( int side )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImmuneToExplosion( Entity exploder )
|
||||
{
|
||||
if( getFamily() == ComputerFamily.Advanced )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( exploder != null && ( exploder instanceof EntityLivingBase || exploder instanceof EntityFireball ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB getBounds()
|
||||
{
|
||||
Vec3 offset = getRenderOffset( 1.0f );
|
||||
return new AxisAlignedBB(
|
||||
offset.xCoord + 0.125, offset.yCoord + 0.125, offset.zCoord + 0.125,
|
||||
offset.xCoord + 0.875, offset.yCoord + 0.875, offset.zCoord + 0.875
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double getInteractRange( EntityPlayer player )
|
||||
{
|
||||
return 12.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
super.update();
|
||||
m_brain.update();
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
if( !worldObj.isRemote && m_inventoryChanged )
|
||||
{
|
||||
IComputer computer = getComputer();
|
||||
if( computer != null )
|
||||
{
|
||||
computer.queueEvent( "turtle_inventory" );
|
||||
}
|
||||
|
||||
m_inventoryChanged = false;
|
||||
for( int n=0; n<getSizeInventory(); ++n )
|
||||
{
|
||||
m_previousInventory[n] = InventoryUtil.copyItem( getStackInSlot( n ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.readFromNBT(nbttagcompound);
|
||||
|
||||
// Read inventory
|
||||
NBTTagList nbttaglist = nbttagcompound.getTagList("Items", Constants.NBT.TAG_COMPOUND);
|
||||
m_inventory = new ItemStack[ INVENTORY_SIZE ];
|
||||
m_previousInventory = new ItemStack[ getSizeInventory() ];
|
||||
for( int i=0; i<nbttaglist.tagCount(); ++i )
|
||||
{
|
||||
NBTTagCompound itemtag = nbttaglist.getCompoundTagAt( i );
|
||||
int slot = itemtag.getByte("Slot") & 0xff;
|
||||
if( slot >= 0 && slot < getSizeInventory() )
|
||||
{
|
||||
m_inventory[slot] = ItemStack.loadItemStackFromNBT( itemtag );
|
||||
m_previousInventory[slot] = InventoryUtil.copyItem( m_inventory[slot] );
|
||||
}
|
||||
}
|
||||
|
||||
// Read state
|
||||
m_brain.readFromNBT( nbttagcompound );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.writeToNBT( nbttagcompound );
|
||||
|
||||
// Write inventory
|
||||
NBTTagList nbttaglist = new NBTTagList();
|
||||
for( int i=0; i<INVENTORY_SIZE; ++i )
|
||||
{
|
||||
if( m_inventory[i] != null )
|
||||
{
|
||||
NBTTagCompound itemtag = new NBTTagCompound();
|
||||
itemtag.setByte( "Slot", (byte)i );
|
||||
m_inventory[i].writeToNBT(itemtag);
|
||||
nbttaglist.appendTag(itemtag);
|
||||
}
|
||||
}
|
||||
nbttagcompound.setTag( "Items", nbttaglist );
|
||||
|
||||
// Write brain
|
||||
m_brain.writeToNBT( nbttagcompound );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isPeripheralBlockedOnSide( int localSide )
|
||||
{
|
||||
return hasPeripheralUpgradeOnSide( localSide );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isRedstoneBlockedOnSide( int localSide )
|
||||
{
|
||||
return hasPeripheralUpgradeOnSide( localSide );
|
||||
}
|
||||
|
||||
// IDirectionalTile
|
||||
|
||||
@Override
|
||||
public EnumFacing getDirection()
|
||||
{
|
||||
return m_brain.getDirection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirection( EnumFacing dir )
|
||||
{
|
||||
m_brain.setDirection( dir );
|
||||
}
|
||||
|
||||
// ITurtleTile
|
||||
|
||||
@Override
|
||||
public ITurtleUpgrade getUpgrade( TurtleSide side )
|
||||
{
|
||||
return m_brain.getUpgrade( side );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Colour getColour()
|
||||
{
|
||||
int dye = m_brain.getDyeColour();
|
||||
if( dye >= 0 )
|
||||
{
|
||||
return Colour.values()[ dye ];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getOverlay()
|
||||
{
|
||||
return m_brain.getOverlay();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITurtleAccess getAccess()
|
||||
{
|
||||
return m_brain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3 getRenderOffset( float f )
|
||||
{
|
||||
return m_brain.getRenderOffset( f );
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getRenderYaw( float f )
|
||||
{
|
||||
return m_brain.getVisualYaw( f );
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getToolRenderAngle( TurtleSide side, float f )
|
||||
{
|
||||
return m_brain.getToolRenderAngle( side, f );
|
||||
}
|
||||
|
||||
// IInventory
|
||||
|
||||
@Override
|
||||
public int getSizeInventory()
|
||||
{
|
||||
return INVENTORY_SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot( int slot )
|
||||
{
|
||||
if( slot >= 0 && slot < INVENTORY_SIZE )
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
return m_inventory[ slot ];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeStackFromSlot( int slot )
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
ItemStack result = getStackInSlot( slot );
|
||||
setInventorySlotContents( slot, null );
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack decrStackSize( int slot, int count )
|
||||
{
|
||||
if( count == 0 )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
ItemStack stack = getStackInSlot( slot );
|
||||
if( stack == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if( stack.stackSize <= count )
|
||||
{
|
||||
setInventorySlotContents( slot, null );
|
||||
return stack;
|
||||
}
|
||||
|
||||
ItemStack part = stack.splitStack( count );
|
||||
onInventoryDefinitelyChanged();
|
||||
return part;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInventorySlotContents( int i, ItemStack stack )
|
||||
{
|
||||
if( i >= 0 && i < INVENTORY_SIZE )
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
if( !InventoryUtil.areItemsEqual( stack, m_inventory[ i ] ) )
|
||||
{
|
||||
m_inventory[ i ] = stack;
|
||||
onInventoryDefinitelyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear()
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
boolean changed = false;
|
||||
for( int i = 0; i < INVENTORY_SIZE; ++i )
|
||||
{
|
||||
if( m_inventory[i] != null )
|
||||
{
|
||||
m_inventory[i] = null;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if( changed )
|
||||
{
|
||||
onInventoryDefinitelyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
IComputer computer = getComputer();
|
||||
if( computer != null )
|
||||
{
|
||||
String label = computer.getLabel();
|
||||
if( label != null && label.length() > 0 )
|
||||
{
|
||||
return label;
|
||||
}
|
||||
}
|
||||
return "tile.computercraft:turtle.name";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCustomName()
|
||||
{
|
||||
IComputer computer = getComputer();
|
||||
if( computer != null )
|
||||
{
|
||||
String label = computer.getLabel();
|
||||
if( label != null && label.length() > 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IChatComponent getDisplayName()
|
||||
{
|
||||
if( hasCustomName() )
|
||||
{
|
||||
return new ChatComponentText( getName() );
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ChatComponentTranslation( getName() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInventoryStackLimit()
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openInventory( EntityPlayer player )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeInventory( EntityPlayer player )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValidForSlot( int slot, ItemStack stack )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markDirty()
|
||||
{
|
||||
super.markDirty();
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
if( !m_inventoryChanged )
|
||||
{
|
||||
for( int n=0; n<getSizeInventory(); ++n )
|
||||
{
|
||||
if( !ItemStack.areItemStacksEqual( getStackInSlot( n ), m_previousInventory[n] ) )
|
||||
{
|
||||
m_inventoryChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseableByPlayer( EntityPlayer player )
|
||||
{
|
||||
return isUsable( player, false );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFieldCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getField(int id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setField(int id, int value)
|
||||
{
|
||||
}
|
||||
|
||||
public boolean isUseableByRemote( EntityPlayer player )
|
||||
{
|
||||
return isUsable( player, true );
|
||||
}
|
||||
|
||||
public void onInventoryDefinitelyChanged()
|
||||
{
|
||||
super.markDirty();
|
||||
m_inventoryChanged = true;
|
||||
}
|
||||
|
||||
public void onTileEntityChange()
|
||||
{
|
||||
super.markDirty();
|
||||
}
|
||||
|
||||
// Networking stuff
|
||||
|
||||
@Override
|
||||
public void writeDescription( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.writeDescription( nbttagcompound );
|
||||
m_brain.writeDescription( nbttagcompound );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readDescription( NBTTagCompound nbttagcompound )
|
||||
{
|
||||
super.readDescription( nbttagcompound );
|
||||
m_brain.readDescription( nbttagcompound );
|
||||
updateBlock();
|
||||
}
|
||||
|
||||
// Privates
|
||||
|
||||
private boolean hasPeripheralUpgradeOnSide( int side )
|
||||
{
|
||||
ITurtleUpgrade upgrade;
|
||||
switch( side )
|
||||
{
|
||||
case 4: upgrade = getUpgrade( TurtleSide.Right ); break;
|
||||
case 5: upgrade = getUpgrade( TurtleSide.Left ); break;
|
||||
default: return false;
|
||||
}
|
||||
if( upgrade != null && upgrade.getType() == TurtleUpgradeType.Peripheral )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void transferStateFrom( TileTurtle copy )
|
||||
{
|
||||
super.transferStateFrom( copy );
|
||||
m_inventory = copy.m_inventory;
|
||||
m_previousInventory = copy.m_previousInventory;
|
||||
m_inventoryChanged = copy.m_inventoryChanged;
|
||||
m_brain = copy.m_brain;
|
||||
m_brain.setOwner( this );
|
||||
copy.m_moved = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.turtle.blocks;
|
||||
|
||||
public class TileTurtleAdvanced extends TileTurtle
|
||||
{
|
||||
public TileTurtleAdvanced()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.turtle.blocks;
|
||||
|
||||
public class TileTurtleExpanded extends TileTurtle
|
||||
{
|
||||
public TileTurtleExpanded()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.turtle.core;
|
||||
|
||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
public enum InteractDirection
|
||||
{
|
||||
Forward,
|
||||
Up,
|
||||
Down;
|
||||
|
||||
public EnumFacing toWorldDir( ITurtleAccess turtle )
|
||||
{
|
||||
switch( this )
|
||||
{
|
||||
case Forward:
|
||||
default:
|
||||
{
|
||||
return turtle.getDirection();
|
||||
}
|
||||
case Up:
|
||||
{
|
||||
return EnumFacing.UP;
|
||||
}
|
||||
case Down:
|
||||
{
|
||||
return EnumFacing.DOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.turtle.core;
|
||||
|
||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
public enum MoveDirection
|
||||
{
|
||||
Forward,
|
||||
Back,
|
||||
Up,
|
||||
Down;
|
||||
|
||||
public EnumFacing toWorldDir( ITurtleAccess turtle )
|
||||
{
|
||||
switch( this )
|
||||
{
|
||||
case Forward:
|
||||
default:
|
||||
{
|
||||
return turtle.getDirection();
|
||||
}
|
||||
case Back:
|
||||
{
|
||||
return turtle.getDirection().getOpposite();
|
||||
}
|
||||
case Up:
|
||||
{
|
||||
return EnumFacing.UP;
|
||||
}
|
||||
case Down:
|
||||
{
|
||||
return EnumFacing.DOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.turtle.core;
|
||||
|
||||
public enum TurnDirection
|
||||
{
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2016. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.turtle.core;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import dan200.computercraft.api.turtle.TurtleSide;
|
||||
import dan200.computercraft.api.turtle.TurtleVerb;
|
||||
|
||||
public class TurtleAttackCommand extends TurtleToolCommand
|
||||
{
|
||||
public TurtleAttackCommand( InteractDirection direction, Optional<TurtleSide> side )
|
||||
{
|
||||
super( TurtleVerb.Attack, direction, side );
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user