Relocate Source to proper directory.
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
package appeng.spatial;
|
||||
|
||||
import net.minecraft.world.biome.BiomeGenBase;
|
||||
|
||||
public class BiomeGenStorage extends BiomeGenBase
|
||||
{
|
||||
|
||||
public BiomeGenStorage(int id) {
|
||||
super( id );
|
||||
this.setBiomeName( "Storage Cell" );
|
||||
|
||||
this.setDisableRain();
|
||||
this.temperature = -100;
|
||||
|
||||
this.theBiomeDecorator.treesPerChunk = 0;
|
||||
this.theBiomeDecorator.flowersPerChunk = 0;
|
||||
this.theBiomeDecorator.grassPerChunk = 0;
|
||||
|
||||
this.spawnableMonsterList.clear();
|
||||
this.spawnableCreatureList.clear();
|
||||
this.spawnableWaterCreatureList.clear();
|
||||
this.spawnableCaveCreatureList.clear();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,403 @@
|
||||
package appeng.spatial;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.ChunkPosition;
|
||||
import net.minecraft.world.NextTickListEntry;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.movable.IMovableHandler;
|
||||
import appeng.api.movable.IMovableRegistry;
|
||||
import appeng.api.util.WorldCoord;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.WorldSettings;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class CachedPlane
|
||||
{
|
||||
|
||||
class Column
|
||||
{
|
||||
|
||||
private final int x;
|
||||
private final int z;
|
||||
private final Chunk c;
|
||||
private final Object ch[] = { 0, 0, 0 };
|
||||
private List<Integer> skipThese = null;
|
||||
|
||||
private ExtendedBlockStorage[] storage;
|
||||
|
||||
public Column(Chunk _c, int _x, int _z, int cy, int y_clen) {
|
||||
x = _x;
|
||||
z = _z;
|
||||
c = _c;
|
||||
storage = c.getBlockStorageArray();
|
||||
|
||||
// make sure storage exists before hand...
|
||||
for (int ay = 0; ay < y_clen; ay++)
|
||||
{
|
||||
int by = (ay + cy);
|
||||
ExtendedBlockStorage extendedblockstorage = storage[by];
|
||||
if ( extendedblockstorage == null )
|
||||
extendedblockstorage = storage[by] = new ExtendedBlockStorage( by << 4, !c.worldObj.provider.hasNoSky );
|
||||
}
|
||||
}
|
||||
|
||||
public void setBlockIDWithMetadata(int y, Object[] blk)
|
||||
{
|
||||
if ( blk[0] == matrixFrame )
|
||||
blk[0] = Platform.air;
|
||||
|
||||
ExtendedBlockStorage extendedblockstorage = storage[y >> 4];
|
||||
extendedblockstorage.func_150818_a( x, y & 15, z, (Block) blk[0] );
|
||||
// extendedblockstorage.setExtBlockID( x, y & 15, z, blk[0] );
|
||||
extendedblockstorage.setExtBlockMetadata( x, y & 15, z, (Integer) blk[1] );
|
||||
extendedblockstorage.setExtBlocklightValue( x, y & 15, z, (Integer) blk[2] );
|
||||
}
|
||||
|
||||
public Object[] getDetails(int y)
|
||||
{
|
||||
ExtendedBlockStorage extendedblockstorage = storage[y >> 4];
|
||||
ch[0] = extendedblockstorage.getBlockByExtId( x, y & 15, z );
|
||||
ch[1] = extendedblockstorage.getExtBlockMetadata( x, y & 15, z );
|
||||
ch[2] = extendedblockstorage.getExtBlocklightValue( x, y & 15, z );
|
||||
return ch;
|
||||
}
|
||||
|
||||
public boolean dontSkip(int y)
|
||||
{
|
||||
ExtendedBlockStorage extendedblockstorage = storage[y >> 4];
|
||||
if ( reg.isBlacklisted( extendedblockstorage.getBlockByExtId( x, y & 15, z ) ) )
|
||||
return false;
|
||||
|
||||
return skipThese == null ? true : !skipThese.contains( y );
|
||||
}
|
||||
|
||||
public void setSkip(int yCoord)
|
||||
{
|
||||
if ( skipThese == null )
|
||||
skipThese = new LinkedList<Integer>();
|
||||
skipThese.add( yCoord );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
int verticalBits;
|
||||
|
||||
int x_size;
|
||||
int z_size;
|
||||
|
||||
int cx_size;
|
||||
int cz_size;
|
||||
|
||||
int x_offset;
|
||||
int y_offset;
|
||||
int z_offset;
|
||||
|
||||
int y_size;
|
||||
|
||||
Chunk myChunks[][];
|
||||
Column myColumns[][];
|
||||
|
||||
LinkedList<TileEntity> tiles = new LinkedList<TileEntity>();
|
||||
LinkedList<NextTickListEntry> ticks = new LinkedList<NextTickListEntry>();
|
||||
|
||||
World world;
|
||||
Block matrixFrame = AEApi.instance().blocks().blockMatrixFrame.block();
|
||||
IMovableRegistry reg = AEApi.instance().registries().movable();
|
||||
|
||||
LinkedList<WorldCoord> updates = new LinkedList<WorldCoord>();
|
||||
|
||||
public CachedPlane(World w, int minx, int miny, int minz, int maxx, int maxy, int maxz) {
|
||||
|
||||
world = w;
|
||||
|
||||
x_size = maxx - minx + 1;
|
||||
y_size = maxy - miny + 1;
|
||||
z_size = maxz - minz + 1;
|
||||
|
||||
x_offset = minx;
|
||||
y_offset = miny;
|
||||
z_offset = minz;
|
||||
|
||||
int minCX = minx >> 4;
|
||||
int minCY = miny >> 4;
|
||||
int minCZ = minz >> 4;
|
||||
int maxCX = maxx >> 4;
|
||||
int maxCY = maxy >> 4;
|
||||
int maxCZ = maxz >> 4;
|
||||
|
||||
cx_size = maxCX - minCX + 1;
|
||||
int cy_size = maxCY - minCY + 1;
|
||||
cz_size = maxCZ - minCZ + 1;
|
||||
|
||||
myChunks = new Chunk[cx_size][cz_size];
|
||||
myColumns = new Column[x_size][z_size];
|
||||
|
||||
verticalBits = 0;
|
||||
for (int cy = 0; cy < cy_size; cy++)
|
||||
{
|
||||
verticalBits |= 1 << (minCY + cy);
|
||||
}
|
||||
|
||||
for (int x = 0; x < x_size; x++)
|
||||
for (int z = 0; z < z_size; z++)
|
||||
{
|
||||
myColumns[x][z] = new Column( w.getChunkFromChunkCoords( (minx + x) >> 4, (minz + z) >> 4 ), (minx + x) & 0xF, (minz + z) & 0xF, minCY, cy_size );
|
||||
}
|
||||
|
||||
IMovableRegistry mr = AEApi.instance().registries().movable();
|
||||
|
||||
for (int cx = 0; cx < cx_size; cx++)
|
||||
for (int cz = 0; cz < cz_size; cz++)
|
||||
{
|
||||
LinkedList<Entry<ChunkPosition, TileEntity>> rwarTiles = new LinkedList();
|
||||
LinkedList<ChunkPosition> deadTiles = new LinkedList<ChunkPosition>();
|
||||
|
||||
Chunk c = w.getChunkFromChunkCoords( minCX + cx, minCZ + cz );
|
||||
myChunks[cx][cz] = c;
|
||||
|
||||
rwarTiles.addAll( ((HashMap<ChunkPosition, TileEntity>) c.chunkTileEntityMap).entrySet() );
|
||||
for (Entry<ChunkPosition, TileEntity> tx : rwarTiles)
|
||||
{
|
||||
ChunkPosition cp = tx.getKey();
|
||||
TileEntity te = tx.getValue();
|
||||
if ( te.xCoord >= minx && te.xCoord <= maxx && te.yCoord >= miny && te.yCoord <= maxy && te.zCoord >= minz && te.zCoord <= maxz )
|
||||
{
|
||||
if ( mr.askToMove( te ) )
|
||||
{
|
||||
tiles.add( te );
|
||||
deadTiles.add( cp );
|
||||
}
|
||||
else
|
||||
{
|
||||
Object[] details = myColumns[te.xCoord - minx][te.zCoord - minz].getDetails( te.yCoord );
|
||||
Block blk = (Block) details[0];
|
||||
|
||||
// don't skip air, juset let the code replace it...
|
||||
if ( blk != null && blk.isAir( c.worldObj, te.xCoord, te.yCoord, te.zCoord )
|
||||
&& blk.isReplaceable( c.worldObj, te.xCoord, te.yCoord, te.zCoord ) )
|
||||
{
|
||||
c.worldObj.setBlock( te.xCoord, te.yCoord, te.zCoord, Platform.air );
|
||||
c.worldObj.notifyBlocksOfNeighborChange( te.xCoord, te.yCoord, te.zCoord, Platform.air );
|
||||
}
|
||||
else
|
||||
myColumns[te.xCoord - minx][te.zCoord - minz].setSkip( te.yCoord );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (ChunkPosition cp : deadTiles)
|
||||
{
|
||||
c.chunkTileEntityMap.remove( cp );
|
||||
}
|
||||
|
||||
long k = world.getTotalWorldTime();
|
||||
List list = world.getPendingBlockUpdates( c, false );
|
||||
if ( list != null )
|
||||
{
|
||||
for (Object o : list)
|
||||
{
|
||||
NextTickListEntry ntle = (NextTickListEntry) o;
|
||||
if ( ntle.xCoord >= minx && ntle.xCoord <= maxx && ntle.yCoord >= miny && ntle.yCoord <= maxy && ntle.zCoord >= minz
|
||||
&& ntle.zCoord <= maxz )
|
||||
{
|
||||
NextTickListEntry newEntry = new NextTickListEntry( ntle.xCoord, ntle.yCoord, ntle.zCoord, ntle.func_151351_a() );
|
||||
newEntry.scheduledTime = ntle.scheduledTime - k;
|
||||
ticks.add( newEntry );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (TileEntity te : tiles)
|
||||
{
|
||||
try
|
||||
{
|
||||
world.loadedTileEntityList.remove( te );
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
AELog.error( e );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IMovableHandler getHandler(TileEntity te)
|
||||
{
|
||||
IMovableRegistry mr = AEApi.instance().registries().movable();
|
||||
return mr.getHandler( te );
|
||||
}
|
||||
|
||||
void Swap(CachedPlane dst)
|
||||
{
|
||||
IMovableRegistry mr = AEApi.instance().registries().movable();
|
||||
|
||||
if ( dst.x_size == x_size && dst.y_size == y_size && dst.z_size == z_size )
|
||||
{
|
||||
AELog.info( "Block Copy Scale: " + x_size + ", " + y_size + ", " + z_size );
|
||||
|
||||
long startTime = System.nanoTime();
|
||||
|
||||
for (int x = 0; x < x_size; x++)
|
||||
{
|
||||
for (int z = 0; z < z_size; z++)
|
||||
{
|
||||
Column a = myColumns[x][z];
|
||||
Column b = dst.myColumns[x][z];
|
||||
|
||||
for (int y = 0; y < y_size; y++)
|
||||
{
|
||||
int src_y = y + y_offset;
|
||||
int dst_y = y + dst.y_offset;
|
||||
|
||||
if ( a.dontSkip( src_y ) && b.dontSkip( dst_y ) )
|
||||
{
|
||||
Object[] aD = a.getDetails( src_y );
|
||||
Object[] bD = b.getDetails( dst_y );
|
||||
|
||||
a.setBlockIDWithMetadata( src_y, bD );
|
||||
b.setBlockIDWithMetadata( dst_y, aD );
|
||||
}
|
||||
else
|
||||
{
|
||||
markForUpdate( x + x_offset, src_y, z + 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 (TileEntity te : tiles)
|
||||
{
|
||||
dst.addTile( te.xCoord - x_offset, te.yCoord - y_offset, te.zCoord - z_offset, te, this, mr );
|
||||
}
|
||||
|
||||
for (TileEntity te : dst.tiles)
|
||||
{
|
||||
addTile( te.xCoord - dst.x_offset, te.yCoord - dst.y_offset, te.zCoord - dst.z_offset, te, dst, mr );
|
||||
}
|
||||
|
||||
for (NextTickListEntry ntle : ticks)
|
||||
{
|
||||
dst.addTick( ntle.xCoord - x_offset, ntle.yCoord - y_offset, ntle.zCoord - z_offset, ntle );
|
||||
}
|
||||
|
||||
for (NextTickListEntry ntle : dst.ticks)
|
||||
{
|
||||
addTick( ntle.xCoord - dst.x_offset, ntle.yCoord - dst.y_offset, ntle.zCoord - dst.z_offset, ntle );
|
||||
}
|
||||
|
||||
startTime = System.nanoTime();
|
||||
updateChunks();
|
||||
dst.updateChunks();
|
||||
endTime = System.nanoTime();
|
||||
|
||||
duration = endTime - startTime;
|
||||
AELog.info( "Update Time: " + duration );
|
||||
}
|
||||
}
|
||||
|
||||
private void markForUpdate(int src_x, int src_y, int src_z)
|
||||
{
|
||||
updates.add( new WorldCoord( src_x, src_y, src_z ) );
|
||||
for (ForgeDirection d : ForgeDirection.VALID_DIRECTIONS)
|
||||
updates.add( new WorldCoord( src_x + d.offsetX, src_y + d.offsetY, src_z + d.offsetZ ) );
|
||||
}
|
||||
|
||||
private void addTick(int x, int y, int z, NextTickListEntry ntle)
|
||||
{
|
||||
world.scheduleBlockUpdate( x + x_offset, y + y_offset, z + z_offset, ntle.func_151351_a(), (int) ntle.scheduledTime );
|
||||
}
|
||||
|
||||
private void addTile(int x, int y, int z, TileEntity te, CachedPlane alternateDest, IMovableRegistry mr)
|
||||
{
|
||||
try
|
||||
{
|
||||
Column c = myColumns[x][z];
|
||||
|
||||
if ( c.dontSkip( y + y_offset ) || alternateDest == null )
|
||||
{
|
||||
IMovableHandler handler = getHandler( te );
|
||||
|
||||
try
|
||||
{
|
||||
handler.moveTile( te, world, x + x_offset, y + y_offset, z + z_offset );
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
AELog.error( e );
|
||||
|
||||
// attempt recovery...
|
||||
te.setWorldObj( world );
|
||||
te.xCoord = x;
|
||||
te.yCoord = y;
|
||||
te.zCoord = z;
|
||||
|
||||
c.c.func_150812_a( c.x, y + y, c.z, te );
|
||||
// c.c.setChunkTileEntity( c.x, y + y, c.z, te );
|
||||
|
||||
if ( c.c.isChunkLoaded )
|
||||
{
|
||||
world.addTileEntity( te );
|
||||
world.markBlockForUpdate( x, y, z );
|
||||
}
|
||||
}
|
||||
|
||||
mr.doneMoving( te );
|
||||
}
|
||||
else
|
||||
{
|
||||
alternateDest.addTile( x, y, z, te, null, mr );
|
||||
}
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
AELog.error( e );
|
||||
}
|
||||
}
|
||||
|
||||
private void updateChunks()
|
||||
{
|
||||
|
||||
// update shit..
|
||||
for (int x = 0; x < cx_size; x++)
|
||||
for (int z = 0; z < cz_size; z++)
|
||||
{
|
||||
Chunk c = myChunks[x][z];
|
||||
c.resetRelightChecks();
|
||||
c.generateSkylightMap();
|
||||
c.isModified = true;
|
||||
}
|
||||
|
||||
// send shit...
|
||||
for (int x = 0; x < cx_size; x++)
|
||||
for (int z = 0; z < cz_size; z++)
|
||||
{
|
||||
|
||||
Chunk c = myChunks[x][z];
|
||||
|
||||
for (int y = 1; y < 255; y += 32)
|
||||
WorldSettings.getInstance().getCompass().updateArea( world, c.xPosition << 4, y, c.zPosition << 4 );
|
||||
|
||||
Platform.sendChunk( c, verticalBits );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package appeng.spatial;
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import appeng.api.movable.IMovableHandler;
|
||||
|
||||
public class DefaultSpatialHandler implements IMovableHandler
|
||||
{
|
||||
|
||||
@Override
|
||||
public void moveTile(TileEntity te, World w, int x, int y, int z)
|
||||
{
|
||||
|
||||
te.setWorldObj( w );
|
||||
te.xCoord = x;
|
||||
te.yCoord = y;
|
||||
te.zCoord = z;
|
||||
|
||||
Chunk c = w.getChunkFromBlockCoords( x, z );
|
||||
c.func_150812_a( x & 0xF, y, z & 0xF, te );
|
||||
// c.setChunkBlockTileEntity( x & 0xF, y, z & 0xF, te );
|
||||
|
||||
if ( c.isChunkLoaded )
|
||||
{
|
||||
w.addTileEntity( te );
|
||||
w.markBlockForUpdate( x, y, z );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* never called for the default.
|
||||
*
|
||||
* @param tile
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean canHandle(Class<? extends TileEntity> myClass, TileEntity tile)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package appeng.spatial;
|
||||
|
||||
public interface ISpatialVisitor
|
||||
{
|
||||
|
||||
void visit(int x, int y, int z);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package appeng.spatial;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.EnumCreatureType;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.IChunkProvider;
|
||||
import net.minecraft.world.gen.ChunkProviderGenerate;
|
||||
import appeng.api.AEApi;
|
||||
import appeng.core.AEConfig;
|
||||
|
||||
public class StorageChunkProvider extends ChunkProviderGenerate implements IChunkProvider
|
||||
{
|
||||
|
||||
final static Block[] ablock;
|
||||
|
||||
static {
|
||||
|
||||
ablock = new Block[255 * 256];
|
||||
|
||||
Block matrixFrame = AEApi.instance().blocks().blockMatrixFrame.block();
|
||||
for (int x = 0; x < ablock.length; x++)
|
||||
ablock[x] = matrixFrame;
|
||||
|
||||
}
|
||||
|
||||
World w;
|
||||
|
||||
public StorageChunkProvider(World wrd, long i) {
|
||||
super( wrd, i, false );
|
||||
this.w = wrd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unloadQueuedChunks()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk provideChunk(int x, int z)
|
||||
{
|
||||
Chunk chunk = new Chunk( w, ablock, x, z );
|
||||
|
||||
byte[] abyte = chunk.getBiomeArray();
|
||||
AEConfig config = AEConfig.instance;
|
||||
|
||||
for (int k = 0; k < abyte.length; ++k)
|
||||
abyte[k] = (byte) config.storageBiomeID;
|
||||
|
||||
if ( !chunk.isTerrainPopulated )
|
||||
{
|
||||
chunk.isTerrainPopulated = true;
|
||||
chunk.resetRelightChecks();
|
||||
}
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populate(IChunkProvider par1iChunkProvider, int par2, int par3)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List getPossibleCreatures(EnumCreatureType a, int b, int c, int d)
|
||||
{
|
||||
return new ArrayList();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,322 @@
|
||||
package appeng.spatial;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityHanging;
|
||||
import net.minecraft.entity.EntityList;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.world.Teleporter;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.util.WorldCoord;
|
||||
import appeng.block.spatial.BlockMatrixFrame;
|
||||
import appeng.core.stats.Achievements;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class StorageHelper
|
||||
{
|
||||
|
||||
private static StorageHelper instance;
|
||||
|
||||
public static StorageHelper getInstance()
|
||||
{
|
||||
if ( instance == null )
|
||||
instance = new StorageHelper();
|
||||
return instance;
|
||||
}
|
||||
|
||||
class triggerUpdates implements ISpatialVisitor
|
||||
{
|
||||
|
||||
World dst;
|
||||
|
||||
public triggerUpdates(World dst2) {
|
||||
dst = dst2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int x, int y, int z)
|
||||
{
|
||||
Block blk = dst.getBlock( x, y, z );
|
||||
blk.onNeighborBlockChange( dst, x, y, z, Platform.air );
|
||||
}
|
||||
};
|
||||
|
||||
class WrapInMatrixFrame implements ISpatialVisitor
|
||||
{
|
||||
|
||||
World dst;
|
||||
Block blkID;
|
||||
int Meta;
|
||||
|
||||
public WrapInMatrixFrame(Block blockID, int metaData, World dst2) {
|
||||
dst = dst2;
|
||||
blkID = blockID;
|
||||
Meta = metaData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int x, int y, int z)
|
||||
{
|
||||
dst.setBlock( x, y, z, blkID, Meta, 3 );
|
||||
}
|
||||
};
|
||||
|
||||
class TelDestination
|
||||
{
|
||||
|
||||
TelDestination(World _dim, AxisAlignedBB srcBox, double _x, double _y, double _z, int tileX, int tileY, int tileZ) {
|
||||
dim = _dim;
|
||||
x = Math.min( srcBox.maxX - 0.5, Math.max( srcBox.minX + 0.5, _x + tileX ) );
|
||||
y = Math.min( srcBox.maxY - 0.5, Math.max( srcBox.minY + 0.5, _y + tileY ) );
|
||||
z = Math.min( srcBox.maxZ - 0.5, Math.max( srcBox.minZ + 0.5, _z + tileZ ) );
|
||||
xOff = tileX;
|
||||
yOff = tileY;
|
||||
zOff = tileZ;
|
||||
}
|
||||
|
||||
final World dim;
|
||||
final double x;
|
||||
final double y;
|
||||
final double z;
|
||||
|
||||
final int xOff;
|
||||
final int yOff;
|
||||
final int zOff;
|
||||
};
|
||||
|
||||
class METeleporter extends Teleporter
|
||||
{
|
||||
|
||||
TelDestination dest;
|
||||
|
||||
public METeleporter(WorldServer par1WorldServer, TelDestination d) {
|
||||
super( par1WorldServer );
|
||||
dest = d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void placeInPortal(Entity par1Entity, double par2, double par4, double par6, float par8)
|
||||
{
|
||||
par1Entity.setLocationAndAngles( dest.x, dest.y, dest.z, par1Entity.rotationYaw, 0.0F );
|
||||
par1Entity.motionX = par1Entity.motionY = par1Entity.motionZ = 0.0D;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean makePortal(Entity par1Entity)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean placeInExistingPortal(Entity par1Entity, double par2, double par4, double par6, float par8)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeStalePortalLocations(long par1)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Method onEntityRemoved;
|
||||
|
||||
/**
|
||||
* Mostly from dimensional doors.. which mostly got it form X-Comp.
|
||||
*
|
||||
* @param world
|
||||
* @param entity
|
||||
* @param link
|
||||
* @return
|
||||
*/
|
||||
public Entity teleportEntity(Entity entity, TelDestination link)
|
||||
{
|
||||
WorldServer oldWorld, newWorld;
|
||||
EntityPlayerMP player;
|
||||
|
||||
try
|
||||
{
|
||||
oldWorld = (WorldServer) entity.worldObj;
|
||||
newWorld = (WorldServer) link.dim;
|
||||
player = (entity instanceof EntityPlayerMP) ? (EntityPlayerMP) entity : null;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
return entity;
|
||||
}
|
||||
|
||||
if ( oldWorld == null )
|
||||
return entity;
|
||||
if ( newWorld == null )
|
||||
return entity;
|
||||
|
||||
// Is something riding? Handle it first.
|
||||
if ( entity.riddenByEntity != null )
|
||||
{
|
||||
return teleportEntity( entity.riddenByEntity, link );
|
||||
}
|
||||
// Are we riding something? Dismount and tell the mount to go first.
|
||||
Entity cart = entity.ridingEntity;
|
||||
if ( cart != null )
|
||||
{
|
||||
entity.mountEntity( null );
|
||||
cart = teleportEntity( cart, link );
|
||||
// We keep track of both so we can remount them on the other side.
|
||||
}
|
||||
|
||||
// load the chunk!
|
||||
WorldServer.class.cast( newWorld ).getChunkProvider().loadChunk( MathHelper.floor_double( link.x ) >> 4, MathHelper.floor_double( link.z ) >> 4 );
|
||||
|
||||
boolean difDest = newWorld != oldWorld;
|
||||
if ( difDest )
|
||||
{
|
||||
if ( player != null )
|
||||
{
|
||||
if ( link.dim.provider instanceof StorageWorldProvider )
|
||||
Achievements.SpatialIOExplorer.addToPlayer( player );
|
||||
|
||||
player.mcServer.getConfigurationManager().transferPlayerToDimension( player, link.dim.provider.dimensionId, new METeleporter( newWorld, link ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
int entX = entity.chunkCoordX;
|
||||
int entZ = entity.chunkCoordZ;
|
||||
|
||||
if ( (entity.addedToChunk) && (oldWorld.getChunkProvider().chunkExists( entX, entZ )) )
|
||||
{
|
||||
oldWorld.getChunkFromChunkCoords( entX, entZ ).removeEntity( entity );
|
||||
oldWorld.getChunkFromChunkCoords( entX, entZ ).isModified = true;
|
||||
}
|
||||
|
||||
Entity newEntity = EntityList.createEntityByName( EntityList.getEntityString( entity ), newWorld );
|
||||
if ( newEntity != null )
|
||||
{
|
||||
entity.lastTickPosX = entity.prevPosX = entity.posX = link.x;
|
||||
entity.lastTickPosY = entity.prevPosY = entity.posY = link.y;
|
||||
entity.lastTickPosZ = entity.prevPosZ = entity.posZ = link.z;
|
||||
|
||||
if ( entity instanceof EntityHanging )
|
||||
{
|
||||
EntityHanging h = (EntityHanging) entity;
|
||||
h.field_146063_b += link.xOff;
|
||||
h.field_146064_c += link.yOff;
|
||||
h.field_146062_d += link.zOff;
|
||||
}
|
||||
|
||||
newEntity.copyDataFrom( entity, true );
|
||||
newEntity.dimension = newWorld.provider.dimensionId;
|
||||
newEntity.forceSpawn = true;
|
||||
|
||||
entity.isDead = true;
|
||||
entity = newEntity;
|
||||
}
|
||||
else
|
||||
return null;
|
||||
|
||||
// myChunk.addEntity( entity );
|
||||
// newWorld.loadedEntityList.add( entity );
|
||||
// newWorld.onEntityAdded( entity );
|
||||
newWorld.spawnEntityInWorld( entity );
|
||||
}
|
||||
}
|
||||
|
||||
entity.worldObj.updateEntityWithOptionalForce( entity, false );
|
||||
|
||||
if ( cart != null )
|
||||
{
|
||||
if ( player != null )
|
||||
entity.worldObj.updateEntityWithOptionalForce( entity, true );
|
||||
|
||||
entity.mountEntity( cart );
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
public void transverseEdges(int minx, int miny, int minz, int maxx, int maxy, int maxz, ISpatialVisitor obj)
|
||||
{
|
||||
for (int y = miny; y < maxy; y++)
|
||||
for (int z = minz; z < maxz; z++)
|
||||
{
|
||||
obj.visit( minx, y, z );
|
||||
obj.visit( maxx, y, z );
|
||||
}
|
||||
|
||||
for (int x = minx; x < maxx; x++)
|
||||
for (int z = minz; z < maxz; z++)
|
||||
{
|
||||
obj.visit( x, miny, z );
|
||||
obj.visit( x, maxy, z );
|
||||
}
|
||||
|
||||
for (int x = minx; x < maxx; x++)
|
||||
for (int y = miny; y < maxy; y++)
|
||||
{
|
||||
obj.visit( x, y, minz );
|
||||
obj.visit( x, y, maxz );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void swapRegions(World src /** over world **/
|
||||
, World dst /** storage cell **/
|
||||
, int x, int y, int z, int i, int j, int k, int scaleX, int scaleY, int scaleZ)
|
||||
{
|
||||
BlockMatrixFrame blkMF = (BlockMatrixFrame) AEApi.instance().blocks().blockMatrixFrame.block();
|
||||
|
||||
transverseEdges( i - 1, j - 1, k - 1, i + scaleX + 1, j + scaleY + 1, k + scaleZ + 1, new WrapInMatrixFrame( blkMF, 0, dst ) );
|
||||
|
||||
AxisAlignedBB srcBox = AxisAlignedBB.getBoundingBox( x, y, z, x + scaleX + 1, y + scaleY + 1, z + scaleZ + 1 );
|
||||
|
||||
AxisAlignedBB dstBox = AxisAlignedBB.getBoundingBox( i, j, k, i + scaleX + 1, j + scaleY + 1, k + scaleZ + 1 );
|
||||
|
||||
CachedPlane cDst = new CachedPlane( dst, i, j, k, i + scaleX, j + scaleY, k + scaleZ );
|
||||
CachedPlane cSrc = new CachedPlane( src, x, y, z, x + scaleX, y + scaleY, z + scaleZ );
|
||||
|
||||
// do nearly all the work... swaps blocks, tiles, and block ticks
|
||||
cSrc.Swap( cDst );
|
||||
|
||||
List<Entity> srcE = src.getEntitiesWithinAABB( Entity.class, srcBox );
|
||||
List<Entity> dstE = dst.getEntitiesWithinAABB( Entity.class, dstBox );
|
||||
|
||||
for (Entity e : dstE)
|
||||
{
|
||||
teleportEntity( e, new TelDestination( src, srcBox, e.posX, e.posY, e.posZ, -i + x, -j + y, -k + z ) );
|
||||
}
|
||||
|
||||
for (Entity e : srcE)
|
||||
{
|
||||
teleportEntity( e, new TelDestination( dst, dstBox, e.posX, e.posY, e.posZ, -x + i, -y + j, -z + k ) );
|
||||
}
|
||||
|
||||
for (WorldCoord wc : cDst.updates)
|
||||
cDst.world.notifyBlockOfNeighborChange( wc.x, wc.y, wc.z, Platform.air );
|
||||
|
||||
for (WorldCoord wc : cSrc.updates)
|
||||
cSrc.world.notifyBlockOfNeighborChange( wc.x, wc.y, wc.z, Platform.air );
|
||||
|
||||
transverseEdges( x - 1, y - 1, z - 1, x + scaleX + 1, y + scaleY + 1, z + scaleZ + 1, new triggerUpdates( src ) );
|
||||
transverseEdges( i - 1, j - 1, k - 1, i + scaleX + 1, j + scaleY + 1, k + scaleZ + 1, new triggerUpdates( dst ) );
|
||||
|
||||
transverseEdges( x, y, z, x + scaleX, y + scaleY, z + scaleZ, new triggerUpdates( src ) );
|
||||
transverseEdges( i, j, k, i + scaleX, j + scaleY, k + scaleZ, new triggerUpdates( dst ) );
|
||||
|
||||
/*
|
||||
* IChunkProvider cp = dest.getChunkProvider(); if ( cp instanceof ChunkProviderServer ) { ChunkProviderServer
|
||||
* srv = (ChunkProviderServer) cp; srv.unloadAllChunks(); }
|
||||
*
|
||||
* cp.unloadQueuedChunks();
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package appeng.spatial;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.ChunkCoordinates;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.WorldProvider;
|
||||
import net.minecraft.world.biome.WorldChunkManagerHell;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.IChunkProvider;
|
||||
import net.minecraftforge.client.IRenderHandler;
|
||||
import appeng.client.render.SpatialSkyRender;
|
||||
import appeng.core.Registration;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
public class StorageWorldProvider extends WorldProvider
|
||||
{
|
||||
|
||||
public StorageWorldProvider() {
|
||||
this.hasNoSky = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkCoordinates getSpawnPoint()
|
||||
{
|
||||
return new ChunkCoordinates( 0, 0, 0 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRespawnHere()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerWorldChunkManager()
|
||||
{
|
||||
super.worldChunkMgr = new WorldChunkManagerHell( Registration.instance.storageBiome, 0.0F );
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public float[] calcSunriseSunsetColors(float p_76560_1_, float p_76560_2_)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getStarBrightness(float par1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSurfaceWorld()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSnowAt(int x, int y, int z, boolean checkLight)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDoLightning(Chunk chunk)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlockHighHumidity(int x, int y, int z)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDaytime()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3 getSkyColor(Entity cameraEntity, float partialTicks)
|
||||
{
|
||||
return Vec3.createVectorHelper( 0.07, 0.07, 0.07 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesXZShowFog(int par1, int par2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float calculateCelestialAngle(long par1, float par3)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public boolean isSkyColored()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3 getFogColor(float par1, float par2)
|
||||
{
|
||||
return Vec3.createVectorHelper( 0.07, 0.07, 0.07 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IChunkProvider createChunkGenerator()
|
||||
{
|
||||
return new StorageChunkProvider( worldObj, 0 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDimensionName()
|
||||
{
|
||||
return "Storage Cell";
|
||||
}
|
||||
|
||||
@Override
|
||||
public IRenderHandler getSkyRenderer()
|
||||
{
|
||||
return SpatialSkyRender.getInstance();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user