1
0
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:
Daniel Ratcliffe
2017-05-01 14:32:39 +01:00
parent 38623b31c4
commit e85cdacbc5
1123 changed files with 191332 additions and 3 deletions

View File

@@ -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 );
}
}
}

View File

@@ -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 );
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}

View File

@@ -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 );
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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 );
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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 );
}
}

View File

@@ -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 );
}
}

View File

@@ -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();
}
}
}

View File

@@ -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());
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}

View File

@@ -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;
}
}
}

View File

@@ -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 ];
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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" );
}
}

View File

@@ -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
}

View File

@@ -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());
}
}

View File

@@ -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 );
}

View File

@@ -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();
}

View File

@@ -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;
}
}
}
}

View File

@@ -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" );
}
}

View File

@@ -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 );
}
}

View File

@@ -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;
}
}

View File

@@ -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 );
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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 );
}

View File

@@ -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();
}
}
}

View File

@@ -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(); }
}

View File

@@ -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());
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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 ) );
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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 );
}

View File

@@ -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();
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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() );
}
}

View File

@@ -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;
}
}

View File

@@ -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 );
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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() );
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}

View File

@@ -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 );
}

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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 );
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}
}

View File

@@ -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 )
{
}
}
}

View File

@@ -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 );
}

View File

@@ -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 );
}

View File

@@ -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;
}
}
}
}

View File

@@ -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() );
}
}

View File

@@ -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();
}
}

View File

@@ -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 );
}

View File

@@ -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;
}
}

View File

@@ -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()
{
}
}

View File

@@ -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()
{
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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,
}

View File

@@ -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