1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-06-25 22:53:22 +00:00

Merge pull request #101 from SquidDev-CC/feature/no-ticking

Make several tile entities non-ticking, hopefully reducing
server load.
This commit is contained in:
SquidDev 2019-01-21 08:29:42 +00:00 committed by GitHub
commit 2681e578c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 770 additions and 851 deletions

View File

@ -229,6 +229,14 @@ public static class PocketUpgrades
public static PocketModem wirelessModem;
public static PocketModem advancedModem;
public static PocketSpeaker speaker;
@Deprecated
public static PocketSpeaker pocketSpeaker;
}
@Deprecated
public static class Upgrades {
public static TurtleModem advancedModem;
}
// Registries

View File

@ -16,6 +16,7 @@ public interface ILuaAPI extends dan200.computercraft.api.lua.ILuaAPI
{
void advance( double v );
@Override
default void update()
{
advance( 0.05 );

View File

@ -26,12 +26,14 @@ public ResourceQueue()
{
}
@Override
public synchronized void shutdown()
{
super.shutdown();
pending.clear();
}
@Override
public synchronized boolean queue( Supplier<T> resource )
{
if( !active ) return false;
@ -40,6 +42,7 @@ public synchronized boolean queue( Supplier<T> resource )
return true;
}
@Override
public synchronized void release( T resource )
{
super.release( resource );

View File

@ -239,6 +239,7 @@ void success( ILuaObject object )
if( tryClose() ) environment.queueEvent( SUCCESS_EVENT, new Object[] { address, object } );
}
@Override
protected void dispose()
{
super.dispose();

View File

@ -29,11 +29,18 @@ public class Terminal
private final Palette m_palette;
private boolean m_changed;
private final Runnable onChanged;
public Terminal( int width, int height )
{
this( width, height, null );
}
public Terminal( int width, int height, Runnable changedCallback )
{
m_width = width;
m_height = height;
this.onChanged = changedCallback;
m_cursorColour = 0;
m_cursorBackgroundColour = 15;
@ -65,7 +72,7 @@ public synchronized void reset()
m_cursorY = 0;
m_cursorBlink = false;
clear();
m_changed = true;
setChanged();
m_palette.resetColours();
}
@ -122,7 +129,7 @@ else if( m_width == oldWidth )
m_backgroundColour[i].write( oldBackgroundColour[i] );
}
}
m_changed = true;
setChanged();
}
public void setCursorPos( int x, int y )
@ -131,7 +138,7 @@ public void setCursorPos( int x, int y )
{
m_cursorX = x;
m_cursorY = y;
m_changed = true;
setChanged();
}
}
@ -140,7 +147,7 @@ public void setCursorBlink( boolean blink )
if( m_cursorBlink != blink )
{
m_cursorBlink = blink;
m_changed = true;
setChanged();
}
}
@ -149,7 +156,7 @@ public void setTextColour( int colour )
if( m_cursorColour != colour )
{
m_cursorColour = colour;
m_changed = true;
setChanged();
}
}
@ -158,7 +165,7 @@ public void setBackgroundColour( int colour )
if( m_cursorBackgroundColour != colour )
{
m_cursorBackgroundColour = colour;
m_changed = true;
setChanged();
}
}
@ -201,7 +208,7 @@ public synchronized void blit( String text, String textColour, String background
m_text[y].write( text, x );
m_textColour[y].write( textColour, x );
m_backgroundColour[y].write( backgroundColour, x );
m_changed = true;
setChanged();
}
}
@ -214,7 +221,7 @@ public synchronized void write( String text )
m_text[y].write( text, x );
m_textColour[y].fill( base16.charAt( m_cursorColour ), x, x + text.length() );
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ), x, x + text.length() );
m_changed = true;
setChanged();
}
}
@ -244,7 +251,7 @@ public synchronized void scroll( int yDiff )
m_text = newText;
m_textColour = newTextColour;
m_backgroundColour = newBackgroundColour;
m_changed = true;
setChanged();
}
}
@ -256,7 +263,7 @@ public synchronized void clear()
m_textColour[y].fill( base16.charAt( m_cursorColour ) );
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ) );
}
m_changed = true;
setChanged();
}
public synchronized void clearLine()
@ -267,7 +274,7 @@ public synchronized void clearLine()
m_text[y].fill( ' ' );
m_textColour[y].fill( base16.charAt( m_cursorColour ) );
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ) );
m_changed = true;
setChanged();
}
}
@ -285,7 +292,7 @@ public synchronized void setLine( int y, String text, String textColour, String
m_text[y].write( text );
m_textColour[y].write( textColour );
m_backgroundColour[y].write( backgroundColour );
m_changed = true;
setChanged();
}
public synchronized TextBuffer getTextColourLine( int y )
@ -306,17 +313,23 @@ public synchronized TextBuffer getBackgroundColourLine( int y )
return null;
}
public boolean getChanged()
/**
* @deprecated All {@code *Changed()} methods are deprecated: one should pass in a callback
* instead.
*/
@Deprecated
public final boolean getChanged()
{
return m_changed;
}
public void setChanged()
public final void setChanged()
{
m_changed = true;
if( onChanged != null ) onChanged.run();
}
public void clearChanged()
public final void clearChanged()
{
m_changed = false;
}
@ -371,6 +384,6 @@ public synchronized void readFromNBT( NBTTagCompound nbt )
{
m_palette.readFromNBT( nbt );
}
m_changed = true;
setChanged();
}
}

View File

@ -200,6 +200,7 @@ public static void registerItems( RegistryEvent.Register<Item> event )
registerTurtleUpgrades();
registerPocketUpgrades();
registerLegacyUpgrades();
}
@SubscribeEvent
@ -336,6 +337,13 @@ public static void registerPocketUpgrades()
ComputerCraftAPI.registerPocketUpgrade( ComputerCraft.PocketUpgrades.speaker );
}
@SuppressWarnings( "deprecation" )
private static void registerLegacyUpgrades()
{
ComputerCraft.PocketUpgrades.pocketSpeaker = ComputerCraft.PocketUpgrades.speaker;
ComputerCraft.Upgrades.advancedModem = ComputerCraft.TurtleUpgrades.advancedModem;
}
@SubscribeEvent
public static void remapItems( RegistryEvent.MissingMappings<Item> mappings )
{

View File

@ -21,6 +21,7 @@
import net.minecraft.world.World;
import javax.annotation.Nonnull;
import java.util.Random;
public abstract class BlockGeneric extends Block implements ITileEntityProvider
{
@ -138,6 +139,13 @@ public final void onNeighborChange( IBlockAccess world, BlockPos pos, BlockPos n
}
}
@Override
public void updateTick( World world, BlockPos pos, IBlockState state, Random rand )
{
TileEntity te = world.getTileEntity( pos );
if( te instanceof TileGeneric ) ((TileGeneric) te).updateTick();
}
@Override
@Deprecated
public final boolean canProvidePower( IBlockState state )

View File

@ -22,19 +22,14 @@ public ClientTerminal( boolean colour )
m_terminalChanged = false;
}
public void update()
{
if( m_terminal != null )
{
m_terminalChanged |= m_terminal.getChanged();
m_terminal.clearChanged();
}
}
public boolean pollTerminalChanged()
{
boolean changed = m_terminalChanged;
m_terminalChanged = false;
Terminal terminal = m_terminal;
if( terminal != null ) terminal.clearChanged();
return changed;
}
@ -71,7 +66,7 @@ private void resizeTerminal( int width, int height )
{
if( m_terminal == null )
{
m_terminal = new Terminal( width, height );
m_terminal = new Terminal( width, height, () -> m_terminalChanged = true );
m_terminalChanged = true;
}
else

View File

@ -9,35 +9,33 @@
import dan200.computercraft.core.terminal.Terminal;
import net.minecraft.nbt.NBTTagCompound;
import java.util.concurrent.atomic.AtomicBoolean;
public class ServerTerminal implements ITerminal
{
private final boolean m_colour;
private Terminal m_terminal;
private boolean m_terminalChanged;
private boolean m_terminalChangedLastFrame;
private final AtomicBoolean m_terminalChanged = new AtomicBoolean( false );
private boolean m_terminalChangedLastFrame = false;
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;
m_terminal = new Terminal( terminalWidth, terminalHeight, this::markTerminalChanged );
}
public void resize( int width, int height )
protected void resize( int width, int height )
{
if( m_terminal == null )
{
m_terminal = new Terminal( width, height );
m_terminalChanged = true;
m_terminal = new Terminal( width, height, this::markTerminalChanged );
markTerminalChanged();
}
else
{
@ -50,23 +48,21 @@ public void delete()
if( m_terminal != null )
{
m_terminal = null;
m_terminalChanged = true;
markTerminalChanged();
}
}
protected void markTerminalChanged()
{
m_terminalChanged = true;
m_terminalChanged.set( true );
}
public void update()
{
m_terminalChangedLastFrame = m_terminalChanged || (m_terminal != null && m_terminal.getChanged());
if( m_terminal != null )
{
m_terminal.clearChanged();
}
m_terminalChanged = false;
Terminal terminal = m_terminal;
if( terminal != null ) terminal.clearChanged();
m_terminalChangedLastFrame = m_terminalChanged.getAndSet( false );
}
public boolean hasTerminalChanged()

View File

@ -72,6 +72,10 @@ public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour )
{
}
protected void updateTick()
{
}
public boolean getRedstoneConnectivity( EnumFacing side )
{
return false;

View File

@ -8,19 +8,15 @@
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.util.DirectionUtil;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyDirection;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.state.BlockStateContainer;
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.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import javax.annotation.Nonnull;

View File

@ -32,10 +32,8 @@ public ClientComputer( int instanceID )
m_instanceID = instanceID;
}
@Override
public void update()
{
super.update();
m_changedLastFrame = m_changed;
m_changed = false;
}

View File

@ -7,6 +7,8 @@
package dan200.computercraft.shared.peripheral.common;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.common.BlockGeneric;
import dan200.computercraft.shared.common.TileGeneric;
import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
import dan200.computercraft.shared.peripheral.modem.ModemBounds;
@ -15,18 +17,21 @@
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
import dan200.computercraft.shared.peripheral.speaker.TileSpeaker;
import dan200.computercraft.shared.util.DirectionUtil;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyDirection;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.state.BlockFaceShape;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
@ -34,7 +39,7 @@
import javax.annotation.Nonnull;
public class BlockPeripheral extends BlockPeripheralBase
public class BlockPeripheral extends BlockGeneric
{
public static class Properties
{
@ -44,6 +49,7 @@ public static class Properties
public BlockPeripheral()
{
super( Material.ROCK );
setHardness( 2.0f );
setTranslationKey( "computercraft:peripheral" );
setCreativeTab( ComputerCraft.mainCreativeTab );
@ -187,202 +193,107 @@ public int getMetaFromState( IBlockState state )
@Deprecated
public IBlockState getActualState( @Nonnull IBlockState state, IBlockAccess world, BlockPos pos )
{
int anim;
EnumFacing dir;
TileEntity tile = world.getTileEntity( pos );
if( tile instanceof TilePeripheralBase )
{
TilePeripheralBase peripheral = (TilePeripheralBase) tile;
anim = peripheral.getAnim();
dir = peripheral.getDirection();
}
else
{
anim = 0;
dir = state.getValue( Properties.FACING );
switch( state.getValue( 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 )
if( !(tile instanceof TileDiskDrive) ) return state;
TileDiskDrive drive = (TileDiskDrive) tile;
state = state.withProperty( Properties.FACING, drive.getDirection() );
switch( drive.getAnim() )
{
case 0:
default:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveEmpty );
break;
}
case 0:
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveEmpty );
case 1:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveInvalid );
break;
}
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveInvalid );
case 2:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveFull );
break;
}
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveFull );
}
break;
}
case Printer:
{
state = state.withProperty( Properties.FACING, dir );
switch( anim )
if( !(tile instanceof TilePrinter) ) return state;
TilePrinter printer = (TilePrinter) tile;
state = state.withProperty( Properties.FACING, printer.getDirection() );
switch( printer.getAnim() )
{
case 0:
default:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterEmpty );
break;
}
case 0:
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterEmpty );
case 1:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterTopFull );
break;
}
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterTopFull );
case 2:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterBottomFull );
break;
}
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterBottomFull );
case 3:
{
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterBothFull );
break;
}
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterBothFull );
}
break;
}
case WirelessModem:
{
switch( dir )
if( !(tile instanceof TileWirelessModem) ) return state;
TileWirelessModem modem = (TileWirelessModem) tile;
EnumFacing direction = modem.getDirection();
switch( direction )
{
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;
}
return state
.withProperty( Properties.FACING, EnumFacing.NORTH )
.withProperty( Properties.VARIANT,
modem.isOn() ? BlockPeripheralVariant.WirelessModemUpOn : BlockPeripheralVariant.WirelessModemUpOff );
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;
}
return state
.withProperty( Properties.FACING, EnumFacing.NORTH )
.withProperty( Properties.VARIANT,
modem.isOn() ? BlockPeripheralVariant.WirelessModemDownOn : BlockPeripheralVariant.WirelessModemDownOff );
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;
return state
.withProperty( Properties.FACING, direction )
.withProperty( Properties.VARIANT,
modem.isOn() ? BlockPeripheralVariant.WirelessModemOn : BlockPeripheralVariant.WirelessModemOff );
}
}
break;
}
case Speaker:
{
state = state.withProperty( Properties.FACING, dir );
break;
if( !(tile instanceof TileSpeaker) ) return state;
return state.withProperty( Properties.FACING, ((TileSpeaker) tile).getDirection() );
}
case Monitor:
case AdvancedMonitor:
{
EnumFacing front;
int xIndex, yIndex, width, height;
if( 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;
}
if( !(tile instanceof TileMonitor) ) return state;
TileMonitor monitor = (TileMonitor) tile;
EnumFacing dir = monitor.getDirection();
EnumFacing front = monitor.getFront();
int xIndex = monitor.getXIndex();
int yIndex = monitor.getYIndex();
int width = monitor.getWidth();
int height = monitor.getHeight();
BlockPeripheralVariant baseVariant;
if( front == EnumFacing.UP )
{
baseVariant = (type == PeripheralType.AdvancedMonitor) ?
baseVariant = type == PeripheralType.AdvancedMonitor ?
BlockPeripheralVariant.AdvancedMonitorUp :
BlockPeripheralVariant.MonitorUp;
}
else if( front == EnumFacing.DOWN )
{
baseVariant = (type == PeripheralType.AdvancedMonitor) ?
baseVariant = type == PeripheralType.AdvancedMonitor ?
BlockPeripheralVariant.AdvancedMonitorDown :
BlockPeripheralVariant.MonitorDown;
}
else
{
baseVariant = (type == PeripheralType.AdvancedMonitor) ?
baseVariant = type == PeripheralType.AdvancedMonitor ?
BlockPeripheralVariant.AdvancedMonitor :
BlockPeripheralVariant.Monitor;
}
@ -446,20 +357,21 @@ else if( yIndex < height - 1 )
}
}
state = state.withProperty( Properties.FACING, dir );
state = state.withProperty( Properties.VARIANT,
BlockPeripheralVariant.values()[baseVariant.ordinal() + subType]
);
break;
return state
.withProperty( Properties.FACING, dir )
.withProperty( Properties.VARIANT, BlockPeripheralVariant.values()[baseVariant.ordinal() + subType] );
}
default:
return state;
}
return state;
}
@Nonnull
@Override
public IBlockState getDefaultBlockState( PeripheralType type, EnumFacing placedSide )
@Deprecated
public final IBlockState getStateForPlacement( World world, BlockPos pos, EnumFacing placedSide, float hitX, float hitY, float hitZ, int damage, EntityLivingBase placer )
{
switch( type )
switch( getPeripheralType( damage ) )
{
case DiskDrive:
default:
@ -515,45 +427,32 @@ else if( dir == EnumFacing.UP )
}
}
@Override
public PeripheralType getPeripheralType( int damage )
{
return ComputerCraft.Items.peripheral.getPeripheralType( damage );
}
@Override
public PeripheralType getPeripheralType( IBlockState state )
{
return state.getValue( Properties.VARIANT ).getPeripheralType();
}
@Override
public TilePeripheralBase createTile( PeripheralType type )
private TileGeneric 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();
}
case Speaker:
{
return new TileSpeaker();
}
}
}
@ -568,11 +467,11 @@ public void onBlockPlacedBy( World world, BlockPos pos, IBlockState state, Entit
case Printer:
{
EnumFacing dir = DirectionUtil.fromEntityRot( player );
setDirection( world, pos, dir );
if( stack.hasDisplayName() && tile instanceof TilePeripheralBase )
{
TilePeripheralBase peripheral = (TilePeripheralBase) tile;
peripheral.setLabel( stack.getDisplayName() );
peripheral.setDirection( dir );
}
break;
}
@ -659,13 +558,46 @@ public int getLightOpacity( IBlockState state )
@Override
@Deprecated
public AxisAlignedBB getBoundingBox( IBlockState state, IBlockAccess source, BlockPos pos )
@Nonnull
public AxisAlignedBB getBoundingBox( IBlockState state, IBlockAccess world, BlockPos pos )
{
if( getPeripheralType( state ) == PeripheralType.WirelessModem )
{
return ModemBounds.getBounds( getDirection( source, pos ) );
TileEntity tile = world.getTileEntity( pos );
if( tile instanceof TileWirelessModem )
{
return ModemBounds.getBounds( ((TileWirelessModem) tile).getDirection() );
}
}
return super.getBoundingBox( state, source, pos );
return super.getBoundingBox( state, world, pos );
}
@Override
public final boolean canPlaceBlockOnSide( @Nonnull World world, @Nonnull BlockPos pos, EnumFacing side )
{
return true; // ItemPeripheralBase handles this
}
@Override
public final TileGeneric createTile( IBlockState state )
{
return createTile( getPeripheralType( state ) );
}
@Override
public final TileGeneric createTile( int damage )
{
return createTile( getPeripheralType( damage ) );
}
@Nonnull
@Override
public ItemStack getPickBlock( @Nonnull IBlockState state, RayTraceResult target, @Nonnull World world, @Nonnull BlockPos pos, EntityPlayer player )
{
TileEntity tile = world.getTileEntity( pos );
return tile instanceof ITilePeripheral
? PeripheralItemFactory.create( (ITilePeripheral) tile )
: super.getPickBlock( state, target, world, pos, player );
}
}

View File

@ -1,79 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. 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.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
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 canPlaceBlockOnSide( @Nonnull World world, @Nonnull BlockPos pos, EnumFacing side )
{
return true; // ItemPeripheralBase handles this
}
@Nonnull
@Override
@Deprecated
public final IBlockState getStateForPlacement( World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ, int damage, EntityLivingBase placer )
{
return getDefaultBlockState( getPeripheralType( damage ), side );
}
@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 ) );
}
@Nonnull
@Override
public ItemStack getPickBlock( @Nonnull IBlockState state, RayTraceResult target, @Nonnull World world, @Nonnull BlockPos pos, EntityPlayer player )
{
TileEntity tile = world.getTileEntity( pos );
return tile instanceof IPeripheralTile ? PeripheralItemFactory.create( (IPeripheralTile) tile ) : super.getPickBlock( state, target, world, pos, player );
}
}

View File

@ -7,15 +7,9 @@
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 interface IPeripheralTile
{
PeripheralType getPeripheralType();
IPeripheral getPeripheral( EnumFacing side );
String getLabel();
}

View File

@ -0,0 +1,26 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.peripheral.common;
import dan200.computercraft.shared.peripheral.PeripheralType;
/**
* The tile for {@link BlockPeripheral}.
*/
public interface ITilePeripheral
{
PeripheralType getPeripheralType();
default String getLabel()
{
return null;
}
default void setLabel( String label )
{
}
}

View File

@ -15,7 +15,7 @@
public class PeripheralItemFactory
{
@Nonnull
public static ItemStack create( IPeripheralTile tile )
public static ItemStack create( ITilePeripheral tile )
{
return create( tile.getPeripheralType(), tile.getLabel(), 1 );
}
@ -34,7 +34,7 @@ public static ItemStack create( PeripheralType type, String label, int quantity
return ComputerCraft.Items.peripheral.create( type, label, quantity );
case WiredModem:
case Cable:
return ComputerCraft.Items.cable.create( type, label, quantity );
return ComputerCraft.Items.cable.create( type, quantity );
case AdvancedModem:
return new ItemStack( ComputerCraft.Blocks.advancedModem, quantity );
case WiredModemFull:

View File

@ -7,6 +7,7 @@
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;
@ -17,12 +18,9 @@
import javax.annotation.Nonnull;
public abstract class TilePeripheralBase extends TileGeneric
implements IPeripheralTile, ITickable
public abstract class TilePeripheralBase extends TileGeneric implements IPeripheralTile, ITickable, IDirectionalTile, ITilePeripheral
{
// Statics
protected EnumFacing m_dir;
private EnumFacing m_dir;
private int m_anim;
private boolean m_changed;
@ -39,9 +37,9 @@ public TilePeripheralBase()
@Override
public BlockPeripheralBase getBlock()
public BlockPeripheral getBlock()
{
return (BlockPeripheralBase) super.getBlock();
return (BlockPeripheral) super.getBlock();
}
@Override
@ -53,8 +51,6 @@ public void getDroppedItems( @Nonnull NonNullList<ItemStack> drops, boolean crea
}
}
// IPeripheralTile implementation
@Override
public final PeripheralType getPeripheralType()
{
@ -77,6 +73,7 @@ public String getLabel()
return null;
}
@Override
public void setLabel( String label )
{
m_label = label;
@ -90,11 +87,6 @@ public EnumFacing getDirection()
return m_dir;
}
public EnumFacing getCachedDirection()
{
return m_dir;
}
@Override
public void setDirection( EnumFacing dir )
{
@ -110,7 +102,7 @@ public int getAnim()
return m_anim;
}
public void setAnim( int anim )
protected void setAnim( int anim )
{
if( anim != m_anim )
{

View File

@ -14,16 +14,27 @@
public class ModemState
{
private boolean open = false;
private AtomicBoolean changed = new AtomicBoolean( true );
private final Runnable onChanged;
private final AtomicBoolean changed = new AtomicBoolean( true );
private boolean open = false;
private final IntSet channels = new IntOpenHashSet();
public ModemState()
{
this.onChanged = null;
}
public ModemState( Runnable onChanged )
{
this.onChanged = onChanged;
}
private void setOpen( boolean open )
{
if( this.open == open ) return;
this.open = open;
this.changed.set( true );
if( !changed.getAndSet( true ) && onChanged != null ) onChanged.run();
}
public boolean pollChanged()

View File

@ -1,80 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. 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.EnumFacing;
import javax.annotation.Nonnull;
public abstract class TileModemBase extends TilePeripheralBase
{
protected ModemPeripheral m_modem;
protected TileModemBase()
{
m_modem = createPeripheral();
}
protected abstract ModemPeripheral createPeripheral();
@Override
public void destroy()
{
if( m_modem != null )
{
m_modem.destroy();
m_modem = null;
}
}
@Override
public void onNeighbourChange()
{
EnumFacing dir = getDirection();
if( !getWorld().isSideSolid( getPos().offset( dir ), dir.getOpposite() ) )
{
// Drop everything and remove block
((BlockGeneric) getBlockType()).dropAllItems( getWorld(), getPos(), false );
getWorld().setBlockToAir( getPos() );
}
}
@Override
public void update()
{
super.update();
if( !getWorld().isRemote && m_modem.getModemState().pollChanged() )
{
updateAnim();
}
}
protected void updateAnim()
{
setAnim( m_modem.getModemState().isOpen() ? 1 : 0 );
}
@Override
public final void readDescription( @Nonnull NBTTagCompound nbt )
{
super.readDescription( nbt );
updateBlock();
}
// IPeripheralTile implementation
@Override
public IPeripheral getPeripheral( EnumFacing side )
{
return side == getDirection() ? m_modem : null;
}
}

View File

@ -9,11 +9,12 @@
import com.google.common.collect.ImmutableMap;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.shared.common.BlockGeneric;
import dan200.computercraft.shared.common.TileGeneric;
import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.common.BlockPeripheralBase;
import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory;
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.state.BlockFaceShape;
@ -38,7 +39,7 @@
import java.util.EnumMap;
import java.util.List;
public class BlockCable extends BlockPeripheralBase
public class BlockCable extends BlockGeneric
{
// Statics
@ -65,6 +66,7 @@ public static class Properties
public BlockCable()
{
super( Material.ROCK );
setHardness( 1.5f );
setTranslationKey( "computercraft:cable" );
setCreativeTab( ComputerCraft.mainCreativeTab );
@ -141,10 +143,12 @@ else if( cable )
return meta;
}
@Override
public IBlockState getDefaultBlockState( PeripheralType type, EnumFacing placedSide )
@Deprecated
public final IBlockState getStateForPlacement( World world, BlockPos pos, EnumFacing placedSide, float hitX, float hitY, float hitZ, int damage, EntityLivingBase placer )
{
switch( type )
switch( ComputerCraft.Items.cable.getPeripheralType( damage ) )
{
case Cable:
return getDefaultState()
@ -189,7 +193,7 @@ public IBlockState getActualState( @Nonnull IBlockState state, IBlockAccess worl
.withProperty( Properties.DOWN, doesConnectVisually( state, world, pos, EnumFacing.DOWN ) );
TileEntity tile = world.getTileEntity( pos );
int anim = tile instanceof TilePeripheralBase ? ((TilePeripheralBase) tile).getAnim() : 0;
int anim = tile instanceof TileCable ? ((TileCable) tile).getState() : 0;
BlockCableModemVariant modem = state.getValue( Properties.MODEM );
if( modem != BlockCableModemVariant.None )
@ -208,13 +212,6 @@ public boolean shouldSideBeRendered( IBlockState state, @Nonnull IBlockAccess wo
return true;
}
@Override
public PeripheralType getPeripheralType( int damage )
{
return ComputerCraft.Items.cable.getPeripheralType( damage );
}
@Override
public PeripheralType getPeripheralType( IBlockState state )
{
boolean cable = state.getValue( Properties.CABLE );
@ -234,7 +231,13 @@ else if( modem != BlockCableModemVariant.None )
}
@Override
public TilePeripheralBase createTile( PeripheralType type )
protected TileGeneric createTile( IBlockState state )
{
return new TileCable();
}
@Override
protected TileGeneric createTile( int damage )
{
return new TileCable();
}

View File

@ -7,20 +7,19 @@
package dan200.computercraft.shared.peripheral.modem.wired;
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 dan200.computercraft.shared.common.BlockGeneric;
import dan200.computercraft.shared.common.TileGeneric;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import javax.annotation.Nonnull;
public class BlockWiredModemFull extends BlockPeripheralBase
public class BlockWiredModemFull extends BlockGeneric
{
// Statics
@ -34,6 +33,7 @@ public static class Properties
public BlockWiredModemFull()
{
super( Material.ROCK );
setHardness( 1.5f );
setTranslationKey( "computercraft:wired_modem_full" );
setCreativeTab( ComputerCraft.mainCreativeTab );
@ -43,12 +43,6 @@ public BlockWiredModemFull()
);
}
@Override
protected IBlockState getDefaultBlockState( PeripheralType type, EnumFacing placedSide )
{
return getDefaultState();
}
@Nonnull
@Override
protected BlockStateContainer createBlockState()
@ -74,7 +68,7 @@ public IBlockState getActualState( @Nonnull IBlockState state, IBlockAccess worl
if( te instanceof TileWiredModemFull )
{
TileWiredModemFull modem = (TileWiredModemFull) te;
int anim = modem.getAnim();
int anim = modem.getState();
state = state
.withProperty( Properties.MODEM_ON, (anim & 1) != 0 )
.withProperty( Properties.PERIPHERAL_ON, (anim & 2) != 0 );
@ -84,19 +78,13 @@ public IBlockState getActualState( @Nonnull IBlockState state, IBlockAccess worl
}
@Override
public PeripheralType getPeripheralType( int damage )
protected TileGeneric createTile( IBlockState state )
{
return PeripheralType.WiredModemFull;
return new TileWiredModemFull();
}
@Override
public PeripheralType getPeripheralType( IBlockState state )
{
return PeripheralType.WiredModemFull;
}
@Override
public TilePeripheralBase createTile( PeripheralType type )
protected TileGeneric createTile( int damage )
{
return new TileWiredModemFull();
}

View File

@ -34,7 +34,7 @@ public ItemCable( Block block )
}
@Nonnull
public ItemStack create( PeripheralType type, String label, int quantity )
public ItemStack create( PeripheralType type, int quantity )
{
ItemStack stack;
switch( type )
@ -54,10 +54,7 @@ public ItemStack create( PeripheralType type, String label, int quantity )
return ItemStack.EMPTY;
}
}
if( label != null )
{
stack.setStackDisplayName( label );
}
return stack;
}
@ -81,11 +78,11 @@ public EnumActionResult onItemUse( @Nonnull EntityPlayer player, World world, @N
// Try to add a cable to a modem
PeripheralType type = getPeripheralType( stack );
Block existing = world.getBlockState( pos ).getBlock();
IBlockState existingState = world.getBlockState( pos );
Block existing = existingState.getBlock();
if( existing == ComputerCraft.Blocks.cable )
{
PeripheralType existingType = ComputerCraft.Blocks.cable.getPeripheralType( world, pos );
PeripheralType existingType = ComputerCraft.Blocks.cable.getPeripheralType( existingState );
if( existingType == PeripheralType.WiredModem && type == PeripheralType.Cable )
{
if( !stack.isEmpty() )
@ -112,12 +109,12 @@ public EnumActionResult onItemUse( @Nonnull EntityPlayer player, World world, @N
if( !existing.isAir( existingState, world, pos ) && (type == PeripheralType.Cable || existingState.isSideSolid( world, pos, side )) )
{
BlockPos offset = pos.offset( side );
Block offsetExisting = world.getBlockState( offset ).getBlock();
IBlockState offsetExistingState = world.getBlockState( offset );
Block offsetExisting = offsetExistingState.getBlock();
if( offsetExisting == ComputerCraft.Blocks.cable )
{
// Try to add a modem to a cable
PeripheralType offsetExistingType = ComputerCraft.Blocks.cable.getPeripheralType( world, offset );
PeripheralType offsetExistingType = ComputerCraft.Blocks.cable.getPeripheralType( offsetExistingState );
if( offsetExistingType == PeripheralType.Cable && type == PeripheralType.WiredModem )
{
if( !stack.isEmpty() )

View File

@ -7,17 +7,18 @@
package dan200.computercraft.shared.peripheral.modem.wired;
import com.google.common.base.Objects;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.network.wired.IWiredNode;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.command.CommandCopy;
import dan200.computercraft.shared.common.BlockGeneric;
import dan200.computercraft.shared.common.TileGeneric;
import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.common.IPeripheralTile;
import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory;
import dan200.computercraft.shared.peripheral.modem.ModemPeripheral;
import dan200.computercraft.shared.peripheral.modem.ModemState;
import dan200.computercraft.shared.peripheral.modem.TileModemBase;
import dan200.computercraft.shared.util.TickScheduler;
import dan200.computercraft.shared.wired.CapabilityWiredElement;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
@ -37,42 +38,35 @@
import java.util.Collections;
import java.util.Map;
public class TileCable extends TileModemBase
public class TileCable extends TileGeneric implements IPeripheralTile
{
private static class CableElement extends WiredModemElement
private class CableElement extends WiredModemElement
{
private final TileCable m_entity;
private CableElement( TileCable m_entity )
{
this.m_entity = m_entity;
}
@Nonnull
@Override
public World getWorld()
{
return m_entity.getWorld();
return TileCable.this.getWorld();
}
@Nonnull
@Override
public Vec3d getPosition()
{
BlockPos pos = m_entity.getPos();
BlockPos pos = TileCable.this.getPos();
return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );
}
@Override
protected void attachPeripheral( String name, IPeripheral peripheral )
{
((WiredModemPeripheral) m_entity.m_modem).attachPeripheral( name, peripheral );
m_modem.attachPeripheral( name, peripheral );
}
@Override
protected void detachPeripheral( String name )
{
((WiredModemPeripheral) m_entity.m_modem).detachPeripheral( name );
m_modem.detachPeripheral( name );
}
}
@ -83,35 +77,35 @@ protected void detachPeripheral( String name )
private boolean m_destroyed = false;
private boolean m_hasDirection = false;
private EnumFacing modemDirection;
private boolean hasModemDirection = false;
private boolean m_connectionsFormed = false;
private WiredModemElement m_cable;
private IWiredNode m_node;
@Override
protected ModemPeripheral createPeripheral()
private final WiredModemElement m_cable = new CableElement();
private final IWiredNode m_node = m_cable.getNode();
private final WiredModemPeripheral m_modem = new WiredModemPeripheral(
new ModemState( () -> TickScheduler.schedule( this ) ),
m_cable
)
{
m_cable = new CableElement( this );
m_node = m_cable.getNode();
return new WiredModemPeripheral( new ModemState(), m_cable )
@Nonnull
@Override
protected WiredModemLocalPeripheral getLocalPeripheral()
{
@Nonnull
@Override
protected WiredModemLocalPeripheral getLocalPeripheral()
{
return m_peripheral;
}
return m_peripheral;
}
@Nonnull
@Override
public Vec3d getPosition()
{
BlockPos pos = getPos().offset( getCachedDirection() );
return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );
}
};
}
@Nonnull
@Override
public Vec3d getPosition()
{
BlockPos pos = getPos().offset( modemDirection );
return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );
}
};
private int m_state = 0;
private void remove()
{
@ -128,9 +122,9 @@ public void destroy()
if( !m_destroyed )
{
m_destroyed = true;
m_modem.destroy();
remove();
}
super.destroy();
}
@Override
@ -151,43 +145,37 @@ public void invalidate()
public void onLoad()
{
super.onLoad();
updateDirection();
if( !world.isRemote )
{
updateDirection();
world.scheduleUpdate( pos, getBlockType(), 0 );
}
}
@Override
public void updateContainingBlockInfo()
{
m_hasDirection = false;
super.updateContainingBlockInfo();
hasModemDirection = false;
if( !world.isRemote ) world.scheduleUpdate( pos, getBlockType(), 0 );
}
private void updateDirection()
{
if( !m_hasDirection )
if( !hasModemDirection )
{
m_hasDirection = true;
m_dir = getDirection();
hasModemDirection = true;
modemDirection = getDirection();
}
}
@Override
public EnumFacing getDirection()
private EnumFacing getDirection()
{
IBlockState state = getBlockState();
EnumFacing facing = state.getValue( BlockCable.Properties.MODEM ).getFacing();
return facing != null ? facing : EnumFacing.NORTH;
}
@Override
public void setDirection( EnumFacing dir )
{
IBlockState state = getBlockState();
BlockCableModemVariant modem = state.getValue( BlockCable.Properties.MODEM );
if( modem != BlockCableModemVariant.None )
{
setBlockState( state.withProperty( BlockCable.Properties.MODEM, BlockCableModemVariant.fromFacing( dir ) ) );
}
}
@Override
public void getDroppedItems( @Nonnull NonNullList<ItemStack> drops, boolean creative )
{
@ -199,12 +187,12 @@ public void getDroppedItems( @Nonnull NonNullList<ItemStack> drops, boolean crea
case Cable:
case WiredModem:
{
drops.add( PeripheralItemFactory.create( type, getLabel(), 1 ) );
drops.add( PeripheralItemFactory.create( type, null, 1 ) );
break;
}
case WiredModemWithCable:
{
drops.add( PeripheralItemFactory.create( PeripheralType.WiredModem, getLabel(), 1 ) );
drops.add( PeripheralItemFactory.create( PeripheralType.WiredModem, null, 1 ) );
drops.add( PeripheralItemFactory.create( PeripheralType.Cable, null, 1 ) );
break;
}
@ -226,7 +214,7 @@ public void onNeighbourChange()
case WiredModem:
{
// Drop everything and remove block
((BlockGeneric) getBlockType()).dropAllItems( getWorld(), getPos(), false );
getBlock().dropAllItems( getWorld(), getPos(), false );
getWorld().setBlockToAir( getPos() );
// This'll call #destroy(), so we don't need to reset the network here.
@ -235,8 +223,7 @@ public void onNeighbourChange()
case WiredModemWithCable:
{
// Drop the modem and convert to cable
((BlockGeneric) getBlockType()).dropItem( getWorld(), getPos(), PeripheralItemFactory.create( PeripheralType.WiredModem, getLabel(), 1 ) );
setLabel( null );
getBlock().dropItem( getWorld(), getPos(), PeripheralItemFactory.create( PeripheralType.WiredModem, null, 1 ) );
setBlockState( getBlockState().withProperty( BlockCable.Properties.MODEM, BlockCableModemVariant.None ) );
modemChanged();
connectionsChanged();
@ -328,21 +315,46 @@ public NBTTagCompound writeToNBT( NBTTagCompound nbt )
}
@Override
protected void updateAnim()
protected void writeDescription( @Nonnull NBTTagCompound nbt )
{
int anim = 0;
if( m_modem.getModemState().isOpen() ) anim |= 1;
if( m_peripheralAccessAllowed ) anim |= 2;
setAnim( anim );
super.writeDescription( nbt );
nbt.setInteger( "state", m_state );
}
@Override
public void update()
public final void readDescription( @Nonnull NBTTagCompound nbt )
{
super.readDescription( nbt );
m_state = nbt.getInteger( "state" );
updateBlock();
}
public int getState()
{
return m_state;
}
private void updateState()
{
int state = 0;
if( m_modem.getModemState().isOpen() ) state |= 1;
if( m_peripheralAccessAllowed ) state |= 2;
if( state != m_state )
{
m_state = state;
updateBlock();
}
}
@Override
protected void updateTick()
{
super.update();
updateDirection();
if( !getWorld().isRemote )
{
updateDirection();
if( m_modem.getModemState().pollChanged() ) updateState();
if( !m_connectionsFormed )
{
m_connectionsFormed = true;
@ -350,7 +362,7 @@ public void update()
connectionsChanged();
if( m_peripheralAccessAllowed )
{
m_peripheral.attach( world, pos, m_dir );
m_peripheral.attach( world, pos, modemDirection );
updateConnectedPeripherals();
}
}
@ -396,7 +408,7 @@ public void modemChanged()
m_peripheral.detach();
m_node.updatePeripherals( Collections.emptyMap() );
markDirty();
updateAnim();
updateState();
}
}
@ -419,7 +431,7 @@ private void togglePeripheralAccess()
m_node.updatePeripherals( Collections.emptyMap() );
}
updateAnim();
updateState();
}
private void updateConnectedPeripherals()
@ -429,7 +441,7 @@ private void updateConnectedPeripherals()
{
// If there are no peripherals then disable access and update the display state.
m_peripheralAccessAllowed = false;
updateAnim();
updateState();
}
m_node.updatePeripherals( peripherals );
@ -441,12 +453,14 @@ public boolean canRenderBreaking()
return true;
}
// IWiredElement capability
@Override
public boolean hasCapability( @Nonnull Capability<?> capability, @Nullable EnumFacing facing )
{
if( capability == CapabilityWiredElement.CAPABILITY ) return BlockCable.canConnectIn( getBlockState(), facing );
if( capability == CapabilityWiredElement.CAPABILITY )
{
return !m_destroyed && BlockCable.canConnectIn( getBlockState(), facing );
}
return super.hasCapability( capability, facing );
}
@ -456,21 +470,23 @@ public <T> T getCapability( @Nonnull Capability<T> capability, @Nullable EnumFac
{
if( capability == CapabilityWiredElement.CAPABILITY )
{
return BlockCable.canConnectIn( getBlockState(), facing ) ? CapabilityWiredElement.CAPABILITY.cast( m_cable ) : null;
return !m_destroyed && BlockCable.canConnectIn( getBlockState(), facing )
? CapabilityWiredElement.CAPABILITY.cast( m_cable )
: null;
}
return super.getCapability( capability, facing );
}
// IPeripheralTile
@Override
public IPeripheral getPeripheral( EnumFacing side )
{
if( getPeripheralType() != PeripheralType.Cable )
{
return super.getPeripheral( side );
}
return null;
return !m_destroyed && getPeripheralType() != PeripheralType.Cable && side == getDirection() ? m_modem : null;
}
public PeripheralType getPeripheralType()
{
IBlockState state = getBlockState();
return ComputerCraft.Blocks.cable.getPeripheralType( state );
}
}

View File

@ -7,18 +7,23 @@
package dan200.computercraft.shared.peripheral.modem.wired;
import com.google.common.base.Objects;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.network.wired.IWiredNode;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.command.CommandCopy;
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
import dan200.computercraft.shared.common.TileGeneric;
import dan200.computercraft.shared.peripheral.common.IPeripheralTile;
import dan200.computercraft.shared.peripheral.modem.ModemState;
import dan200.computercraft.shared.util.TickScheduler;
import dan200.computercraft.shared.wired.CapabilityWiredElement;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.TextComponentString;
@ -30,7 +35,7 @@
import javax.annotation.Nullable;
import java.util.*;
public class TileWiredModemFull extends TilePeripheralBase
public class TileWiredModemFull extends TileGeneric implements IPeripheralTile
{
private static class FullElement extends WiredModemElement
{
@ -85,10 +90,12 @@ public Vec3d getPosition()
private boolean m_destroyed = false;
private boolean m_connectionsFormed = false;
private final ModemState m_modemState = new ModemState();
private final ModemState m_modemState = new ModemState( () -> TickScheduler.schedule( this ) );
private final WiredModemElement m_element = new FullElement( this );
private final IWiredNode m_node = m_element.getNode();
private int m_state = 0;
public TileWiredModemFull()
{
for( int i = 0; i < m_peripherals.length; i++ ) m_peripherals[i] = new WiredModemLocalPeripheral();
@ -129,14 +136,9 @@ public void invalidate()
}
@Override
public EnumFacing getDirection()
{
return EnumFacing.NORTH;
}
@Override
public void setDirection( EnumFacing dir )
public void getDroppedItems( @Nonnull NonNullList<ItemStack> drops, boolean creative )
{
drops.add( new ItemStack( ComputerCraft.Items.wiredModemFull ) );
}
@Override
@ -231,27 +233,51 @@ public NBTTagCompound writeToNBT( NBTTagCompound nbt )
return nbt;
}
protected void updateAnim()
public int getState()
{
int anim = 0;
if( m_modemState.isOpen() ) anim |= 1;
if( m_peripheralAccessAllowed ) anim |= 2;
setAnim( anim );
return m_state;
}
private void updateState()
{
int state = 0;
if( m_modemState.isOpen() ) state |= 1;
if( m_peripheralAccessAllowed ) state |= 2;
if( state != m_state )
{
m_state = state;
updateBlock();
}
}
@Override
protected void writeDescription( @Nonnull NBTTagCompound nbt )
{
super.writeDescription( nbt );
nbt.setInteger( "state", m_state );
}
@Override
public final void readDescription( @Nonnull NBTTagCompound nbt )
{
super.readDescription( nbt );
m_state = nbt.getInteger( "state" );
updateBlock();
}
@Override
public void update()
public void onLoad()
{
super.onLoad();
if( !world.isRemote ) world.scheduleUpdate( pos, getBlockType(), 0 );
}
@Override
protected void updateTick()
{
if( !getWorld().isRemote )
{
if( m_modemState.pollChanged() ) updateAnim();
if( m_modemState.pollChanged() ) updateState();
if( !m_connectionsFormed )
{
@ -268,8 +294,6 @@ public void update()
}
}
}
super.update();
}
private void connectionsChanged()
@ -291,7 +315,6 @@ private void connectionsChanged()
}
}
// private stuff
private void togglePeripheralAccess()
{
if( !m_peripheralAccessAllowed )
@ -317,7 +340,7 @@ private void togglePeripheralAccess()
m_node.updatePeripherals( Collections.emptyMap() );
}
updateAnim();
updateState();
}
private Set<String> getConnectedPeripheralNames()
@ -349,7 +372,7 @@ private void updateConnectedPeripherals()
{
// If there are no peripherals then disable access and update the display state.
m_peripheralAccessAllowed = false;
updateAnim();
updateState();
}
m_node.updatePeripherals( peripherals );
@ -360,7 +383,8 @@ private void updateConnectedPeripherals()
@Override
public boolean hasCapability( @Nonnull Capability<?> capability, @Nullable EnumFacing facing )
{
return capability == CapabilityWiredElement.CAPABILITY || super.hasCapability( capability, facing );
if( capability == CapabilityWiredElement.CAPABILITY ) return !m_destroyed;
return super.hasCapability( capability, facing );
}
@Nullable
@ -369,17 +393,18 @@ public <T> T getCapability( @Nonnull Capability<T> capability, @Nullable EnumFac
{
if( capability == CapabilityWiredElement.CAPABILITY )
{
if( m_destroyed ) return null;
return CapabilityWiredElement.CAPABILITY.cast( m_element );
}
return super.getCapability( capability, facing );
}
// IPeripheralTile
@Override
public IPeripheral getPeripheral( EnumFacing side )
{
if( m_destroyed ) return null;
WiredModemPeripheral peripheral = m_modems[side.ordinal()];
if( peripheral == null )
{

View File

@ -7,33 +7,37 @@
package dan200.computercraft.shared.peripheral.modem.wireless;
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 dan200.computercraft.shared.common.BlockGeneric;
import dan200.computercraft.shared.common.TileGeneric;
import dan200.computercraft.shared.peripheral.modem.ModemBounds;
import net.minecraft.block.BlockDirectional;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.properties.PropertyDirection;
import net.minecraft.block.state.BlockFaceShape;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
public class BlockAdvancedModem extends BlockPeripheralBase
public class BlockAdvancedModem extends BlockGeneric
{
public static class Properties
{
public static final PropertyDirection FACING = PropertyDirection.create( "facing" );
public static final PropertyDirection FACING = BlockDirectional.FACING;
public static final PropertyBool ON = PropertyBool.create( "on" );
}
public BlockAdvancedModem()
{
super( Material.ROCK );
setHardness( 2.0f );
setTranslationKey( "computercraft:advanced_modem" );
setCreativeTab( ComputerCraft.mainCreativeTab );
@ -55,17 +59,13 @@ protected BlockStateContainer createBlockState()
@Deprecated
public IBlockState getStateFromMeta( int meta )
{
IBlockState state = getDefaultState();
state = state.withProperty( Properties.FACING, EnumFacing.byIndex( meta ) );
state = state.withProperty( Properties.ON, false );
return state;
return getDefaultState().withProperty( Properties.FACING, EnumFacing.byIndex( meta ) );
}
@Override
public int getMetaFromState( IBlockState state )
{
EnumFacing dir = state.getValue( Properties.FACING );
return dir.getIndex();
return state.getValue( Properties.FACING ).getIndex();
}
@Nonnull
@ -73,47 +73,26 @@ public int getMetaFromState( IBlockState state )
@Deprecated
public IBlockState getActualState( @Nonnull IBlockState state, IBlockAccess world, BlockPos pos )
{
int anim;
EnumFacing dir;
TileEntity tile = world.getTileEntity( pos );
if( tile instanceof TilePeripheralBase )
{
TilePeripheralBase peripheral = (TilePeripheralBase) tile;
anim = peripheral.getAnim();
dir = peripheral.getDirection();
}
else
{
anim = 0;
dir = state.getValue( Properties.FACING );
}
state = state.withProperty( Properties.FACING, dir );
state = state.withProperty( Properties.ON, anim > 0 );
return state;
return state.withProperty( Properties.ON, tile instanceof TileAdvancedModem && ((TileAdvancedModem) tile).isOn() );
}
@Nonnull
@Override
public IBlockState getDefaultBlockState( PeripheralType type, EnumFacing placedSide )
@Deprecated
public IBlockState getStateForPlacement( World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer )
{
EnumFacing dir = placedSide.getOpposite();
return getDefaultState().withProperty( Properties.FACING, dir );
return getDefaultState().withProperty( Properties.FACING, facing.getOpposite() );
}
@Override
public PeripheralType getPeripheralType( int damage )
protected TileGeneric createTile( IBlockState state )
{
return PeripheralType.AdvancedModem;
return new TileAdvancedModem();
}
@Override
public PeripheralType getPeripheralType( IBlockState state )
{
return PeripheralType.AdvancedModem;
}
@Override
public TilePeripheralBase createTile( PeripheralType type )
protected TileGeneric createTile( int damage )
{
return new TileAdvancedModem();
}
@ -140,6 +119,7 @@ public BlockFaceShape getBlockFaceShape( IBlockAccess world, IBlockState state,
return BlockFaceShape.UNDEFINED;
}
@Nonnull
@Override
@Deprecated
public AxisAlignedBB getBoundingBox( IBlockState state, IBlockAccess source, BlockPos pos )

View File

@ -6,116 +6,24 @@
package dan200.computercraft.shared.peripheral.modem.wireless;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.peripheral.modem.ModemPeripheral;
import dan200.computercraft.shared.peripheral.modem.ModemState;
import dan200.computercraft.shared.peripheral.modem.TileModemBase;
import net.minecraft.block.state.IBlockState;
import dan200.computercraft.ComputerCraft;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraft.util.NonNullList;
import javax.annotation.Nonnull;
public class TileAdvancedModem extends TileModemBase
public class TileAdvancedModem extends TileWirelessModemBase
{
// Statics
private static class Peripheral extends WirelessModemPeripheral
@Override
protected EnumFacing getDirection()
{
private TileModemBase m_entity;
public Peripheral( TileModemBase entity )
{
super( new ModemState(), true );
m_entity = entity;
}
@Nonnull
@Override
public World getWorld()
{
return m_entity.getWorld();
}
@Nonnull
@Override
public Vec3d getPosition()
{
BlockPos pos = m_entity.getPos().offset( m_entity.getCachedDirection() );
return new Vec3d( pos.getX(), pos.getY(), 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
private boolean m_hasDirection = false;
public TileAdvancedModem()
{
m_dir = EnumFacing.DOWN;
return getBlockState().getValue( BlockAdvancedModem.Properties.FACING );
}
@Override
public void onLoad()
public void getDroppedItems( @Nonnull NonNullList<ItemStack> drops, boolean creative )
{
super.onLoad();
updateDirection();
}
@Override
public void updateContainingBlockInfo()
{
m_hasDirection = false;
}
@Override
public void update()
{
super.update();
updateDirection();
}
private void updateDirection()
{
if( !m_hasDirection )
{
m_hasDirection = true;
m_dir = getDirection();
}
}
@Override
public EnumFacing getDirection()
{
// Wireless Modem
IBlockState state = getBlockState();
return state.getValue( BlockAdvancedModem.Properties.FACING );
}
@Override
public void setDirection( EnumFacing dir )
{
// Wireless Modem
setBlockState( getBlockState()
.withProperty( BlockAdvancedModem.Properties.FACING, dir )
);
}
@Override
protected ModemPeripheral createPeripheral()
{
return new Peripheral( this );
if( !creative ) drops.add( new ItemStack( ComputerCraft.Items.advancedModem ) );
}
}

View File

@ -7,100 +7,23 @@
package dan200.computercraft.shared.peripheral.modem.wireless;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.common.IDirectionalTile;
import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
import dan200.computercraft.shared.peripheral.common.BlockPeripheralVariant;
import dan200.computercraft.shared.peripheral.modem.ModemPeripheral;
import dan200.computercraft.shared.peripheral.modem.ModemState;
import dan200.computercraft.shared.peripheral.modem.TileModemBase;
import dan200.computercraft.shared.peripheral.common.ITilePeripheral;
import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
public class TileWirelessModem extends TileModemBase
public class TileWirelessModem extends TileWirelessModemBase implements IDirectionalTile, ITilePeripheral
{
// Statics
private static class Peripheral extends WirelessModemPeripheral
{
private TileModemBase m_entity;
public Peripheral( TileModemBase entity )
{
super( new ModemState(), false );
m_entity = entity;
}
@Nonnull
@Override
public World getWorld()
{
return m_entity.getWorld();
}
@Nonnull
@Override
public Vec3d getPosition()
{
BlockPos pos = m_entity.getPos().offset( m_entity.getCachedDirection() );
return new Vec3d( pos.getX(), pos.getY(), 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
private boolean m_hasDirection = false;
public TileWirelessModem()
{
m_dir = EnumFacing.DOWN;
}
@Override
public void onLoad()
{
super.onLoad();
updateDirection();
}
@Override
public void updateContainingBlockInfo()
{
m_hasDirection = false;
}
@Override
public void update()
{
super.update();
updateDirection();
}
private void updateDirection()
{
if( !m_hasDirection )
{
m_hasDirection = true;
m_dir = getDirection();
}
}
@Override
public EnumFacing getDirection()
{
@ -110,18 +33,12 @@ public EnumFacing getDirection()
{
case WirelessModemDownOff:
case WirelessModemDownOn:
{
return EnumFacing.DOWN;
}
case WirelessModemUpOff:
case WirelessModemUpOn:
{
return EnumFacing.UP;
}
default:
{
return state.getValue( BlockPeripheral.Properties.FACING );
}
}
}
@ -152,15 +69,21 @@ else if( dir == EnumFacing.DOWN )
}
}
@Override
protected ModemPeripheral createPeripheral()
{
return new Peripheral( this );
}
@Override
public boolean shouldRefresh( World world, BlockPos pos, @Nonnull IBlockState oldState, @Nonnull IBlockState newState )
{
return super.shouldRefresh( world, pos, oldState, newState ) || ComputerCraft.Blocks.peripheral.getPeripheralType( newState ) != PeripheralType.WirelessModem;
}
@Override
public void getDroppedItems( @Nonnull NonNullList<ItemStack> drops, boolean creative )
{
if( !creative ) drops.add( PeripheralItemFactory.create( PeripheralType.WirelessModem, null, 1 ) );
}
@Override
public PeripheralType getPeripheralType()
{
return PeripheralType.WirelessModem;
}
}

View File

@ -0,0 +1,154 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.peripheral.modem.wireless;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.common.TileGeneric;
import dan200.computercraft.shared.peripheral.common.IPeripheralTile;
import dan200.computercraft.shared.peripheral.modem.ModemPeripheral;
import dan200.computercraft.shared.peripheral.modem.ModemState;
import dan200.computercraft.shared.util.TickScheduler;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
public abstract class TileWirelessModemBase extends TileGeneric implements IPeripheralTile
{
private static class Peripheral extends WirelessModemPeripheral
{
private final TileWirelessModemBase entity;
Peripheral( TileWirelessModemBase entity )
{
super( new ModemState( () -> TickScheduler.schedule( entity ) ), true );
this.entity = entity;
}
@Nonnull
@Override
public World getWorld()
{
return entity.getWorld();
}
@Nonnull
@Override
public Vec3d getPosition()
{
BlockPos pos = entity.getPos().offset( entity.modemDirection );
return new Vec3d( pos.getX(), pos.getY(), pos.getZ() );
}
@Override
public boolean equals( IPeripheral other )
{
return this == other;
}
}
private boolean hasModemDirection = false;
private EnumFacing modemDirection = EnumFacing.DOWN;
private final ModemPeripheral modem = new Peripheral( this );
private boolean destroyed = false;
private boolean on = false;
@Override
public void onLoad()
{
super.onLoad();
updateDirection();
world.scheduleUpdate( getPos(), getBlockType(), 0 );
}
@Override
public void destroy()
{
if( !destroyed )
{
modem.destroy();
destroyed = true;
}
}
@Override
public void updateContainingBlockInfo()
{
hasModemDirection = false;
super.updateContainingBlockInfo();
world.scheduleUpdate( getPos(), getBlockType(), 0 );
}
@Override
public void updateTick()
{
updateDirection();
if( modem.getModemState().pollChanged() )
{
boolean newOn = modem.getModemState().isOpen();
if( newOn != on )
{
on = newOn;
updateBlock();
}
}
}
private void updateDirection()
{
if( !hasModemDirection )
{
hasModemDirection = true;
modemDirection = getDirection();
}
}
protected abstract EnumFacing getDirection();
@Override
public void onNeighbourChange()
{
EnumFacing dir = getDirection();
if( !getWorld().isSideSolid( getPos().offset( dir ), dir.getOpposite() ) )
{
// Drop everything and remove block
getBlock().dropAllItems( getWorld(), getPos(), false );
getWorld().setBlockToAir( getPos() );
}
}
@Override
protected void writeDescription( @Nonnull NBTTagCompound nbt )
{
super.writeDescription( nbt );
nbt.setBoolean( "on", on );
}
@Override
public final void readDescription( @Nonnull NBTTagCompound nbt )
{
super.readDescription( nbt );
on = nbt.getBoolean( "on" );
updateBlock();
}
public boolean isOn()
{
return on;
}
@Override
public IPeripheral getPeripheral( EnumFacing side )
{
return !destroyed && side == getDirection() ? modem : null;
}
}

View File

@ -8,12 +8,16 @@
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.shared.common.ServerTerminal;
import dan200.computercraft.shared.util.TickScheduler;
import java.util.concurrent.atomic.AtomicBoolean;
public class ServerMonitor extends ServerTerminal
{
private final TileMonitor origin;
private int textScale = 2;
private boolean resized;
private final AtomicBoolean resized = new AtomicBoolean( false );
private final AtomicBoolean changed = new AtomicBoolean( false );
public ServerMonitor( boolean colour, TileMonitor origin )
{
@ -41,10 +45,28 @@ public synchronized void rebuild()
if( oldWidth != termWidth || oldHeight != termHeight )
{
getTerminal().clear();
resized = true;
resized.set( true );
markChanged();
}
}
@Override
protected void markTerminalChanged()
{
super.markTerminalChanged();
markChanged();
}
private void markChanged()
{
if( !changed.getAndSet( true ) ) TickScheduler.schedule( origin );
}
protected void clearChanged()
{
changed.set( false );
}
public int getTextScale()
{
return textScale;
@ -57,14 +79,14 @@ public synchronized void setTextScale( int textScale )
rebuild();
}
public synchronized boolean pollResized()
public boolean pollResized()
{
if( resized )
{
resized = false;
return true;
}
return resized.getAndSet( false );
}
return false;
public boolean pollTerminalChanged()
{
update();
return hasTerminalChanged();
}
}

View File

@ -11,15 +11,20 @@
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.shared.common.ServerTerminal;
import dan200.computercraft.shared.common.TileGeneric;
import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
import dan200.computercraft.shared.peripheral.common.IPeripheralTile;
import dan200.computercraft.shared.peripheral.common.ITilePeripheral;
import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory;
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.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@ -28,7 +33,7 @@
import java.util.HashSet;
import java.util.Set;
public class TileMonitor extends TilePeripheralBase
public class TileMonitor extends TileGeneric implements ITilePeripheral, IPeripheralTile
{
// Statics
@ -78,6 +83,7 @@ public void onLoad()
super.onLoad();
m_advanced = getBlockState().getValue( BlockPeripheral.Properties.VARIANT )
.getPeripheralType() == PeripheralType.AdvancedMonitor;
world.scheduleUpdate( getPos(), getBlockType(), 0 );
}
@Override
@ -146,44 +152,32 @@ public void readFromNBT( NBTTagCompound nbt )
}
@Override
public void update()
public void updateTick()
{
super.update();
if( m_xIndex != 0 || m_yIndex != 0 || m_serverMonitor == null ) return;
if( !getWorld().isRemote )
m_serverMonitor.clearChanged();
if( m_serverMonitor.pollResized() )
{
if( m_xIndex == 0 && m_yIndex == 0 && m_serverMonitor != null )
for( int x = 0; x < m_width; x++ )
{
if( m_serverMonitor.pollResized() )
for( int y = 0; y < m_height; y++ )
{
for( int x = 0; x < m_width; x++ )
{
for( int y = 0; y < m_height; y++ )
{
TileMonitor monitor = getNeighbour( x, y );
if( monitor == null ) continue;
TileMonitor monitor = getNeighbour( x, y );
if( monitor == null ) continue;
for( IComputerAccess computer : monitor.m_computers )
{
computer.queueEvent( "monitor_resize", new Object[] {
computer.getAttachmentName()
} );
}
}
for( IComputerAccess computer : monitor.m_computers )
{
computer.queueEvent( "monitor_resize", new Object[] {
computer.getAttachmentName()
} );
}
}
}
}
m_serverMonitor.update();
if( m_serverMonitor.hasTerminalChanged() ) updateBlock();
}
}
else
{
if( m_xIndex == 0 && m_yIndex == 0 && m_clientMonitor != null )
{
m_clientMonitor.update();
}
}
if( m_serverMonitor.pollTerminalChanged() ) updateBlock();
}
// IPeripheralTile implementation
@ -197,6 +191,12 @@ public IPeripheral getPeripheral( EnumFacing side )
return m_peripheral;
}
@Override
public PeripheralType getPeripheralType()
{
return m_advanced ? PeripheralType.AdvancedMonitor : PeripheralType.Monitor;
}
public ServerMonitor getCachedServerMonitor()
{
return m_serverMonitor;
@ -319,7 +319,6 @@ public final void readDescription( @Nonnull NBTTagCompound nbt )
}
// Sizing and placement stuff
@Override
public EnumFacing getDirection()
{
int dir = getDir() % 6;
@ -444,7 +443,7 @@ private TileMonitor getNeighbour( int x, int y )
return getSimilarMonitorAt( pos.offset( right, xOffset ).offset( down, yOffset ) );
}
public TileMonitor getOrigin()
private TileMonitor getOrigin()
{
return getNeighbour( 0, 0 );
}
@ -752,15 +751,16 @@ public boolean shouldRefresh( World world, BlockPos pos, @Nonnull IBlockState ol
{
case Monitor:
case AdvancedMonitor:
{
return false;
}
default:
{
return true;
}
}
}
}
@Override
public void getDroppedItems( @Nonnull NonNullList<ItemStack> drops, boolean creative )
{
if( !creative ) drops.add( PeripheralItemFactory.create( this ) );
}
}

View File

@ -16,6 +16,7 @@
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
@ -39,7 +40,13 @@ public void update()
public abstract World getWorld();
public abstract Vec3d getPos();
public abstract Vec3d getPosition();
@Deprecated
public BlockPos getPos()
{
return new BlockPos( getPosition() );
}
public boolean madeSound( long ticks )
{
@ -125,7 +132,7 @@ private synchronized boolean playSound( ILuaContext context, String name, float
}
World world = getWorld();
Vec3d pos = getPos();
Vec3d pos = getPosition();
context.issueMainThreadTask( () -> {
MinecraftServer server = world.getMinecraftServer();

View File

@ -59,7 +59,7 @@ public World getWorld()
}
@Override
public Vec3d getPos()
public Vec3d getPosition()
{
BlockPos pos = speaker.getPos();
return new Vec3d( pos.getX(), pos.getY(), pos.getZ() );

View File

@ -177,6 +177,7 @@ public synchronized void updateValues( Entity entity, @Nonnull ItemStack stack,
}
}
@Override
public void broadcastState( boolean force )
{
super.broadcastState( force );

View File

@ -29,7 +29,7 @@ public World getWorld()
}
@Override
public Vec3d getPos()
public Vec3d getPosition()
{
return world != null ? position : null;
}

View File

@ -48,7 +48,7 @@ public World getWorld()
}
@Override
public Vec3d getPos()
public Vec3d getPosition()
{
BlockPos pos = turtle.getPosition();
return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );

View File

@ -0,0 +1,68 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.util;
import com.google.common.collect.MapMaker;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.common.TileGeneric;
import net.minecraft.block.Block;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
/**
* A thread-safe version of {@link World#scheduleUpdate(BlockPos, Block, int)}.
*
* We use this when modems and other peripherals change a block in a different thread.
*/
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID )
public final class TickScheduler
{
private TickScheduler()
{
}
private static final Set<TileEntity> toTick = Collections.newSetFromMap(
new MapMaker()
.weakKeys()
.makeMap()
);
public static void schedule( TileGeneric tile )
{
World world = tile.getWorld();
if( world != null && !world.isRemote ) toTick.add( tile );
}
@SubscribeEvent
public static void tick( TickEvent.ServerTickEvent event )
{
if( event.phase != TickEvent.Phase.START ) return;
Iterator<TileEntity> iterator = toTick.iterator();
while( iterator.hasNext() )
{
TileEntity tile = iterator.next();
iterator.remove();
World world = tile.getWorld();
BlockPos pos = tile.getPos();
if( world != null && pos != null && world.isBlockLoaded( pos ) && world.getTileEntity( pos ) == tile )
{
world.scheduleUpdate( pos, tile.getBlockType(), 0 );
}
}
}
}