mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-14 20:20:30 +00:00
Rewrite monitor resizing
- Some improvements to validation of monitors. This rejects monitors with invalid dimensions, specifically those with a width or height of 0. Should fix #922. - Simplify monitor collapsing a little. This now just attempts to resize the four "corner" monitors (where present) and then expands them if needed. Fixes #913. - Rewrite monitor expansion so that it's no longer recursive. Instead we track the "origin" monitor and replace it whenever we resize to the left or upwards. Also add a upper bound on the loop count, which should prevent things like #922 happening again. Though as mentioned above, validation should prevent this anyway. - Some small bits of cleanup to general monitor code. I have absolutely no confidence that this code is any better behaved than the previous version. Let's find out I guess!
This commit is contained in:
parent
603119e1e6
commit
c2dc8bf675
@ -93,7 +93,7 @@ public class BlockMonitor extends BlockGeneric
|
||||
return;
|
||||
}
|
||||
|
||||
monitor.updateNeighbors();
|
||||
monitor.expand();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.shared.peripheral.monitor;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Expands a monitor into available space. This tries to expand in each direction until a fixed point is reached.
|
||||
*/
|
||||
class Expander
|
||||
{
|
||||
private final World level;
|
||||
private final Direction down;
|
||||
private final Direction right;
|
||||
|
||||
private TileMonitor origin;
|
||||
private int width;
|
||||
private int height;
|
||||
|
||||
Expander( TileMonitor origin )
|
||||
{
|
||||
this.origin = origin;
|
||||
width = origin.getWidth();
|
||||
height = origin.getHeight();
|
||||
|
||||
level = Objects.requireNonNull( origin.getLevel(), "level cannot be null" );
|
||||
down = origin.getDown();
|
||||
right = origin.getRight();
|
||||
}
|
||||
|
||||
void expand()
|
||||
{
|
||||
int changedCount = 0;
|
||||
|
||||
// Impose a limit on the number of resizes we can attempt. There's a risk of getting into an infinite loop
|
||||
// if we merge right/down and the next monitor has a width/height of 0. This /should/ never happen - validation
|
||||
// will catch it - but I also have a complete lack of faith in the code.
|
||||
// As an aside, I think the actual limit is width+height resizes, but again - complete lack of faith.
|
||||
int changeLimit = ComputerCraft.monitorWidth * ComputerCraft.monitorHeight + 1;
|
||||
while( expandIn( true, false ) || expandIn( true, true ) ||
|
||||
expandIn( false, false ) || expandIn( false, true )
|
||||
)
|
||||
{
|
||||
changedCount++;
|
||||
if( changedCount > changeLimit )
|
||||
{
|
||||
ComputerCraft.log.error( "Monitor has grown too much. This suggests there's an empty monitor in the world." );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( changedCount > 0 ) origin.resize( width, height );
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to expand a monitor in a particular direction as much as possible.
|
||||
*
|
||||
* @param useXAxis {@literal true} if we're expanding on the X Axis, {@literal false} if on the Y.
|
||||
* @param isPositive {@literal true} if we're expanding in the positive direction, {@literal false} if negative.
|
||||
* @return If the monitor changed.
|
||||
*/
|
||||
private boolean expandIn( boolean useXAxis, boolean isPositive )
|
||||
{
|
||||
BlockPos pos = origin.getBlockPos();
|
||||
int height = this.height, width = this.width;
|
||||
|
||||
int otherOffset = isPositive ? (useXAxis ? width : height) : -1;
|
||||
BlockPos otherPos = useXAxis ? pos.relative( right, otherOffset ) : pos.relative( down, otherOffset );
|
||||
TileEntity other = level.getBlockEntity( otherPos );
|
||||
if( !(other instanceof TileMonitor) || !origin.isCompatible( (TileMonitor) other ) ) return false;
|
||||
|
||||
TileMonitor otherMonitor = (TileMonitor) other;
|
||||
if( useXAxis )
|
||||
{
|
||||
if( otherMonitor.getYIndex() != 0 || otherMonitor.getHeight() != height ) return false;
|
||||
width += otherMonitor.getWidth();
|
||||
if( width > ComputerCraft.monitorWidth ) return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( otherMonitor.getXIndex() != 0 || otherMonitor.getWidth() != width ) return false;
|
||||
height += otherMonitor.getHeight();
|
||||
if( height > ComputerCraft.monitorHeight ) return false;
|
||||
}
|
||||
|
||||
if( !isPositive )
|
||||
{
|
||||
TileEntity otherOrigin = level.getBlockEntity( otherMonitor.toWorldPos( 0, 0 ) );
|
||||
if( otherOrigin == null || !origin.isCompatible( (TileMonitor) otherOrigin ) ) return false;
|
||||
|
||||
origin = (TileMonitor) otherOrigin;
|
||||
}
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -33,6 +33,7 @@ import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static dan200.computercraft.shared.Capabilities.CAPABILITY_PERIPHERAL;
|
||||
|
||||
@ -58,7 +59,6 @@ public class TileMonitor extends TileGeneric
|
||||
private boolean needsUpdate = false;
|
||||
private boolean needsValidating = false;
|
||||
private boolean destroyed = false;
|
||||
private boolean visiting = false;
|
||||
|
||||
// MonitorWatcher state.
|
||||
boolean enqueued;
|
||||
@ -79,7 +79,7 @@ public class TileMonitor extends TileGeneric
|
||||
public void onLoad()
|
||||
{
|
||||
super.onLoad();
|
||||
needsValidating = true;
|
||||
needsValidating = true; // Same, tbh
|
||||
TickScheduler.schedule( this );
|
||||
}
|
||||
|
||||
@ -160,30 +160,14 @@ public class TileMonitor extends TileGeneric
|
||||
if( needsUpdate )
|
||||
{
|
||||
needsUpdate = false;
|
||||
updateNeighbors();
|
||||
expand();
|
||||
}
|
||||
|
||||
if( xIndex != 0 || yIndex != 0 || serverMonitor == null ) return;
|
||||
|
||||
serverMonitor.clearChanged();
|
||||
|
||||
if( serverMonitor.pollResized() )
|
||||
{
|
||||
for( int x = 0; x < width; x++ )
|
||||
{
|
||||
for( int y = 0; y < height; y++ )
|
||||
{
|
||||
TileMonitor monitor = getNeighbour( x, y ).getMonitor();
|
||||
if( monitor == null ) continue;
|
||||
|
||||
for( IComputerAccess computer : monitor.computers )
|
||||
{
|
||||
computer.queueEvent( "monitor_resize", computer.getAttachmentName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( serverMonitor.pollResized() ) eachComputer( c -> c.queueEvent( "monitor_resize", c.getAttachmentName() ) );
|
||||
if( serverMonitor.pollTerminalChanged() ) MonitorWatcher.enqueue( this );
|
||||
}
|
||||
|
||||
@ -208,11 +192,13 @@ public class TileMonitor extends TileGeneric
|
||||
return super.getCapability( cap, side );
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ServerMonitor getCachedServerMonitor()
|
||||
{
|
||||
return serverMonitor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ServerMonitor getServerMonitor()
|
||||
{
|
||||
if( serverMonitor != null ) return serverMonitor;
|
||||
@ -223,6 +209,7 @@ public class TileMonitor extends TileGeneric
|
||||
return serverMonitor = origin.serverMonitor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ServerMonitor createServerMonitor()
|
||||
{
|
||||
if( serverMonitor != null ) return serverMonitor;
|
||||
@ -238,7 +225,7 @@ public class TileMonitor extends TileGeneric
|
||||
{
|
||||
for( int y = 0; y < height; y++ )
|
||||
{
|
||||
TileMonitor monitor = getNeighbour( x, y ).getMonitor();
|
||||
TileMonitor monitor = getLoadedMonitor( x, y ).getMonitor();
|
||||
if( monitor != null ) monitor.serverMonitor = serverMonitor;
|
||||
}
|
||||
}
|
||||
@ -250,19 +237,20 @@ public class TileMonitor extends TileGeneric
|
||||
// Otherwise fetch the origin and attempt to get its monitor
|
||||
// Note this may load chunks, but we don't really have a choice here.
|
||||
BlockPos pos = getBlockPos();
|
||||
TileEntity te = level.getBlockEntity( pos.relative( getRight(), -xIndex ).relative( getDown(), -yIndex ) );
|
||||
TileEntity te = level.getBlockEntity( toWorldPos( 0, 0 ) );
|
||||
if( !(te instanceof TileMonitor) ) return null;
|
||||
|
||||
return serverMonitor = ((TileMonitor) te).createServerMonitor();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ClientMonitor getClientMonitor()
|
||||
{
|
||||
if( clientMonitor != null ) return clientMonitor;
|
||||
|
||||
BlockPos pos = getBlockPos();
|
||||
TileEntity te = level.getBlockEntity( pos.relative( getRight(), -xIndex ).relative( getDown(), -yIndex ) );
|
||||
TileEntity te = level.getBlockEntity( toWorldPos( 0, 0 ) );
|
||||
if( !(te instanceof TileMonitor) ) return null;
|
||||
|
||||
return clientMonitor = ((TileMonitor) te).clientMonitor;
|
||||
@ -383,10 +371,23 @@ public class TileMonitor extends TileGeneric
|
||||
return yIndex;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private MonitorState getSimilarMonitorAt( BlockPos pos )
|
||||
boolean isCompatible( TileMonitor other )
|
||||
{
|
||||
if( pos.equals( getBlockPos() ) ) return MonitorState.present( this );
|
||||
return !other.destroyed && advanced == other.advanced && getOrientation() == other.getOrientation() && getDirection() == other.getDirection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a tile within the current monitor only if it is loaded and compatible.
|
||||
*
|
||||
* @param x Absolute X position in monitor coordinates
|
||||
* @param y Absolute Y position in monitor coordinates
|
||||
* @return The located monitor
|
||||
*/
|
||||
@Nonnull
|
||||
private MonitorState getLoadedMonitor( int x, int y )
|
||||
{
|
||||
if( x == xIndex && y == yIndex ) return MonitorState.present( this );
|
||||
BlockPos pos = toWorldPos( x, y );
|
||||
|
||||
World world = getLevel();
|
||||
if( world == null || !world.isAreaLoaded( pos, 0 ) ) return MonitorState.UNLOADED;
|
||||
@ -395,27 +396,28 @@ public class TileMonitor extends TileGeneric
|
||||
if( !(tile instanceof TileMonitor) ) return MonitorState.MISSING;
|
||||
|
||||
TileMonitor monitor = (TileMonitor) tile;
|
||||
return !monitor.visiting && !monitor.destroyed && advanced == monitor.advanced
|
||||
&& getDirection() == monitor.getDirection() && getOrientation() == monitor.getOrientation()
|
||||
? MonitorState.present( monitor ) : MonitorState.MISSING;
|
||||
}
|
||||
|
||||
private MonitorState getNeighbour( int x, int y )
|
||||
{
|
||||
BlockPos pos = getBlockPos();
|
||||
Direction right = getRight();
|
||||
Direction down = getDown();
|
||||
int xOffset = -xIndex + x;
|
||||
int yOffset = -yIndex + y;
|
||||
return getSimilarMonitorAt( pos.relative( right, xOffset ).relative( down, yOffset ) );
|
||||
return isCompatible( monitor ) ? MonitorState.present( monitor ) : MonitorState.MISSING;
|
||||
}
|
||||
|
||||
private MonitorState getOrigin()
|
||||
{
|
||||
return getNeighbour( 0, 0 );
|
||||
return getLoadedMonitor( 0, 0 );
|
||||
}
|
||||
|
||||
private void resize( int width, int height )
|
||||
/**
|
||||
* Convert monitor coordinates to world coordinates.
|
||||
*
|
||||
* @param x Absolute X position in monitor coordinates
|
||||
* @param y Absolute Y position in monitor coordinates
|
||||
* @return The monitor's position.
|
||||
*/
|
||||
BlockPos toWorldPos( int x, int y )
|
||||
{
|
||||
if( xIndex == x && yIndex == y ) return getBlockPos();
|
||||
return getBlockPos().relative( getRight(), -xIndex + x ).relative( getDown(), -yIndex + y );
|
||||
}
|
||||
|
||||
void resize( int width, int height )
|
||||
{
|
||||
// If we're not already the origin then we'll need to generate a new terminal.
|
||||
if( xIndex != 0 || yIndex != 0 ) serverMonitor = null;
|
||||
@ -434,7 +436,7 @@ public class TileMonitor extends TileGeneric
|
||||
{
|
||||
for( int y = 0; y < height; y++ )
|
||||
{
|
||||
TileMonitor monitor = getNeighbour( x, y ).getMonitor();
|
||||
TileMonitor monitor = getLoadedMonitor( x, y ).getMonitor();
|
||||
if( monitor != null && monitor.peripheral != null )
|
||||
{
|
||||
needsTerminal = true;
|
||||
@ -458,190 +460,80 @@ public class TileMonitor extends TileGeneric
|
||||
if( serverMonitor != null ) serverMonitor.rebuild();
|
||||
|
||||
// Update the other monitors, setting coordinates, dimensions and the server terminal
|
||||
BlockPos pos = getBlockPos();
|
||||
Direction down = getDown(), right = getRight();
|
||||
for( int x = 0; x < width; x++ )
|
||||
{
|
||||
for( int y = 0; y < height; y++ )
|
||||
{
|
||||
TileMonitor monitor = getNeighbour( x, y ).getMonitor();
|
||||
if( monitor == null ) continue;
|
||||
TileEntity other = getLevel().getBlockEntity( pos.relative( right, x ).relative( down, y ) );
|
||||
if( !(other instanceof TileMonitor) || !isCompatible( (TileMonitor) other ) ) continue;
|
||||
|
||||
TileMonitor monitor = (TileMonitor) other;
|
||||
monitor.xIndex = x;
|
||||
monitor.yIndex = y;
|
||||
monitor.width = width;
|
||||
monitor.height = height;
|
||||
monitor.serverMonitor = serverMonitor;
|
||||
monitor.needsUpdate = monitor.needsValidating = false;
|
||||
monitor.updateBlockState();
|
||||
monitor.updateBlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean mergeLeft()
|
||||
{
|
||||
TileMonitor left = getNeighbour( -1, 0 ).getMonitor();
|
||||
if( left == null || left.yIndex != 0 || left.height != height ) return false;
|
||||
|
||||
int width = left.width + this.width;
|
||||
if( width > ComputerCraft.monitorWidth ) return false;
|
||||
|
||||
TileMonitor origin = left.getOrigin().getMonitor();
|
||||
if( origin != null ) origin.resize( width, height );
|
||||
left.expand();
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean mergeRight()
|
||||
{
|
||||
TileMonitor right = getNeighbour( width, 0 ).getMonitor();
|
||||
if( right == null || right.yIndex != 0 || right.height != height ) return false;
|
||||
|
||||
int width = this.width + right.width;
|
||||
if( width > ComputerCraft.monitorWidth ) return false;
|
||||
|
||||
TileMonitor origin = getOrigin().getMonitor();
|
||||
if( origin != null ) origin.resize( width, height );
|
||||
expand();
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean mergeUp()
|
||||
{
|
||||
TileMonitor above = getNeighbour( 0, height ).getMonitor();
|
||||
if( above == null || above.xIndex != 0 || above.width != width ) return false;
|
||||
|
||||
int height = above.height + this.height;
|
||||
if( height > ComputerCraft.monitorHeight ) return false;
|
||||
|
||||
TileMonitor origin = getOrigin().getMonitor();
|
||||
if( origin != null ) origin.resize( width, height );
|
||||
expand();
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean mergeDown()
|
||||
{
|
||||
TileMonitor below = getNeighbour( 0, -1 ).getMonitor();
|
||||
if( below == null || below.xIndex != 0 || below.width != width ) return false;
|
||||
|
||||
int height = this.height + below.height;
|
||||
if( height > ComputerCraft.monitorHeight ) return false;
|
||||
|
||||
TileMonitor origin = below.getOrigin().getMonitor();
|
||||
if( origin != null ) origin.resize( width, height );
|
||||
below.expand();
|
||||
return true;
|
||||
}
|
||||
|
||||
void updateNeighborsDeferred()
|
||||
{
|
||||
needsUpdate = true;
|
||||
}
|
||||
|
||||
void updateNeighbors()
|
||||
{
|
||||
contractNeighbours();
|
||||
contract();
|
||||
expand();
|
||||
}
|
||||
|
||||
@SuppressWarnings( "StatementWithEmptyBody" )
|
||||
void expand()
|
||||
{
|
||||
while( mergeLeft() || mergeRight() || mergeUp() || mergeDown() ) ;
|
||||
TileMonitor monitor = getOrigin().getMonitor();
|
||||
if( monitor != null && monitor.xIndex == 0 && monitor.yIndex == 0 ) new Expander( monitor ).expand();
|
||||
}
|
||||
|
||||
void contractNeighbours()
|
||||
private void contractNeighbours()
|
||||
{
|
||||
visiting = true;
|
||||
if( xIndex > 0 )
|
||||
if( width == 1 && height == 1 ) return;
|
||||
|
||||
BlockPos pos = getBlockPos();
|
||||
Direction down = getDown(), right = getRight();
|
||||
BlockPos origin = toWorldPos( 0, 0 );
|
||||
|
||||
TileMonitor toLeft = null, toAbove = null, toRight = null, toBelow = null;
|
||||
if( xIndex > 0 ) toLeft = tryResizeAt( pos.relative( right, -xIndex ), xIndex, 1 );
|
||||
if( yIndex > 0 ) toAbove = tryResizeAt( origin, width, yIndex );
|
||||
if( xIndex < width - 1 ) toRight = tryResizeAt( pos.relative( right, 1 ), width - xIndex - 1, 1 );
|
||||
if( yIndex < height - 1 )
|
||||
{
|
||||
TileMonitor left = getNeighbour( xIndex - 1, yIndex ).getMonitor();
|
||||
if( left != null ) left.contract();
|
||||
toBelow = tryResizeAt( origin.relative( down, yIndex + 1 ), width, height - yIndex - 1 );
|
||||
}
|
||||
if( xIndex + 1 < width )
|
||||
{
|
||||
TileMonitor right = getNeighbour( xIndex + 1, yIndex ).getMonitor();
|
||||
if( right != null ) right.contract();
|
||||
}
|
||||
if( yIndex > 0 )
|
||||
{
|
||||
TileMonitor below = getNeighbour( xIndex, yIndex - 1 ).getMonitor();
|
||||
if( below != null ) below.contract();
|
||||
}
|
||||
if( yIndex + 1 < height )
|
||||
{
|
||||
TileMonitor above = getNeighbour( xIndex, yIndex + 1 ).getMonitor();
|
||||
if( above != null ) above.contract();
|
||||
}
|
||||
visiting = false;
|
||||
|
||||
if( toLeft != null ) toLeft.expand();
|
||||
if( toAbove != null ) toAbove.expand();
|
||||
if( toRight != null ) toRight.expand();
|
||||
if( toBelow != null ) toBelow.expand();
|
||||
}
|
||||
|
||||
void contract()
|
||||
@Nullable
|
||||
private TileMonitor tryResizeAt( BlockPos pos, int width, int height )
|
||||
{
|
||||
int height = this.height;
|
||||
int width = this.width;
|
||||
|
||||
TileMonitor origin = getOrigin().getMonitor();
|
||||
if( origin == null )
|
||||
TileEntity tile = level.getBlockEntity( pos );
|
||||
if( tile instanceof TileMonitor && isCompatible( (TileMonitor) tile ) )
|
||||
{
|
||||
TileMonitor right = width > 1 ? getNeighbour( 1, 0 ).getMonitor() : null;
|
||||
TileMonitor below = height > 1 ? getNeighbour( 0, 1 ).getMonitor() : null;
|
||||
|
||||
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;
|
||||
TileMonitor monitor = (TileMonitor) tile;
|
||||
monitor.resize( width, height );
|
||||
return monitor;
|
||||
}
|
||||
|
||||
for( int y = 0; y < height; y++ )
|
||||
{
|
||||
for( int x = 0; x < width; x++ )
|
||||
{
|
||||
TileMonitor monitor = origin.getNeighbour( x, y ).getMonitor();
|
||||
if( monitor != null ) continue;
|
||||
|
||||
// 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 ).getMonitor();
|
||||
left.resize( x, 1 );
|
||||
}
|
||||
if( x + 1 < width )
|
||||
{
|
||||
right = origin.getNeighbour( x + 1, y ).getMonitor();
|
||||
right.resize( width - (x + 1), 1 );
|
||||
}
|
||||
if( y + 1 < height )
|
||||
{
|
||||
below = origin.getNeighbour( 0, y + 1 ).getMonitor();
|
||||
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;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private boolean checkMonitorAt( int xIndex, int yIndex )
|
||||
{
|
||||
MonitorState state = getNeighbour( xIndex, yIndex );
|
||||
MonitorState state = getLoadedMonitor( xIndex, yIndex );
|
||||
if( state.isMissing() ) return false;
|
||||
|
||||
TileMonitor monitor = state.getMonitor();
|
||||
@ -652,9 +544,11 @@ public class TileMonitor extends TileGeneric
|
||||
|
||||
private void validate()
|
||||
{
|
||||
if( xIndex == 0 && yIndex == 0 && width == 1 || height == 1 ) return;
|
||||
if( xIndex == 0 && yIndex == 0 && width == 1 && height == 1 ) return;
|
||||
|
||||
if( checkMonitorAt( 0, 0 ) && checkMonitorAt( 0, height - 1 ) &&
|
||||
if( xIndex >= 0 && xIndex <= width && width > 0 && width <= ComputerCraft.monitorWidth &&
|
||||
yIndex >= 0 && yIndex <= height && height > 0 && height <= ComputerCraft.monitorHeight &&
|
||||
checkMonitorAt( 0, 0 ) && checkMonitorAt( 0, height - 1 ) &&
|
||||
checkMonitorAt( width - 1, 0 ) && checkMonitorAt( width - 1, height - 1 ) )
|
||||
{
|
||||
return;
|
||||
@ -666,6 +560,7 @@ public class TileMonitor extends TileGeneric
|
||||
resize( 1, 1 );
|
||||
needsUpdate = true;
|
||||
}
|
||||
// endregion
|
||||
|
||||
private void monitorTouched( float xPos, float yPos, float zPos )
|
||||
{
|
||||
@ -690,21 +585,22 @@ public class TileMonitor extends TileGeneric
|
||||
int xCharPos = (int) Math.min( originTerminal.getWidth(), Math.max( (pair.x - RENDER_BORDER - RENDER_MARGIN) / xCharWidth + 1.0, 1.0 ) );
|
||||
int yCharPos = (int) Math.min( originTerminal.getHeight(), Math.max( (pair.y - RENDER_BORDER - RENDER_MARGIN) / yCharHeight + 1.0, 1.0 ) );
|
||||
|
||||
for( int y = 0; y < height; y++ )
|
||||
eachComputer( c -> c.queueEvent( "monitor_touch", c.getAttachmentName(), xCharPos, yCharPos ) );
|
||||
}
|
||||
|
||||
private void eachComputer( Consumer<IComputerAccess> fun )
|
||||
{
|
||||
for( int x = 0; x < width; x++ )
|
||||
{
|
||||
for( int x = 0; x < width; x++ )
|
||||
for( int y = 0; y < height; y++ )
|
||||
{
|
||||
TileMonitor monitor = getNeighbour( x, y ).getMonitor();
|
||||
TileMonitor monitor = getLoadedMonitor( x, y ).getMonitor();
|
||||
if( monitor == null ) continue;
|
||||
|
||||
for( IComputerAccess computer : monitor.computers )
|
||||
{
|
||||
computer.queueEvent( "monitor_touch", computer.getAttachmentName(), xCharPos, yCharPos );
|
||||
}
|
||||
for( IComputerAccess computer : monitor.computers ) fun.accept( computer );
|
||||
}
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
|
||||
void addComputer( IComputerAccess computer )
|
||||
{
|
||||
@ -720,25 +616,16 @@ public class TileMonitor extends TileGeneric
|
||||
@Override
|
||||
public AxisAlignedBB getRenderBoundingBox()
|
||||
{
|
||||
TileMonitor start = getNeighbour( 0, 0 ).getMonitor();
|
||||
TileMonitor end = getNeighbour( width - 1, height - 1 ).getMonitor();
|
||||
if( start != null && end != null )
|
||||
{
|
||||
BlockPos startPos = start.getBlockPos();
|
||||
BlockPos endPos = end.getBlockPos();
|
||||
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 = getBlockPos();
|
||||
return new AxisAlignedBB( pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1 );
|
||||
}
|
||||
BlockPos startPos = toWorldPos( 0, 0 );
|
||||
BlockPos endPos = toWorldPos( width, height );
|
||||
return new AxisAlignedBB(
|
||||
Math.min( startPos.getX(), endPos.getX() ),
|
||||
Math.min( startPos.getY(), endPos.getY() ),
|
||||
Math.min( startPos.getZ(), endPos.getZ() ),
|
||||
Math.max( startPos.getX(), endPos.getX() ) + 1,
|
||||
Math.max( startPos.getY(), endPos.getY() ) + 1,
|
||||
Math.max( startPos.getZ(), endPos.getZ() ) + 1
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -55,7 +55,7 @@ class Monitor_Test {
|
||||
val monitor = helper.getBlockEntity(BlockPos(2, 2, 3)) as TileMonitor
|
||||
monitor.getCapability(Capabilities.CAPABILITY_PERIPHERAL)
|
||||
|
||||
val terminal = monitor.cachedServerMonitor.terminal
|
||||
val terminal = monitor.cachedServerMonitor!!.terminal
|
||||
terminal.write("Hello, world!")
|
||||
terminal.setCursorPos(1, 2)
|
||||
terminal.textColour = 2
|
||||
|
Loading…
Reference in New Issue
Block a user