Scary Meteorite Re-write.

This commit is contained in:
AlgorithmX2 2014-08-07 01:47:42 -05:00
parent 6e8009eb2d
commit aef2396adc
8 changed files with 663 additions and 123 deletions

View file

@ -1,13 +1,19 @@
package appeng.core; package appeng.core;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.config.ConfigCategory; import net.minecraftforge.common.config.ConfigCategory;
import net.minecraftforge.common.config.Configuration; import net.minecraftforge.common.config.Configuration;
@ -41,6 +47,10 @@ public class WorldSettings extends Configuration
compass = new CompassService( AEFolder ); compass = new CompassService( AEFolder );
File spawnData = new File( AEFolder, "spawndata" );
if ( !spawnData.exists() || !spawnData.isDirectory() )
spawnData.mkdir();
for (int dimID : get( "DimensionManager", "StorageCells", new int[0] ).getIntList()) for (int dimID : get( "DimensionManager", "StorageCells", new int[0] ).getIntList())
{ {
storageCellDims.add( dimID ); storageCellDims.add( dimID );
@ -59,6 +69,123 @@ public class WorldSettings extends Configuration
} }
} }
NBTTagCompound loadSpawnData(int dim, int chunkX, int chunkZ)
{
if ( !Thread.holdsLock( WorldSettings.class ) )
throw new RuntimeException( "Invalid Request" );
File f = new File( AEFolder, "spawndata" + File.separatorChar + dim + "_" + (chunkX >> 4) + "_" + (chunkZ >> 4) + ".dat" );
if ( f.isFile() && f.exists() )
{
// open
FileInputStream fis;
try
{
fis = new FileInputStream( f );
NBTTagCompound data = CompressedStreamTools.readCompressed( fis );
fis.close();
return data;
}
catch (Throwable e)
{
}
}
return new NBTTagCompound();
}
void writeSpawnData(int dim, int chunkX, int chunkZ, NBTTagCompound data)
{
if ( !Thread.holdsLock( WorldSettings.class ) )
throw new RuntimeException( "Invalid Request" );
File f = new File( AEFolder, "spawndata" + File.separatorChar + dim + "_" + (chunkX >> 4) + "_" + (chunkZ >> 4) + ".dat" );
try
{
// save
FileOutputStream fos = new FileOutputStream( f );
CompressedStreamTools.writeCompressed( data, fos );
fos.close();
}
catch (Throwable e)
{
}
}
public Collection<NBTTagCompound> getNearByMetetorites(int dim, int chunkX, int chunkZ)
{
LinkedList<NBTTagCompound> ll = new LinkedList<NBTTagCompound>();
synchronized (WorldSettings.class)
{
for (int x = -1; x <= 1; x++)
{
for (int z = -1; z <= 1; z++)
{
int cx = x + (chunkX >> 4);
int cz = z + (chunkZ >> 4);
NBTTagCompound data = loadSpawnData( dim, cx << 4, cz << 4 );
if ( data != null )
{
// edit.
int size = data.getInteger( "num" );
for (int s = 0; s < size; s++)
ll.add( data.getCompoundTag( "" + s ) );
}
}
}
}
return ll;
}
public boolean hasGenerated(int dim, int chunkX, int chunkZ)
{
synchronized (WorldSettings.class)
{
NBTTagCompound data = loadSpawnData( dim, chunkX, chunkZ );
return data.getBoolean( chunkX + "," + chunkZ );
}
}
public void setGenerated(int dim, int chunkX, int chunkZ)
{
synchronized (WorldSettings.class)
{
NBTTagCompound data = loadSpawnData( dim, chunkX, chunkZ );
// edit.
data.setBoolean( chunkX + "," + chunkZ, true );
writeSpawnData( dim, chunkX, chunkZ, data );
}
}
public boolean addNearByMetetorites(int dim, int chunkX, int chunkZ, NBTTagCompound newData)
{
synchronized (WorldSettings.class)
{
NBTTagCompound data = loadSpawnData( dim, chunkX, chunkZ );
// edit.
int size = data.getInteger( "num" );
data.setTag( "" + size, newData );
data.setInteger( "num", size + 1 );
writeSpawnData( dim, chunkX, chunkZ, data );
return true;
}
}
public void shutdown() public void shutdown()
{ {
save(); save();

View file

@ -28,7 +28,7 @@ public class ToolMeteoritePlacer extends AEBaseItem
return false; return false;
MeteoritePlacer mp = new MeteoritePlacer(); MeteoritePlacer mp = new MeteoritePlacer();
boolean worked = mp.spawnMeteorite( world, x, y, z ); boolean worked = mp.spawnMeteorite( new MeteoritePlacer.StandardWorld( world ), x, y, z );
if ( !worked ) if ( !worked )
player.addChatMessage( new ChatComponentText( "Un-suiteable Location." ) ); player.addChatMessage( new ChatComponentText( "Un-suiteable Location." ) );

View file

@ -10,9 +10,11 @@ import net.minecraft.entity.item.EntityItem;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.inventory.IInventory; import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.oredict.OreDictionary; import net.minecraftforge.oredict.OreDictionary;
import appeng.api.AEApi; import appeng.api.AEApi;
@ -31,7 +33,7 @@ public class MeteoritePlacer
return 0; return 0;
} }
public void getRandomFall(World w, int x, int y, int z) public void getRandomFall(IMetroiteWorld w, int x, int y, int z)
{ {
double a = Math.random(); double a = Math.random();
if ( a > 0.9 ) if ( a > 0.9 )
@ -44,7 +46,7 @@ public class MeteoritePlacer
put( w, x, y, z, Blocks.gravel ); put( w, x, y, z, Blocks.gravel );
} }
public void getRandomInset(World w, int x, int y, int z) public void getRandomInset(IMetroiteWorld w, int x, int y, int z)
{ {
double a = Math.random(); double a = Math.random();
if ( a > 0.9 ) if ( a > 0.9 )
@ -69,17 +71,17 @@ public class MeteoritePlacer
Block blk; Block blk;
int meta; int meta;
public FalloutCopy(World w, int x, int y, int z) { public FalloutCopy(IMetroiteWorld w, int x, int y, int z) {
blk = w.getBlock( x, y, z ); blk = w.getBlock( x, y, z );
meta = w.getBlockMetadata( x, y, z ); meta = w.getBlockMetadata( x, y, z );
} }
public void getOther(World w, int x, int y, int z, double a) public void getOther(IMetroiteWorld w, int x, int y, int z, double a)
{ {
} }
public void getRandomFall(World w, int x, int y, int z) public void getRandomFall(IMetroiteWorld w, int x, int y, int z)
{ {
double a = Math.random(); double a = Math.random();
if ( a > 0.9 ) if ( a > 0.9 )
@ -88,7 +90,7 @@ public class MeteoritePlacer
getOther( w, x, y, z, a ); getOther( w, x, y, z, a );
} }
public void getRandomInset(World w, int x, int y, int z) public void getRandomInset(IMetroiteWorld w, int x, int y, int z)
{ {
double a = Math.random(); double a = Math.random();
if ( a > 0.9 ) if ( a > 0.9 )
@ -103,7 +105,7 @@ public class MeteoritePlacer
private class FalloutSand extends FalloutCopy private class FalloutSand extends FalloutCopy
{ {
public FalloutSand(World w, int x, int y, int z) { public FalloutSand(IMetroiteWorld w, int x, int y, int z) {
super( w, x, y, z ); super( w, x, y, z );
} }
@ -112,7 +114,7 @@ public class MeteoritePlacer
return 2; return 2;
} }
public void getOther(World w, int x, int y, int z, double a) public void getOther(IMetroiteWorld w, int x, int y, int z, double a)
{ {
if ( a > 0.66 ) if ( a > 0.66 )
put( w, x, y, z, Blocks.glass ); put( w, x, y, z, Blocks.glass );
@ -123,7 +125,7 @@ public class MeteoritePlacer
private class FalloutSnow extends FalloutCopy private class FalloutSnow extends FalloutCopy
{ {
public FalloutSnow(World w, int x, int y, int z) { public FalloutSnow(IMetroiteWorld w, int x, int y, int z) {
super( w, x, y, z ); super( w, x, y, z );
} }
@ -132,7 +134,7 @@ public class MeteoritePlacer
return 2; return 2;
} }
public void getOther(World w, int x, int y, int z, double a) public void getOther(IMetroiteWorld w, int x, int y, int z, double a)
{ {
if ( a > 0.7 ) if ( a > 0.7 )
put( w, x, y, z, Blocks.snow ); put( w, x, y, z, Blocks.snow );
@ -142,6 +144,231 @@ public class MeteoritePlacer
}; };
public interface IMetroiteWorld
{
int minX(int in);
int minZ(int in);
int maxX(int in);
int maxZ(int in);
boolean hasNoSky();
int getBlockMetadata(int x, int y, int z);
Block getBlock(int x, int y, int z);
boolean canBlockSeeTheSky(int i, int j, int k);
TileEntity getTileEntity(int x, int y, int z);
World getWorld();
void setBlock(int i, int j, int k, Block blk);
void setBlock(int i, int j, int k, Block blk_b, int meta_b, int l);
void done();
};
static public class StandardWorld implements IMetroiteWorld
{
protected World w;
public StandardWorld(World w) {
this.w = w;
}
@Override
public boolean hasNoSky()
{
return !w.provider.hasNoSky;
}
@Override
public int getBlockMetadata(int x, int y, int z)
{
if ( range( x, y, z ) )
return w.getBlockMetadata( x, y, z );
return 0;
}
@Override
public Block getBlock(int x, int y, int z)
{
if ( range( x, y, z ) )
return w.getBlock( x, y, z );
return Platform.air;
}
@Override
public boolean canBlockSeeTheSky(int x, int y, int z)
{
if ( range( x, y, z ) )
return w.canBlockSeeTheSky( x, y, z );
return false;
}
@Override
public TileEntity getTileEntity(int x, int y, int z)
{
if ( range( x, y, z ) )
return w.getTileEntity( x, y, z );
return null;
}
@Override
public World getWorld()
{
return w;
}
@Override
public void setBlock(int x, int y, int z, Block blk)
{
if ( range( x, y, z ) )
w.setBlock( x, y, z, blk );
}
@Override
public void setBlock(int x, int y, int z, Block blk, int metadata, int flags)
{
if ( range( x, y, z ) )
w.setBlock( x, y, z, blk, metadata, flags );
}
public boolean range(int x, int y, int z)
{
return true;
}
@Override
public int minX(int in)
{
return in;
}
@Override
public int minZ(int in)
{
return in;
}
@Override
public int maxX(int in)
{
return in;
}
@Override
public int maxZ(int in)
{
return in;
}
@Override
public void done()
{
}
}
static public class ChunkOnly extends StandardWorld
{
Chunk target;
int verticalBits = 0;
final int cx, cz;
public ChunkOnly(World w, int cx, int cz) {
super( w );
target = w.getChunkFromChunkCoords( cx, cz );
this.cx = cx;
this.cz = cz;
}
@Override
public void done()
{
if ( verticalBits != 0 )
Platform.sendChunk( target, verticalBits );
}
@Override
public void setBlock(int x, int y, int z, Block blk)
{
if ( range( x, y, z ) )
{
verticalBits |= 1 << (y >> 4);
w.setBlock( x, y, z, blk, 0, 1 );
}
}
@Override
public void setBlock(int x, int y, int z, Block blk, int metadata, int flags)
{
if ( range( x, y, z ) )
{
verticalBits |= 1 << (y >> 4);
w.setBlock( x, y, z, blk, metadata, flags & (~2) );
}
}
@Override
public Block getBlock(int x, int y, int z)
{
if ( range( x, y, z ) )
return target.getBlock( x & 0xF, y, z & 0xF );
return Platform.air;
}
@Override
public int getBlockMetadata(int x, int y, int z)
{
if ( range( x, y, z ) )
return target.getBlockMetadata( x & 0xF, y, z & 0xF );
return 0;
}
@Override
public boolean range(int x, int y, int z)
{
return cx == (x >> 4) && cz == (z >> 4);
}
@Override
public int minX(int in)
{
return Math.max( in, cx << 4 );
}
@Override
public int minZ(int in)
{
return Math.max( in, cz << 4 );
}
@Override
public int maxX(int in)
{
return Math.min( in, (cx + 1) << 4 );
}
@Override
public int maxZ(int in)
{
return Math.min( in, (cz + 1) << 4 );
}
};
int minBLocks = 200; int minBLocks = 200;
HashSet<Block> validSpawn = new HashSet(); HashSet<Block> validSpawn = new HashSet();
HashSet<Block> invalidSpawn = new HashSet(); HashSet<Block> invalidSpawn = new HashSet();
@ -191,17 +418,78 @@ public class MeteoritePlacer
invalidSpawn.add( Blocks.log2 ); invalidSpawn.add( Blocks.log2 );
} }
public boolean spawnMeteorite(World w, int x, int y, int z) NBTTagCompound settings;
public boolean spawnMeteorite(IMetroiteWorld w, NBTTagCompound metoriteBlob)
{
settings = metoriteBlob;
int x = settings.getInteger( "x" );
int y = settings.getInteger( "y" );
int z = settings.getInteger( "z" );
real_sizeOfMetorite = settings.getDouble( "real_sizeOfMetorite" );
real_crator = settings.getDouble( "real_crator" );
sizeOfMetorite = settings.getDouble( "sizeOfMetorite" );
crator = settings.getDouble( "crator" );
Block blk = Block.getBlockById( settings.getInteger( "blk" ) );
if ( blk == Blocks.sand )
type = new FalloutSand( w, x, y, z );
else if ( blk == Blocks.hardened_clay )
type = new FalloutCopy( w, x, y, z );
else if ( blk == Blocks.ice || blk == Blocks.snow )
type = new FalloutSnow( w, x, y, z );
int skyMode = settings.getInteger( "skyMode" );
// creator
if ( skyMode > 10 )
placeCrator( w, x, y, z );
placeMetor( w, x, y, z );
// collapse blocks...
if ( skyMode > 3 )
Decay( w, x, y, z );
w.done();
return true;
}
public double getSqDistance(int x, int z)
{
int Cx = settings.getInteger( "x" ) - x;
int Cz = settings.getInteger( "z" ) - z;
return Cx * Cx + Cz * Cz;
}
public boolean spawnMeteorite(IMetroiteWorld w, int x, int y, int z)
{ {
int validBlocks = 0; int validBlocks = 0;
if ( w.provider.hasNoSky ) if ( !w.hasNoSky() )
return false; return false;
Block blk = w.getBlock( x, y, z ); Block blk = w.getBlock( x, y, z );
if ( !validSpawn.contains( blk ) ) if ( !validSpawn.contains( blk ) )
return false; // must spawn on a valid block.. return false; // must spawn on a valid block..
settings = new NBTTagCompound();
settings.setInteger( "x", x );
settings.setInteger( "y", y );
settings.setInteger( "z", z );
settings.setInteger( "blk", Block.getIdFromBlock( blk ) );
settings.setDouble( "real_sizeOfMetorite", real_sizeOfMetorite );
settings.setDouble( "real_crator", real_crator );
settings.setDouble( "sizeOfMetorite", sizeOfMetorite );
settings.setDouble( "crator", crator );
settings.setBoolean( "lava", Math.random() > 0.9 );
if ( blk == Blocks.sand ) if ( blk == Blocks.sand )
type = new FalloutSand( w, x, y, z ); type = new FalloutSand( w, x, y, z );
else if ( blk == Blocks.hardened_clay ) else if ( blk == Blocks.hardened_clay )
@ -265,20 +553,24 @@ public class MeteoritePlacer
if ( skyMode > 3 ) if ( skyMode > 3 )
Decay( w, x, y, z ); Decay( w, x, y, z );
settings.setInteger( "skyMode", skyMode );
w.done();
WorldSettings.getInstance().addNearByMetetorites( w.getWorld().provider.dimensionId, x >> 4, z >> 4, settings );
return true; return true;
} }
return false; return false;
} }
private void placeCrator(World w, int x, int y, int z) private void placeCrator(IMetroiteWorld w, int x, int y, int z)
{ {
boolean lava = Math.random() > 0.9; boolean lava = settings.getBoolean( "lava" );
int maxY = Math.min( y + 20, 255 ); int maxY = 255;
int minX = x - 40; int minX = w.minX( x - 200 );
int maxX = x + 40; int maxX = w.maxX( x + 200 );
int minZ = z - 40; int minZ = w.minZ( z - 200 );
int maxZ = z + 40; int maxZ = w.maxZ( z + 200 );
for (int j = y - 5; j < maxY; j++) for (int j = y - 5; j < maxY; j++)
{ {
@ -295,7 +587,7 @@ public class MeteoritePlacer
if ( j > h + distanceFrom * 0.02 ) if ( j > h + distanceFrom * 0.02 )
{ {
if ( lava && j < y && w.getBlock( x, y - 1, z ).isBlockSolid( w, i, j, k, 0 ) ) if ( lava && j < y && w.getBlock( x, y - 1, z ).isBlockSolid( w.getWorld(), i, j, k, 0 ) )
{ {
if ( j > h + distanceFrom * 0.02 ) if ( j > h + distanceFrom * 0.02 )
put( w, i, j, k, Blocks.lava ); put( w, i, j, k, Blocks.lava );
@ -304,32 +596,27 @@ public class MeteoritePlacer
changed = put( w, i, j, k, Platform.air ) || changed; changed = put( w, i, j, k, Platform.air ) || changed;
} }
} }
if ( changed && j > maxY - 5 )
{
maxY = Math.min( maxY + 5, 255 );
minX -= 7;
maxX += 7;
minZ -= 7;
maxZ += 7;
}
} }
for (Object o : w.getEntitiesWithinAABB( EntityItem.class, AxisAlignedBB.getBoundingBox( x - 30, y - 5, z - 30, x + 30, y + 30, z + 30 ) )) for (Object o : w.getWorld().getEntitiesWithinAABB( EntityItem.class,
AxisAlignedBB.getBoundingBox( w.minX( x - 30 ), y - 5, w.minZ( z - 30 ), w.maxX( x + 30 ), y + 30, w.maxZ( z + 30 ) ) ))
{ {
Entity e = (Entity) o; Entity e = (Entity) o;
e.setDead(); e.setDead();
} }
} }
private void placeMetor(World w, int x, int y, int z) private void placeMetor(IMetroiteWorld w, int x, int y, int z)
{ {
int Xmeteor_l = w.minX( x - 8 );
int Xmeteor_h = w.maxX( x + 8 );
int Zmeteor_l = w.minZ( z - 8 );
int Zmeteor_h = w.maxZ( z + 8 );
// spawn metor // spawn metor
for (int i = x - 8; i < x + 8; i++) for (int i = Xmeteor_l; i < Xmeteor_h; i++)
for (int j = y - 8; j < y + 8; j++) for (int j = y - 8; j < y + 8; j++)
for (int k = z - 8; k < z + 8; k++) for (int k = Zmeteor_l; k < Zmeteor_h; k++)
{ {
double dx = i - x; double dx = i - x;
double dy = j - y; double dy = j - y;
@ -341,7 +628,7 @@ public class MeteoritePlacer
put( w, x, y, z, skychest ); put( w, x, y, z, skychest );
TileEntity te = w.getTileEntity( x, y, z ); TileEntity te = w.getTileEntity( x, y, z );
if ( te instanceof IInventory ) if ( te != null && te instanceof IInventory )
{ {
InventoryAdaptor ap = InventoryAdaptor.getAdaptor( te, ForgeDirection.UP ); InventoryAdaptor ap = InventoryAdaptor.getAdaptor( te, ForgeDirection.UP );
@ -428,19 +715,24 @@ public class MeteoritePlacer
} }
} }
private void Decay(World w, int x, int y, int z) private void Decay(IMetroiteWorld w, int x, int y, int z)
{ {
double randomShit = 0; double randomShit = 0;
for (int i = x - 30; i < x + 30; i++) int Xmeteor_l = w.minX( x - 30 );
for (int k = z - 30; k < z + 30; k++) int Xmeteor_h = w.maxX( x + 30 );
int Zmeteor_l = w.minZ( z - 30 );
int Zmeteor_h = w.maxZ( z + 30 );
for (int i = Xmeteor_l; i < Xmeteor_h; i++)
for (int k = Zmeteor_l; k < Zmeteor_h; k++)
for (int j = y - 9; j < y + 30; j++) for (int j = y - 9; j < y + 30; j++)
{ {
Block blk = w.getBlock( i, j, k ); Block blk = w.getBlock( i, j, k );
if ( blk == Blocks.lava ) if ( blk == Blocks.lava )
continue; continue;
if ( blk.isReplaceable( w, i, j, k ) ) if ( blk.isReplaceable( w.getWorld(), i, j, k ) )
{ {
blk = Platform.air; blk = Platform.air;
Block blk_b = w.getBlock( i, j + 1, k ); Block blk_b = w.getBlock( i, j + 1, k );
@ -460,7 +752,7 @@ public class MeteoritePlacer
double dist = dx * dx + dy * dy + dz * dz; double dist = dx * dx + dy * dy + dz * dz;
Block xf = w.getBlock( i, j - 1, k ); Block xf = w.getBlock( i, j - 1, k );
if ( !xf.isReplaceable( w, i, j - 1, k ) ) if ( !xf.isReplaceable( w.getWorld(), i, j - 1, k ) )
{ {
double extrRange = Math.random() * 0.6; double extrRange = Math.random() * 0.6;
double height = crator * (extrRange + 0.2) - Math.abs( dist - crator * 1.7 ); double height = crator * (extrRange + 0.2) - Math.abs( dist - crator * 1.7 );
@ -497,7 +789,7 @@ public class MeteoritePlacer
} }
} }
private boolean put(World w, int i, int j, int k, Block blk) private boolean put(IMetroiteWorld w, int i, int j, int k, Block blk)
{ {
Block original = w.getBlock( i, j, k ); Block original = w.getBlock( i, j, k );
@ -508,11 +800,16 @@ public class MeteoritePlacer
return true; return true;
} }
private void put(World w, int i, int j, int k, Block blk, int meta) private void put(IMetroiteWorld w, int i, int j, int k, Block blk, int meta)
{ {
if ( w.getBlock( i, j, k ) == Blocks.bedrock ) if ( w.getBlock( i, j, k ) == Blocks.bedrock )
return; return;
w.setBlock( i, j, k, blk, meta, 3 ); w.setBlock( i, j, k, blk, meta, 3 );
} }
public NBTTagCompound getSettings()
{
return settings;
}
} }

View file

@ -1,18 +1,19 @@
package appeng.hooks; package appeng.hooks;
import java.util.Collection;
import java.util.Random; import java.util.Random;
import java.util.concurrent.Future; import java.util.concurrent.Callable;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.chunk.IChunkProvider;
import appeng.api.features.IWorldGen.WorldGenType; import appeng.api.features.IWorldGen.WorldGenType;
import appeng.api.util.DimensionalCoord;
import appeng.core.AEConfig; import appeng.core.AEConfig;
import appeng.core.AELog;
import appeng.core.WorldSettings; import appeng.core.WorldSettings;
import appeng.core.features.registries.WorldGenRegistry; import appeng.core.features.registries.WorldGenRegistry;
import appeng.helpers.MeteoritePlacer; import appeng.helpers.MeteoritePlacer;
import appeng.services.helpers.ICompassCallback; import appeng.services.helpers.ICompassCallback;
import appeng.util.Platform;
import cpw.mods.fml.common.IWorldGenerator; import cpw.mods.fml.common.IWorldGenerator;
final public class MeteoriteWorldGen implements IWorldGenerator final public class MeteoriteWorldGen implements IWorldGenerator
@ -37,41 +38,105 @@ final public class MeteoriteWorldGen implements IWorldGenerator
@Override @Override
public void generate(Random r, int chunkX, int chunkZ, World w, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) public void generate(Random r, int chunkX, int chunkZ, World w, IChunkProvider chunkGenerator, IChunkProvider chunkProvider)
{ {
if ( WorldGenRegistry.instance.isWorldGenEnabled( WorldGenType.Metorites, w ) && r.nextFloat() > 0.9 ) if ( WorldGenRegistry.instance.isWorldGenEnabled( WorldGenType.Metorites, w ) )
{ {
int x = r.nextInt( 16 ) + (chunkX << 4); // add new metorites?
int z = r.nextInt( 16 ) + (chunkZ << 4); if ( r.nextFloat() > 0.7 )
myGen obj = new myGen();
Future<?> future = WorldSettings.getInstance().getCompass().getCompassDirection( new DimensionalCoord( w, x, 128, z ), 70, obj );
try
{ {
future.get(); int x = r.nextInt( 16 ) + (chunkX << 4);
int z = r.nextInt( 16 ) + (chunkZ << 4);
if ( obj.distance > AEConfig.instance.minMeteoriteDistanceSq )
{
int depth = 180 + r.nextInt( 20 );
for (int trys = 0; trys < 20; trys++)
{
MeteoritePlacer mp = new MeteoritePlacer();
if ( mp.spawnMeteorite( w, x, depth, z ) )
return;
depth -= 15;
if ( depth < 40 )
return;
}
}
int depth = 180 + r.nextInt( 20 );
TickHandler.instance.addCallable( w, new MetoriteSpawn( x, depth, z, w ) );
} }
catch (Throwable e) else
{ TickHandler.instance.addCallable( w, new MetoriteSpawn( chunkX << 4, 128, chunkZ << 4, w ) );
AELog.error( e );
}
} }
} }
class MetoriteSpawn implements Callable
{
final int x;
final int z;
final World w;
int depth;
public MetoriteSpawn(int x, int depth, int z, World w) {
this.x = x;
this.z = z;
this.w = w;
this.depth = depth;
}
@Override
public Object call() throws Exception
{
int chunkX = x >> 4;
int chunkZ = z >> 4;
double minSqDist = Double.MAX_VALUE;
// near by meteorites!
for (NBTTagCompound data : getNearByMetetorites( w, chunkX, chunkZ ))
{
MeteoritePlacer mp = new MeteoritePlacer();
mp.spawnMeteorite( new MeteoritePlacer.ChunkOnly( w, chunkX, chunkZ ), data );
minSqDist = Math.min( minSqDist, mp.getSqDistance( x, z ) );
}
boolean isCluster = (minSqDist < 30 * 30) && Platform.getRandomFloat() > 0.8;
if ( minSqDist > AEConfig.instance.minMeteoriteDistanceSq || isCluster )
tryMetroite( w, depth, x, z );
WorldSettings.getInstance().setGenerated( w.provider.dimensionId, chunkX, chunkZ );
return null;
}
}
private boolean tryMetroite(World w, int depth, int x, int z)
{
for (int trys = 0; trys < 20; trys++)
{
MeteoritePlacer mp = new MeteoritePlacer();
if ( mp.spawnMeteorite( new MeteoritePlacer.ChunkOnly( w, x >> 4, z >> 4 ), x, depth, z ) )
{
int px = x >> 4;
int pz = z >> 4;
for (int cx = px - 6; cx < px + 6; cx++)
for (int cz = pz - 6; cz < pz + 6; cz++)
{
if ( w.getChunkProvider().chunkExists( cx, cz ) )
{
if ( px == cx && pz == cz )
continue;
if ( WorldSettings.getInstance().hasGenerated( w.provider.dimensionId, cx, cz ) )
{
MeteoritePlacer mp2 = new MeteoritePlacer();
mp2.spawnMeteorite( new MeteoritePlacer.ChunkOnly( w, cx, cz ), mp.getSettings() );
}
}
}
return true;
}
depth -= 15;
if ( depth < 40 )
return false;
}
return false;
}
private Collection<NBTTagCompound> getNearByMetetorites(World w, int chunkX, int chunkZ)
{
return WorldSettings.getInstance().getNearByMetetorites( w.provider.dimensionId, chunkX, chunkZ );
}
} }

View file

@ -7,6 +7,7 @@ import java.util.LinkedList;
import java.util.Queue; import java.util.Queue;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.event.world.ChunkEvent; import net.minecraftforge.event.world.ChunkEvent;
@ -25,6 +26,7 @@ import appeng.me.NetworkList;
import appeng.tile.AEBaseTile; import appeng.tile.AEBaseTile;
import appeng.util.Platform; import appeng.util.Platform;
import com.google.common.base.Stopwatch;
import com.google.common.collect.LinkedListMultimap; import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
@ -251,18 +253,27 @@ public class TickHandler
if ( queue == null ) if ( queue == null )
return; return;
Stopwatch sw = Stopwatch.createStarted();
Callable c = null; Callable c = null;
while ((c = queue.poll()) != null) while ((c = queue.poll()) != null)
{ {
try try
{ {
c.call(); c.call();
if ( sw.elapsed( TimeUnit.MILLISECONDS ) > 50 )
break;
} }
catch (Exception e) catch (Exception e)
{ {
AELog.error( e ); AELog.error( e );
} }
} }
// long time = sw.elapsed( TimeUnit.MILLISECONDS );
// if ( time > 0 )
// AELog.info( "processQueue Time: " + time + "ms" );
} }
Multimap<World, CraftingJob> craftingJobs = LinkedListMultimap.create(); Multimap<World, CraftingJob> craftingJobs = LinkedListMultimap.create();

View file

@ -18,6 +18,8 @@ import appeng.services.helpers.ICompassCallback;
public class CompassService implements ThreadFactory public class CompassService implements ThreadFactory
{ {
int jobSize = 0;
private class CMUpdatePost implements Runnable private class CMUpdatePost implements Runnable
{ {
@ -38,9 +40,13 @@ public class CompassService implements ThreadFactory
@Override @Override
public void run() public void run()
{ {
jobSize--;
CompassReader cr = getReader( world ); CompassReader cr = getReader( world );
cr.setHasBeacon( chunkX, chunkZ, doubleChunkY, value ); cr.setHasBeacon( chunkX, chunkZ, doubleChunkY, value );
cr.close();
if ( jobSize() < 2 )
cleanUp();
} }
}; };
@ -61,6 +67,8 @@ public class CompassService implements ThreadFactory
@Override @Override
public void run() public void run()
{ {
jobSize--;
int cx = coord.x >> 4; int cx = coord.x >> 4;
int cz = coord.z >> 4; int cz = coord.z >> 4;
@ -70,6 +78,10 @@ public class CompassService implements ThreadFactory
if ( cr.hasBeacon( cx, cz ) ) if ( cr.hasBeacon( cx, cz ) )
{ {
callback.calculatedDirection( true, true, -999, 0 ); callback.calculatedDirection( true, true, -999, 0 );
if ( jobSize() < 2 )
cleanUp();
return; return;
} }
@ -138,22 +150,43 @@ public class CompassService implements ThreadFactory
if ( closest < Integer.MAX_VALUE ) if ( closest < Integer.MAX_VALUE )
{ {
callback.calculatedDirection( true, false, rad( cx, cz, chosen_x, chosen_z ), dist( cx, cz, chosen_x, chosen_z ) ); callback.calculatedDirection( true, false, rad( cx, cz, chosen_x, chosen_z ), dist( cx, cz, chosen_x, chosen_z ) );
if ( jobSize() < 2 )
cleanUp();
return; return;
} }
} }
// didn't find shit... // didn't find shit...
callback.calculatedDirection( false, true, -999, 999 ); callback.calculatedDirection( false, true, -999, 999 );
if ( jobSize() < 2 )
cleanUp();
} }
}; };
public Future<?> getCompassDirection(DimensionalCoord coord, int maxRange, ICompassCallback cc) public Future<?> getCompassDirection(DimensionalCoord coord, int maxRange, ICompassCallback cc)
{ {
jobSize++;
return executor.submit( new CMDirectionRequest( coord, maxRange, cc ) ); return executor.submit( new CMDirectionRequest( coord, maxRange, cc ) );
} }
public int jobSize()
{
return jobSize;
}
public void cleanUp()
{
for (CompassReader cr : worldSet.values())
cr.close();
}
public Future<?> updateArea(World w, int x, int y, int z) public Future<?> updateArea(World w, int x, int y, int z)
{ {
jobSize++;
int cx = x >> 4; int cx = x >> 4;
int cdy = y >> 5; int cdy = y >> 5;
int cz = z >> 4; int cz = z >> 4;
@ -194,6 +227,7 @@ public class CompassService implements ThreadFactory
public CompassService(File aEFolder) { public CompassService(File aEFolder) {
rootFolder = aEFolder; rootFolder = aEFolder;
executor = Executors.newSingleThreadExecutor( this ); executor = Executors.newSingleThreadExecutor( this );
jobSize = 0;
} }
private CompassReader getReader(World w) private CompassReader getReader(World w)
@ -232,6 +266,7 @@ public class CompassService implements ThreadFactory
try try
{ {
executor.awaitTermination( 6, TimeUnit.MINUTES ); executor.awaitTermination( 6, TimeUnit.MINUTES );
jobSize = 0;
for (CompassReader cr : worldSet.values()) for (CompassReader cr : worldSet.values())
{ {

View file

@ -1,20 +1,15 @@
package appeng.spatial; package appeng.spatial;
import java.lang.reflect.Method;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.S21PacketChunkData;
import net.minecraft.server.management.PlayerManager;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.ChunkPosition; import net.minecraft.world.ChunkPosition;
import net.minecraft.world.NextTickListEntry; import net.minecraft.world.NextTickListEntry;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage; import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.common.util.ForgeDirection;
@ -25,7 +20,6 @@ import appeng.api.util.WorldCoord;
import appeng.core.AELog; import appeng.core.AELog;
import appeng.core.WorldSettings; import appeng.core.WorldSettings;
import appeng.util.Platform; import appeng.util.Platform;
import cpw.mods.fml.relauncher.ReflectionHelper;
public class CachedPlane public class CachedPlane
{ {
@ -400,47 +394,10 @@ public class CachedPlane
for (int y = 1; y < 255; y += 32) for (int y = 1; y < 255; y += 32)
WorldSettings.getInstance().getCompass().updateArea( wrld, c.xPosition << 4, y, c.zPosition << 4 ); WorldSettings.getInstance().getCompass().updateArea( wrld, c.xPosition << 4, y, c.zPosition << 4 );
try Platform.sendChunk( c, verticalBits );
{
WorldServer ws = (WorldServer) c.worldObj;
PlayerManager pm = ws.getPlayerManager();
if ( getOrCreateChunkWatcher == null )
{
getOrCreateChunkWatcher = ReflectionHelper.findMethod( PlayerManager.class, pm, new String[] { "getOrCreateChunkWatcher",
"func_72690_a" }, int.class, int.class, boolean.class );
}
if ( getOrCreateChunkWatcher != null )
{
Object playerinstance = getOrCreateChunkWatcher.invoke( pm, c.xPosition, c.zPosition, false );
if ( playerinstance != null )
{
Playerinstance = playerinstance.getClass();
if ( sendToAllPlayersWatchingChunk == null )
{
sendToAllPlayersWatchingChunk = ReflectionHelper.findMethod( Playerinstance, playerinstance, new String[] {
"sendToAllPlayersWatchingChunk", "func_151251_a" }, Packet.class );
}
if ( sendToAllPlayersWatchingChunk != null )
sendToAllPlayersWatchingChunk.invoke( playerinstance, new S21PacketChunkData( c, false, verticalBits ) );
}
}
}
catch (Throwable t)
{
AELog.error( t );
}
} }
} }
Class Playerinstance;
Method getOrCreateChunkWatcher;
Method sendToAllPlayersWatchingChunk;
} }

View file

@ -1,6 +1,7 @@
package appeng.util; package appeng.util;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -37,6 +38,9 @@ import net.minecraft.nbt.NBTTagInt;
import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagLong; import net.minecraft.nbt.NBTTagLong;
import net.minecraft.nbt.NBTTagString; import net.minecraft.nbt.NBTTagString;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.S21PacketChunkData;
import net.minecraft.server.management.PlayerManager;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityChest; import net.minecraft.tileentity.TileEntityChest;
import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.AxisAlignedBB;
@ -47,6 +51,7 @@ import net.minecraft.util.Vec3;
import net.minecraft.world.IBlockAccess; import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldServer; import net.minecraft.world.WorldServer;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.common.util.FakePlayerFactory; import net.minecraftforge.common.util.FakePlayerFactory;
import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.AEApi; import appeng.api.AEApi;
@ -101,6 +106,7 @@ import buildcraft.api.tools.IToolWrench;
import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModContainer; import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.relauncher.ReflectionHelper;
import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly; import cpw.mods.fml.relauncher.SideOnly;
@ -1720,4 +1726,46 @@ public class Platform
return is; return is;
} }
private static Class Playerinstance;
private static Method getOrCreateChunkWatcher;
private static Method sendToAllPlayersWatchingChunk;
public static void sendChunk(Chunk c, int verticalBits)
{
try
{
WorldServer ws = (WorldServer) c.worldObj;
PlayerManager pm = ws.getPlayerManager();
if ( getOrCreateChunkWatcher == null )
{
getOrCreateChunkWatcher = ReflectionHelper.findMethod( PlayerManager.class, pm, new String[] { "getOrCreateChunkWatcher", "func_72690_a" },
int.class, int.class, boolean.class );
}
if ( getOrCreateChunkWatcher != null )
{
Object playerinstance = getOrCreateChunkWatcher.invoke( pm, c.xPosition, c.zPosition, false );
if ( playerinstance != null )
{
Playerinstance = playerinstance.getClass();
if ( sendToAllPlayersWatchingChunk == null )
{
sendToAllPlayersWatchingChunk = ReflectionHelper.findMethod( Playerinstance, playerinstance, new String[] {
"sendToAllPlayersWatchingChunk", "func_151251_a" }, Packet.class );
}
if ( sendToAllPlayersWatchingChunk != null )
sendToAllPlayersWatchingChunk.invoke( playerinstance, new S21PacketChunkData( c, false, verticalBits ) );
}
}
}
catch (Throwable t)
{
AELog.error( t );
}
}
} }