pick 97420a31d The big reformat of 2020

This commit is contained in:
yueh
2020-06-16 21:41:28 +02:00
parent 5304b3febe
commit 5225ea426b
2252 changed files with 95466 additions and 118582 deletions
+366 -422
View File
@@ -18,7 +18,6 @@
package appeng.spatial;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
@@ -33,6 +32,9 @@ import net.minecraft.world.ITickList;
import net.minecraft.world.NextTickListEntry;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkSection;
import net.minecraft.world.server.ServerChunkProvider;
import net.minecraft.world.server.ServerTickList;
import appeng.api.AEApi;
import appeng.api.movable.IMovableHandler;
@@ -42,425 +44,367 @@ import appeng.api.util.WorldCoord;
import appeng.core.AELog;
import appeng.core.worlddata.WorldData;
import appeng.util.Platform;
import net.minecraft.world.chunk.ChunkSection;
import net.minecraft.world.server.ServerChunkProvider;
import net.minecraft.world.server.ServerTickList;
public class CachedPlane
{
private final int x_size;
private final int z_size;
private final int cx_size;
private final int cz_size;
private final int x_offset;
private final int y_offset;
private final int z_offset;
private final int y_size;
private final Chunk[][] myChunks;
private final Column[][] myColumns;
private final List<TileEntity> tiles = new ArrayList<>();
private final List<NextTickListEntry<Block>> ticks = new ArrayList<>();
private final World world;
private final IMovableRegistry reg = AEApi.instance().registries().movable();
private final List<WorldCoord> updates = new ArrayList<>();
private int verticalBits;
private final BlockState matrixBlockState;
public CachedPlane( final World w, final int minX, final int minY, final int minZ, final int maxX, final int maxY, final int maxZ )
{
Block matrixFrameBlock = AEApi.instance().definitions().blocks().matrixFrame().maybeBlock().orElse( null );
if( matrixFrameBlock != null )
{
this.matrixBlockState = matrixFrameBlock.getDefaultState();
}
else
{
this.matrixBlockState = null;
}
this.world = w;
this.x_size = maxX - minX + 1;
this.y_size = maxY - minY + 1;
this.z_size = maxZ - minZ + 1;
this.x_offset = minX;
this.y_offset = minY;
this.z_offset = minZ;
final int minCX = minX >> 4;
final int minCY = minY >> 4;
final int minCZ = minZ >> 4;
final int maxCX = maxX >> 4;
final int maxCY = maxY >> 4;
final int maxCZ = maxZ >> 4;
this.cx_size = maxCX - minCX + 1;
final int cy_size = maxCY - minCY + 1;
this.cz_size = maxCZ - minCZ + 1;
this.myChunks = new Chunk[this.cx_size][this.cz_size];
this.myColumns = new Column[this.x_size][this.z_size];
this.verticalBits = 0;
for( int cy = 0; cy < cy_size; cy++ )
{
this.verticalBits |= 1 << ( minCY + cy );
}
for( int x = 0; x < this.x_size; x++ )
{
for( int z = 0; z < this.z_size; z++ )
{
this.myColumns[x][z] = new Column( w.getChunk( ( minX + x ) >> 4, ( minZ + z ) >> 4 ), ( minX + x ) & 0xF, ( minZ + z ) & 0xF, minCY, cy_size );
}
}
final IMovableRegistry mr = AEApi.instance().registries().movable();
for( int cx = 0; cx < this.cx_size; cx++ )
{
for( int cz = 0; cz < this.cz_size; cz++ )
{
final List<BlockPos> deadTiles = new ArrayList<>();
final Chunk c = w.getChunk( minCX + cx, minCZ + cz );
this.myChunks[cx][cz] = c;
final List<Entry<BlockPos, TileEntity>> rawTiles = new ArrayList<>(c.getTileEntityMap().entrySet());
for( final Entry<BlockPos, TileEntity> tx : rawTiles )
{
final BlockPos cp = tx.getKey();
final TileEntity te = tx.getValue();
final BlockPos tePOS = te.getPos();
if( tePOS.getX() >= minX && tePOS.getX() <= maxX && tePOS.getY() >= minY && tePOS.getY() <= maxY && tePOS.getZ() >= minZ && tePOS
.getZ() <= maxZ )
{
if( mr.askToMove( te ) )
{
this.tiles.add( te );
deadTiles.add( cp );
}
else
{
final BlockStorageData details = new BlockStorageData();
this.myColumns[tePOS.getX() - minX][tePOS.getZ() - minZ].fillData( tePOS.getY(), details );
// don't skip air, just let the code replace it...
if( details.state != null && details.state.getBlock() == Platform.AIR_BLOCK && details.state.getMaterial().isReplaceable() )
{
w.removeBlock( tePOS, false );
}
else
{
this.myColumns[tePOS.getX() - minX][tePOS.getZ() - minZ].setSkip( tePOS.getY() );
}
}
}
}
for( final BlockPos cp : deadTiles )
{
c.getTileEntityMap().remove( cp );
}
final long gameTime = this.getWorld().getGameTime();
final ITickList<Block> pendingBlockTicks = this.getWorld().getPendingBlockTicks();
if (pendingBlockTicks instanceof ServerTickList) {
List<NextTickListEntry<Block>> pending = ((ServerTickList<Block>) pendingBlockTicks).getPending(c.getPos(), false, true);
for (final NextTickListEntry<Block> entry : pending) {
final BlockPos tePOS = entry.position;
if (tePOS.getX() >= minX && tePOS.getX() <= maxX && tePOS.getY() >= minY && tePOS.getY() <= maxY && tePOS.getZ() >= minZ && tePOS
.getZ() <= maxZ) {
this.ticks.add(new NextTickListEntry<>(tePOS, entry.getTarget(), entry.scheduledTime - gameTime, entry.priority));
}
}
}
}
}
for( final TileEntity te : this.tiles )
{
try
{
this.getWorld().loadedTileEntityList.remove( te );
if( te instanceof ITickableTileEntity)
{
this.getWorld().tickableTileEntities.remove( te );
}
}
catch( final Exception e )
{
AELog.debug( e );
}
}
}
private IMovableHandler getHandler( final TileEntity te )
{
final IMovableRegistry mr = AEApi.instance().registries().movable();
return mr.getHandler( te );
}
void swap( final CachedPlane dst )
{
final IMovableRegistry mr = AEApi.instance().registries().movable();
if( dst.x_size == this.x_size && dst.y_size == this.y_size && dst.z_size == this.z_size )
{
AELog.info( "Block Copy Scale: " + this.x_size + ", " + this.y_size + ", " + this.z_size );
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 z = 0; z < this.z_size; z++ )
{
final Column a = this.myColumns[x][z];
final Column b = dst.myColumns[x][z];
for( int y = 0; y < this.y_size; y++ )
{
final int src_y = y + this.y_offset;
final int dst_y = y + dst.y_offset;
if( a.doNotSkip( src_y ) && b.doNotSkip( dst_y ) )
{
a.fillData( src_y, aD );
b.fillData( dst_y, bD );
a.setBlockState( src_y, bD );
b.setBlockState( dst_y, aD );
}
else
{
this.markForUpdate( x + this.x_offset, src_y, z + this.z_offset );
dst.markForUpdate( x + dst.x_offset, dst_y, z + dst.z_offset );
}
}
}
}
long endTime = System.nanoTime();
long duration = endTime - startTime;
AELog.info( "Block Copy Time: " + duration );
for( final TileEntity te : this.tiles )
{
final BlockPos tePOS = te.getPos();
dst.addTile( tePOS.getX() - this.x_offset, tePOS.getY() - this.y_offset, tePOS.getZ() - this.z_offset, te, this, mr );
}
for( final TileEntity te : dst.tiles )
{
final BlockPos tePOS = te.getPos();
this.addTile( tePOS.getX() - dst.x_offset, tePOS.getY() - dst.y_offset, tePOS.getZ() - dst.z_offset, te, dst, mr );
}
for( final NextTickListEntry<Block> entry : this.ticks )
{
final BlockPos tePOS = entry.position;
dst.addTick( tePOS.getX() - this.x_offset, tePOS.getY() - this.y_offset, tePOS.getZ() - this.z_offset, entry );
}
for( final NextTickListEntry<Block> entry : dst.ticks )
{
final BlockPos tePOS = entry.position;
this.addTick( tePOS.getX() - dst.x_offset, tePOS.getY() - dst.y_offset, tePOS.getZ() - dst.z_offset, entry );
}
startTime = System.nanoTime();
this.updateChunks();
dst.updateChunks();
endTime = System.nanoTime();
duration = endTime - startTime;
AELog.info( "Update Time: " + duration );
}
}
private void markForUpdate( final int x, final int y, final int z )
{
this.updates.add( new WorldCoord( x, y, z ) );
for( final AEPartLocation d : AEPartLocation.SIDE_LOCATIONS )
{
this.updates.add( new WorldCoord( x + d.xOffset, y + d.yOffset, z + d.zOffset ) );
}
}
private void addTick( final int x, final int y, final int z, final NextTickListEntry<Block> entry )
{
BlockPos where = new BlockPos(x + this.x_offset, y + this.y_offset, z + this.z_offset);
this.world.getPendingBlockTicks().scheduleTick(where, entry.getTarget(), (int) entry.scheduledTime, entry.priority);
}
private void addTile( final int x, final int y, final int z, final TileEntity te, final CachedPlane alternateDestination, final IMovableRegistry mr )
{
try
{
final Column c = this.myColumns[x][z];
if( c.doNotSkip( y + this.y_offset ) || alternateDestination == null )
{
final IMovableHandler handler = this.getHandler( te );
try
{
handler.moveTile( te, this.world, new BlockPos( x + this.x_offset, y + this.y_offset, z + this.z_offset ) );
}
catch( final Throwable e )
{
AELog.debug( e );
final BlockPos pos = new BlockPos( x, y, z );
// attempt recovery...
c.c.addTileEntity(te);
this.world.notifyBlockUpdate( pos, this.world.getBlockState( pos ), this.world.getBlockState( pos ), z );
}
mr.doneMoving( te );
}
else
{
alternateDestination.addTile( x, y, z, te, null, mr );
}
}
catch( final Throwable e )
{
AELog.debug( e );
}
}
private void updateChunks()
{
// update shit..
for( int x = 0; x < this.cx_size; x++ )
{
for( int z = 0; z < this.cz_size; z++ )
{
final Chunk c = this.myChunks[x][z];
// FIXME: Light shit
c.markDirty();
}
}
// send shit...
for( int x = 0; x < this.cx_size; x++ )
{
for( int z = 0; z < this.cz_size; z++ )
{
final Chunk c = this.myChunks[x][z];
for( int y = 1; y < 255; y += 32 )
{
WorldData.instance().compassData().service().updateArea( this.getWorld(), c.getPos().x << 4, y, c.getPos().z << 4 );
}
// FIXME this was sending chunks to players...
SChunkDataPacket cdp = new SChunkDataPacket(c, verticalBits);
((ServerChunkProvider) world.getChunkProvider()).chunkManager.getTrackingPlayers(c.getPos(), false)
.forEach(spe -> spe.connection.sendPacket(cdp));
}
}
// FIXME check if this makes any sense at all to send changes to players asap
ServerChunkProvider serverChunkProvider = (ServerChunkProvider) world.getChunkProvider();
serverChunkProvider.tick(() -> false);
}
List<WorldCoord> getUpdates()
{
return this.updates;
}
World getWorld()
{
return this.world;
}
private static class BlockStorageData
{
public BlockState state;
public int light;
}
private class Column
{
private final int x;
private final int z;
private final Chunk c;
private List<Integer> skipThese = null;
public Column( final Chunk chunk, final int x, final int z, final int chunkY, final int chunkHeight )
{
this.x = x;
this.z = z;
this.c = chunk;
final ChunkSection[] storage = this.c.getSections();
// make sure storage exists before hand...
for( int ay = 0; ay < chunkHeight; ay++ )
{
final int by = ( ay + chunkY );
ChunkSection extendedblockstorage = storage[by];
if( extendedblockstorage == null )
{
extendedblockstorage = storage[by] = new ChunkSection( by << 4 );
}
}
}
private void setBlockState(final int y, BlockStorageData data )
{
if( data.state == CachedPlane.this.matrixBlockState )
{
data.state = Platform.AIR_BLOCK.getDefaultState();
}
final ChunkSection[] storage = this.c.getSections();
final ChunkSection extendedBlockStorage = storage[y >> 4];
extendedBlockStorage.setBlockState( this.x, y & 15, this.z, data.state );
// FIXME extendedBlockStorage.setBlockLight( this.x, y & 15, this.z, data.light );
}
private void fillData( final int y, BlockStorageData data )
{
final ChunkSection[] storage = this.c.getSections();
final ChunkSection extendedblockstorage = storage[y >> 4];
data.state = extendedblockstorage.getBlockState( this.x, y & 15, this.z );
// FIXME data.light = extendedblockstorage.getBlockLight( this.x, y & 15, this.z );
}
private boolean doNotSkip( final int y )
{
final ChunkSection[] storage = this.c.getSections();
final ChunkSection extendedblockstorage = storage[y >> 4];
if( CachedPlane.this.reg.isBlacklisted( extendedblockstorage.getBlockState( this.x, y & 15, this.z ).getBlock() ) )
{
return false;
}
return this.skipThese == null || !this.skipThese.contains( y );
}
private void setSkip( final int yCoord )
{
if( this.skipThese == null )
{
this.skipThese = new ArrayList<>();
}
this.skipThese.add( yCoord );
}
}
public class CachedPlane {
private final int x_size;
private final int z_size;
private final int cx_size;
private final int cz_size;
private final int x_offset;
private final int y_offset;
private final int z_offset;
private final int y_size;
private final Chunk[][] myChunks;
private final Column[][] myColumns;
private final List<TileEntity> tiles = new ArrayList<>();
private final List<NextTickListEntry<Block>> ticks = new ArrayList<>();
private final World world;
private final IMovableRegistry reg = AEApi.instance().registries().movable();
private final List<WorldCoord> updates = new ArrayList<>();
private int verticalBits;
private final BlockState matrixBlockState;
public CachedPlane(final World w, final int minX, final int minY, final int minZ, final int maxX, final int maxY,
final int maxZ) {
Block matrixFrameBlock = AEApi.instance().definitions().blocks().matrixFrame().maybeBlock().orElse(null);
if (matrixFrameBlock != null) {
this.matrixBlockState = matrixFrameBlock.getDefaultState();
} else {
this.matrixBlockState = null;
}
this.world = w;
this.x_size = maxX - minX + 1;
this.y_size = maxY - minY + 1;
this.z_size = maxZ - minZ + 1;
this.x_offset = minX;
this.y_offset = minY;
this.z_offset = minZ;
final int minCX = minX >> 4;
final int minCY = minY >> 4;
final int minCZ = minZ >> 4;
final int maxCX = maxX >> 4;
final int maxCY = maxY >> 4;
final int maxCZ = maxZ >> 4;
this.cx_size = maxCX - minCX + 1;
final int cy_size = maxCY - minCY + 1;
this.cz_size = maxCZ - minCZ + 1;
this.myChunks = new Chunk[this.cx_size][this.cz_size];
this.myColumns = new Column[this.x_size][this.z_size];
this.verticalBits = 0;
for (int cy = 0; cy < cy_size; cy++) {
this.verticalBits |= 1 << (minCY + cy);
}
for (int x = 0; x < this.x_size; x++) {
for (int z = 0; z < this.z_size; z++) {
this.myColumns[x][z] = new Column(w.getChunk((minX + x) >> 4, (minZ + z) >> 4), (minX + x) & 0xF,
(minZ + z) & 0xF, minCY, cy_size);
}
}
final IMovableRegistry mr = AEApi.instance().registries().movable();
for (int cx = 0; cx < this.cx_size; cx++) {
for (int cz = 0; cz < this.cz_size; cz++) {
final List<BlockPos> deadTiles = new ArrayList<>();
final Chunk c = w.getChunk(minCX + cx, minCZ + cz);
this.myChunks[cx][cz] = c;
final List<Entry<BlockPos, TileEntity>> rawTiles = new ArrayList<>(c.getTileEntityMap().entrySet());
for (final Entry<BlockPos, TileEntity> tx : rawTiles) {
final BlockPos cp = tx.getKey();
final TileEntity te = tx.getValue();
final BlockPos tePOS = te.getPos();
if (tePOS.getX() >= minX && tePOS.getX() <= maxX && tePOS.getY() >= minY && tePOS.getY() <= maxY
&& tePOS.getZ() >= minZ && tePOS.getZ() <= maxZ) {
if (mr.askToMove(te)) {
this.tiles.add(te);
deadTiles.add(cp);
} else {
final BlockStorageData details = new BlockStorageData();
this.myColumns[tePOS.getX() - minX][tePOS.getZ() - minZ].fillData(tePOS.getY(), details);
// don't skip air, just let the code replace it...
if (details.state != null && details.state.getBlock() == Platform.AIR_BLOCK
&& details.state.getMaterial().isReplaceable()) {
w.removeBlock(tePOS, false);
} else {
this.myColumns[tePOS.getX() - minX][tePOS.getZ() - minZ].setSkip(tePOS.getY());
}
}
}
}
for (final BlockPos cp : deadTiles) {
c.getTileEntityMap().remove(cp);
}
final long gameTime = this.getWorld().getGameTime();
final ITickList<Block> pendingBlockTicks = this.getWorld().getPendingBlockTicks();
if (pendingBlockTicks instanceof ServerTickList) {
List<NextTickListEntry<Block>> pending = ((ServerTickList<Block>) pendingBlockTicks)
.getPending(c.getPos(), false, true);
for (final NextTickListEntry<Block> entry : pending) {
final BlockPos tePOS = entry.position;
if (tePOS.getX() >= minX && tePOS.getX() <= maxX && tePOS.getY() >= minY && tePOS.getY() <= maxY
&& tePOS.getZ() >= minZ && tePOS.getZ() <= maxZ) {
this.ticks.add(new NextTickListEntry<>(tePOS, entry.getTarget(),
entry.scheduledTime - gameTime, entry.priority));
}
}
}
}
}
for (final TileEntity te : this.tiles) {
try {
this.getWorld().loadedTileEntityList.remove(te);
if (te instanceof ITickableTileEntity) {
this.getWorld().tickableTileEntities.remove(te);
}
} catch (final Exception e) {
AELog.debug(e);
}
}
}
private IMovableHandler getHandler(final TileEntity te) {
final IMovableRegistry mr = AEApi.instance().registries().movable();
return mr.getHandler(te);
}
void swap(final CachedPlane dst) {
final IMovableRegistry mr = AEApi.instance().registries().movable();
if (dst.x_size == this.x_size && dst.y_size == this.y_size && dst.z_size == this.z_size) {
AELog.info("Block Copy Scale: " + this.x_size + ", " + this.y_size + ", " + this.z_size);
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 z = 0; z < this.z_size; z++) {
final Column a = this.myColumns[x][z];
final Column b = dst.myColumns[x][z];
for (int y = 0; y < this.y_size; y++) {
final int src_y = y + this.y_offset;
final int dst_y = y + dst.y_offset;
if (a.doNotSkip(src_y) && b.doNotSkip(dst_y)) {
a.fillData(src_y, aD);
b.fillData(dst_y, bD);
a.setBlockState(src_y, bD);
b.setBlockState(dst_y, aD);
} else {
this.markForUpdate(x + this.x_offset, src_y, z + this.z_offset);
dst.markForUpdate(x + dst.x_offset, dst_y, z + dst.z_offset);
}
}
}
}
long endTime = System.nanoTime();
long duration = endTime - startTime;
AELog.info("Block Copy Time: " + duration);
for (final TileEntity te : this.tiles) {
final BlockPos tePOS = te.getPos();
dst.addTile(tePOS.getX() - this.x_offset, tePOS.getY() - this.y_offset, tePOS.getZ() - this.z_offset,
te, this, mr);
}
for (final TileEntity te : dst.tiles) {
final BlockPos tePOS = te.getPos();
this.addTile(tePOS.getX() - dst.x_offset, tePOS.getY() - dst.y_offset, tePOS.getZ() - dst.z_offset, te,
dst, mr);
}
for (final NextTickListEntry<Block> entry : this.ticks) {
final BlockPos tePOS = entry.position;
dst.addTick(tePOS.getX() - this.x_offset, tePOS.getY() - this.y_offset, tePOS.getZ() - this.z_offset,
entry);
}
for (final NextTickListEntry<Block> entry : dst.ticks) {
final BlockPos tePOS = entry.position;
this.addTick(tePOS.getX() - dst.x_offset, tePOS.getY() - dst.y_offset, tePOS.getZ() - dst.z_offset,
entry);
}
startTime = System.nanoTime();
this.updateChunks();
dst.updateChunks();
endTime = System.nanoTime();
duration = endTime - startTime;
AELog.info("Update Time: " + duration);
}
}
private void markForUpdate(final int x, final int y, final int z) {
this.updates.add(new WorldCoord(x, y, z));
for (final AEPartLocation d : AEPartLocation.SIDE_LOCATIONS) {
this.updates.add(new WorldCoord(x + d.xOffset, y + d.yOffset, z + d.zOffset));
}
}
private void addTick(final int x, final int y, final int z, final NextTickListEntry<Block> entry) {
BlockPos where = new BlockPos(x + this.x_offset, y + this.y_offset, z + this.z_offset);
this.world.getPendingBlockTicks().scheduleTick(where, entry.getTarget(), (int) entry.scheduledTime,
entry.priority);
}
private void addTile(final int x, final int y, final int z, final TileEntity te,
final CachedPlane alternateDestination, final IMovableRegistry mr) {
try {
final Column c = this.myColumns[x][z];
if (c.doNotSkip(y + this.y_offset) || alternateDestination == null) {
final IMovableHandler handler = this.getHandler(te);
try {
handler.moveTile(te, this.world,
new BlockPos(x + this.x_offset, y + this.y_offset, z + this.z_offset));
} catch (final Throwable e) {
AELog.debug(e);
final BlockPos pos = new BlockPos(x, y, z);
// attempt recovery...
c.c.addTileEntity(te);
this.world.notifyBlockUpdate(pos, this.world.getBlockState(pos), this.world.getBlockState(pos), z);
}
mr.doneMoving(te);
} else {
alternateDestination.addTile(x, y, z, te, null, mr);
}
} catch (final Throwable e) {
AELog.debug(e);
}
}
private void updateChunks() {
// update shit..
for (int x = 0; x < this.cx_size; x++) {
for (int z = 0; z < this.cz_size; z++) {
final Chunk c = this.myChunks[x][z];
// FIXME: Light shit
c.markDirty();
}
}
// send shit...
for (int x = 0; x < this.cx_size; x++) {
for (int z = 0; z < this.cz_size; z++) {
final Chunk c = this.myChunks[x][z];
for (int y = 1; y < 255; y += 32) {
WorldData.instance().compassData().service().updateArea(this.getWorld(), c.getPos().x << 4, y,
c.getPos().z << 4);
}
// FIXME this was sending chunks to players...
SChunkDataPacket cdp = new SChunkDataPacket(c, verticalBits);
((ServerChunkProvider) world.getChunkProvider()).chunkManager.getTrackingPlayers(c.getPos(), false)
.forEach(spe -> spe.connection.sendPacket(cdp));
}
}
// FIXME check if this makes any sense at all to send changes to players asap
ServerChunkProvider serverChunkProvider = (ServerChunkProvider) world.getChunkProvider();
serverChunkProvider.tick(() -> false);
}
List<WorldCoord> getUpdates() {
return this.updates;
}
World getWorld() {
return this.world;
}
private static class BlockStorageData {
public BlockState state;
public int light;
}
private class Column {
private final int x;
private final int z;
private final Chunk c;
private List<Integer> skipThese = null;
public Column(final Chunk chunk, final int x, final int z, final int chunkY, final int chunkHeight) {
this.x = x;
this.z = z;
this.c = chunk;
final ChunkSection[] storage = this.c.getSections();
// make sure storage exists before hand...
for (int ay = 0; ay < chunkHeight; ay++) {
final int by = (ay + chunkY);
ChunkSection extendedblockstorage = storage[by];
if (extendedblockstorage == null) {
extendedblockstorage = storage[by] = new ChunkSection(by << 4);
}
}
}
private void setBlockState(final int y, BlockStorageData data) {
if (data.state == CachedPlane.this.matrixBlockState) {
data.state = Platform.AIR_BLOCK.getDefaultState();
}
final ChunkSection[] storage = this.c.getSections();
final ChunkSection extendedBlockStorage = storage[y >> 4];
extendedBlockStorage.setBlockState(this.x, y & 15, this.z, data.state);
// FIXME extendedBlockStorage.setBlockLight( this.x, y & 15, this.z, data.light
// );
}
private void fillData(final int y, BlockStorageData data) {
final ChunkSection[] storage = this.c.getSections();
final ChunkSection extendedblockstorage = storage[y >> 4];
data.state = extendedblockstorage.getBlockState(this.x, y & 15, this.z);
// FIXME data.light = extendedblockstorage.getBlockLight( this.x, y & 15, this.z
// );
}
private boolean doNotSkip(final int y) {
final ChunkSection[] storage = this.c.getSections();
final ChunkSection extendedblockstorage = storage[y >> 4];
if (CachedPlane.this.reg
.isBlacklisted(extendedblockstorage.getBlockState(this.x, y & 15, this.z).getBlock())) {
return false;
}
return this.skipThese == null || !this.skipThese.contains(y);
}
private void setSkip(final int yCoord) {
if (this.skipThese == null) {
this.skipThese = new ArrayList<>();
}
this.skipThese.add(yCoord);
}
}
}
@@ -18,7 +18,6 @@
package appeng.spatial;
import net.minecraft.block.BlockState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
@@ -27,36 +26,31 @@ import net.minecraft.world.chunk.Chunk;
import appeng.api.movable.IMovableHandler;
public class DefaultSpatialHandler implements IMovableHandler {
public class DefaultSpatialHandler implements IMovableHandler
{
/**
* never called for the default.
*
* @param tile tile entity
*
* @return true
*/
@Override
public boolean canHandle(final Class<? extends TileEntity> myClass, final TileEntity tile) {
return true;
}
/**
* never called for the default.
*
* @param tile tile entity
*
* @return true
*/
@Override
public boolean canHandle( final Class<? extends TileEntity> myClass, final TileEntity tile )
{
return true;
}
@Override
public void moveTile(final TileEntity te, final World w, final BlockPos newPosition) {
te.setWorldAndPos(w, newPosition);
@Override
public void moveTile( final TileEntity te, final World w, final BlockPos newPosition )
{
te.setWorldAndPos( w, newPosition );
final Chunk c = w.getChunkAt(newPosition);
c.addTileEntity(newPosition, te);
final Chunk c = w.getChunkAt( newPosition );
c.addTileEntity( newPosition, te );
if( w.getChunkProvider().isChunkLoaded(c.getPos()) )
{
final BlockState state = w.getBlockState( newPosition );
w.addTileEntity( te );
w.notifyBlockUpdate( newPosition, state, state, 1 );
}
}
if (w.getChunkProvider().isChunkLoaded(c.getPos())) {
final BlockState state = w.getBlockState(newPosition);
w.addTileEntity(te);
w.notifyBlockUpdate(newPosition, state, state, 1);
}
}
}
@@ -18,12 +18,9 @@
package appeng.spatial;
import net.minecraft.util.math.BlockPos;
public interface ISpatialVisitor {
public interface ISpatialVisitor
{
void visit( BlockPos pos );
void visit(BlockPos pos);
}
@@ -1,17 +1,20 @@
package appeng.spatial;
import appeng.core.AELog;
import io.netty.buffer.Unpooled;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.BlockPos;
import javax.annotation.Nullable;
import io.netty.buffer.Unpooled;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.BlockPos;
import appeng.core.AELog;
/**
* Helps with encoding and decoding the extra data we attach to the
* spatial {@link net.minecraft.world.dimension.DimensionType} as "extra data".
* Keep in mind this data will also be sent to the client unless
* {@link net.minecraftforge.common.ModDimension#write(PacketBuffer, boolean)} is overridden.
* Helps with encoding and decoding the extra data we attach to the spatial
* {@link net.minecraft.world.dimension.DimensionType} as "extra data". Keep in
* mind this data will also be sent to the client unless
* {@link net.minecraftforge.common.ModDimension#write(PacketBuffer, boolean)}
* is overridden.
*/
public final class SpatialDimensionExtraData {
@@ -19,8 +22,9 @@ public final class SpatialDimensionExtraData {
private static final int CURRENT_FORMAT = 1;
/**
* The storage size of this dimension. This is dicateted by the pylon structure size used to perform
* the first transfer into this dimension. Once it's set, it cannot be changed anymore.
* The storage size of this dimension. This is dicateted by the pylon structure
* size used to perform the first transfer into this dimension. Once it's set,
* it cannot be changed anymore.
*/
private final BlockPos size;
@@ -50,7 +54,8 @@ public final class SpatialDimensionExtraData {
buf.readerIndex(0);
byte version = buf.readByte();
if (version != CURRENT_FORMAT) {
// Currently no new format has been defined, as such anything but the current version is invalid
// Currently no new format has been defined, as such anything but the current
// version is invalid
return null;
}
@@ -18,11 +18,11 @@
package appeng.spatial;
import java.util.List;
import java.util.Locale;
import javax.annotation.Nullable;
import appeng.api.storage.ISpatialDimension;
import appeng.core.AELog;
import appeng.core.AppEng;
import appeng.core.localization.GuiText;
import net.minecraft.network.PacketBuffer;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ResourceLocation;
@@ -33,144 +33,138 @@ import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Locale;
import appeng.api.storage.ISpatialDimension;
import appeng.core.AELog;
import appeng.core.AppEng;
import appeng.core.localization.GuiText;
public final class SpatialDimensionManager implements ISpatialDimension {
public final class SpatialDimensionManager implements ISpatialDimension
{
public static final ISpatialDimension INSTANCE = new SpatialDimensionManager();
public static final ISpatialDimension INSTANCE = new SpatialDimensionManager();
private static final String DIM_ID_PREFIX = "spatial_";
private static final String DIM_ID_PREFIX = "spatial_";
private SpatialDimensionManager() {
}
private SpatialDimensionManager() {
}
@Override
public ServerWorld getWorld(DimensionType cellDim) {
return DimensionManager.getWorld(getServer(), cellDim, true, true);
}
@Override
public ServerWorld getWorld(DimensionType cellDim) {
return DimensionManager.getWorld(getServer(), cellDim, true, true);
}
@Override
public DimensionType createNewCellDimension(BlockPos size) {
ResourceLocation dimKey = findFreeDimensionId();
AELog.info("Allocating storage cell dimension '%s'", dimKey);
@Override
public DimensionType createNewCellDimension(BlockPos size)
{
ResourceLocation dimKey = findFreeDimensionId();
AELog.info("Allocating storage cell dimension '%s'", dimKey);
PacketBuffer extraData = new SpatialDimensionExtraData(size).write();
PacketBuffer extraData = new SpatialDimensionExtraData(size).write();
return DimensionManager.registerDimension(dimKey, StorageCellModDimension.INSTANCE, extraData, true);
}
return DimensionManager.registerDimension(dimKey, StorageCellModDimension.INSTANCE, extraData, true);
}
/**
* Tries finding the next free storage cell dimension ID based on the currently
* registered storage cell dimensions.
*/
private ResourceLocation findFreeDimensionId() {
int maxId = 0;
for (DimensionType dimensionType : DimensionType.getAll()) {
ResourceLocation regName = dimensionType.getRegistryName();
if (regName == null || !AppEng.MOD_ID.equals(regName.getNamespace())) {
continue;
}
/**
* Tries finding the next free storage cell dimension ID based on the currently registered storage
* cell dimensions.
*/
private ResourceLocation findFreeDimensionId() {
int maxId = 0;
for (DimensionType dimensionType : DimensionType.getAll()) {
ResourceLocation regName = dimensionType.getRegistryName();
if (regName == null || !AppEng.MOD_ID.equals(regName.getNamespace())) {
continue;
}
String path = regName.getPath();
if (!path.startsWith(DIM_ID_PREFIX)) {
continue;
}
String path = regName.getPath();
if (!path.startsWith(DIM_ID_PREFIX)) {
continue;
}
try {
String numericIdPart = path.substring(DIM_ID_PREFIX.length());
maxId = Math.max(Integer.parseUnsignedInt(numericIdPart), maxId);
} catch (NumberFormatException e) {
AELog.warn("Unparsable storage cell dimension id '%s'", path, e);
}
}
try {
String numericIdPart = path.substring(DIM_ID_PREFIX.length());
maxId = Math.max(Integer.parseUnsignedInt(numericIdPart), maxId);
} catch (NumberFormatException e) {
AELog.warn("Unparsable storage cell dimension id '%s'", path, e);
}
}
++maxId;
++maxId;
return new ResourceLocation(AppEng.MOD_ID, DIM_ID_PREFIX + maxId);
}
return new ResourceLocation(AppEng.MOD_ID, DIM_ID_PREFIX + maxId);
}
@Override
public void deleteCellDimension(DimensionType cellDim) {
AELog.info("Unregistering storage cell dimension %s", cellDim.getRegistryName());
MinecraftServer server = getServer();
ServerWorld world = DimensionManager.getWorld(server, cellDim, false, false);
if (world != null) {
DimensionManager.unloadWorld(world);
}
DimensionManager.unloadWorlds(server, true);
DimensionManager.unregisterDimension(cellDim.getId());
}
@Override
public void deleteCellDimension( DimensionType cellDim )
{
AELog.info("Unregistering storage cell dimension %s", cellDim.getRegistryName());
MinecraftServer server = getServer();
ServerWorld world = DimensionManager.getWorld(server, cellDim, false, false);
if (world != null) {
DimensionManager.unloadWorld(world);
}
DimensionManager.unloadWorlds(server, true);
DimensionManager.unregisterDimension(cellDim.getId());
}
@Override
public boolean isCellDimension(DimensionType cellDim) {
// Check if the cell dimension type is even registered
if (cellDim.getRegistryName() == null || !cellDim.getRegistryName().equals(DimensionType.getKey(cellDim))) {
return false;
}
@Override
public boolean isCellDimension( DimensionType cellDim )
{
// Check if the cell dimension type is even registered
if (cellDim.getRegistryName() == null || !cellDim.getRegistryName().equals(DimensionType.getKey(cellDim))) {
return false;
}
return cellDim.getModType() instanceof StorageCellModDimension;
}
return cellDim.getModType() instanceof StorageCellModDimension;
}
@Override
public BlockPos getCellDimensionOrigin(DimensionType cellDim) {
return StorageCellDimension.REGION_CENTER;
}
@Override
public BlockPos getCellDimensionOrigin( DimensionType cellDim )
{
return StorageCellDimension.REGION_CENTER;
}
@Override
public BlockPos getCellDimensionSize(DimensionType cellDim) {
SpatialDimensionExtraData extraData = getExtraData(cellDim);
return extraData != null ? extraData.getSize() : BlockPos.ZERO;
}
@Override
public BlockPos getCellDimensionSize(DimensionType cellDim )
{
SpatialDimensionExtraData extraData = getExtraData(cellDim);
return extraData != null ? extraData.getSize() : BlockPos.ZERO;
}
@Override
public void addCellDimensionTooltip(DimensionType cellDim, List<ITextComponent> lines) {
// Check if the cell dimension type is even registered
ResourceLocation registryName = cellDim.getRegistryName();
if (registryName == null || !AppEng.MOD_ID.equals(registryName.getNamespace())) {
return;
}
@Override
public void addCellDimensionTooltip(DimensionType cellDim, List<ITextComponent> lines) {
// Check if the cell dimension type is even registered
ResourceLocation registryName = cellDim.getRegistryName();
if (registryName == null || !AppEng.MOD_ID.equals(registryName.getNamespace())) {
return;
}
if (!registryName.getPath().startsWith(DIM_ID_PREFIX)) {
return;
}
if (!registryName.getPath().startsWith(DIM_ID_PREFIX)) {
return;
}
// Add the actual stored size
BlockPos size = SpatialDimensionManager.INSTANCE.getCellDimensionSize(cellDim);
lines.add(GuiText.StoredSize.textComponent(size.getX(), size.getY(), size.getZ()));
// Add the actual stored size
BlockPos size = SpatialDimensionManager.INSTANCE.getCellDimensionSize(cellDim);
lines.add( GuiText.StoredSize.textComponent(size.getX(), size.getY(), size.getZ()));
// Add a serial number to allows players to keep different cells apart
int dimId;
try {
String numericIdPart = registryName.getPath().substring(DIM_ID_PREFIX.length());
dimId = Integer.parseUnsignedInt(numericIdPart);
} catch (NumberFormatException ignored) {
return;
}
// Add a serial number to allows players to keep different cells apart
int dimId;
try {
String numericIdPart = registryName.getPath().substring(DIM_ID_PREFIX.length());
dimId = Integer.parseUnsignedInt(numericIdPart);
} catch (NumberFormatException ignored) {
return;
}
// Try to make this a little more flavorful.
String serialNumber = String.format(Locale.ROOT, "SP-%04d", dimId);
lines.add(GuiText.SerialNumber.textComponent(serialNumber));
}
// Try to make this a little more flavorful.
String serialNumber = String.format(Locale.ROOT, "SP-%04d", dimId);
lines.add(GuiText.SerialNumber.textComponent(serialNumber));
}
@Nullable
private SpatialDimensionExtraData getExtraData(DimensionType cellDim) {
if (!(cellDim.getModType() instanceof StorageCellModDimension)) {
return null;
}
return SpatialDimensionExtraData.read(cellDim.getData());
}
@Nullable
private SpatialDimensionExtraData getExtraData( DimensionType cellDim) {
if (!(cellDim.getModType() instanceof StorageCellModDimension)) {
return null;
}
return SpatialDimensionExtraData.read(cellDim.getData());
}
private static MinecraftServer getServer() {
return ServerLifecycleHooks.getCurrentServer();
}
private static MinecraftServer getServer() {
return ServerLifecycleHooks.getCurrentServer();
}
}
@@ -18,7 +18,6 @@
package appeng.spatial;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.biome.Biome;
@@ -26,30 +25,19 @@ import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class StorageCellBiome extends Biome {
public class StorageCellBiome extends Biome
{
public static final StorageCellBiome INSTANCE = new StorageCellBiome();
public static final StorageCellBiome INSTANCE = new StorageCellBiome();
static {
INSTANCE.setRegistryName("appliedenergistics2:storage");
}
static {
INSTANCE.setRegistryName("appliedenergistics2:storage");
}
public StorageCellBiome()
{
super( new Biome.Builder()
.surfaceBuilder(SurfaceBuilder.NOPE, SurfaceBuilder.STONE_STONE_GRAVEL_CONFIG)
.precipitation(RainType.NONE)
.category(Category.NONE)
.depth(0)
.scale(1)
// Copied from the vanilla void biome
.temperature(0.5F)
.downfall(0.5F)
.waterColor(4159204)
.waterFogColor(329011)
.parent(null) );
public StorageCellBiome() {
super(new Biome.Builder().surfaceBuilder(SurfaceBuilder.NOPE, SurfaceBuilder.STONE_STONE_GRAVEL_CONFIG)
.precipitation(RainType.NONE).category(Category.NONE).depth(0).scale(1)
// Copied from the vanilla void biome
.temperature(0.5F).downfall(0.5F).waterColor(4159204).waterFogColor(329011).parent(null));
// FIXME this.decorator.treesPerChunk = 0;
// FIXME this.decorator.flowersPerChunk = 0;
// FIXME this.decorator.grassPerChunk = 0;
@@ -58,26 +46,26 @@ public class StorageCellBiome extends Biome
// FIXME this.spawnableCreatureList.clear();
// FIXME this.spawnableWaterCreatureList.clear();
// FIXME this.spawnableCaveCreatureList.clear();
}
}
@OnlyIn(Dist.CLIENT)
public int getSkyColor() {
return 0x111111;
}
@OnlyIn(Dist.CLIENT)
public int getSkyColor() {
return 0x111111;
}
@Override
public boolean doesWaterFreeze(IWorldReader worldIn, BlockPos pos) {
return false;
}
@Override
public boolean doesWaterFreeze(IWorldReader worldIn, BlockPos pos) {
return false;
}
@Override
public boolean doesWaterFreeze(IWorldReader worldIn, BlockPos water, boolean mustBeAtEdge) {
return false;
}
@Override
public boolean doesWaterFreeze(IWorldReader worldIn, BlockPos water, boolean mustBeAtEdge) {
return false;
}
@Override
public boolean doesSnowGenerate(IWorldReader worldIn, BlockPos pos) {
return false;
}
@Override
public boolean doesSnowGenerate(IWorldReader worldIn, BlockPos pos) {
return false;
}
}
@@ -18,6 +18,7 @@
package appeng.spatial;
import javax.annotation.Nullable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
@@ -28,123 +29,107 @@ import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.dimension.Dimension;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraftforge.client.IRenderHandler;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.IRenderHandler;
import appeng.client.render.SpatialSkyRender;
import appeng.core.AppEng;
import javax.annotation.Nullable;
public class StorageCellDimension extends Dimension {
public class StorageCellDimension extends Dimension
{
// A region file is 512x512 blocks (32x32 chunks),
// to avoid creating the 4 regions around 0,0,0,
// we move the origin to the middle of region 0,0
public static final BlockPos REGION_CENTER = new BlockPos(512 / 2, 64, 512 / 2);
// A region file is 512x512 blocks (32x32 chunks),
// to avoid creating the 4 regions around 0,0,0,
// we move the origin to the middle of region 0,0
public static final BlockPos REGION_CENTER = new BlockPos(512 / 2, 64, 512 / 2);
public StorageCellDimension(World world, DimensionType dimensionType) {
// FIXME: check light value
super(world, dimensionType, 1.0f);
}
public StorageCellDimension(World world, DimensionType dimensionType) {
// FIXME: check light value
super(world, dimensionType, 1.0f);
}
@Override
public ChunkGenerator createChunkGenerator() {
return new StorageChunkGenerator(this.world);
}
@Override
public ChunkGenerator createChunkGenerator()
{
return new StorageChunkGenerator( this.world );
}
@Override
public float calculateCelestialAngle(final long par1, final float par3) {
return 0;
}
@Override
public float calculateCelestialAngle( final long par1, final float par3 )
{
return 0;
}
@Override
public boolean isSurfaceWorld() {
return false;
}
@Override
public boolean isSurfaceWorld()
{
return false;
}
@Override
@OnlyIn(Dist.CLIENT)
public float[] calcSunriseSunsetColors(final float celestialAngle, final float partialTicks) {
return null;
}
@Override
@OnlyIn( Dist.CLIENT )
public float[] calcSunriseSunsetColors( final float celestialAngle, final float partialTicks )
{
return null;
}
@Override
public Vec3d getFogColor(final float par1, final float par2) {
return new Vec3d(0.07, 0.07, 0.07);
}
@Override
public Vec3d getFogColor( final float par1, final float par2 )
{
return new Vec3d( 0.07, 0.07, 0.07 );
}
@Override
public boolean canRespawnHere() {
return false;
}
@Override
public boolean canRespawnHere()
{
return false;
}
@Override
@OnlyIn(Dist.CLIENT)
public boolean isSkyColored() {
return true;
}
@Override
@OnlyIn( Dist.CLIENT )
public boolean isSkyColored()
{
return true;
}
@Override
public boolean doesXZShowFog(final int par1, final int par2) {
return false;
}
@Override
public boolean doesXZShowFog( final int par1, final int par2 )
{
return false;
}
@Override
public IRenderHandler getSkyRenderer() {
return SpatialSkyRender.getInstance();
}
@Override
public IRenderHandler getSkyRenderer()
{
return SpatialSkyRender.getInstance();
}
@Override
public boolean isDaytime() {
return false;
}
@Override
public boolean isDaytime()
{
return false;
}
@Override
public BlockPos getSpawnCoordinate() {
return REGION_CENTER;
}
@Override
public BlockPos getSpawnCoordinate()
{
return REGION_CENTER;
}
@Override
public boolean isHighHumidity(final BlockPos pos) {
return false;
}
@Override
public boolean isHighHumidity( final BlockPos pos )
{
return false;
}
@Override
public boolean canDoLightning(final Chunk chunk) {
return false;
}
@Override
public boolean canDoLightning( final Chunk chunk )
{
return false;
}
@Override
public boolean canDoRainSnowIce(Chunk chunk) {
return false;
}
@Override
public boolean canDoRainSnowIce(Chunk chunk) {
return false;
}
@Nullable
@Override
public BlockPos findSpawn(ChunkPos chunkPosIn, boolean checkValid) {
return getSpawnCoordinate();
}
@Nullable
@Override
public BlockPos findSpawn(ChunkPos chunkPosIn, boolean checkValid) {
return getSpawnCoordinate();
}
@Nullable
@Override
public BlockPos findSpawn(int posX, int posZ, boolean checkValid) {
return getSpawnCoordinate();
}
@Nullable
@Override
public BlockPos findSpawn(int posX, int posZ, boolean checkValid) {
return getSpawnCoordinate();
}
}
@@ -18,27 +18,26 @@
package appeng.spatial;
import java.util.function.BiFunction;
import appeng.core.AppEng;
import net.minecraft.world.World;
import net.minecraft.world.dimension.Dimension;
import net.minecraft.world.dimension.DimensionType;
import net.minecraftforge.common.ModDimension;
import java.util.function.BiFunction;
import appeng.core.AppEng;
public class StorageCellModDimension extends ModDimension
{
public class StorageCellModDimension extends ModDimension {
public static final StorageCellModDimension INSTANCE = new StorageCellModDimension();
public static final StorageCellModDimension INSTANCE = new StorageCellModDimension();
static {
INSTANCE.setRegistryName(AppEng.MOD_ID, "storage_cell");
}
static {
INSTANCE.setRegistryName(AppEng.MOD_ID, "storage_cell");
}
@Override
public BiFunction<World, DimensionType, ? extends Dimension> getFactory() {
return StorageCellDimension::new;
}
@Override
public BiFunction<World, DimensionType, ? extends Dimension> getFactory() {
return StorageCellDimension::new;
}
}
@@ -18,8 +18,6 @@
package appeng.spatial;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld;
@@ -29,76 +27,70 @@ import net.minecraft.world.biome.provider.SingleBiomeProvider;
import net.minecraft.world.biome.provider.SingleBiomeProviderSettings;
import net.minecraft.world.chunk.IChunk;
import net.minecraft.world.gen.ChunkGenerator;
import appeng.api.AEApi;
import net.minecraft.world.gen.GenerationSettings;
import net.minecraft.world.gen.Heightmap;
import net.minecraft.world.gen.WorldGenRegion;
import appeng.api.AEApi;
public class StorageChunkGenerator extends ChunkGenerator<GenerationSettings>
{
public class StorageChunkGenerator extends ChunkGenerator<GenerationSettings> {
private final BlockState defaultBlockState;
private final BlockState defaultBlockState;
public StorageChunkGenerator(final World world )
{
super( world, createBiomeProvider(), createSettings() );
this.defaultBlockState = AEApi.instance().definitions().blocks().matrixFrame().block().getDefaultState();
}
public StorageChunkGenerator(final World world) {
super(world, createBiomeProvider(), createSettings());
this.defaultBlockState = AEApi.instance().definitions().blocks().matrixFrame().block().getDefaultState();
}
private static BiomeProvider createBiomeProvider() {
SingleBiomeProviderSettings biomeSettings = new SingleBiomeProviderSettings(null);
biomeSettings.setBiome(StorageCellBiome.INSTANCE);
return new SingleBiomeProvider(biomeSettings);
}
private static BiomeProvider createBiomeProvider() {
SingleBiomeProviderSettings biomeSettings = new SingleBiomeProviderSettings(null);
biomeSettings.setBiome(StorageCellBiome.INSTANCE);
return new SingleBiomeProvider(biomeSettings);
}
private static GenerationSettings createSettings() {
return new GenerationSettings();
}
private static GenerationSettings createSettings() {
return new GenerationSettings();
}
@Override
public void generateSurface(WorldGenRegion region, IChunk chunk) {
this.fillChunk( chunk );
chunk.setModified( false );
}
@Override
public void generateSurface(WorldGenRegion region, IChunk chunk) {
this.fillChunk(chunk);
chunk.setModified(false);
}
private void fillChunk( IChunk chunk )
{
BlockPos.Mutable mutPos = new BlockPos.Mutable();
for( int cx = 0; cx < 16; cx++ )
{
mutPos.setX(cx);
for( int cz = 0; cz < 16; cz++ )
{
// FIXME: It's likely a bad idea to fill Y in the inner-loop given the storage layout of chunks
mutPos.setZ(cz);
for( int cy = 0; cy < 256; cy++ )
{
mutPos.setY(cy);
chunk.setBlockState(mutPos, defaultBlockState, false);
}
}
}
}
private void fillChunk(IChunk chunk) {
BlockPos.Mutable mutPos = new BlockPos.Mutable();
for (int cx = 0; cx < 16; cx++) {
mutPos.setX(cx);
for (int cz = 0; cz < 16; cz++) {
// FIXME: It's likely a bad idea to fill Y in the inner-loop given the storage
// layout of chunks
mutPos.setZ(cz);
for (int cy = 0; cy < 256; cy++) {
mutPos.setY(cy);
chunk.setBlockState(mutPos, defaultBlockState, false);
}
}
}
}
@Override
public int getGroundHeight() {
return 0;
}
@Override
public int getGroundHeight() {
return 0;
}
@Override
public void makeBase(IWorld worldIn, IChunk chunkIn) {
}
@Override
public void makeBase(IWorld worldIn, IChunk chunkIn) {
}
@Override
public int func_222529_a(int p_222529_1_, int p_222529_2_, Heightmap.Type heightmapType) {
return 0;
}
@Override
public int func_222529_a(int p_222529_1_, int p_222529_2_, Heightmap.Type heightmapType) {
return 0;
}
@Override
public void decorate(WorldGenRegion region) {
// Do not decorate chunks at all
}
@Override
public void decorate(WorldGenRegion region) {
// Do not decorate chunks at all
}
}
+174 -201
View File
@@ -18,7 +18,6 @@
package appeng.spatial;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
@@ -40,245 +39,219 @@ import appeng.api.util.WorldCoord;
import appeng.core.AppEng;
import appeng.util.Platform;
public class StorageHelper {
public class StorageHelper
{
private static StorageHelper instance;
private static StorageHelper instance;
public static StorageHelper getInstance() {
if (instance == null) {
instance = new StorageHelper();
}
return instance;
}
public static StorageHelper getInstance()
{
if( instance == null )
{
instance = new StorageHelper();
}
return instance;
}
/**
* Mostly from dimensional doors.. which mostly got it form X-Comp.
*
* @param entity to be teleported entity
* @param link destination
*
* @return teleported entity
*/
private Entity teleportEntity(Entity entity, final TelDestination link) {
final ServerWorld oldWorld;
final ServerWorld newWorld;
/**
* Mostly from dimensional doors.. which mostly got it form X-Comp.
*
* @param entity to be teleported entity
* @param link destination
*
* @return teleported entity
*/
private Entity teleportEntity( Entity entity, final TelDestination link )
{
final ServerWorld oldWorld;
final ServerWorld newWorld;
try {
oldWorld = (ServerWorld) entity.world;
newWorld = (ServerWorld) link.dim;
} catch (final Throwable e) {
return entity;
}
try
{
oldWorld = (ServerWorld) entity.world;
newWorld = (ServerWorld) link.dim;
}
catch( final Throwable e )
{
return entity;
}
if (oldWorld == null) {
return entity;
}
if (newWorld == null) {
return entity;
}
if (newWorld == oldWorld) {
return entity;
}
if( oldWorld == null )
{
return entity;
}
if( newWorld == null )
{
return entity;
}
if( newWorld == oldWorld )
{
return entity;
}
// Are we riding something? Teleport it instead.
if (entity.isPassenger()) {
return this.teleportEntity(entity.getRidingEntity(), link);
}
// Are we riding something? Teleport it instead.
if( entity.isPassenger() )
{
return this.teleportEntity( entity.getRidingEntity(), link );
}
// Is something riding us? Handle it first.
final List<Entity> passengers = entity.getPassengers();
final List<Entity> passengersOnOtherSide = new ArrayList<>(passengers.size());
for (Entity passenger : passengers) {
passenger.stopRiding();
passengersOnOtherSide.add(this.teleportEntity(passenger, link));
}
// We keep track of all so we can remount them on the other side.
// Is something riding us? Handle it first.
final List<Entity> passengers = entity.getPassengers();
final List<Entity> passengersOnOtherSide = new ArrayList<>(passengers.size());
for( Entity passenger : passengers )
{
passenger.stopRiding();
passengersOnOtherSide.add( this.teleportEntity( passenger, link ) );
}
// We keep track of all so we can remount them on the other side.
// load the chunk!
newWorld.getChunkProvider().getChunk(MathHelper.floor(link.x) >> 4, MathHelper.floor(link.z) >> 4,
ChunkStatus.FULL, true);
// load the chunk!
newWorld.getChunkProvider().getChunk( MathHelper.floor( link.x ) >> 4, MathHelper.floor( link.z ) >> 4, ChunkStatus.FULL, true );
if (entity instanceof ServerPlayerEntity && link.dim.getDimension() instanceof StorageCellDimension) {
AppEng.instance().getAdvancementTriggers().getSpatialExplorer().trigger((ServerPlayerEntity) entity);
}
if( entity instanceof ServerPlayerEntity && link.dim.getDimension() instanceof StorageCellDimension)
{
AppEng.instance().getAdvancementTriggers().getSpatialExplorer().trigger( (ServerPlayerEntity) entity );
}
entity.changeDimension(link.dim.getDimension().getType(), new METeleporter(link));
entity.changeDimension( link.dim.getDimension().getType(), new METeleporter( link ) );
if (!passengersOnOtherSide.isEmpty()) {
for (Entity passanger : passengersOnOtherSide) {
passanger.startRiding(entity, true);
}
}
if( !passengersOnOtherSide.isEmpty() )
{
for( Entity passanger : passengersOnOtherSide )
{
passanger.startRiding( entity, true );
}
}
return entity;
}
return entity;
}
private void transverseEdges(final int minX, final int minY, final int minZ, final int maxX, final int maxY,
final int maxZ, final ISpatialVisitor visitor) {
for (int y = minY; y < maxY; y++) {
for (int z = minZ; z < maxZ; z++) {
visitor.visit(new BlockPos(minX, y, z));
visitor.visit(new BlockPos(maxX, y, z));
}
}
private void transverseEdges( final int minX, final int minY, final int minZ, final int maxX, final int maxY, final int maxZ, final ISpatialVisitor visitor )
{
for( int y = minY; y < maxY; y++ )
{
for( int z = minZ; z < maxZ; z++ )
{
visitor.visit( new BlockPos( minX, y, z ) );
visitor.visit( new BlockPos( maxX, y, z ) );
}
}
for (int x = minX; x < maxX; x++) {
for (int z = minZ; z < maxZ; z++) {
visitor.visit(new BlockPos(x, minY, z));
visitor.visit(new BlockPos(x, maxY, z));
}
}
for( int x = minX; x < maxX; x++ )
{
for( int z = minZ; z < maxZ; z++ )
{
visitor.visit( new BlockPos( x, minY, z ) );
visitor.visit( new BlockPos( x, maxY, z ) );
}
}
for (int x = minX; x < maxX; x++) {
for (int y = minY; y < maxY; y++) {
visitor.visit(new BlockPos(x, y, minZ));
visitor.visit(new BlockPos(x, y, maxZ));
}
}
}
for( int x = minX; x < maxX; x++ )
{
for( int y = minY; y < maxY; y++ )
{
visitor.visit( new BlockPos( x, y, minZ ) );
visitor.visit( new BlockPos( x, y, maxZ ) );
}
}
}
public void swapRegions(final World srcWorld, final int srcX, final int srcY, final int srcZ, final World dstWorld,
final int dstX, final int dstY, final int dstZ, final int scaleX, final int scaleY, final int scaleZ) {
AEApi.instance().definitions().blocks().matrixFrame().maybeBlock()
.ifPresent(matrixFrameBlock -> this.transverseEdges(dstX - 1, dstY - 1, dstZ - 1, dstX + scaleX + 1,
dstY + scaleY + 1, dstZ + scaleZ + 1,
new WrapInMatrixFrame(matrixFrameBlock.getDefaultState(), dstWorld)));
public void swapRegions( final World srcWorld, final int srcX, final int srcY, final int srcZ, final World dstWorld, final int dstX, final int dstY, final int dstZ, final int scaleX, final int scaleY, final int scaleZ )
{
AEApi.instance()
.definitions()
.blocks()
.matrixFrame()
.maybeBlock()
.ifPresent( matrixFrameBlock -> this.transverseEdges( dstX - 1, dstY - 1, dstZ - 1,
dstX + scaleX + 1, dstY + scaleY + 1, dstZ + scaleZ + 1, new WrapInMatrixFrame( matrixFrameBlock.getDefaultState(), dstWorld ) ) );
final AxisAlignedBB srcBox = new AxisAlignedBB(srcX, srcY, srcZ, srcX + scaleX + 1, srcY + scaleY + 1,
srcZ + scaleZ + 1);
final AxisAlignedBB srcBox = new AxisAlignedBB( srcX, srcY, srcZ, srcX + scaleX + 1, srcY + scaleY + 1, srcZ + scaleZ + 1 );
final AxisAlignedBB dstBox = new AxisAlignedBB(dstX, dstY, dstZ, dstX + scaleX + 1, dstY + scaleY + 1,
dstZ + scaleZ + 1);
final AxisAlignedBB dstBox = new AxisAlignedBB( dstX, dstY, dstZ, dstX + scaleX + 1, dstY + scaleY + 1, dstZ + scaleZ + 1 );
final CachedPlane cDst = new CachedPlane(dstWorld, dstX, dstY, dstZ, dstX + scaleX, dstY + scaleY,
dstZ + scaleZ);
final CachedPlane cSrc = new CachedPlane(srcWorld, srcX, srcY, srcZ, srcX + scaleX, srcY + scaleY,
srcZ + scaleZ);
final CachedPlane cDst = new CachedPlane( dstWorld, dstX, dstY, dstZ, dstX + scaleX, dstY + scaleY, dstZ + scaleZ );
final CachedPlane cSrc = new CachedPlane( srcWorld, srcX, srcY, srcZ, srcX + scaleX, srcY + scaleY, srcZ + scaleZ );
// do nearly all the work... swaps blocks, tiles, and block ticks
cSrc.swap(cDst);
// do nearly all the work... swaps blocks, tiles, and block ticks
cSrc.swap( cDst );
final List<Entity> srcE = srcWorld.getEntitiesWithinAABB(Entity.class, srcBox);
final List<Entity> dstE = dstWorld.getEntitiesWithinAABB(Entity.class, dstBox);
final List<Entity> srcE = srcWorld.getEntitiesWithinAABB( Entity.class, srcBox );
final List<Entity> dstE = dstWorld.getEntitiesWithinAABB( Entity.class, dstBox );
for (final Entity e : dstE) {
this.teleportEntity(e, new TelDestination(srcWorld, srcBox, e.getPosX(), e.getPosY(), e.getPosZ(),
-dstX + srcX, -dstY + srcY, -dstZ + srcZ));
}
for( final Entity e : dstE )
{
this.teleportEntity( e, new TelDestination( srcWorld, srcBox, e.getPosX(), e.getPosY(), e.getPosZ(), -dstX + srcX, -dstY + srcY, -dstZ + srcZ ) );
}
for (final Entity e : srcE) {
this.teleportEntity(e, new TelDestination(dstWorld, dstBox, e.getPosX(), e.getPosY(), e.getPosZ(),
-srcX + dstX, -srcY + dstY, -srcZ + dstZ));
}
for( final Entity e : srcE )
{
this.teleportEntity( e, new TelDestination( dstWorld, dstBox, e.getPosX(), e.getPosY(), e.getPosZ(), -srcX + dstX, -srcY + dstY, -srcZ + dstZ ) );
}
for (final WorldCoord wc : cDst.getUpdates()) {
cSrc.getWorld().notifyNeighborsOfStateChange(wc.getPos(), Platform.AIR_BLOCK);
}
for( final WorldCoord wc : cDst.getUpdates() )
{
cSrc.getWorld().notifyNeighborsOfStateChange( wc.getPos(), Platform.AIR_BLOCK );
}
for (final WorldCoord wc : cSrc.getUpdates()) {
cSrc.getWorld().notifyNeighborsOfStateChange(wc.getPos(), Platform.AIR_BLOCK);
}
for( final WorldCoord wc : cSrc.getUpdates() )
{
cSrc.getWorld().notifyNeighborsOfStateChange( wc.getPos(), Platform.AIR_BLOCK );
}
this.transverseEdges(srcX - 1, srcY - 1, srcZ - 1, srcX + scaleX + 1, srcY + scaleY + 1, srcZ + scaleZ + 1,
new TriggerUpdates(srcWorld));
this.transverseEdges(dstX - 1, dstY - 1, dstZ - 1, dstX + scaleX + 1, dstY + scaleY + 1, dstZ + scaleZ + 1,
new TriggerUpdates(dstWorld));
this.transverseEdges( srcX - 1, srcY - 1, srcZ - 1, srcX + scaleX + 1, srcY + scaleY + 1, srcZ + scaleZ + 1, new TriggerUpdates( srcWorld ) );
this.transverseEdges( dstX - 1, dstY - 1, dstZ - 1, dstX + scaleX + 1, dstY + scaleY + 1, dstZ + scaleZ + 1, new TriggerUpdates( dstWorld ) );
this.transverseEdges(srcX, srcY, srcZ, srcX + scaleX, srcY + scaleY, srcZ + scaleZ,
new TriggerUpdates(srcWorld));
this.transverseEdges(dstX, dstY, dstZ, dstX + scaleX, dstY + scaleY, dstZ + scaleZ,
new TriggerUpdates(dstWorld));
}
this.transverseEdges( srcX, srcY, srcZ, srcX + scaleX, srcY + scaleY, srcZ + scaleZ, new TriggerUpdates( srcWorld ) );
this.transverseEdges( dstX, dstY, dstZ, dstX + scaleX, dstY + scaleY, dstZ + scaleZ, new TriggerUpdates( dstWorld ) );
}
private static class TriggerUpdates implements ISpatialVisitor {
private static class TriggerUpdates implements ISpatialVisitor
{
private final World dst;
private final World dst;
public TriggerUpdates(final World dst2) {
this.dst = dst2;
}
public TriggerUpdates( final World dst2 )
{
this.dst = dst2;
}
@Override
public void visit(final BlockPos pos) {
final BlockState state = this.dst.getBlockState(pos);
final Block blk = state.getBlock();
blk.neighborChanged(state, this.dst, pos, blk, pos, false);
}
}
@Override
public void visit( final BlockPos pos )
{
final BlockState state = this.dst.getBlockState( pos );
final Block blk = state.getBlock();
blk.neighborChanged( state, this.dst, pos, blk, pos, false );
}
}
private static class WrapInMatrixFrame implements ISpatialVisitor {
private static class WrapInMatrixFrame implements ISpatialVisitor
{
private final World dst;
private final BlockState state;
private final World dst;
private final BlockState state;
public WrapInMatrixFrame(final BlockState state, final World dst2) {
this.dst = dst2;
this.state = state;
}
public WrapInMatrixFrame( final BlockState state, final World dst2 )
{
this.dst = dst2;
this.state = state;
}
@Override
public void visit(final BlockPos pos) {
this.dst.setBlockState(pos, this.state);
}
}
@Override
public void visit( final BlockPos pos )
{
this.dst.setBlockState( pos, this.state );
}
}
private static class TelDestination {
private final World dim;
private final double x;
private final double y;
private final double z;
private static class TelDestination
{
private final World dim;
private final double x;
private final double y;
private final double z;
TelDestination(final World dimension, final AxisAlignedBB srcBox, final double x, final double y,
final double z, final int tileX, final int tileY, final int tileZ) {
this.dim = dimension;
this.x = Math.min(srcBox.maxX - 0.5, Math.max(srcBox.minX + 0.5, x + tileX));
this.y = Math.min(srcBox.maxY - 0.5, Math.max(srcBox.minY + 0.5, y + tileY));
this.z = Math.min(srcBox.maxZ - 0.5, Math.max(srcBox.minZ + 0.5, z + tileZ));
}
}
TelDestination( final World dimension, final AxisAlignedBB srcBox, final double x, final double y, final double z, final int tileX, final int tileY, final int tileZ )
{
this.dim = dimension;
this.x = Math.min( srcBox.maxX - 0.5, Math.max( srcBox.minX + 0.5, x + tileX ) );
this.y = Math.min( srcBox.maxY - 0.5, Math.max( srcBox.minY + 0.5, y + tileY ) );
this.z = Math.min( srcBox.maxZ - 0.5, Math.max( srcBox.minZ + 0.5, z + tileZ ) );
}
}
private static class METeleporter implements ITeleporter {
private static class METeleporter implements ITeleporter
{
private final TelDestination destination;
private final TelDestination destination;
METeleporter(final TelDestination d) {
this.destination = d;
}
METeleporter( final TelDestination d )
{
this.destination = d;
}
@Override
public Entity placeEntity(Entity entity, ServerWorld currentWorld, ServerWorld destWorld, float yaw, Function<Boolean, Entity> repositionEntity) {
Entity newEntity = repositionEntity.apply(false);
newEntity.rotationYaw = yaw;
newEntity.setPositionAndUpdate( this.destination.x, this.destination.y, this.destination.z );
newEntity.setMotion(0, 0, 0);
return newEntity;
}
}
@Override
public Entity placeEntity(Entity entity, ServerWorld currentWorld, ServerWorld destWorld, float yaw,
Function<Boolean, Entity> repositionEntity) {
Entity newEntity = repositionEntity.apply(false);
newEntity.rotationYaw = yaw;
newEntity.setPositionAndUpdate(this.destination.x, this.destination.y, this.destination.z);
newEntity.setMotion(0, 0, 0);
return newEntity;
}
}
}