split chunk class into server and client

This commit is contained in:
Sen 2025-05-24 18:18:04 +02:00
parent 7126ca5a9f
commit 71e50743fd
35 changed files with 734 additions and 715 deletions

View file

@ -94,6 +94,7 @@ import client.window.Keysym;
import client.window.Wheel; import client.window.Wheel;
import client.window.Window; import client.window.Window;
import client.window.WindowEvent; import client.window.WindowEvent;
import client.world.ChunkClient;
import client.world.WorldClient; import client.world.WorldClient;
import common.biome.Biome; import common.biome.Biome;
import common.block.Block; import common.block.Block;
@ -156,7 +157,6 @@ import common.util.HitPosition;
import common.util.LazyLoadBase; import common.util.LazyLoadBase;
import common.util.Util; import common.util.Util;
import common.util.HitPosition.ObjectType; import common.util.HitPosition.ObjectType;
import common.world.Chunk;
import common.world.LightType; import common.world.LightType;
import common.world.State; import common.world.State;
import common.world.World; import common.world.World;
@ -1735,8 +1735,8 @@ public class Client implements IThreadListener {
String bline; String bline;
String lline; String lline;
if(this.world.isBlockLoaded(blockpos)) { if(this.world.isBlockLoaded(blockpos)) {
Chunk chunk = this.world.getChunk(blockpos); ChunkClient chunk = this.world.getChunk(blockpos);
biome = chunk.getBiome(blockpos, null); biome = chunk.getBiome(blockpos);
bline = "Biom: " + biome.display + " (" + biome.id + ")" + /* (this.debugHideInfo ? "" : */ (", D: " + bline = "Biom: " + biome.display + " (" + biome.id + ")" + /* (this.debugHideInfo ? "" : */ (", D: " +
TextColor.stripCodes(this.world.dimension.getFormattedName(false)) + TextColor.stripCodes(this.world.dimension.getFormattedName(false)) +
" (" + this.world.dimension.getDimensionId() + ")"); " (" + this.world.dimension.getDimensionId() + ")");

View file

@ -28,6 +28,7 @@ import client.gui.ingame.GuiSign;
import client.gui.ingame.GuiForm; import client.gui.ingame.GuiForm;
import client.renderer.particle.EntityPickupFX; import client.renderer.particle.EntityPickupFX;
import client.renderer.texture.EntityTexManager; import client.renderer.texture.EntityTexManager;
import client.world.ChunkClient;
import client.world.WorldClient; import client.world.WorldClient;
import common.attributes.Attribute; import common.attributes.Attribute;
import common.attributes.AttributeInstance; import common.attributes.AttributeInstance;
@ -137,7 +138,6 @@ import common.tileentity.TileEntityMachine;
import common.tileentity.TileEntitySign; import common.tileentity.TileEntitySign;
import common.util.BlockPos; import common.util.BlockPos;
import common.village.MerchantRecipeList; import common.village.MerchantRecipeList;
import common.world.Chunk;
import common.world.Explosion; import common.world.Explosion;
import common.world.Weather; import common.world.Weather;
import common.world.World; import common.world.World;
@ -741,9 +741,9 @@ public class ClientPlayer extends NetHandler implements IClientPlayer
{ {
NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController);
for (SPacketMultiBlockChange.BlockUpdateData s22packetmultiblockchange$blockupdatedata : packetIn.getChangedBlocks()) for (SPacketMultiBlockChange.BlockUpdateData update : packetIn.getChangedBlocks())
{ {
this.clientWorldController.invalidateRegionAndSetBlock(s22packetmultiblockchange$blockupdatedata.getPos(), s22packetmultiblockchange$blockupdatedata.getBlockState()); this.clientWorldController.invalidateRegionAndSetBlock(SPacketMultiBlockChange.getPos(packetIn.getChunkPos(), update.getRawPos()), update.getBlockState());
} }
} }
@ -766,7 +766,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer
} }
// this.clientWorldController.invalidateBlockReceiveRegion(packetIn.getChunkX() << 4, 0, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, 512, (packetIn.getChunkZ() << 4) + 15); // this.clientWorldController.invalidateBlockReceiveRegion(packetIn.getChunkX() << 4, 0, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, 512, (packetIn.getChunkZ() << 4) + 15);
Chunk chunk = this.clientWorldController.getChunk(packetIn.getChunkX(), packetIn.getChunkZ()); ChunkClient chunk = this.clientWorldController.getChunk(packetIn.getChunkX(), packetIn.getChunkZ());
chunk.setData(packetIn.getExtractedDataBytes(), packetIn.getExtractedExtend(), packetIn.hasBiomes()); chunk.setData(packetIn.getExtractedDataBytes(), packetIn.getExtractedExtend(), packetIn.hasBiomes());
this.clientWorldController.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, -World.MAX_SIZE_Y, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, World.MAX_SIZE_Y, (packetIn.getChunkZ() << 4) + 15); this.clientWorldController.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, -World.MAX_SIZE_Y, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, World.MAX_SIZE_Y, (packetIn.getChunkZ() << 4) + 15);
@ -779,7 +779,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer
public void handleBiomes(SPacketBiomes packetIn) public void handleBiomes(SPacketBiomes packetIn)
{ {
NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController); NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController);
Chunk chunk = this.clientWorldController.getChunk(packetIn.getChunkX(), packetIn.getChunkZ()); ChunkClient chunk = this.clientWorldController.getChunk(packetIn.getChunkX(), packetIn.getChunkZ());
chunk.setBiomes(packetIn.getBiomes()); chunk.setBiomes(packetIn.getBiomes());
this.clientWorldController.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, -World.MAX_SIZE_Y, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, World.MAX_SIZE_Y, (packetIn.getChunkZ() << 4) + 15); this.clientWorldController.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, -World.MAX_SIZE_Y, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, World.MAX_SIZE_Y, (packetIn.getChunkZ() << 4) + 15);
} }
@ -1412,7 +1412,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer
int k = packetIn.getChunkZ(i); int k = packetIn.getChunkZ(i);
this.clientWorldController.doPreChunk(j, k, true); this.clientWorldController.doPreChunk(j, k, true);
// this.clientWorldController.invalidateBlockReceiveRegion(j << 4, 0, k << 4, (j << 4) + 15, 512, (k << 4) + 15); // this.clientWorldController.invalidateBlockReceiveRegion(j << 4, 0, k << 4, (j << 4) + 15, 512, (k << 4) + 15);
Chunk chunk = this.clientWorldController.getChunk(j, k); ChunkClient chunk = this.clientWorldController.getChunk(j, k);
chunk.setData(packetIn.getChunkBytes(i), packetIn.getChunkExtend(i), true); chunk.setData(packetIn.getChunkBytes(i), packetIn.getChunkExtend(i), true);
this.clientWorldController.markBlockRangeForRenderUpdate(j << 4, -World.MAX_SIZE_Y, k << 4, (j << 4) + 15, World.MAX_SIZE_Y, (k << 4) + 15); this.clientWorldController.markBlockRangeForRenderUpdate(j << 4, -World.MAX_SIZE_Y, k << 4, (j << 4) + 15, World.MAX_SIZE_Y, (k << 4) + 15);

View file

@ -2,48 +2,62 @@ package client.renderer;
import java.util.Arrays; import java.util.Arrays;
import client.world.ChunkClient;
import client.world.WorldClient;
import common.biome.Biome; import common.biome.Biome;
import common.init.Blocks; import common.init.Blocks;
import common.tileentity.TileEntity; import common.tileentity.TileEntity;
import common.util.BlockPos; import common.util.BlockPos;
import common.util.Facing; import common.util.Facing;
import common.util.Vec3i; import common.util.Vec3i;
import common.world.Chunk;
import common.world.ChunkCache;
import common.world.IWorldAccess; import common.world.IWorldAccess;
import common.world.LightType; import common.world.LightType;
import common.world.State; import common.world.State;
import common.world.World; import common.world.World;
public class RegionRenderCache extends ChunkCache implements IWorldAccess public class RegionRenderCache implements IWorldAccess
{ {
private static final State DEFAULT_STATE = Blocks.air.getState(); private static final State DEFAULT_STATE = Blocks.air.getState();
private final World worldObj; private final int xPos;
private final int zPos;
private final ChunkClient[][] chunks;
private final World world;
private final BlockPos position; private final BlockPos position;
private final boolean empty; private final boolean empty;
private int[] combinedLights; private int[] combinedLights;
private State[] blockStates; private State[] blockStates;
public RegionRenderCache(World worldIn, BlockPos posFromIn, BlockPos posToIn, int subIn) public RegionRenderCache(WorldClient world, BlockPos from, BlockPos to, int sub)
{ {
super(worldIn, posFromIn, posToIn, subIn); this.world = world;
this.worldObj = worldIn; this.xPos = from.getX() - sub >> 4;
boolean empty = true; this.zPos = from.getZ() - sub >> 4;
for (int i1 = posFromIn.getX() >> 4; i1 <= posToIn.getX() >> 4; ++i1) int x2 = to.getX() + sub >> 4;
int z2 = to.getZ() + sub >> 4;
this.chunks = new ChunkClient[x2 - this.xPos + 1][z2 - this.zPos + 1];
for (int x = this.xPos; x <= x2; ++x)
{ {
for (int j1 = posFromIn.getZ() >> 4; j1 <= posToIn.getZ() >> 4; ++j1) for (int z = this.zPos; z <= z2; ++z)
{ {
Chunk chunk = this.chunkArray[i1 - this.chunkX][j1 - this.chunkZ]; this.chunks[x - this.xPos][z - this.zPos] = world.getChunk(x, z);
}
}
boolean empty = true;
for (int x = from.getX() >> 4; x <= to.getX() >> 4; ++x)
{
for (int z = from.getZ() >> 4; z <= to.getZ() >> 4; ++z)
{
ChunkClient chunk = this.chunks[x - this.xPos][z - this.zPos];
if (chunk != null && !chunk.isEmpty(posFromIn.getY(), posToIn.getY())) if (chunk != null && !chunk.isEmpty(from.getY(), to.getY()))
{ {
empty = false; empty = false;
} }
} }
} }
this.empty = empty; this.empty = empty;
this.position = posFromIn.subtract(new Vec3i(subIn, subIn, subIn)); this.position = from.subtract(new Vec3i(sub, sub, sub));
int i = 16000; int i = 16000;
this.combinedLights = new int[16000]; this.combinedLights = new int[16000];
Arrays.fill((int[])this.combinedLights, (int) - 1); Arrays.fill((int[])this.combinedLights, (int) - 1);
@ -52,9 +66,9 @@ public class RegionRenderCache extends ChunkCache implements IWorldAccess
public TileEntity getTileEntity(BlockPos pos) public TileEntity getTileEntity(BlockPos pos)
{ {
int i = (pos.getX() >> 4) - this.chunkX; int i = (pos.getX() >> 4) - this.xPos;
int j = (pos.getZ() >> 4) - this.chunkZ; int j = (pos.getZ() >> 4) - this.zPos;
return this.chunkArray[i][j].getTileEntity(pos, TileEntity.EnumCreateEntityType.QUEUED); return this.chunks[i][j].getTileEntity(pos, TileEntity.EnumCreateEntityType.QUEUED);
} }
public int getCombinedLight(BlockPos pos, int lightValue) public int getCombinedLight(BlockPos pos, int lightValue)
@ -89,9 +103,9 @@ public class RegionRenderCache extends ChunkCache implements IWorldAccess
{ {
if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y)
{ {
int i = (pos.getX() >> 4) - this.chunkX; int i = (pos.getX() >> 4) - this.xPos;
int j = (pos.getZ() >> 4) - this.chunkZ; int j = (pos.getZ() >> 4) - this.zPos;
return this.chunkArray[i][j].getState(pos); return this.chunks[i][j].getState(pos);
} }
else else
{ {
@ -127,12 +141,12 @@ public class RegionRenderCache extends ChunkCache implements IWorldAccess
public Biome getBiomeGenForCoords(BlockPos pos) public Biome getBiomeGenForCoords(BlockPos pos)
{ {
return this.worldObj.getBiomeGenForCoords(pos); return this.world.getBiomeGenForCoords(pos);
} }
private int getLightForExt(LightType p_175629_1_, BlockPos pos) private int getLightForExt(LightType p_175629_1_, BlockPos pos)
{ {
if (p_175629_1_ == LightType.SKY && this.worldObj.dimension.hasNoLight()) if (p_175629_1_ == LightType.SKY && this.world.dimension.hasNoLight())
{ {
return 0; return 0;
} }
@ -161,9 +175,9 @@ public class RegionRenderCache extends ChunkCache implements IWorldAccess
} }
else else
{ {
int i = (pos.getX() >> 4) - this.chunkX; int i = (pos.getX() >> 4) - this.xPos;
int j = (pos.getZ() >> 4) - this.chunkZ; int j = (pos.getZ() >> 4) - this.zPos;
return this.chunkArray[i][j].getLight(p_175629_1_, pos); return this.chunks[i][j].getLight(p_175629_1_, pos);
} }
} }
else else
@ -185,9 +199,9 @@ public class RegionRenderCache extends ChunkCache implements IWorldAccess
{ {
if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y) if (pos.getY() >= -World.MAX_SIZE_Y && pos.getY() < World.MAX_SIZE_Y)
{ {
int i = (pos.getX() >> 4) - this.chunkX; int i = (pos.getX() >> 4) - this.xPos;
int j = (pos.getZ() >> 4) - this.chunkZ; int j = (pos.getZ() >> 4) - this.zPos;
return this.chunkArray[i][j].getLight(p_175628_1_, pos); return this.chunks[i][j].getLight(p_175628_1_, pos);
} }
else else
{ {

View file

@ -25,6 +25,7 @@ import client.renderer.texture.TextureAtlasSprite;
import client.renderer.texture.TextureManager; import client.renderer.texture.TextureManager;
import client.renderer.texture.TextureMap; import client.renderer.texture.TextureMap;
import client.renderer.tileentity.TileEntityRendererDispatcher; import client.renderer.tileentity.TileEntityRendererDispatcher;
import client.world.ChunkClient;
import client.world.WorldClient; import client.world.WorldClient;
import common.block.Block; import common.block.Block;
import common.block.BlockChest; import common.block.BlockChest;
@ -51,7 +52,6 @@ import common.util.Facing;
import common.util.HitPosition; import common.util.HitPosition;
import common.util.Vec3; import common.util.Vec3;
import common.util.Vector3f; import common.util.Vector3f;
import common.world.Chunk;
import common.world.State; import common.world.State;
import common.world.World; import common.world.World;
@ -604,7 +604,7 @@ public class RenderGlobal
for (RenderGlobal.ContainerLocalRenderInformation renderglobal$containerlocalrenderinformation : this.renderInfos) for (RenderGlobal.ContainerLocalRenderInformation renderglobal$containerlocalrenderinformation : this.renderInfos)
{ {
Chunk chunk = this.theWorld.getChunk(renderglobal$containerlocalrenderinformation.renderChunk.getPosition()); ChunkClient chunk = this.theWorld.getChunk(renderglobal$containerlocalrenderinformation.renderChunk.getPosition());
ClassInheritanceMultiMap<Entity> classinheritancemultimap = chunk.getEntities()[ExtMath.clampi(renderglobal$containerlocalrenderinformation.renderChunk.getPosition().getY() / 16, 0, 31)]; ClassInheritanceMultiMap<Entity> classinheritancemultimap = chunk.getEntities()[ExtMath.clampi(renderglobal$containerlocalrenderinformation.renderChunk.getPosition().getY() / 16, 0, 31)];
if (!classinheritancemultimap.isEmpty()) if (!classinheritancemultimap.isEmpty())
@ -935,7 +935,7 @@ public class RenderGlobal
{ {
VisGraph visgraph = new VisGraph(); VisGraph visgraph = new VisGraph();
BlockPos blockpos = new BlockPos(pos.getX() >> 4 << 4, pos.getY() >> 4 << 4, pos.getZ() >> 4 << 4); BlockPos blockpos = new BlockPos(pos.getX() >> 4 << 4, pos.getY() >> 4 << 4, pos.getZ() >> 4 << 4);
Chunk chunk = this.theWorld.getChunk(blockpos); ChunkClient chunk = this.theWorld.getChunk(blockpos);
for (BlockPos.MutableBlockPos blockpos$mutableblockpos : BlockPos.getAllInBoxMutable(blockpos, blockpos.add(15, 15, 15))) for (BlockPos.MutableBlockPos blockpos$mutableblockpos : BlockPos.getAllInBoxMutable(blockpos, blockpos.add(15, 15, 15)))
{ {

View file

@ -1,14 +1,14 @@
package client.renderer; package client.renderer;
import client.renderer.chunk.RenderChunk; import client.renderer.chunk.RenderChunk;
import client.world.WorldClient;
import common.util.BlockPos; import common.util.BlockPos;
import common.util.ExtMath; import common.util.ExtMath;
import common.world.World;
public class ViewFrustum public class ViewFrustum
{ {
protected final RenderGlobal renderGlobal; protected final RenderGlobal renderGlobal;
protected final World world; protected final WorldClient world;
protected int countChunksY; protected int countChunksY;
protected int countChunksX; protected int countChunksX;
protected int countChunksZ; protected int countChunksZ;
@ -18,7 +18,7 @@ public class ViewFrustum
return i < 0 ? -((-i - 1) / 16) - 1 : i / 16; return i < 0 ? -((-i - 1) / 16) - 1 : i / 16;
} }
public ViewFrustum(World worldIn, int renderDistanceChunks, RenderGlobal p_i46246_3_) public ViewFrustum(WorldClient worldIn, int renderDistanceChunks, RenderGlobal p_i46246_3_)
{ {
this.renderGlobal = p_i46246_3_; this.renderGlobal = p_i46246_3_;
this.world = worldIn; this.world = worldIn;

View file

@ -19,6 +19,7 @@ import client.renderer.RenderGlobal;
import client.renderer.VertexBuffer; import client.renderer.VertexBuffer;
import client.renderer.tileentity.TileEntityRendererDispatcher; import client.renderer.tileentity.TileEntityRendererDispatcher;
import client.renderer.tileentity.TileEntitySpecialRenderer; import client.renderer.tileentity.TileEntitySpecialRenderer;
import client.world.WorldClient;
import common.block.Block; import common.block.Block;
import common.collect.Maps; import common.collect.Maps;
import common.collect.Sets; import common.collect.Sets;
@ -28,11 +29,10 @@ import common.util.BlockPos;
import common.util.BoundingBox; import common.util.BoundingBox;
import common.util.Facing; import common.util.Facing;
import common.world.State; import common.world.State;
import common.world.World;
public class RenderChunk public class RenderChunk
{ {
private World world; private WorldClient world;
private final RenderGlobal renderGlobal; private final RenderGlobal renderGlobal;
public static int renderChunksUpdated; public static int renderChunksUpdated;
private BlockPos position; private BlockPos position;
@ -49,7 +49,7 @@ public class RenderChunk
private boolean needsUpdate = true; private boolean needsUpdate = true;
private EnumMap<Facing, BlockPos> mapEnumFacing = Maps.newEnumMap(Facing.class); private EnumMap<Facing, BlockPos> mapEnumFacing = Maps.newEnumMap(Facing.class);
public RenderChunk(World worldIn, RenderGlobal renderGlobalIn, BlockPos blockPosIn, int indexIn) public RenderChunk(WorldClient worldIn, RenderGlobal renderGlobalIn, BlockPos blockPosIn, int indexIn)
{ {
this.world = worldIn; this.world = worldIn;
this.renderGlobal = renderGlobalIn; this.renderGlobal = renderGlobalIn;

View file

@ -0,0 +1,140 @@
package client.world;
import common.biome.Biome;
import common.block.Block;
import common.init.Blocks;
import common.tileentity.TileEntity;
import common.util.BlockPos;
import common.util.NibbleArray;
import common.world.BlockArray;
import common.world.Chunk;
import common.world.World;
public class ChunkClient extends Chunk {
public ChunkClient(World world, int x, int z) {
super(world, x, z);
}
private void clearArrays() {
this.blocks.clearMap();
this.blockList.clear();
this.bottom = Integer.MAX_VALUE;
this.top = Integer.MIN_VALUE;
}
private void genHeights() {
int top = this.top;
int bottom = this.bottom;
this.minHeight = Integer.MAX_VALUE;
for(int x = 0; x < 16; ++x) {
for(int z = 0; z < 16; ++z) {
this.precHeight[x + (z << 4)] = -99999999;
for(int y = top + 16; y > bottom; --y) {
Block block = this.getBlock0(x, y - 1, z);
if(block.getLightOpacity() != 0) {
this.height[z << 4 | x] = y;
if(y < this.minHeight) {
this.minHeight = y;
}
break;
}
}
}
}
this.modified = true;
}
public boolean isEmpty(int bottom, int top) {
for(int y = bottom; y <= top; y += 16) {
BlockArray stor = this.getArray(y >> 4);
if(stor != null ? !stor.isEmpty() : (y < 0 && this.fillerBlock != Blocks.air)) {
return false;
}
}
return true;
}
public void setData(byte[] data, int[] extend, boolean biomes) {
int pos = 0;
boolean sky = !this.world.dimension.hasNoLight();
if(biomes) {
this.clearArrays();
}
for(int cy : extend) {
BlockArray arr = this.getArray(cy);
if(arr == null) {
arr = new BlockArray(cy << 4, sky, null);
this.setArray(arr);
}
char[] blocks = arr.getData();
for(int k = 0; k < blocks.length; ++k) {
blocks[k] = (char)((data[pos + 1] & 255) << 8 | data[pos] & 255);
pos += 2;
}
}
for(int cy : extend) {
BlockArray arr = this.getArray(cy);
if(arr != null) {
NibbleArray light = arr.getBlocklight();
System.arraycopy(data, pos, light.getData(), 0, light.getData().length);
pos += light.getData().length;
}
}
if(sky) {
for(int cy : extend) {
BlockArray arr = this.getArray(cy);
if(arr != null) {
NibbleArray slight = arr.getSkylight();
System.arraycopy(data, pos, slight.getData(), 0, slight.getData().length);
pos += slight.getData().length;
}
}
}
if(biomes) {
System.arraycopy(data, pos, this.biomes, 0, this.biomes.length);
}
for(int cy : extend) {
BlockArray arr = this.getArray(cy);
if(arr != null) {
arr.update();
}
}
this.lightInit = true;
this.populated = true;
this.genHeights();
for(TileEntity tile : this.tiles.values()) {
tile.updateContainingBlockInfo();
}
}
public void setLoaded() {
this.loaded = true;
}
public Biome getBiome(BlockPos pos) {
int x = pos.getX() & 15;
int z = pos.getZ() & 15;
return Biome.getBiomeDef(this.biomes[z << 4 | x] & 255);
}
public boolean isDummy() {
return false;
}
}

View file

@ -10,17 +10,15 @@ import common.init.Blocks;
import common.tileentity.TileEntity; import common.tileentity.TileEntity;
import common.util.BlockPos; import common.util.BlockPos;
import common.util.BoundingBox; import common.util.BoundingBox;
import common.world.Chunk;
import common.world.LightType; import common.world.LightType;
import common.world.State; import common.world.State;
import common.worldgen.BiomeGenerator;
public class EmptyChunk extends Chunk { public class ChunkEmpty extends ChunkClient {
private final int liquidY; private final int liquidY;
private final State liquid; private final State liquid;
private final Block liquidBlock; private final Block liquidBlock;
public EmptyChunk(WorldClient world) { public ChunkEmpty(WorldClient world) {
super(world, 0, 0); super(world, 0, 0);
this.liquidY = world.dimension.getSeaLevel() - 1; this.liquidY = world.dimension.getSeaLevel() - 1;
this.liquid = world.dimension.getLiquid(); this.liquid = world.dimension.getLiquid();
@ -66,9 +64,6 @@ public class EmptyChunk extends Chunk {
public void removeTileEntity(BlockPos pos) { public void removeTileEntity(BlockPos pos) {
} }
public void setModified() {
}
public void getEntities(Entity exclude, BoundingBox bb, List<Entity> list, Predicate<? super Entity> pred) { public void getEntities(Entity exclude, BoundingBox bb, List<Entity> list, Predicate<? super Entity> pred) {
} }
@ -108,7 +103,7 @@ public class EmptyChunk extends Chunk {
public void setData(byte[] data, int[] extend, boolean biomes) { public void setData(byte[] data, int[] extend, boolean biomes) {
} }
public Biome getBiome(BlockPos pos, BiomeGenerator gen) { public Biome getBiome(BlockPos pos) {
return Biome.DEF_BIOME; return Biome.DEF_BIOME;
} }
@ -128,7 +123,7 @@ public class EmptyChunk extends Chunk {
return false; return false;
} }
public void setLoaded(boolean loaded) { public void setLoaded() {
} }
public int getLowest() { public int getLowest() {

View file

@ -33,7 +33,6 @@ import common.util.ExtMath;
import common.util.LongHashMap; import common.util.LongHashMap;
import common.util.Vec3; import common.util.Vec3;
import common.util.BlockPos.MutableBlockPos; import common.util.BlockPos.MutableBlockPos;
import common.world.Chunk;
import common.world.AWorldClient; import common.world.AWorldClient;
import common.world.State; import common.world.State;
import common.world.World; import common.world.World;
@ -46,11 +45,11 @@ public class WorldClient extends AWorldClient
private final Set<Entity> entityList = Sets.<Entity>newHashSet(); private final Set<Entity> entityList = Sets.<Entity>newHashSet();
private final Set<Entity> spawnQueue = Sets.<Entity>newHashSet(); private final Set<Entity> spawnQueue = Sets.<Entity>newHashSet();
private final Set<ChunkPos> previousActive = Sets.<ChunkPos>newHashSet(); private final Set<ChunkPos> previousActive = Sets.<ChunkPos>newHashSet();
private final LongHashMap<Chunk> chunkMapping = new LongHashMap(); private final LongHashMap<ChunkClient> chunkMapping = new LongHashMap();
private final List<Chunk> chunkListing = Lists.<Chunk>newArrayList(); private final List<ChunkClient> chunkListing = Lists.<ChunkClient>newArrayList();
private final Set<Long> emptyChunkListing = Sets.<Long>newHashSet(); private final Set<Long> emptyChunkListing = Sets.<Long>newHashSet();
private final Set<Long> nextEmptyChunkListing = Sets.<Long>newHashSet(); private final Set<Long> nextEmptyChunkListing = Sets.<Long>newHashSet();
private final Chunk emptyChunk = new EmptyChunk(this); private final ChunkClient emptyChunk = new ChunkEmpty(this);
// public final Profiler profiler; // public final Profiler profiler;
protected int lastLightning; protected int lastLightning;
protected Vec3 lightColor = new Vec3(0xffffff); protected Vec3 lightColor = new Vec3(0xffffff);
@ -120,7 +119,7 @@ public class WorldClient extends AWorldClient
} }
} }
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
for (Chunk chunk : this.chunkListing) for (ChunkClient chunk : this.chunkListing)
{ {
chunk.update(System.currentTimeMillis() - time > 5L); chunk.update(System.currentTimeMillis() - time > 5L);
} }
@ -149,7 +148,7 @@ public class WorldClient extends AWorldClient
{ {
int j = chunkcoordintpair.x * 16; int j = chunkcoordintpair.x * 16;
int k = chunkcoordintpair.z * 16; int k = chunkcoordintpair.z * 16;
Chunk chunk = this.getChunk(chunkcoordintpair.x, chunkcoordintpair.z); ChunkClient chunk = this.getChunk(chunkcoordintpair.x, chunkcoordintpair.z);
chunk.enqueueRelight(); chunk.enqueueRelight();
this.previousActive.add(chunkcoordintpair); this.previousActive.add(chunkcoordintpair);
++i; ++i;
@ -169,14 +168,14 @@ public class WorldClient extends AWorldClient
{ {
if(this.chunkMapping.getValueByKey(id) != null) if(this.chunkMapping.getValueByKey(id) != null)
this.doPreChunk(x, z, false); this.doPreChunk(x, z, false);
Chunk chunk = new Chunk(this, x, z); ChunkClient chunk = new ChunkClient(this, x, z);
this.chunkMapping.add(id, chunk); this.chunkMapping.add(id, chunk);
this.chunkListing.add(chunk); this.chunkListing.add(chunk);
chunk.setLoaded(true); chunk.setLoaded();
} }
else else
{ {
Chunk chunk = this.getChunk(x, z); ChunkClient chunk = this.getChunk(x, z);
chunk.onChunkUnload(); chunk.onChunkUnload();
this.chunkMapping.remove(id); this.chunkMapping.remove(id);
this.chunkListing.remove(chunk); this.chunkListing.remove(chunk);
@ -387,12 +386,27 @@ public class WorldClient extends AWorldClient
this.gm.effectRenderer.addEffect(new EntityFirework.StarterFX(this.gm.world, x, y, z, motionX, motionY, motionZ, this.gm.effectRenderer, compund)); this.gm.effectRenderer.addEffect(new EntityFirework.StarterFX(this.gm.world, x, y, z, motionX, motionY, motionZ, this.gm.effectRenderer, compund));
} }
public Chunk getChunk(int x, int z) public ChunkClient getChunk(int x, int z)
{ {
Chunk chunk = this.chunkMapping.getValueByKey(LongHashMap.packInt(x, z)); ChunkClient chunk = this.chunkMapping.getValueByKey(LongHashMap.packInt(x, z));
return chunk == null ? this.emptyChunk : chunk; return chunk == null ? this.emptyChunk : chunk;
} }
public ChunkClient getChunk(BlockPos pos) {
return this.getChunk(pos.getX() >> 4, pos.getZ() >> 4);
}
public Biome getBiomeGenForCoords(BlockPos pos) {
if(this.isBlockLoaded(pos))
return this.getChunk(pos).getBiome(pos);
else
return Biome.DEF_BIOME;
}
protected boolean isLoaded(int x, int z, boolean allowEmpty) {
return allowEmpty || !this.getChunk(x, z).isDummy();
}
public String getInfo() public String getInfo()
{ {
return "Chunk-Cache: M " + this.chunkMapping.getNumHashElements() + ", L " + this.chunkListing.size(); return "Chunk-Cache: M " + this.chunkMapping.getNumHashElements() + ", L " + this.chunkListing.size();

View file

@ -19,7 +19,6 @@ import common.util.BoundingBox;
import common.util.Facing; import common.util.Facing;
import common.util.HitPosition; import common.util.HitPosition;
import common.util.Vec3; import common.util.Vec3;
import common.world.Chunk;
import common.world.AWorldClient; import common.world.AWorldClient;
import common.world.State; import common.world.State;
import common.world.World; import common.world.World;
@ -36,20 +35,10 @@ public class BlockTorch extends Block
}); });
private static boolean isBlockNormalCube(World world, BlockPos pos, boolean def) { private static boolean isBlockNormalCube(World world, BlockPos pos, boolean def) {
if(!World.isValid(pos)) { if(!World.isValid(pos) || (world.client && !world.isBlockLoaded(pos, false)))
return def; return def;
} Block block = world.getState(pos).getBlock();
else { return block.getMaterial().isOpaque() && block.isFullCube();
Chunk chunk = world.getChunk(pos.getX() >> 4, pos.getZ() >> 4);
if(chunk.isDummy()) {
return def;
}
else {
Block block = world.getState(pos).getBlock();
return block.getMaterial().isOpaque() && block.isFullCube();
}
}
} }
public BlockTorch() public BlockTorch()

View file

@ -21,9 +21,6 @@ import common.util.ExtMath;
import common.util.Vec3; import common.util.Vec3;
import common.world.State; import common.world.State;
import common.world.Weather; import common.world.Weather;
import common.worldgen.FeatureLake;
import common.worldgen.FeatureLiquid;
import common.worldgen.FeatureOre;
public abstract class Dimension extends Nameable implements Comparable<Dimension> { public abstract class Dimension extends Nameable implements Comparable<Dimension> {
public class GeneratorSettings { public class GeneratorSettings {
@ -288,9 +285,9 @@ public abstract class Dimension extends Nameable implements Comparable<Dimension
private Biome[] hotBiomes = null; // b.layered private Biome[] hotBiomes = null; // b.layered
private Biome[] addBiomes = null; // b.layered private Biome[] addBiomes = null; // b.layered
private final List<FeatureOre> ores = Lists.newArrayList(); private final List<Ore> ores = Lists.newArrayList();
private final List<FeatureLake> lakes = Lists.newArrayList(); private final List<Lake> lakes = Lists.newArrayList();
private final List<FeatureLiquid> liquids = Lists.newArrayList(); private final List<Liquid> liquids = Lists.newArrayList();
private long seed = 0L; private long seed = 0L;
@ -584,24 +581,24 @@ public abstract class Dimension extends Nameable implements Comparable<Dimension
public final Dimension addLake(State state, State filler, State top, int chance, int minHeight, int maxHeight, public final Dimension addLake(State state, State filler, State top, int chance, int minHeight, int maxHeight,
boolean ratiod) { boolean ratiod) {
this.lakes.add(new FeatureLake(state, filler, top, chance, minHeight, maxHeight, ratiod)); this.lakes.add(new Lake(state, filler, top, chance, minHeight, maxHeight, ratiod));
return this; return this;
} }
public final Dimension addLiquid(State state, int chance, int minHeight, int maxHeight, boolean lower) { public final Dimension addLiquid(State state, int chance, int minHeight, int maxHeight, boolean lower) {
this.liquids.add(new FeatureLiquid(state, chance, minHeight, maxHeight, lower)); this.liquids.add(new Liquid(state, chance, minHeight, maxHeight, lower));
return this; return this;
} }
public final Dimension addOre(State state, int count, int more, int size, int minHeight, int maxHeight, boolean distrib) { public final Dimension addOre(State state, int count, int more, int size, int minHeight, int maxHeight, boolean distrib) {
this.ores.add(new FeatureOre(state, count, more, size, minHeight, maxHeight, distrib)); this.ores.add(new Ore(state, count, more, size, minHeight, maxHeight, distrib));
return this; return this;
} }
public final Dimension addMetalOres(MetalType ... metals) { public final Dimension addMetalOres(MetalType ... metals) {
for(MetalType metal : metals) { for(MetalType metal : metals) {
int count = METAL_COUNTS[metal.rarity]; int count = METAL_COUNTS[metal.rarity];
this.ores.add(new FeatureOre(BlockRegistry.getRegisteredBlock(metal.name + "_ore").getState(), this.ores.add(new Ore(BlockRegistry.getRegisteredBlock(metal.name + "_ore").getState(),
count < 0 ? 0 : count, count < 0 ? (-count) : 0, METAL_SIZES[metal.rarity], 0, METAL_HEIGHTS[metal.rarity], false)); count < 0 ? 0 : count, count < 0 ? (-count) : 0, METAL_SIZES[metal.rarity], 0, METAL_HEIGHTS[metal.rarity], false));
} }
return this; return this;
@ -1103,7 +1100,7 @@ public abstract class Dimension extends Nameable implements Comparable<Dimension
NBTTagList list = tag.getTagList("Ores", 10); NBTTagList list = tag.getTagList("Ores", 10);
for(int z = 0; z < list.tagCount(); z++) { for(int z = 0; z < list.tagCount(); z++) {
NBTTagCompound gen = list.getCompoundTagAt(z); NBTTagCompound gen = list.getCompoundTagAt(z);
this.ores.add(new FeatureOre(BlockRegistry.getFromIdName(gen.getString("Block"), Blocks.iron_ore.getState()), this.ores.add(new Ore(BlockRegistry.getFromIdName(gen.getString("Block"), Blocks.iron_ore.getState()),
gen.getInteger("Count"), gen.getInteger("Add"), gen.getInteger("Size"), gen.getInteger("Count"), gen.getInteger("Add"), gen.getInteger("Size"),
gen.getInteger("MinC"), gen.getInteger("MaxS"), gen.getBoolean("Distrib"))); gen.getInteger("MinC"), gen.getInteger("MaxS"), gen.getBoolean("Distrib")));
} }
@ -1113,7 +1110,7 @@ public abstract class Dimension extends Nameable implements Comparable<Dimension
NBTTagList list = tag.getTagList("Lakes", 10); NBTTagList list = tag.getTagList("Lakes", 10);
for(int z = 0; z < list.tagCount(); z++) { for(int z = 0; z < list.tagCount(); z++) {
NBTTagCompound gen = list.getCompoundTagAt(z); NBTTagCompound gen = list.getCompoundTagAt(z);
this.lakes.add(new FeatureLake( this.lakes.add(new Lake(
BlockRegistry.getFromIdName(gen.getString("Block"), Blocks.iron_ore.getState()), BlockRegistry.getFromIdName(gen.getString("Block"), Blocks.iron_ore.getState()),
gen.hasKey("Filler", 8) ? BlockRegistry.getFromIdName(gen.getString("Filler"), null) : null, gen.hasKey("Filler", 8) ? BlockRegistry.getFromIdName(gen.getString("Filler"), null) : null,
gen.hasKey("Top", 8) ? BlockRegistry.getFromIdName(gen.getString("Top"), null) : null, gen.hasKey("Top", 8) ? BlockRegistry.getFromIdName(gen.getString("Top"), null) : null,
@ -1125,7 +1122,7 @@ public abstract class Dimension extends Nameable implements Comparable<Dimension
NBTTagList list = tag.getTagList("Liquids", 10); NBTTagList list = tag.getTagList("Liquids", 10);
for(int z = 0; z < list.tagCount(); z++) { for(int z = 0; z < list.tagCount(); z++) {
NBTTagCompound gen = list.getCompoundTagAt(z); NBTTagCompound gen = list.getCompoundTagAt(z);
this.liquids.add(new FeatureLiquid( this.liquids.add(new Liquid(
BlockRegistry.getFromIdName(gen.getString("Block"), Blocks.iron_ore.getState()), BlockRegistry.getFromIdName(gen.getString("Block"), Blocks.iron_ore.getState()),
gen.getInteger("Chance"), gen.getInteger("Min"), gen.getInteger("Max"), gen.getBoolean("Lower"))); gen.getInteger("Chance"), gen.getInteger("Min"), gen.getInteger("Max"), gen.getBoolean("Lower")));
} }
@ -1294,7 +1291,7 @@ public abstract class Dimension extends Nameable implements Comparable<Dimension
} }
if(!this.ores.isEmpty()) { if(!this.ores.isEmpty()) {
NBTTagList list = new NBTTagList(); NBTTagList list = new NBTTagList();
for(FeatureOre gen : this.ores) { for(Ore gen : this.ores) {
NBTTagCompound ore = new NBTTagCompound(); NBTTagCompound ore = new NBTTagCompound();
ore.setString("Block", BlockRegistry.toIdName(gen.state)); ore.setString("Block", BlockRegistry.toIdName(gen.state));
ore.setBoolean("Distrib", gen.dist); ore.setBoolean("Distrib", gen.dist);
@ -1309,7 +1306,7 @@ public abstract class Dimension extends Nameable implements Comparable<Dimension
} }
if(!this.lakes.isEmpty()) { if(!this.lakes.isEmpty()) {
NBTTagList list = new NBTTagList(); NBTTagList list = new NBTTagList();
for(FeatureLake gen : this.lakes) { for(Lake gen : this.lakes) {
NBTTagCompound lake = new NBTTagCompound(); NBTTagCompound lake = new NBTTagCompound();
lake.setString("Block", BlockRegistry.toIdName(gen.state)); lake.setString("Block", BlockRegistry.toIdName(gen.state));
if(gen.filler != null) if(gen.filler != null)
@ -1326,7 +1323,7 @@ public abstract class Dimension extends Nameable implements Comparable<Dimension
} }
if(!this.liquids.isEmpty()) { if(!this.liquids.isEmpty()) {
NBTTagList list = new NBTTagList(); NBTTagList list = new NBTTagList();
for(FeatureLiquid gen : this.liquids) { for(Liquid gen : this.liquids) {
NBTTagCompound liquid = new NBTTagCompound(); NBTTagCompound liquid = new NBTTagCompound();
liquid.setString("Block", BlockRegistry.toIdName(gen.state)); liquid.setString("Block", BlockRegistry.toIdName(gen.state));
liquid.setBoolean("Lower", gen.lower); liquid.setBoolean("Lower", gen.lower);
@ -1509,15 +1506,15 @@ public abstract class Dimension extends Nameable implements Comparable<Dimension
return this.strideCaves; return this.strideCaves;
} }
public List<FeatureOre> getOres() { public List<Ore> getOres() {
return this.ores; return this.ores;
} }
public List<FeatureLake> getLakes() { public List<Lake> getLakes() {
return this.lakes; return this.lakes;
} }
public List<FeatureLiquid> getLiquids() { public List<Liquid> getLiquids() {
return this.liquids; return this.liquids;
} }
} }

View file

@ -1,8 +1,8 @@
package common.worldgen; package common.dimension;
import common.world.State; import common.world.State;
public class FeatureLake { public class Lake {
public final State state; public final State state;
public final State filler; public final State filler;
public final State top; public final State top;
@ -11,7 +11,7 @@ public class FeatureLake {
public final int maxHeight; public final int maxHeight;
public final boolean ratiod; public final boolean ratiod;
public FeatureLake(State state, State filler, State top, int chance, int minHeight, int maxHeight, boolean ratiod) { public Lake(State state, State filler, State top, int chance, int minHeight, int maxHeight, boolean ratiod) {
this.state = state; this.state = state;
this.filler = filler; this.filler = filler;
this.top = top; this.top = top;

View file

@ -1,15 +1,15 @@
package common.worldgen; package common.dimension;
import common.world.State; import common.world.State;
public class FeatureLiquid { public class Liquid {
public final State state; public final State state;
public final int chance; public final int chance;
public final int minHeight; public final int minHeight;
public final int maxHeight; public final int maxHeight;
public final boolean lower; public final boolean lower;
public FeatureLiquid(State state, int chance, int minHeight, int maxHeight, boolean lower) { public Liquid(State state, int chance, int minHeight, int maxHeight, boolean lower) {
this.state = state; this.state = state;
this.chance = chance; this.chance = chance;
this.minHeight = minHeight; this.minHeight = minHeight;

View file

@ -1,8 +1,8 @@
package common.worldgen; package common.dimension;
import common.world.State; import common.world.State;
public class FeatureOre { public class Ore {
public final State state; public final State state;
public final int count; public final int count;
public final int more; public final int more;
@ -11,7 +11,7 @@ public class FeatureOre {
public final int max; public final int max;
public final boolean dist; public final boolean dist;
public FeatureOre(State state, int count, int more, int size, int min, int max, boolean dist) { public Ore(State state, int count, int more, int size, int min, int max, boolean dist) {
this.state = state; this.state = state;
this.count = count; this.count = count;
this.more = more; this.more = more;

View file

@ -15,7 +15,6 @@ import common.pathfinding.PathNavigateGround;
import common.rng.Random; import common.rng.Random;
import common.util.BlockPos; import common.util.BlockPos;
import common.util.ExtMath; import common.util.ExtMath;
import common.world.Chunk;
import common.world.World; import common.world.World;
import common.world.AWorldServer; import common.world.AWorldServer;
@ -386,7 +385,6 @@ public class EntitySlime extends EntityNPC
public boolean getCanSpawnHere() public boolean getCanSpawnHere()
{ {
BlockPos blockpos = new BlockPos(ExtMath.floord(this.posX), 0, ExtMath.floord(this.posZ)); BlockPos blockpos = new BlockPos(ExtMath.floord(this.posX), 0, ExtMath.floord(this.posZ));
Chunk chunk = this.worldObj.getChunk(blockpos);
// if (this.worldObj.getWorldInfo().getTerrainType() == WorldType.FLAT && this.rand.nextInt(4) != 1) // if (this.worldObj.getWorldInfo().getTerrainType() == WorldType.FLAT && this.rand.nextInt(4) != 1)
// { // {
@ -403,7 +401,7 @@ public class EntitySlime extends EntityNPC
return super.getCanSpawnHere(); return super.getCanSpawnHere();
} }
if (this.rand.zrange(10) == 0 && getRandomWithSeed((AWorldServer)this.worldObj, chunk.xPos, chunk.zPos, 987234911L).zrange(10) == 0 && this.posY < 40.0D) if (this.rand.zrange(10) == 0 && getRandomWithSeed((AWorldServer)this.worldObj, blockpos.getX() >> 4, blockpos.getZ() >> 4, 987234911L).zrange(10) == 0 && this.posY < 40.0D)
{ {
return super.getCanSpawnHere(); return super.getCanSpawnHere();
} }

View file

@ -1,15 +1,9 @@
package common.packet; package common.packet;
import java.io.IOException; import java.io.IOException;
import java.util.List;
import java.util.Set;
import common.collect.Lists;
import common.network.IClientPlayer; import common.network.IClientPlayer;
import common.network.Packet; import common.network.Packet;
import common.network.PacketBuffer; import common.network.PacketBuffer;
import common.world.BlockArray;
import common.world.Chunk;
public class SPacketChunkData implements Packet<IClientPlayer> public class SPacketChunkData implements Packet<IClientPlayer>
{ {
@ -22,12 +16,12 @@ public class SPacketChunkData implements Packet<IClientPlayer>
{ {
} }
public SPacketChunkData(Chunk chunkIn, boolean biomes, int[] extend) public SPacketChunkData(int x, int z, boolean biomes, SPacketChunkData.Extracted data)
{ {
this.chunkX = chunkIn.xPos; this.chunkX = x;
this.chunkZ = chunkIn.zPos; this.chunkZ = z;
this.biomes = biomes; this.biomes = biomes;
this.extractedData = getExtractedData(chunkIn, biomes, !chunkIn.getWorld().dimension.hasNoLight(), extend); this.extractedData = data;
} }
/** /**
@ -74,7 +68,7 @@ public class SPacketChunkData implements Packet<IClientPlayer>
return this.extractedData.data; return this.extractedData.data;
} }
protected static int getSize(int segments, boolean overworld, boolean biomes) public static int getSize(int segments, boolean overworld, boolean biomes)
{ {
int i = segments * 2 * 16 * 16 * 16; int i = segments * 2 * 16 * 16 * 16;
int j = segments * 16 * 16 * 16 / 2; int j = segments * 16 * 16 * 16 / 2;
@ -83,72 +77,6 @@ public class SPacketChunkData implements Packet<IClientPlayer>
return i + j + k + l; return i + j + k + l;
} }
public static SPacketChunkData.Extracted getExtractedData(Chunk chunk, boolean biomes, boolean overworld, int[] extend)
{
Set<BlockArray> aextendedblockstorage = chunk.getStorage();
SPacketChunkData.Extracted s21packetchunkdata$extracted = new SPacketChunkData.Extracted();
List<BlockArray> list = Lists.<BlockArray>newArrayList();
if(extend == null) {
for(BlockArray arr : aextendedblockstorage) {
if(arr != null && (!biomes || !arr.isEmpty()))
list.add(arr);
}
}
else {
for(int cy : extend) {
BlockArray arr = chunk.getArray(cy);
if(arr != null && (!biomes || !arr.isEmpty()))
list.add(arr);
}
}
extend = new int[list.size()];
for(int z = 0; z < extend.length; z++) {
extend[z] = list.get(z).getY() >> 4;
}
s21packetchunkdata$extracted.extend = extend;
s21packetchunkdata$extracted.data = new byte[getSize(extend.length, overworld, biomes)];
int j = 0;
for (BlockArray extendedblockstorage1 : list)
{
char[] achar = extendedblockstorage1.getData();
for (char c0 : achar)
{
s21packetchunkdata$extracted.data[j++] = (byte)(c0 & 255);
s21packetchunkdata$extracted.data[j++] = (byte)(c0 >> 8 & 255);
}
}
for (BlockArray extendedblockstorage2 : list)
{
j = copyTo(extendedblockstorage2.getBlocklight().getData(), s21packetchunkdata$extracted.data, j);
}
if (overworld)
{
for (BlockArray extendedblockstorage3 : list)
{
j = copyTo(extendedblockstorage3.getSkylight().getData(), s21packetchunkdata$extracted.data, j);
}
}
if (biomes)
{
copyTo(chunk.getBiomes(), s21packetchunkdata$extracted.data, j);
}
return s21packetchunkdata$extracted;
}
private static int copyTo(byte[] src, byte[] dest, int offset)
{
System.arraycopy(src, 0, dest, offset, src.length);
return offset + src.length;
}
public int getChunkX() public int getChunkX()
{ {
return this.chunkX; return this.chunkX;

View file

@ -1,40 +1,27 @@
package common.packet; package common.packet;
import java.io.IOException; import java.io.IOException;
import java.util.List;
import common.network.IClientPlayer; import common.network.IClientPlayer;
import common.network.Packet; import common.network.Packet;
import common.network.PacketBuffer; import common.network.PacketBuffer;
import common.world.Chunk;
public class SPacketMapChunkBulk implements Packet<IClientPlayer> public class SPacketMapChunkBulk implements Packet<IClientPlayer>
{ {
private int[] xPositions; private int[] xPositions;
private int[] zPositions; private int[] zPositions;
private SPacketChunkData.Extracted[] chunksData; private SPacketChunkData.Extracted[] chunksData;
private boolean isOverworld; private boolean sky;
public SPacketMapChunkBulk() public SPacketMapChunkBulk()
{ {
} }
public SPacketMapChunkBulk(List<Chunk> chunks) public SPacketMapChunkBulk(int[] x, int[] z, SPacketChunkData.Extracted[] chunks, boolean sky)
{ {
int i = chunks.size(); this.xPositions = x;
this.xPositions = new int[i]; this.zPositions = z;
this.zPositions = new int[i]; this.chunksData = chunks;
this.chunksData = new SPacketChunkData.Extracted[i]; this.sky = sky;
this.isOverworld = !((Chunk)chunks.get(0)).getWorld().dimension.hasNoLight();
for (int j = 0; j < i; ++j)
{
Chunk chunk = (Chunk)chunks.get(j);
SPacketChunkData.Extracted s21packetchunkdata$extracted = SPacketChunkData.getExtractedData(chunk, true, this.isOverworld, null);
this.xPositions[j] = chunk.xPos;
this.zPositions[j] = chunk.zPos;
this.chunksData[j] = s21packetchunkdata$extracted;
}
} }
/** /**
@ -42,7 +29,7 @@ public class SPacketMapChunkBulk implements Packet<IClientPlayer>
*/ */
public void readPacketData(PacketBuffer buf) throws IOException public void readPacketData(PacketBuffer buf) throws IOException
{ {
this.isOverworld = buf.readBoolean(); this.sky = buf.readBoolean();
int i = buf.readVarIntFromBuffer(); int i = buf.readVarIntFromBuffer();
this.xPositions = new int[i]; this.xPositions = new int[i];
this.zPositions = new int[i]; this.zPositions = new int[i];
@ -57,7 +44,7 @@ public class SPacketMapChunkBulk implements Packet<IClientPlayer>
for(int z = 0; z < this.chunksData[j].extend.length; z++) { for(int z = 0; z < this.chunksData[j].extend.length; z++) {
this.chunksData[j].extend[z] = buf.readVarIntFromBuffer(); this.chunksData[j].extend[z] = buf.readVarIntFromBuffer();
} }
this.chunksData[j].data = new byte[SPacketChunkData.getSize(this.chunksData[j].extend.length, this.isOverworld, true)]; this.chunksData[j].data = new byte[SPacketChunkData.getSize(this.chunksData[j].extend.length, this.sky, true)];
} }
for (int k = 0; k < i; ++k) for (int k = 0; k < i; ++k)
@ -71,7 +58,7 @@ public class SPacketMapChunkBulk implements Packet<IClientPlayer>
*/ */
public void writePacketData(PacketBuffer buf) throws IOException public void writePacketData(PacketBuffer buf) throws IOException
{ {
buf.writeBoolean(this.isOverworld); buf.writeBoolean(this.sky);
buf.writeVarIntToBuffer(this.chunksData.length); buf.writeVarIntToBuffer(this.chunksData.length);
for (int i = 0; i < this.xPositions.length; ++i) for (int i = 0; i < this.xPositions.length; ++i)

View file

@ -8,7 +8,6 @@ import common.network.Packet;
import common.network.PacketBuffer; import common.network.PacketBuffer;
import common.util.BlockPos; import common.util.BlockPos;
import common.util.ChunkPos; import common.util.ChunkPos;
import common.world.Chunk;
import common.world.State; import common.world.State;
public class SPacketMultiBlockChange implements Packet<IClientPlayer> public class SPacketMultiBlockChange implements Packet<IClientPlayer>
@ -16,19 +15,18 @@ public class SPacketMultiBlockChange implements Packet<IClientPlayer>
private ChunkPos chunkPosCoord; private ChunkPos chunkPosCoord;
private SPacketMultiBlockChange.BlockUpdateData[] changedBlocks; private SPacketMultiBlockChange.BlockUpdateData[] changedBlocks;
public static BlockPos getPos(ChunkPos pos, long position)
{
return new BlockPos(new BlockPos((pos.x << 4) + (int)(position >> 36 & 15L), (int)(position & 4294967295L), (pos.z << 4) + (int)(position >> 32 & 15L)));
}
public SPacketMultiBlockChange() public SPacketMultiBlockChange()
{ {
} }
public SPacketMultiBlockChange(int p_i45181_1_, long[] crammedPositionsIn, Chunk chunkIn) public SPacketMultiBlockChange(ChunkPos pos, SPacketMultiBlockChange.BlockUpdateData[] changes) {
{ this.chunkPosCoord = pos;
this.chunkPosCoord = new ChunkPos(chunkIn.xPos, chunkIn.zPos); this.changedBlocks = changes;
this.changedBlocks = new SPacketMultiBlockChange.BlockUpdateData[p_i45181_1_];
for (int i = 0; i < this.changedBlocks.length; ++i)
{
this.changedBlocks[i] = new SPacketMultiBlockChange.BlockUpdateData(crammedPositionsIn[i], chunkIn);
}
} }
/** /**
@ -74,7 +72,12 @@ public class SPacketMultiBlockChange implements Packet<IClientPlayer>
return this.changedBlocks; return this.changedBlocks;
} }
public class BlockUpdateData public ChunkPos getChunkPos()
{
return this.chunkPosCoord;
}
public static class BlockUpdateData
{ {
private final long position; private final long position;
private final State blockState; private final State blockState;
@ -85,18 +88,6 @@ public class SPacketMultiBlockChange implements Packet<IClientPlayer>
this.blockState = state; this.blockState = state;
} }
public BlockUpdateData(long raw, Chunk chunkIn)
{
this.position = raw;
this.blockState = chunkIn.getState(this.getPos());
}
public BlockPos getPos()
{
ChunkPos pos = SPacketMultiBlockChange.this.chunkPosCoord;
return new BlockPos(new BlockPos((pos.x << 4) + (int)(this.position >> 36 & 15L), (int)(this.position & 4294967295L), (pos.z << 4) + (int)(this.position >> 32 & 15L)));
}
public long getRawPos() public long getRawPos()
{ {
return this.position; return this.position;

View file

@ -3,16 +3,30 @@ package common.pathfinding;
import common.init.Blocks; import common.init.Blocks;
import common.util.BlockPos; import common.util.BlockPos;
import common.world.Chunk; import common.world.Chunk;
import common.world.ChunkCache;
import common.world.IBlockAccess; import common.world.IBlockAccess;
import common.world.State; import common.world.State;
import common.world.World; import common.world.World;
public class PathCache extends ChunkCache implements IBlockAccess public class PathCache implements IBlockAccess
{ {
public PathCache(World worldIn, BlockPos posFromIn, BlockPos posToIn) protected final int chunkX;
protected final int chunkZ;
protected final Chunk[][] data;
public PathCache(World world, BlockPos pos1, BlockPos pos2)
{ {
super(worldIn, posFromIn, posToIn, 0); this.chunkX = pos1.getX() >> 4;
this.chunkZ = pos1.getZ() >> 4;
int cx2 = pos2.getX() >> 4;
int cz2 = pos2.getZ() >> 4;
this.data = new Chunk[cx2 - this.chunkX + 1][cz2 - this.chunkZ + 1];
for (int x = this.chunkX; x <= cx2; ++x)
{
for (int z = this.chunkZ; z <= cz2; ++z)
{
this.data[x - this.chunkX][z - this.chunkZ] = world.getChunk(x, z);
}
}
} }
public State getState(BlockPos pos) public State getState(BlockPos pos)
@ -22,9 +36,9 @@ public class PathCache extends ChunkCache implements IBlockAccess
int i = (pos.getX() >> 4) - this.chunkX; int i = (pos.getX() >> 4) - this.chunkX;
int j = (pos.getZ() >> 4) - this.chunkZ; int j = (pos.getZ() >> 4) - this.chunkZ;
if (i >= 0 && i < this.chunkArray.length && j >= 0 && j < this.chunkArray[i].length) if (i >= 0 && i < this.data.length && j >= 0 && j < this.data[i].length)
{ {
Chunk chunk = this.chunkArray[i][j]; Chunk chunk = this.data[i][j];
if (chunk != null) if (chunk != null)
{ {

View file

@ -7,6 +7,7 @@ import common.log.Log;
import common.nbt.NBTTagCompound; import common.nbt.NBTTagCompound;
import common.network.Packet; import common.network.Packet;
import common.util.BlockPos; import common.util.BlockPos;
import common.world.AWorldServer;
import common.world.State; import common.world.State;
import common.world.World; import common.world.World;
@ -128,7 +129,8 @@ public abstract class TileEntity
{ {
State iblockstate = this.worldObj.getState(this.pos); State iblockstate = this.worldObj.getState(this.pos);
this.blockMetadata = iblockstate.getBlock().getMetaFromState(iblockstate); this.blockMetadata = iblockstate.getBlock().getMetaFromState(iblockstate);
this.worldObj.markChunkDirty(this.pos, this); if(!this.worldObj.client)
((AWorldServer)this.worldObj).markChunkDirty(this.pos);
if (this.getBlockType() != Blocks.air) if (this.getBlockType() != Blocks.air)
{ {

View file

@ -46,4 +46,5 @@ public abstract class AWorldServer extends World {
public abstract <T extends Entity> T findNearestEntityWithinAABB(Class<? extends T> entityType, BoundingBox aabb, T closestTo); public abstract <T extends Entity> T findNearestEntityWithinAABB(Class<? extends T> entityType, BoundingBox aabb, T closestTo);
public abstract long getTime(); public abstract long getTime();
public abstract void setBiome(BlockPos pos, Biome biome); public abstract void setBiome(BlockPos pos, Biome biome);
public abstract void markChunkDirty(BlockPos pos);
} }

View file

@ -7,58 +7,49 @@ import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.function.Predicate; import java.util.function.Predicate;
import common.biome.Biome;
import common.block.Block; import common.block.Block;
import common.block.ITileEntityProvider; import common.block.ITileEntityProvider;
import common.collect.Maps; import common.collect.Maps;
import common.collect.Sets; import common.collect.Sets;
import common.entity.Entity; import common.entity.Entity;
import common.init.BlockRegistry;
import common.init.Blocks; import common.init.Blocks;
import common.log.Log; import common.log.Log;
import common.material.Material; import common.material.Material;
import common.rng.Random;
import common.tileentity.TileEntity; import common.tileentity.TileEntity;
import common.util.BlockPos; import common.util.BlockPos;
import common.util.BoundingBox; import common.util.BoundingBox;
import common.util.ChunkPos;
import common.util.ClassInheritanceMultiMap; import common.util.ClassInheritanceMultiMap;
import common.util.ExtMath; import common.util.ExtMath;
import common.util.Facing; import common.util.Facing;
import common.util.IntHashMap; import common.util.IntHashMap;
import common.util.NibbleArray;
import common.worldgen.BiomeGenerator;
import common.worldgen.DebugStates;
public class Chunk { public abstract class Chunk {
public final int xPos; public final int xPos;
public final int zPos; public final int zPos;
private final World world; protected final World world;
private final State filler; protected final State filler;
private final Block fillerBlock; protected final Block fillerBlock;
private final IntHashMap<BlockArray> blocks = new IntHashMap(); protected final IntHashMap<BlockArray> blocks = new IntHashMap();
private final Set<BlockArray> blockList = Sets.newHashSet(); protected final Set<BlockArray> blockList = Sets.newHashSet();
private final byte[] biomes = new byte[256]; protected final byte[] biomes = new byte[256];
private final int[] precHeight = new int[256]; protected final int[] precHeight = new int[256];
private final boolean[] updateSky = new boolean[256]; protected final boolean[] updateSky = new boolean[256];
private final int[] height = new int[256]; protected final int[] height = new int[256];
private final Map<BlockPos, TileEntity> tiles = Maps.<BlockPos, TileEntity>newHashMap(); protected final Map<BlockPos, TileEntity> tiles = Maps.<BlockPos, TileEntity>newHashMap();
private final ClassInheritanceMultiMap<Entity>[] entities = new ClassInheritanceMultiMap[32]; protected final ClassInheritanceMultiMap<Entity>[] entities = new ClassInheritanceMultiMap[32];
private final ConcurrentLinkedQueue<BlockPos> tileQueue = new ConcurrentLinkedQueue<BlockPos>(); protected final ConcurrentLinkedQueue<BlockPos> tileQueue = new ConcurrentLinkedQueue<BlockPos>();
private boolean loaded; protected boolean loaded;
private boolean gapUpdate; protected boolean gapUpdate;
private boolean populated; protected boolean populated;
private boolean lightInit; protected boolean lightInit;
private boolean updated; protected boolean updated;
private boolean modified; protected boolean modified;
private boolean hasEntity; protected boolean hasEntity;
private int minHeight; protected int minHeight;
private int lightChecks = Integer.MAX_VALUE; protected int lightChecks = Integer.MAX_VALUE;
private int bottom = Integer.MAX_VALUE; protected int bottom = Integer.MAX_VALUE;
private int top = Integer.MIN_VALUE; protected int top = Integer.MIN_VALUE;
private long lastSave;
private long inhabited;
public Chunk(World world, int x, int z) { public Chunk(World world, int x, int z) {
this.world = world; this.world = world;
@ -73,100 +64,15 @@ public class Chunk {
Arrays.fill(this.biomes, (byte)-1); Arrays.fill(this.biomes, (byte)-1);
} }
public Chunk(World world, short[] data, int height, boolean base, boolean ceil, Random rand, Biome[] biomes, int x, int z) {
this(world, x, z);
boolean sky = !world.dimension.hasNoLight();
for(int bx = 0; bx < 16; ++bx) {
for(int bz = 0; bz < 16; ++bz) {
for(int by = 0; by < height; ++by) {
State state = BlockRegistry.STATEMAP.getByValue(data[bx << 4 | bz | by << 8]);
if(state != null && state.getBlock().getMaterial() != Material.air) {
int y = by >> 4;
BlockArray arr = this.getArray(y);
if(arr == null) {
arr = new BlockArray(y << 4, sky, null);
this.setArray(arr);
}
arr.set(bx, by & 15, bz, state);
}
}
}
}
if(base) {
Block caves = world.dimension.getCaveFiller().getBlock();
BlockArray arr = this.getArray(0);
if(arr == null) {
arr = new BlockArray(0, sky, null);
this.setArray(arr);
}
for(int bx = 0; bx < 16; ++bx) {
for(int bz = 0; bz < 16; ++bz) {
for(int by = 0; by < 5; ++by) {
if(by <= rand.zrange(5)) {
Block block = arr.get(bx, by, bz).getBlock();
if(block == Blocks.air || block.getMaterial().isLiquid() || block == caves)
arr.set(bx, by, bz, this.filler);
}
}
}
}
}
if(ceil) {
int y = (height - 1) >> 4;
BlockArray arr = this.getArray(y);
if(arr == null) {
arr = new BlockArray(y << 4, sky, null);
this.setArray(arr);
}
y = (height - 5) >> 4;
arr = this.getArray(y);
if(arr == null) {
arr = new BlockArray(y << 4, sky, null);
this.setArray(arr);
}
for(int bx = 0; bx < 16; ++bx) {
for(int bz = 0; bz < 16; ++bz) {
for(int by = height - 1; by >= height - 5; --by) {
if(by >= (height - 1) - rand.zrange(5))
this.getArray(by >> 4).set(bx, by & 15, bz, Blocks.air.getState());
}
}
}
}
for(int n = 0; n < this.biomes.length; ++n) {
this.biomes[n] = (byte)biomes[n].id;
}
if(ceil)
this.resetRelight();
else
this.genSkyLight();
}
public int getHeight(BlockPos pos) {
return this.getHeight(pos.getX() & 15, pos.getZ() & 15);
}
public int getHeight(int x, int z) { public int getHeight(int x, int z) {
return this.height[z << 4 | x]; return this.height[z << 4 | x];
} }
public int getTopSegment() {
return this.top;
}
public int getBottomSegment() {
return this.bottom;
}
public Set<BlockArray> getStorage() {
return this.blockList;
}
public BlockArray getArray(int y) { public BlockArray getArray(int y) {
return this.blocks.lookup(y); return this.blocks.lookup(y);
} }
private void setArray(BlockArray array) { protected void setArray(BlockArray array) {
int y = array.getY() >> 4; int y = array.getY() >> 4;
this.blocks.addKey(y, array); this.blocks.addKey(y, array);
this.blockList.add(array); this.blockList.add(array);
@ -175,41 +81,6 @@ public class Chunk {
this.top = y > this.top ? y : this.top; this.top = y > this.top ? y : this.top;
} }
private void clearArrays() {
this.blocks.clearMap();
this.blockList.clear();
this.bottom = Integer.MAX_VALUE;
this.top = Integer.MIN_VALUE;
}
protected void genHeights() {
int top = this.top;
int bottom = this.bottom;
this.minHeight = Integer.MAX_VALUE;
for(int x = 0; x < 16; ++x) {
for(int z = 0; z < 16; ++z) {
this.precHeight[x + (z << 4)] = -99999999;
for(int y = top + 16; y > bottom; --y) {
Block block = this.getBlock0(x, y - 1, z);
if(block.getLightOpacity() != 0) {
this.height[z << 4 | x] = y;
if(y < this.minHeight) {
this.minHeight = y;
}
break;
}
}
}
}
this.modified = true;
}
public void genSkyLight() { public void genSkyLight() {
int top = this.top; int top = this.top;
int bottom = this.bottom; int bottom = this.bottom;
@ -415,7 +286,7 @@ public class Chunk {
} }
} }
public int getOpacity(BlockPos pos) { private int getOpacity(BlockPos pos) {
return this.getBlock(pos).getLightOpacity(); return this.getBlock(pos).getLightOpacity();
} }
@ -423,7 +294,7 @@ public class Chunk {
return this.getBlock0(x, y, z).getLightOpacity(); return this.getBlock0(x, y, z).getLightOpacity();
} }
private Block getBlock0(int x, int y, int z) { protected Block getBlock0(int x, int y, int z) {
BlockArray stor = this.getArray(y >> 4); BlockArray stor = this.getArray(y >> 4);
return stor != null ? stor.getBlock(x, y & 15, z) : (y < 0 ? this.fillerBlock : Blocks.air); return stor != null ? stor.getBlock(x, y & 15, z) : (y < 0 ? this.fillerBlock : Blocks.air);
} }
@ -672,14 +543,6 @@ public class Chunk {
return tile; return tile;
} }
public void addTileEntity(TileEntity tile) {
this.addTileEntity(tile.getPos(), tile);
if(this.loaded) {
this.world.addTileEntity(tile);
}
}
public void addTileEntity(BlockPos pos, TileEntity tile) { public void addTileEntity(BlockPos pos, TileEntity tile) {
tile.setWorldObj(this.world); tile.setWorldObj(this.world);
tile.setPos(pos); tile.setPos(pos);
@ -690,7 +553,7 @@ public class Chunk {
} }
if(tile.validate()) { if(tile.validate()) {
this.setModified(); this.modified = true;
} }
this.tiles.put(pos, tile); this.tiles.put(pos, tile);
} }
@ -706,19 +569,6 @@ public class Chunk {
} }
} }
public void onChunkLoad() {
this.loaded = true;
this.world.addTileEntities(this.tiles.values());
for(int n = 0; n < this.entities.length; ++n) {
for(Entity entity : this.entities[n]) {
entity.onChunkLoad();
}
this.world.loadEntities(this.entities[n]);
}
}
public void onChunkUnload() { public void onChunkUnload() {
this.loaded = false; this.loaded = false;
@ -731,10 +581,6 @@ public class Chunk {
} }
} }
public void setModified() {
this.modified = true;
}
public void getEntities(Entity exclude, BoundingBox bb, List<Entity> list, Predicate<? super Entity> pred) { public void getEntities(Entity exclude, BoundingBox bb, List<Entity> list, Predicate<? super Entity> pred) {
int sy = ExtMath.floord((bb.minY - 2.0D) / 16.0D); int sy = ExtMath.floord((bb.minY - 2.0D) / 16.0D);
int ey = ExtMath.floord((bb.maxY + 2.0D) / 16.0D); int ey = ExtMath.floord((bb.maxY + 2.0D) / 16.0D);
@ -782,17 +628,6 @@ public class Chunk {
} }
} }
public boolean isDirty(long time) {
if(this.hasEntity && time != this.lastSave || this.modified) {
return true;
}
return this.modified;
}
public boolean isDummy() {
return false;
}
public BlockPos getPrecipitation(BlockPos pos) { public BlockPos getPrecipitation(BlockPos pos) {
int x = pos.getX() & 15; int x = pos.getX() & 15;
int z = pos.getZ() & 15; int z = pos.getZ() & 15;
@ -851,108 +686,6 @@ public class Chunk {
return this.updated && this.populated && this.lightInit; return this.updated && this.populated && this.lightInit;
} }
public ChunkPos getPos() {
return new ChunkPos(this.xPos, this.zPos);
}
public boolean isEmpty(int bottom, int top) {
for(int y = bottom; y <= top; y += 16) {
BlockArray stor = this.getArray(y >> 4);
if(stor != null ? !stor.isEmpty() : (y < 0 && this.fillerBlock != Blocks.air)) {
return false;
}
}
return true;
}
public void setStorage(BlockArray[] data) {
for(BlockArray arr : data) {
this.setArray(arr);
}
}
public void setData(byte[] data, int[] extend, boolean biomes) {
int pos = 0;
boolean sky = !this.world.dimension.hasNoLight();
if(biomes) {
this.clearArrays();
}
for(int cy : extend) {
BlockArray arr = this.getArray(cy);
if(arr == null) {
arr = new BlockArray(cy << 4, sky, null);
this.setArray(arr);
}
char[] blocks = arr.getData();
for(int k = 0; k < blocks.length; ++k) {
blocks[k] = (char)((data[pos + 1] & 255) << 8 | data[pos] & 255);
pos += 2;
}
}
for(int cy : extend) {
BlockArray arr = this.getArray(cy);
if(arr != null) {
NibbleArray light = arr.getBlocklight();
System.arraycopy(data, pos, light.getData(), 0, light.getData().length);
pos += light.getData().length;
}
}
if(sky) {
for(int cy : extend) {
BlockArray arr = this.getArray(cy);
if(arr != null) {
NibbleArray slight = arr.getSkylight();
System.arraycopy(data, pos, slight.getData(), 0, slight.getData().length);
pos += slight.getData().length;
}
}
}
if(biomes) {
System.arraycopy(data, pos, this.biomes, 0, this.biomes.length);
}
for(int cy : extend) {
BlockArray arr = this.getArray(cy);
if(arr != null) {
arr.update();
}
}
this.lightInit = true;
this.populated = true;
this.genHeights();
for(TileEntity tile : this.tiles.values()) {
tile.updateContainingBlockInfo();
}
}
public Biome getBiome(BlockPos pos, BiomeGenerator gen) {
int x = pos.getX() & 15;
int z = pos.getZ() & 15;
int o = this.biomes[z << 4 | x] & 255;
if(o == 255) {
Biome biome = gen == null ? Biome.DEF_BIOME : gen.getBiomeGenerator(pos, Biome.DEF_BIOME);
o = biome.id;
this.biomes[z << 4 | x] = (byte)(o & 255);
}
return Biome.getBiomeDef(o);
}
public byte[] getBiomes() {
return this.biomes;
}
public void setBiomes(byte[] biomes) { public void setBiomes(byte[] biomes) {
if(this.biomes.length != biomes.length) { if(this.biomes.length != biomes.length) {
Log.JNI.warn("Konnte Biome des Chunks nicht setzen, Länge des Arrays ist " + biomes.length + " statt " + this.biomes.length); Log.JNI.warn("Konnte Biome des Chunks nicht setzen, Länge des Arrays ist " + biomes.length + " statt " + this.biomes.length);
@ -1115,74 +848,11 @@ public class Chunk {
return this.loaded; return this.loaded;
} }
public void setLoaded(boolean loaded) {
this.loaded = loaded;
}
public World getWorld() {
return this.world;
}
public int[] getHeights() {
return this.height;
}
public void setHeights(int[] map) {
if(this.height.length != map.length) {
Log.JNI.warn("Konnte Höhen des Chunks nicht setzen, Länge des Arrays ist " + map.length + " statt " + this.height.length);
}
else {
for(int n = 0; n < this.height.length; ++n) {
this.height[n] = map[n];
}
}
}
public Map<BlockPos, TileEntity> getTiles() {
return this.tiles;
}
public ClassInheritanceMultiMap<Entity>[] getEntities() { public ClassInheritanceMultiMap<Entity>[] getEntities() {
return this.entities; return this.entities;
} }
public boolean isTerrainPopulated() {
return this.populated;
}
public void setTerrainPopulated(boolean populated) {
this.populated = populated;
}
public boolean isLightPopulated() {
return this.lightInit;
}
public void setLightPopulated(boolean populated) {
this.lightInit = populated;
}
public void setModified(boolean modified) {
this.modified = modified;
}
public void setHasEntities(boolean entities) {
this.hasEntity = entities;
}
public void setSaved(long time) {
this.lastSave = time;
}
public int getLowest() { public int getLowest() {
return this.minHeight; return this.minHeight;
} }
public long getInhabited() {
return this.inhabited;
}
public void setInhabited(long time) {
this.inhabited = time;
}
} }

View file

@ -1,27 +0,0 @@
package common.world;
import common.util.BlockPos;
public class ChunkCache
{
protected final int chunkX;
protected final int chunkZ;
protected final Chunk[][] chunkArray;
public ChunkCache(World worldIn, BlockPos posFromIn, BlockPos posToIn, int subIn)
{
this.chunkX = posFromIn.getX() - subIn >> 4;
this.chunkZ = posFromIn.getZ() - subIn >> 4;
int i = posToIn.getX() + subIn >> 4;
int j = posToIn.getZ() + subIn >> 4;
this.chunkArray = new Chunk[i - this.chunkX + 1][j - this.chunkZ + 1];
for (int k = this.chunkX; k <= i; ++k)
{
for (int l = this.chunkZ; l <= j; ++l)
{
this.chunkArray[k - this.chunkX][l - this.chunkZ] = worldIn.getChunk(k, l);
}
}
}
}

View file

@ -1,4 +1,4 @@
package common.worldgen; package common.world;
import java.util.List; import java.util.List;
@ -6,7 +6,6 @@ import common.block.Block;
import common.collect.Lists; import common.collect.Lists;
import common.init.BlockRegistry; import common.init.BlockRegistry;
import common.util.ExtMath; import common.util.ExtMath;
import common.world.State;
public class DebugStates { public class DebugStates {
private static final List<State> STATES = Lists.<State>newArrayList(); private static final List<State> STATES = Lists.<State>newArrayList();

View file

@ -133,12 +133,7 @@ public abstract class World implements IWorldAccess {
this.gravity = Math.signum(this.gravity) * 0.075; this.gravity = Math.signum(this.gravity) * 0.075;
} }
public Biome getBiomeGenForCoords(final BlockPos pos) { public abstract Biome getBiomeGenForCoords(BlockPos pos);
if(this.isBlockLoaded(pos))
return this.getChunk(pos).getBiome(pos, null);
else
return Biome.DEF_BIOME;
}
public boolean isAirBlock(BlockPos pos) { public boolean isAirBlock(BlockPos pos) {
return this.getState(pos).getBlock().getMaterial() == Material.air; return this.getState(pos).getBlock().getMaterial() == Material.air;
@ -191,9 +186,7 @@ public abstract class World implements IWorldAccess {
} }
} }
protected boolean isLoaded(int x, int z, boolean allowEmpty) { protected abstract boolean isLoaded(int x, int z, boolean allowEmpty);
return allowEmpty || !this.getChunk(x, z).isDummy();
}
public Chunk getChunk(BlockPos pos) { public Chunk getChunk(BlockPos pos) {
return this.getChunk(pos.getX() >> 4, pos.getZ() >> 4); return this.getChunk(pos.getX() >> 4, pos.getZ() >> 4);
@ -1822,12 +1815,6 @@ public abstract class World implements IWorldAccess {
return (Entity)this.entityIds.lookup(id); return (Entity)this.entityIds.lookup(id);
} }
public void markChunkDirty(BlockPos pos, TileEntity unusedTileEntity) {
if(this.isBlockLoaded(pos)) {
this.getChunk(pos).setModified();
}
}
public void loadEntities(Collection<Entity> entityCollection) { public void loadEntities(Collection<Entity> entityCollection) {
this.entities.addAll(entityCollection); this.entities.addAll(entityCollection);

View file

@ -119,7 +119,7 @@ import common.util.Position;
import common.util.Vec3i; import common.util.Vec3i;
import common.util.WorldPos; import common.util.WorldPos;
import common.village.MerchantRecipeList; import common.village.MerchantRecipeList;
import common.world.Chunk; import common.world.BlockArray;
import common.world.State; import common.world.State;
import common.world.World; import common.world.World;
import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Future;
@ -134,6 +134,7 @@ import server.clipboard.RotationValue;
import server.clipboard.Vector; import server.clipboard.Vector;
import server.command.Executor; import server.command.Executor;
import server.util.Form; import server.util.Form;
import server.world.ChunkServer;
import server.world.Region; import server.world.Region;
import server.world.WorldServer; import server.world.WorldServer;
@ -916,6 +917,97 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer
public static SPacketChunkData.Extracted getExtractedData(ChunkServer chunk, boolean biomes, boolean overworld, int[] extend)
{
Set<BlockArray> aextendedblockstorage = chunk.getStorage();
SPacketChunkData.Extracted s21packetchunkdata$extracted = new SPacketChunkData.Extracted();
List<BlockArray> list = Lists.<BlockArray>newArrayList();
if(extend == null) {
for(BlockArray arr : aextendedblockstorage) {
if(arr != null && (!biomes || !arr.isEmpty()))
list.add(arr);
}
}
else {
for(int cy : extend) {
BlockArray arr = chunk.getArray(cy);
if(arr != null && (!biomes || !arr.isEmpty()))
list.add(arr);
}
}
extend = new int[list.size()];
for(int z = 0; z < extend.length; z++) {
extend[z] = list.get(z).getY() >> 4;
}
s21packetchunkdata$extracted.extend = extend;
s21packetchunkdata$extracted.data = new byte[SPacketChunkData.getSize(extend.length, overworld, biomes)];
int j = 0;
for (BlockArray extendedblockstorage1 : list)
{
char[] achar = extendedblockstorage1.getData();
for (char c0 : achar)
{
s21packetchunkdata$extracted.data[j++] = (byte)(c0 & 255);
s21packetchunkdata$extracted.data[j++] = (byte)(c0 >> 8 & 255);
}
}
for (BlockArray extendedblockstorage2 : list)
{
j = copyTo(extendedblockstorage2.getBlocklight().getData(), s21packetchunkdata$extracted.data, j);
}
if (overworld)
{
for (BlockArray extendedblockstorage3 : list)
{
j = copyTo(extendedblockstorage3.getSkylight().getData(), s21packetchunkdata$extracted.data, j);
}
}
if (biomes)
{
copyTo(chunk.getBiomes(), s21packetchunkdata$extracted.data, j);
}
return s21packetchunkdata$extracted;
}
private static int copyTo(byte[] src, byte[] dest, int offset)
{
System.arraycopy(src, 0, dest, offset, src.length);
return offset + src.length;
}
public static SPacketChunkData getPacket(ChunkServer chunkIn, boolean biomes, int[] extend, boolean sky)
{
return new SPacketChunkData(chunkIn.xPos, chunkIn.zPos, biomes, getExtractedData(chunkIn, biomes, sky, extend));
}
private static SPacketMapChunkBulk getPacket(List<ChunkServer> chunks, boolean sky)
{
int i = chunks.size();
int[] xPositions = new int[i];
int[] zPositions = new int[i];
SPacketChunkData.Extracted[] chunksData = new SPacketChunkData.Extracted[i];
for (int j = 0; j < i; ++j)
{
ChunkServer chunk = chunks.get(j);
SPacketChunkData.Extracted s21packetchunkdata$extracted = getExtractedData(chunk, true, sky, null);
xPositions[j] = chunk.xPos;
zPositions[j] = chunk.zPos;
chunksData[j] = s21packetchunkdata$extracted;
}
return new SPacketMapChunkBulk(xPositions, zPositions, chunksData, sky);
}
public void updateEntity() public void updateEntity()
{ {
if (this.entity.hurtResistance > 0) if (this.entity.hurtResistance > 0)
@ -951,7 +1043,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer
if (!this.loadedChunks.isEmpty()) if (!this.loadedChunks.isEmpty())
{ {
List<Chunk> list = Lists.<Chunk>newArrayList(); List<ChunkServer> list = Lists.<ChunkServer>newArrayList();
Iterator<ChunkPos> iterator1 = this.loadedChunks.iterator(); Iterator<ChunkPos> iterator1 = this.loadedChunks.iterator();
List<TileEntity> list1 = Lists.<TileEntity>newArrayList(); List<TileEntity> list1 = Lists.<TileEntity>newArrayList();
@ -965,7 +1057,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer
{ {
if (this.entity.worldObj.isBlockLoaded(new BlockPos(chunkcoordintpair.x << 4, 0, chunkcoordintpair.z << 4))) if (this.entity.worldObj.isBlockLoaded(new BlockPos(chunkcoordintpair.x << 4, 0, chunkcoordintpair.z << 4)))
{ {
Chunk chunk = this.entity.worldObj.getChunk(chunkcoordintpair.x, chunkcoordintpair.z); ChunkServer chunk = this.getEntityWorld().getChunk(chunkcoordintpair.x, chunkcoordintpair.z);
if (chunk.isPopulated()) if (chunk.isPopulated())
{ {
@ -985,11 +1077,11 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer
{ {
if (list.size() == 1) if (list.size() == 1)
{ {
this.sendPacket(new SPacketChunkData((Chunk)list.get(0), true, null)); this.sendPacket(getPacket(list.get(0), true, null, !this.entity.worldObj.dimension.hasNoLight()));
} }
else else
{ {
this.sendPacket(new SPacketMapChunkBulk(list)); this.sendPacket(getPacket(list, !this.entity.worldObj.dimension.hasNoLight()));
} }
for (TileEntity tileentity : list1) for (TileEntity tileentity : list1)
@ -997,7 +1089,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer
this.sendTileEntityUpdate(tileentity); this.sendTileEntityUpdate(tileentity);
} }
for (Chunk chunk1 : list) for (ChunkServer chunk1 : list)
{ {
this.getEntityWorld().updateChunksForPlayer(this.entity, chunk1); this.getEntityWorld().updateChunksForPlayer(this.entity, chunk1);
} }

View file

@ -0,0 +1,216 @@
package server.world;
import java.util.Map;
import java.util.Set;
import common.biome.Biome;
import common.block.Block;
import common.entity.Entity;
import common.init.BlockRegistry;
import common.init.Blocks;
import common.log.Log;
import common.material.Material;
import common.rng.Random;
import common.tileentity.TileEntity;
import common.util.BlockPos;
import common.world.BlockArray;
import common.world.Chunk;
import common.world.State;
import common.world.World;
import server.worldgen.BiomeGenerator;
public class ChunkServer extends Chunk {
private long lastSave;
private long inhabited;
public ChunkServer(World world, int x, int z) {
super(world, x, z);
}
public ChunkServer(World world, short[] data, int height, boolean base, boolean ceil, Random rand, Biome[] biomes, int x, int z) {
this(world, x, z);
boolean sky = !world.dimension.hasNoLight();
for(int bx = 0; bx < 16; ++bx) {
for(int bz = 0; bz < 16; ++bz) {
for(int by = 0; by < height; ++by) {
State state = BlockRegistry.STATEMAP.getByValue(data[bx << 4 | bz | by << 8]);
if(state != null && state.getBlock().getMaterial() != Material.air) {
int y = by >> 4;
BlockArray arr = this.getArray(y);
if(arr == null) {
arr = new BlockArray(y << 4, sky, null);
this.setArray(arr);
}
arr.set(bx, by & 15, bz, state);
}
}
}
}
if(base) {
Block caves = world.dimension.getCaveFiller().getBlock();
BlockArray arr = this.getArray(0);
if(arr == null) {
arr = new BlockArray(0, sky, null);
this.setArray(arr);
}
for(int bx = 0; bx < 16; ++bx) {
for(int bz = 0; bz < 16; ++bz) {
for(int by = 0; by < 5; ++by) {
if(by <= rand.zrange(5)) {
Block block = arr.get(bx, by, bz).getBlock();
if(block == Blocks.air || block.getMaterial().isLiquid() || block == caves)
arr.set(bx, by, bz, this.filler);
}
}
}
}
}
if(ceil) {
int y = (height - 1) >> 4;
BlockArray arr = this.getArray(y);
if(arr == null) {
arr = new BlockArray(y << 4, sky, null);
this.setArray(arr);
}
y = (height - 5) >> 4;
arr = this.getArray(y);
if(arr == null) {
arr = new BlockArray(y << 4, sky, null);
this.setArray(arr);
}
for(int bx = 0; bx < 16; ++bx) {
for(int bz = 0; bz < 16; ++bz) {
for(int by = height - 1; by >= height - 5; --by) {
if(by >= (height - 1) - rand.zrange(5))
this.getArray(by >> 4).set(bx, by & 15, bz, Blocks.air.getState());
}
}
}
}
for(int n = 0; n < this.biomes.length; ++n) {
this.biomes[n] = (byte)biomes[n].id;
}
if(ceil)
this.resetRelight();
else
this.genSkyLight();
}
public int getTopSegment() {
return this.top;
}
public int getBottomSegment() {
return this.bottom;
}
public Set<BlockArray> getStorage() {
return this.blockList;
}
public void addTileEntity(TileEntity tile) {
this.addTileEntity(tile.getPos(), tile);
if(this.loaded) {
this.world.addTileEntity(tile);
}
}
public void onChunkLoad() {
this.loaded = true;
this.world.addTileEntities(this.tiles.values());
for(int n = 0; n < this.entities.length; ++n) {
for(Entity entity : this.entities[n]) {
entity.onChunkLoad();
}
this.world.loadEntities(this.entities[n]);
}
}
public boolean isDirty(long time) {
if(this.hasEntity && time != this.lastSave || this.modified) {
return true;
}
return this.modified;
}
public void setStorage(BlockArray[] data) {
for(BlockArray arr : data) {
this.setArray(arr);
}
}
public Biome getBiome(BlockPos pos, BiomeGenerator gen) {
int x = pos.getX() & 15;
int z = pos.getZ() & 15;
int o = this.biomes[z << 4 | x] & 255;
if(o == 255) {
Biome biome = gen == null ? Biome.DEF_BIOME : gen.getBiomeGenerator(pos, Biome.DEF_BIOME);
o = biome.id;
this.biomes[z << 4 | x] = (byte)(o & 255);
}
return Biome.getBiomeDef(o);
}
public byte[] getBiomes() {
return this.biomes;
}
public int[] getHeights() {
return this.height;
}
public void setHeights(int[] map) {
if(this.height.length != map.length) {
Log.JNI.warn("Konnte Höhen des Chunks nicht setzen, Länge des Arrays ist " + map.length + " statt " + this.height.length);
}
else {
for(int n = 0; n < this.height.length; ++n) {
this.height[n] = map[n];
}
}
}
public Map<BlockPos, TileEntity> getTiles() {
return this.tiles;
}
public boolean isTerrainPopulated() {
return this.populated;
}
public void setTerrainPopulated(boolean populated) {
this.populated = populated;
}
public boolean isLightPopulated() {
return this.lightInit;
}
public void setLightPopulated(boolean populated) {
this.lightInit = populated;
}
public void setModified(boolean modified) {
this.modified = modified;
}
public void setHasEntities(boolean entities) {
this.hasEntity = entities;
}
public void setSaved(long time) {
this.lastSave = time;
}
public long getInhabited() {
return this.inhabited;
}
public void setInhabited(long time) {
this.inhabited = time;
}
}

View file

@ -34,7 +34,6 @@ import common.util.NextTickListEntry;
import common.util.NibbleArray; import common.util.NibbleArray;
import common.util.Util; import common.util.Util;
import common.world.BlockArray; import common.world.BlockArray;
import common.world.Chunk;
public class Region { public class Region {
private static class ChunkBuffer extends ByteArrayOutputStream { private static class ChunkBuffer extends ByteArrayOutputStream {
@ -360,7 +359,7 @@ public class Region {
// getRegionFile(dir, x >> 3, z >> 3).writeTag(x & 7, z & 7, tag); // getRegionFile(dir, x >> 3, z >> 3).writeTag(x & 7, z & 7, tag);
} }
public static Chunk readNbt(WorldServer world, int x, int z, NBTTagCompound tag) { public static ChunkServer readNbt(WorldServer world, int x, int z, NBTTagCompound tag) {
// if(!tag.hasKey("Level", 10)) { // if(!tag.hasKey("Level", 10)) {
// Log.error("Chunk-Datei bei " + x + "," + z + " hat keine Level-Daten, überspringe"); // Log.error("Chunk-Datei bei " + x + "," + z + " hat keine Level-Daten, überspringe");
// return null; // return null;
@ -370,7 +369,7 @@ public class Region {
Log.JNI.warn("Chunk-Datei bei " + x + "," + z + " hat keine Block-Daten, überspringe"); Log.JNI.warn("Chunk-Datei bei " + x + "," + z + " hat keine Block-Daten, überspringe");
return null; return null;
} }
Chunk chunk = new Chunk(world, x, z); ChunkServer chunk = new ChunkServer(world, x, z);
chunk.setHeights(tag.getIntArray("HeightMap")); chunk.setHeights(tag.getIntArray("HeightMap"));
chunk.setTerrainPopulated(tag.getBoolean("TerrainPopulated")); chunk.setTerrainPopulated(tag.getBoolean("TerrainPopulated"));
chunk.setLightPopulated(tag.getBoolean("LightPopulated")); chunk.setLightPopulated(tag.getBoolean("LightPopulated"));
@ -486,7 +485,7 @@ public class Region {
return chunk; return chunk;
} }
public static NBTTagCompound writeNbt(WorldServer world, Chunk chunk) { public static NBTTagCompound writeNbt(WorldServer world, ChunkServer chunk) {
NBTTagCompound tag = new NBTTagCompound(); NBTTagCompound tag = new NBTTagCompound();
// tag.setShort("V", (short)Config.PROTOCOL); // tag.setShort("V", (short)Config.PROTOCOL);
tag.setLong("LastUpdate", world.getTime()); tag.setLong("LastUpdate", world.getTime());

View file

@ -14,7 +14,6 @@ import common.rng.WeightedList;
import common.util.BlockPos; import common.util.BlockPos;
import common.util.ChunkPos; import common.util.ChunkPos;
import common.util.ExtMath; import common.util.ExtMath;
import common.world.Chunk;
import common.world.World; import common.world.World;
import server.biome.GenBiome; import server.biome.GenBiome;
import server.biome.RngSpawn; import server.biome.RngSpawn;
@ -87,7 +86,7 @@ public abstract class Spawner {
if(cur <= max) { if(cur <= max) {
typeLabel: typeLabel:
for(ChunkPos coord : CHUNKS) { for(ChunkPos coord : CHUNKS) {
Chunk chunk = world.getChunk(coord.x, coord.z); ChunkServer chunk = world.getChunk(coord.x, coord.z);
int x = coord.x * 16 + world.rand.zrange(16); int x = coord.x * 16 + world.rand.zrange(16);
int z = coord.z * 16 + world.rand.zrange(16); int z = coord.z * 16 + world.rand.zrange(16);
int h = chunk.getTopSegment(); int h = chunk.getTopSegment();

View file

@ -24,6 +24,9 @@ import common.collect.Lists;
import common.collect.Maps; import common.collect.Maps;
import common.collect.Sets; import common.collect.Sets;
import common.dimension.Dimension; import common.dimension.Dimension;
import common.dimension.Lake;
import common.dimension.Liquid;
import common.dimension.Ore;
import common.entity.DamageSource; import common.entity.DamageSource;
import common.entity.Entity; import common.entity.Entity;
import common.entity.EntityTrackerEntry; import common.entity.EntityTrackerEntry;
@ -55,7 +58,6 @@ import common.packet.SPacketBiomes;
import common.packet.SPacketBlockAction; import common.packet.SPacketBlockAction;
import common.packet.SPacketBlockBreakAnim; import common.packet.SPacketBlockBreakAnim;
import common.packet.SPacketBlockChange; import common.packet.SPacketBlockChange;
import common.packet.SPacketChunkData;
import common.packet.SPacketMultiBlockChange; import common.packet.SPacketMultiBlockChange;
import common.rng.Random; import common.rng.Random;
import common.rng.WeightedList; import common.rng.WeightedList;
@ -73,17 +75,12 @@ import common.util.Position;
import common.util.Vec3; import common.util.Vec3;
import common.village.Village; import common.village.Village;
import common.world.BlockArray; import common.world.BlockArray;
import common.world.Chunk;
import common.world.Explosion; import common.world.Explosion;
import common.world.AWorldServer; import common.world.AWorldServer;
import common.world.LightType; import common.world.LightType;
import common.world.State; import common.world.State;
import common.world.Weather; import common.world.Weather;
import common.world.World; import common.world.World;
import common.worldgen.BiomeGenerator;
import common.worldgen.FeatureLake;
import common.worldgen.FeatureLiquid;
import common.worldgen.FeatureOre;
import server.Server; import server.Server;
import server.biome.GenBiome; import server.biome.GenBiome;
import server.biome.RngSpawn; import server.biome.RngSpawn;
@ -93,6 +90,7 @@ import server.village.VillageCollection;
import server.worldgen.BiomeGenLayered; import server.worldgen.BiomeGenLayered;
import server.worldgen.BiomeGenPerlin; import server.worldgen.BiomeGenPerlin;
import server.worldgen.BiomeGenSingle; import server.worldgen.BiomeGenSingle;
import server.worldgen.BiomeGenerator;
import server.worldgen.BlockReplacer; import server.worldgen.BlockReplacer;
import server.worldgen.ChunkGenerator; import server.worldgen.ChunkGenerator;
import server.worldgen.ChunkPrimer; import server.worldgen.ChunkPrimer;
@ -132,8 +130,8 @@ public final class WorldServer extends AWorldServer {
private final EventList[] queue = new EventList[] {new EventList(), new EventList()}; private final EventList[] queue = new EventList[] {new EventList(), new EventList()};
private final List<NextTickListEntry> ticksNow = Lists.<NextTickListEntry>newArrayList(); private final List<NextTickListEntry> ticksNow = Lists.<NextTickListEntry>newArrayList();
private final Set<Long> dropped = Collections.<Long>newSetFromMap(new ConcurrentHashMap()); private final Set<Long> dropped = Collections.<Long>newSetFromMap(new ConcurrentHashMap());
private final LongHashMap<Chunk> chunks = new LongHashMap(); private final LongHashMap<ChunkServer> chunks = new LongHashMap();
private final List<Chunk> loaded = Lists.<Chunk>newArrayList(); private final List<ChunkServer> loaded = Lists.<ChunkServer>newArrayList();
private final Map<ChunkPos, NBTTagCompound> toRemove = new ConcurrentHashMap(); private final Map<ChunkPos, NBTTagCompound> toRemove = new ConcurrentHashMap();
private final Set<ChunkPos> pending = Collections.<ChunkPos>newSetFromMap(new ConcurrentHashMap()); private final Set<ChunkPos> pending = Collections.<ChunkPos>newSetFromMap(new ConcurrentHashMap());
private final LongHashMap<BlockPos> loaders = new LongHashMap(); private final LongHashMap<BlockPos> loaders = new LongHashMap();
@ -263,7 +261,7 @@ public final class WorldServer extends AWorldServer {
return null; return null;
FeatureOres[] gens = new FeatureOres[this.dimension.getOres().size()]; FeatureOres[] gens = new FeatureOres[this.dimension.getOres().size()];
for(int z = 0; z < gens.length; z++) { for(int z = 0; z < gens.length; z++) {
FeatureOre gen = this.dimension.getOres().get(z); Ore gen = this.dimension.getOres().get(z);
gens[z] = new FeatureOres(gen.state, gen.count, gen.more, gen.size, gen.min, gen.max, gen.dist); gens[z] = new FeatureOres(gen.state, gen.count, gen.more, gen.size, gen.min, gen.max, gen.dist);
} }
return gens; return gens;
@ -274,7 +272,7 @@ public final class WorldServer extends AWorldServer {
return null; return null;
FeatureLakes[] gens = new FeatureLakes[this.dimension.getLakes().size()]; FeatureLakes[] gens = new FeatureLakes[this.dimension.getLakes().size()];
for(int z = 0; z < gens.length; z++) { for(int z = 0; z < gens.length; z++) {
FeatureLake gen = this.dimension.getLakes().get(z); Lake gen = this.dimension.getLakes().get(z);
gens[z] = new FeatureLakes(gen.state, gen.filler, gen.top, gen.chance, gen.minHeight, gen.maxHeight, gen.ratiod); gens[z] = new FeatureLakes(gen.state, gen.filler, gen.top, gen.chance, gen.minHeight, gen.maxHeight, gen.ratiod);
} }
return gens; return gens;
@ -285,7 +283,7 @@ public final class WorldServer extends AWorldServer {
return null; return null;
FeatureLiquids[] gens = new FeatureLiquids[this.dimension.getLiquids().size()]; FeatureLiquids[] gens = new FeatureLiquids[this.dimension.getLiquids().size()];
for(int z = 0; z < gens.length; z++) { for(int z = 0; z < gens.length; z++) {
FeatureLiquid gen = this.dimension.getLiquids().get(z); Liquid gen = this.dimension.getLiquids().get(z);
gens[z] = new FeatureLiquids(gen.state, gen.chance, gen.minHeight, gen.maxHeight, gen.lower); gens[z] = new FeatureLiquids(gen.state, gen.chance, gen.minHeight, gen.maxHeight, gen.lower);
} }
return gens; return gens;
@ -515,7 +513,7 @@ public final class WorldServer extends AWorldServer {
for(int i = 0; i < 100; ++i) { for(int i = 0; i < 100; ++i) {
if(!this.dropped.isEmpty()) { if(!this.dropped.isEmpty()) {
Long v = (Long)this.dropped.iterator().next(); Long v = (Long)this.dropped.iterator().next();
Chunk chunk = (Chunk)this.chunks.getValueByKey(v.longValue()); ChunkServer chunk = this.chunks.getValueByKey(v.longValue());
if(chunk != null) { if(chunk != null) {
chunk.onChunkUnload(); chunk.onChunkUnload();
this.saveChunkData(chunk); this.saveChunkData(chunk);
@ -656,7 +654,7 @@ public final class WorldServer extends AWorldServer {
int k = chunkcoordintpair.x * 16; int k = chunkcoordintpair.x * 16;
int l = chunkcoordintpair.z * 16; int l = chunkcoordintpair.z * 16;
// this.profiler.start("getChunk"); // this.profiler.start("getChunk");
Chunk chunk = this.getChunk(chunkcoordintpair.x, chunkcoordintpair.z); ChunkServer chunk = this.getChunk(chunkcoordintpair.x, chunkcoordintpair.z);
// this.profiler.next("moodSound"); // this.profiler.next("moodSound");
// this.playMoodSound(k, l, chunk); // this.playMoodSound(k, l, chunk);
// this.profiler.next("checkLight"); // this.profiler.next("checkLight");
@ -891,7 +889,7 @@ public final class WorldServer extends AWorldServer {
} }
} }
public List<NextTickListEntry> getPendingBlockUpdates(Chunk chunk) { public List<NextTickListEntry> getPendingBlockUpdates(ChunkServer chunk) {
int x1 = (chunk.xPos << 4) - 2; int x1 = (chunk.xPos << 4) - 2;
int x2 = x1 + 16 + 2; int x2 = x1 + 16 + 2;
int z1 = (chunk.zPos << 4) - 2; int z1 = (chunk.zPos << 4) - 2;
@ -1071,15 +1069,15 @@ public final class WorldServer extends AWorldServer {
Log.JNI.error(e, "Konnte Dorfliste nicht speichern"); Log.JNI.error(e, "Konnte Dorfliste nicht speichern");
} }
} }
List<Chunk> list = Lists.newArrayList(this.loaded); List<ChunkServer> list = Lists.newArrayList(this.loaded);
for(int n = 0; n < list.size(); ++n) { for(int n = 0; n < list.size(); ++n) {
Chunk chunk = list.get(n); ChunkServer chunk = list.get(n);
if(chunk.isDirty(this.time)) { if(chunk.isDirty(this.time)) {
this.saveChunkData(chunk); this.saveChunkData(chunk);
chunk.setModified(false); chunk.setModified(false);
} }
} }
for(Chunk chunk : Lists.newArrayList(this.loaded)) { for(ChunkServer chunk : Lists.newArrayList(this.loaded)) {
if(chunk != null && !this.hasPlayerInstance(chunk.xPos, chunk.zPos)) { if(chunk != null && !this.hasPlayerInstance(chunk.xPos, chunk.zPos)) {
this.dropChunk(chunk.xPos, chunk.zPos); this.dropChunk(chunk.xPos, chunk.zPos);
} }
@ -1325,14 +1323,18 @@ public final class WorldServer extends AWorldServer {
} }
protected boolean isLoaded(int x, int z, boolean allowEmpty) { protected boolean isLoaded(int x, int z, boolean allowEmpty) {
return this.chunkExists(x, z) && super.isLoaded(x, z, allowEmpty); return this.chunkExists(x, z);
} }
public Chunk getChunk(int x, int z) { public ChunkServer getChunk(int x, int z) {
Chunk chunk = this.chunks.getValueByKey(LongHashMap.packInt(x, z)); ChunkServer chunk = this.chunks.getValueByKey(LongHashMap.packInt(x, z));
return chunk == null ? this.loadChunk(x, z) : chunk; return chunk == null ? this.loadChunk(x, z) : chunk;
} }
public ChunkServer getChunk(BlockPos pos) {
return this.getChunk(pos.getX() >> 4, pos.getZ() >> 4);
}
private boolean chunkExists(int x, int z) { private boolean chunkExists(int x, int z) {
return this.chunks.containsItem(LongHashMap.packInt(x, z)); return this.chunks.containsItem(LongHashMap.packInt(x, z));
} }
@ -1350,15 +1352,15 @@ public final class WorldServer extends AWorldServer {
} }
public void unloadAllChunks() { public void unloadAllChunks() {
for(Chunk chunk : this.loaded) { for(ChunkServer chunk : this.loaded) {
this.dropChunk(chunk.xPos, chunk.zPos); this.dropChunk(chunk.xPos, chunk.zPos);
} }
} }
public Chunk loadChunk(int x, int z) { public ChunkServer loadChunk(int x, int z) {
long id = LongHashMap.packInt(x, z); long id = LongHashMap.packInt(x, z);
this.dropped.remove(Long.valueOf(id)); this.dropped.remove(Long.valueOf(id));
Chunk chunk = (Chunk)this.chunks.getValueByKey(id); ChunkServer chunk = this.chunks.getValueByKey(id);
if(chunk == null) { if(chunk == null) {
if(!this.debug) if(!this.debug)
@ -1377,7 +1379,7 @@ public final class WorldServer extends AWorldServer {
return chunk; return chunk;
} }
private Chunk loadChunkFromFile(int x, int z) { private ChunkServer loadChunkFromFile(int x, int z) {
try { try {
ChunkPos coord = new ChunkPos(x, z); ChunkPos coord = new ChunkPos(x, z);
NBTTagCompound tag = this.toRemove.get(coord); NBTTagCompound tag = this.toRemove.get(coord);
@ -1389,7 +1391,7 @@ public final class WorldServer extends AWorldServer {
} }
// tag = CompressedStreamTools.read(in); // tag = CompressedStreamTools.read(in);
} }
Chunk chunk = Region.readNbt(this, x, z, tag); ChunkServer chunk = Region.readNbt(this, x, z, tag);
if(chunk != null) { if(chunk != null) {
chunk.setSaved(this.time); chunk.setSaved(this.time);
if(this.mineshaftGen != null) { if(this.mineshaftGen != null) {
@ -1416,7 +1418,7 @@ public final class WorldServer extends AWorldServer {
} }
} }
private void saveChunkData(Chunk chunk) { private void saveChunkData(ChunkServer chunk) {
// try { // try {
chunk.setSaved(this.time); chunk.setSaved(this.time);
// this.lock.check(); // this.lock.check();
@ -1424,7 +1426,7 @@ public final class WorldServer extends AWorldServer {
// NBTTagCompound ltag = new NBTTagCompound(); // NBTTagCompound ltag = new NBTTagCompound();
// tag.setTag("Level", ltag); // tag.setTag("Level", ltag);
NBTTagCompound tag = Region.writeNbt(this, chunk); NBTTagCompound tag = Region.writeNbt(this, chunk);
ChunkPos coord = chunk.getPos(); ChunkPos coord = new ChunkPos(chunk.xPos, chunk.zPos);
if(!this.pending.contains(coord)) { if(!this.pending.contains(coord)) {
this.toRemove.put(coord, tag); this.toRemove.put(coord, tag);
} }
@ -1533,7 +1535,7 @@ public final class WorldServer extends AWorldServer {
} }
private void populate(int x, int z) { private void populate(int x, int z) {
Chunk chunk = this.getChunk(x, z); ChunkServer chunk = this.getChunk(x, z);
if(!chunk.isTerrainPopulated()) { if(!chunk.isTerrainPopulated()) {
chunk.checkLight(); chunk.checkLight();
BlockFalling.fallInstantly = true; BlockFalling.fallInstantly = true;
@ -1602,11 +1604,11 @@ public final class WorldServer extends AWorldServer {
} }
// } // }
BlockFalling.fallInstantly = false; BlockFalling.fallInstantly = false;
chunk.setModified(); chunk.setModified(true);
} }
} }
private Chunk generate(int x, int z) { private ChunkServer generate(int x, int z) {
this.grng.setSeed((long)x * 341873128712L + (long)z * 132897987541L); this.grng.setSeed((long)x * 341873128712L + (long)z * 132897987541L);
ChunkPrimer primer = new ChunkPrimer(this.height); ChunkPrimer primer = new ChunkPrimer(this.height);
this.generator.generateChunk(this, x, z, primer); this.generator.generateChunk(this, x, z, primer);
@ -1638,7 +1640,7 @@ public final class WorldServer extends AWorldServer {
if(this.scatteredGen != null) { if(this.scatteredGen != null) {
this.scatteredGen.generate(this, x, z, primer); this.scatteredGen.generate(this, x, z, primer);
} }
return new Chunk(this, primer.getData(), primer.height, this.base, this.ceil, this.grng, this.biomes, x, z); return new ChunkServer(this, primer.getData(), primer.height, this.base, this.ceil, this.grng, this.biomes, x, z);
} }
public boolean isExterminated() { public boolean isExterminated() {
@ -1673,7 +1675,7 @@ public final class WorldServer extends AWorldServer {
this.exterminated = true; this.exterminated = true;
// this.dataModified = true; // this.dataModified = true;
for(Long v : this.dropped) { for(Long v : this.dropped) {
Chunk chunk = this.chunks.getValueByKey(v.longValue()); ChunkServer chunk = this.chunks.getValueByKey(v.longValue());
if(chunk != null) { if(chunk != null) {
chunk.onChunkUnload(); chunk.onChunkUnload();
this.chunks.remove(v.longValue()); this.chunks.remove(v.longValue());
@ -1681,10 +1683,10 @@ public final class WorldServer extends AWorldServer {
} }
} }
this.dropped.clear(); this.dropped.clear();
List<Chunk> loaded = Lists.<Chunk>newArrayList(this.loaded); List<ChunkServer> loaded = Lists.<ChunkServer>newArrayList(this.loaded);
this.loaded.clear(); this.loaded.clear();
this.setExterminatedGen(); this.setExterminatedGen();
for(Chunk chunk : loaded) { for(ChunkServer chunk : loaded) {
long pos = LongHashMap.packInt(chunk.xPos, chunk.zPos); long pos = LongHashMap.packInt(chunk.xPos, chunk.zPos);
chunk.onChunkUnload(); chunk.onChunkUnload();
this.chunks.remove(pos); this.chunks.remove(pos);
@ -1693,9 +1695,9 @@ public final class WorldServer extends AWorldServer {
this.loaded.add(chunk); this.loaded.add(chunk);
chunk.onChunkLoad(); chunk.onChunkLoad();
chunk.checkLight(); chunk.checkLight();
chunk.setModified(); chunk.setModified(true);
} }
for(Chunk chunk : this.loaded) { for(ChunkServer chunk : this.loaded) {
chunk.update(false); chunk.update(false);
} }
this.entities.removeAll(this.unloaded); this.entities.removeAll(this.unloaded);
@ -1877,8 +1879,8 @@ public final class WorldServer extends AWorldServer {
PlayerInstance ins = this.instances.getValueByKey(v); PlayerInstance ins = this.instances.getValueByKey(v);
if(ins == null) if(ins == null)
return false; return false;
Chunk chunk = this.getChunk(chunkX, chunkZ); ChunkServer chunk = this.getChunk(chunkX, chunkZ);
chunk.setModified(); chunk.setModified(true);
ins.sendToAllPlayersWatchingChunk(new SPacketBiomes(chunkX, chunkZ, chunk.getBiomes())); ins.sendToAllPlayersWatchingChunk(new SPacketBiomes(chunkX, chunkZ, chunk.getBiomes()));
return true; return true;
} }
@ -2176,7 +2178,7 @@ public final class WorldServer extends AWorldServer {
} }
} }
public void updateChunksForPlayer(EntityNPC player, Chunk chunk) { public void updateChunksForPlayer(EntityNPC player, ChunkServer chunk) {
for(EntityTrackerEntry entitytrackerentry : this.tracked) { for(EntityTrackerEntry entitytrackerentry : this.tracked) {
if(entitytrackerentry.trackedEntity != player && entitytrackerentry.trackedEntity.chunkCoordX == chunk.xPos if(entitytrackerentry.trackedEntity != player && entitytrackerentry.trackedEntity.chunkCoordX == chunk.xPos
&& entitytrackerentry.trackedEntity.chunkCoordZ == chunk.zPos) { && entitytrackerentry.trackedEntity.chunkCoordZ == chunk.zPos) {
@ -2189,7 +2191,7 @@ public final class WorldServer extends AWorldServer {
// int x = position.getBlockX(); // int x = position.getBlockX();
// int y = position.getBlockY(); // int y = position.getBlockY();
// int z = position.getBlockZ(); // int z = position.getBlockZ();
Chunk chunk = this.getChunk(pos.getX() >> 4, pos.getZ() >> 4); ChunkServer chunk = this.getChunk(pos.getX() >> 4, pos.getZ() >> 4);
// BlockPos pos = new BlockPos(x, y, z); // BlockPos pos = new BlockPos(x, y, z);
State old = chunk.getState(pos); State old = chunk.getState(pos);
State newState = block.getState(); State newState = block.getState();
@ -2249,7 +2251,7 @@ public final class WorldServer extends AWorldServer {
// } // }
private final boolean setChunkBiome(BlockPos position, Biome biome) { private final boolean setChunkBiome(BlockPos position, Biome biome) {
Chunk chunk = this.getChunk(position); ChunkServer chunk = this.getChunk(position);
if((chunk != null) && (chunk.isLoaded())) { if((chunk != null) && (chunk.isLoaded())) {
chunk.getBiomes()[((position.getZ() & 0xF) << 4 | position.getX() & 0xF)] = (byte)biome.id; chunk.getBiomes()[((position.getZ() & 0xF) << 4 | position.getX() & 0xF)] = (byte)biome.id;
return true; return true;
@ -2437,7 +2439,7 @@ public final class WorldServer extends AWorldServer {
} }
public BlockPos getTopSolidOrLiquidBlock(BlockPos pos) { public BlockPos getTopSolidOrLiquidBlock(BlockPos pos) {
Chunk chunk = this.getChunk(pos); ChunkServer chunk = this.getChunk(pos);
int h = chunk.getTopSegment(); int h = chunk.getTopSegment();
if(h == Integer.MIN_VALUE) if(h == Integer.MIN_VALUE)
return new BlockPos(pos.getX(), 0, pos.getZ()); return new BlockPos(pos.getX(), 0, pos.getZ());
@ -2792,6 +2794,11 @@ public final class WorldServer extends AWorldServer {
return this.server.getWorld(dimension); return this.server.getWorld(dimension);
} }
public void markChunkDirty(BlockPos pos) {
if(this.isBlockLoaded(pos))
this.getChunk(pos).setModified(true);
}
private static class EventList extends ArrayList<BlockEventData> { private static class EventList extends ArrayList<BlockEventData> {
private EventList() { private EventList() {
} }
@ -2809,6 +2816,15 @@ public final class WorldServer extends AWorldServer {
} }
} }
private static SPacketMultiBlockChange getPacket(int amount, long[] list, ChunkServer chunk) {
ChunkPos pos = new ChunkPos(chunk.xPos, chunk.zPos);
SPacketMultiBlockChange.BlockUpdateData[] changes = new SPacketMultiBlockChange.BlockUpdateData[amount];
for(int z = 0; z < changes.length; z++) {
changes[z] = new SPacketMultiBlockChange.BlockUpdateData(list[z], chunk.getState(SPacketMultiBlockChange.getPos(pos, list[z])));
}
return new SPacketMultiBlockChange(pos, changes);
}
private class PlayerInstance { private class PlayerInstance {
private final List<EntityNPC> watching = Lists.<EntityNPC>newArrayList(); private final List<EntityNPC> watching = Lists.<EntityNPC>newArrayList();
private final Set<Integer> extend = Sets.newHashSet(); private final Set<Integer> extend = Sets.newHashSet();
@ -2841,10 +2857,10 @@ public final class WorldServer extends AWorldServer {
public void removePlayer(EntityNPC player) { public void removePlayer(EntityNPC player) {
if(this.watching.contains(player)) { if(this.watching.contains(player)) {
Chunk chunk = WorldServer.this.getChunk(this.position.x, this.position.z); ChunkServer chunk = WorldServer.this.getChunk(this.position.x, this.position.z);
if(chunk.isPopulated()) { if(chunk.isPopulated()) {
player.connection.sendPacket(new SPacketChunkData(chunk, true, new int[0])); player.connection.sendPacket(Player.getPacket(chunk, true, new int[0], !WorldServer.this.dimension.hasNoLight()));
} }
this.watching.remove(player); this.watching.remove(player);
@ -2876,7 +2892,7 @@ public final class WorldServer extends AWorldServer {
this.biomes = true; this.biomes = true;
} }
private void increaseInhabitedTime(Chunk chunk) { private void increaseInhabitedTime(ChunkServer chunk) {
chunk.setInhabited(chunk.getInhabited() + WorldServer.this.time - this.prevTime); chunk.setInhabited(chunk.getInhabited() + WorldServer.this.time - this.prevTime);
this.prevTime = WorldServer.this.time; this.prevTime = WorldServer.this.time;
} }
@ -2935,8 +2951,8 @@ public final class WorldServer extends AWorldServer {
extend[n++] = i; extend[n++] = i;
} }
} }
this.sendToAllPlayersWatchingChunk(new SPacketChunkData(WorldServer.this.getChunk(this.position.x, this.position.z), this.sendToAllPlayersWatchingChunk(Player.getPacket(WorldServer.this.getChunk(this.position.x, this.position.z),
this.biomes, extend)); this.biomes, extend, !WorldServer.this.dimension.hasNoLight()));
if(this.biomes) { if(this.biomes) {
List<TileEntity> list = WorldServer.this.getTileEntitiesIn(x, Integer.MIN_VALUE, z, x + 16, Integer.MAX_VALUE, z + 16); List<TileEntity> list = WorldServer.this.getTileEntitiesIn(x, Integer.MIN_VALUE, z, x + 16, Integer.MAX_VALUE, z + 16);
@ -2957,7 +2973,7 @@ public final class WorldServer extends AWorldServer {
} }
} }
else { else {
this.sendToAllPlayersWatchingChunk(new SPacketMultiBlockChange(this.updates, this.changes, this.sendToAllPlayersWatchingChunk(getPacket(this.updates, this.changes,
WorldServer.this.getChunk(this.position.x, this.position.z))); WorldServer.this.getChunk(this.position.x, this.position.z)));
for(int n = 0; n < this.updates; ++n) { for(int n = 0; n < this.updates; ++n) {

View file

@ -7,7 +7,6 @@ import common.biome.Biome;
import common.collect.Lists; import common.collect.Lists;
import common.util.BlockPos; import common.util.BlockPos;
import common.util.LongHashMap; import common.util.LongHashMap;
import common.worldgen.BiomeGenerator;
import server.worldgen.layer.GenLayer; import server.worldgen.layer.GenLayer;
import server.worldgen.layer.GenLayerAddAreas; import server.worldgen.layer.GenLayerAddAreas;
import server.worldgen.layer.GenLayerAddExtra; import server.worldgen.layer.GenLayerAddExtra;

View file

@ -5,7 +5,6 @@ import java.util.Set;
import common.biome.Biome; import common.biome.Biome;
import common.util.BlockPos; import common.util.BlockPos;
import common.worldgen.BiomeGenerator;
public class BiomeGenSingle implements BiomeGenerator { public class BiomeGenSingle implements BiomeGenerator {
private final Biome biome; private final Biome biome;

View file

@ -1,4 +1,4 @@
package common.worldgen; package server.worldgen;
import java.util.Set; import java.util.Set;

View file

@ -1,7 +1,7 @@
package server.worldgen; package server.worldgen;
import common.world.DebugStates;
import common.world.State; import common.world.State;
import common.worldgen.DebugStates;
import server.world.WorldServer; import server.world.WorldServer;
public class GeneratorDebug implements ChunkGenerator public class GeneratorDebug implements ChunkGenerator

View file

@ -22,8 +22,8 @@ import common.rng.Random;
import common.util.BlockPos; import common.util.BlockPos;
import common.util.Facing; import common.util.Facing;
import common.world.State; import common.world.State;
import common.worldgen.BiomeGenerator;
import server.world.WorldServer; import server.world.WorldServer;
import server.worldgen.BiomeGenerator;
import server.worldgen.LootConstants; import server.worldgen.LootConstants;