Spatial IO fixes (#3195)

* fix warning when transfering entities
* clean removed TileEntities from the ITickable list.
This commit is contained in:
fscan 2017-11-04 23:12:17 +01:00 committed by GitHub
parent 3cf48b2291
commit fe5d9251eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 31 deletions

View file

@ -27,6 +27,7 @@ import java.util.Map.Entry;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.NextTickListEntry; import net.minecraft.world.NextTickListEntry;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -34,7 +35,6 @@ import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage; import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import appeng.api.AEApi; import appeng.api.AEApi;
import appeng.api.definitions.IBlockDefinition;
import appeng.api.movable.IMovableHandler; import appeng.api.movable.IMovableHandler;
import appeng.api.movable.IMovableRegistry; import appeng.api.movable.IMovableRegistry;
import appeng.api.util.AEPartLocation; import appeng.api.util.AEPartLocation;
@ -61,7 +61,6 @@ public class CachedPlane
private final World world; private final World world;
private final IMovableRegistry reg = AEApi.instance().registries().movable(); private final IMovableRegistry reg = AEApi.instance().registries().movable();
private final LinkedList<WorldCoord> updates = new LinkedList<>(); private final LinkedList<WorldCoord> updates = new LinkedList<>();
private final IBlockDefinition matrixFrame = AEApi.instance().definitions().blocks().matrixFrame();
private int verticalBits; private int verticalBits;
private final IBlockState matrixBlockState; private final IBlockState matrixBlockState;
@ -146,11 +145,11 @@ public class CachedPlane
} }
else else
{ {
final Object[] details = this.myColumns[tePOS.getX() - minX][tePOS.getZ() - minZ].getDetails( tePOS.getY() ); final BlockStorageData details = new BlockStorageData();
final IBlockState blkState = (IBlockState) details[0]; this.myColumns[tePOS.getX() - minX][tePOS.getZ() - minZ].fillData( tePOS.getY(), details );
// don't skip air, just let the code replace it... // don't skip air, just let the code replace it...
if( blkState != null && blkState.getBlock() == Platform.AIR_BLOCK && blkState.getMaterial().isReplaceable() ) if( details.state != null && details.state.getBlock() == Platform.AIR_BLOCK && details.state.getMaterial().isReplaceable() )
{ {
w.setBlockToAir( tePOS ); w.setBlockToAir( tePOS );
} }
@ -168,12 +167,11 @@ public class CachedPlane
} }
final long k = this.getWorld().getTotalWorldTime(); final long k = this.getWorld().getTotalWorldTime();
final List list = this.getWorld().getPendingBlockUpdates( c, false ); final List<NextTickListEntry> list = this.getWorld().getPendingBlockUpdates( c, false );
if( list != null ) if( list != null )
{ {
for( final Object o : list ) for( final NextTickListEntry entry : list )
{ {
final NextTickListEntry entry = (NextTickListEntry) o;
final BlockPos tePOS = entry.position; final BlockPos tePOS = entry.position;
if( tePOS.getX() >= minX && tePOS.getX() <= maxX && tePOS.getY() >= minY && tePOS.getY() <= maxY && tePOS.getZ() >= minZ && tePOS if( tePOS.getX() >= minX && tePOS.getX() <= maxX && tePOS.getY() >= minY && tePOS.getY() <= maxY && tePOS.getZ() >= minZ && tePOS
.getZ() <= maxZ ) .getZ() <= maxZ )
@ -192,6 +190,10 @@ public class CachedPlane
try try
{ {
this.getWorld().loadedTileEntityList.remove( te ); this.getWorld().loadedTileEntityList.remove( te );
if( te instanceof ITickable )
{
this.getWorld().tickableTileEntities.remove( te );
}
} }
catch( final Exception e ) catch( final Exception e )
{ {
@ -215,6 +217,8 @@ public class CachedPlane
AELog.info( "Block Copy Scale: " + this.x_size + ", " + this.y_size + ", " + this.z_size ); AELog.info( "Block Copy Scale: " + this.x_size + ", " + this.y_size + ", " + this.z_size );
long startTime = System.nanoTime(); long startTime = System.nanoTime();
final BlockStorageData aD = new BlockStorageData();
final BlockStorageData bD = new BlockStorageData();
for( int x = 0; x < this.x_size; x++ ) for( int x = 0; x < this.x_size; x++ )
{ {
@ -230,8 +234,8 @@ public class CachedPlane
if( a.doNotSkip( src_y ) && b.doNotSkip( dst_y ) ) if( a.doNotSkip( src_y ) && b.doNotSkip( dst_y ) )
{ {
final Object[] aD = a.getDetails( src_y ); a.fillData( src_y, aD );
final Object[] bD = b.getDetails( dst_y ); b.fillData( dst_y, bD );
a.setBlockIDWithMetadata( src_y, bD ); a.setBlockIDWithMetadata( src_y, bD );
b.setBlockIDWithMetadata( dst_y, aD ); b.setBlockIDWithMetadata( dst_y, aD );
@ -386,14 +390,17 @@ public class CachedPlane
return this.world; return this.world;
} }
private static class BlockStorageData
{
public IBlockState state;
public int light;
}
private class Column private class Column
{ {
private final int x; private final int x;
private final int z; private final int z;
private final Chunk c; private final Chunk c;
private final Object[] ch = { 0, 0 };
private final ExtendedBlockStorage[] storage;
private List<Integer> skipThese = null; private List<Integer> skipThese = null;
public Column( final Chunk chunk, final int x, final int z, final int chunkY, final int chunkHeight ) public Column( final Chunk chunk, final int x, final int z, final int chunkY, final int chunkHeight )
@ -401,44 +408,46 @@ public class CachedPlane
this.x = x; this.x = x;
this.z = z; this.z = z;
this.c = chunk; this.c = chunk;
this.storage = this.c.getBlockStorageArray();
final ExtendedBlockStorage[] storage = this.c.getBlockStorageArray();
// make sure storage exists before hand... // make sure storage exists before hand...
for( int ay = 0; ay < chunkHeight; ay++ ) for( int ay = 0; ay < chunkHeight; ay++ )
{ {
final int by = ( ay + chunkY ); final int by = ( ay + chunkY );
ExtendedBlockStorage extendedblockstorage = this.storage[by]; ExtendedBlockStorage extendedblockstorage = storage[by];
if( extendedblockstorage == null ) if( extendedblockstorage == null )
{ {
extendedblockstorage = this.storage[by] = new ExtendedBlockStorage( by << 4, !this.c.getWorld().provider.hasSkyLight() ); extendedblockstorage = storage[by] = new ExtendedBlockStorage( by << 4, !this.c.getWorld().provider.hasSkyLight() );
} }
} }
} }
private void setBlockIDWithMetadata( final int y, final Object[] blk ) private void setBlockIDWithMetadata( final int y, BlockStorageData data )
{ {
if( blk[0] == CachedPlane.this.matrixBlockState ) if( data.state == CachedPlane.this.matrixBlockState )
{ {
blk[0] = Platform.AIR_BLOCK.getDefaultState(); data.state = Platform.AIR_BLOCK.getDefaultState();
} }
final ExtendedBlockStorage[] storage = this.c.getBlockStorageArray();
final ExtendedBlockStorage extendedBlockStorage = this.storage[y >> 4]; final ExtendedBlockStorage extendedBlockStorage = storage[y >> 4];
extendedBlockStorage.set( this.x, y & 15, this.z, (IBlockState) blk[0] ); extendedBlockStorage.set( this.x, y & 15, this.z, data.state );
// extendedBlockStorage.setExtBlockID( x, y & 15, z, blk[0] ); extendedBlockStorage.setBlockLight( this.x, y & 15, this.z, data.light );
extendedBlockStorage.setBlockLight( this.x, y & 15, this.z, (Integer) blk[1] );
} }
private Object[] getDetails( final int y ) private void fillData( final int y, BlockStorageData data )
{ {
final ExtendedBlockStorage extendedblockstorage = this.storage[y >> 4]; final ExtendedBlockStorage[] storage = this.c.getBlockStorageArray();
this.ch[0] = extendedblockstorage.get( this.x, y & 15, this.z ); final ExtendedBlockStorage extendedblockstorage = storage[y >> 4];
this.ch[1] = extendedblockstorage.getBlockLight( this.x, y & 15, this.z );
return this.ch; data.state = extendedblockstorage.get( this.x, y & 15, this.z );
data.light = extendedblockstorage.getBlockLight( this.x, y & 15, this.z );
} }
private boolean doNotSkip( final int y ) private boolean doNotSkip( final int y )
{ {
final ExtendedBlockStorage extendedblockstorage = this.storage[y >> 4]; final ExtendedBlockStorage[] storage = this.c.getBlockStorageArray();
final ExtendedBlockStorage extendedblockstorage = storage[y >> 4];
if( CachedPlane.this.reg.isBlacklisted( extendedblockstorage.get( this.x, y & 15, this.z ).getBlock() ) ) if( CachedPlane.this.reg.isBlacklisted( extendedblockstorage.get( this.x, y & 15, this.z ).getBlock() ) )
{ {
return false; return false;

View file

@ -19,6 +19,7 @@
package appeng.spatial; package appeng.spatial;
import net.minecraft.block.state.IBlockState;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -54,8 +55,9 @@ public class DefaultSpatialHandler implements IMovableHandler
if( c.isLoaded() ) if( c.isLoaded() )
{ {
final IBlockState state = w.getBlockState( newPosition );
w.addTileEntity( te ); w.addTileEntity( te );
w.notifyBlockUpdate( newPosition, w.getBlockState( newPosition ), w.getBlockState( newPosition ), 0 ); w.notifyBlockUpdate( newPosition, state, state, 1 );
} }
} }
} }

View file

@ -122,6 +122,11 @@ public class StorageHelper
} }
else else
{ {
// really remove from world, forge only marks it as removed
final boolean wasDead = entity.isDead;
oldWorld.removeEntityDangerously( entity );
entity.isDead = wasDead;
entity.getServer().getPlayerList().transferEntityToWorld( entity, entity.dimension, entity.getServer().getPlayerList().transferEntityToWorld( entity, entity.dimension,
entity.getServer().getWorld( entity.dimension ), (WorldServer) link.dim, new METeleporter( newWorld, link ) ); entity.getServer().getWorld( entity.dimension ), (WorldServer) link.dim, new METeleporter( newWorld, link ) );
} }