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

@ -119,7 +119,7 @@ import common.util.Position;
import common.util.Vec3i;
import common.util.WorldPos;
import common.village.MerchantRecipeList;
import common.world.Chunk;
import common.world.BlockArray;
import common.world.State;
import common.world.World;
import io.netty.util.concurrent.Future;
@ -134,6 +134,7 @@ import server.clipboard.RotationValue;
import server.clipboard.Vector;
import server.command.Executor;
import server.util.Form;
import server.world.ChunkServer;
import server.world.Region;
import server.world.WorldServer;
@ -915,6 +916,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()
{
@ -951,7 +1043,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer
if (!this.loadedChunks.isEmpty())
{
List<Chunk> list = Lists.<Chunk>newArrayList();
List<ChunkServer> list = Lists.<ChunkServer>newArrayList();
Iterator<ChunkPos> iterator1 = this.loadedChunks.iterator();
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)))
{
Chunk chunk = this.entity.worldObj.getChunk(chunkcoordintpair.x, chunkcoordintpair.z);
ChunkServer chunk = this.getEntityWorld().getChunk(chunkcoordintpair.x, chunkcoordintpair.z);
if (chunk.isPopulated())
{
@ -985,11 +1077,11 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer
{
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
{
this.sendPacket(new SPacketMapChunkBulk(list));
this.sendPacket(getPacket(list, !this.entity.worldObj.dimension.hasNoLight()));
}
for (TileEntity tileentity : list1)
@ -997,7 +1089,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer
this.sendTileEntityUpdate(tileentity);
}
for (Chunk chunk1 : list)
for (ChunkServer chunk1 : list)
{
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.Util;
import common.world.BlockArray;
import common.world.Chunk;
public class Region {
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);
}
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)) {
// Log.error("Chunk-Datei bei " + x + "," + z + " hat keine Level-Daten, überspringe");
// return null;
@ -370,7 +369,7 @@ public class Region {
Log.JNI.warn("Chunk-Datei bei " + x + "," + z + " hat keine Block-Daten, überspringe");
return null;
}
Chunk chunk = new Chunk(world, x, z);
ChunkServer chunk = new ChunkServer(world, x, z);
chunk.setHeights(tag.getIntArray("HeightMap"));
chunk.setTerrainPopulated(tag.getBoolean("TerrainPopulated"));
chunk.setLightPopulated(tag.getBoolean("LightPopulated"));
@ -486,7 +485,7 @@ public class Region {
return chunk;
}
public static NBTTagCompound writeNbt(WorldServer world, Chunk chunk) {
public static NBTTagCompound writeNbt(WorldServer world, ChunkServer chunk) {
NBTTagCompound tag = new NBTTagCompound();
// tag.setShort("V", (short)Config.PROTOCOL);
tag.setLong("LastUpdate", world.getTime());

View file

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

View file

@ -24,6 +24,9 @@ import common.collect.Lists;
import common.collect.Maps;
import common.collect.Sets;
import common.dimension.Dimension;
import common.dimension.Lake;
import common.dimension.Liquid;
import common.dimension.Ore;
import common.entity.DamageSource;
import common.entity.Entity;
import common.entity.EntityTrackerEntry;
@ -55,7 +58,6 @@ import common.packet.SPacketBiomes;
import common.packet.SPacketBlockAction;
import common.packet.SPacketBlockBreakAnim;
import common.packet.SPacketBlockChange;
import common.packet.SPacketChunkData;
import common.packet.SPacketMultiBlockChange;
import common.rng.Random;
import common.rng.WeightedList;
@ -73,17 +75,12 @@ import common.util.Position;
import common.util.Vec3;
import common.village.Village;
import common.world.BlockArray;
import common.world.Chunk;
import common.world.Explosion;
import common.world.AWorldServer;
import common.world.LightType;
import common.world.State;
import common.world.Weather;
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.biome.GenBiome;
import server.biome.RngSpawn;
@ -93,6 +90,7 @@ import server.village.VillageCollection;
import server.worldgen.BiomeGenLayered;
import server.worldgen.BiomeGenPerlin;
import server.worldgen.BiomeGenSingle;
import server.worldgen.BiomeGenerator;
import server.worldgen.BlockReplacer;
import server.worldgen.ChunkGenerator;
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 List<NextTickListEntry> ticksNow = Lists.<NextTickListEntry>newArrayList();
private final Set<Long> dropped = Collections.<Long>newSetFromMap(new ConcurrentHashMap());
private final LongHashMap<Chunk> chunks = new LongHashMap();
private final List<Chunk> loaded = Lists.<Chunk>newArrayList();
private final LongHashMap<ChunkServer> chunks = new LongHashMap();
private final List<ChunkServer> loaded = Lists.<ChunkServer>newArrayList();
private final Map<ChunkPos, NBTTagCompound> toRemove = new ConcurrentHashMap();
private final Set<ChunkPos> pending = Collections.<ChunkPos>newSetFromMap(new ConcurrentHashMap());
private final LongHashMap<BlockPos> loaders = new LongHashMap();
@ -263,7 +261,7 @@ public final class WorldServer extends AWorldServer {
return null;
FeatureOres[] gens = new FeatureOres[this.dimension.getOres().size()];
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);
}
return gens;
@ -274,7 +272,7 @@ public final class WorldServer extends AWorldServer {
return null;
FeatureLakes[] gens = new FeatureLakes[this.dimension.getLakes().size()];
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);
}
return gens;
@ -285,7 +283,7 @@ public final class WorldServer extends AWorldServer {
return null;
FeatureLiquids[] gens = new FeatureLiquids[this.dimension.getLiquids().size()];
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);
}
return gens;
@ -515,7 +513,7 @@ public final class WorldServer extends AWorldServer {
for(int i = 0; i < 100; ++i) {
if(!this.dropped.isEmpty()) {
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) {
chunk.onChunkUnload();
this.saveChunkData(chunk);
@ -656,7 +654,7 @@ public final class WorldServer extends AWorldServer {
int k = chunkcoordintpair.x * 16;
int l = chunkcoordintpair.z * 16;
// 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.playMoodSound(k, l, chunk);
// 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 x2 = x1 + 16 + 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");
}
}
List<Chunk> list = Lists.newArrayList(this.loaded);
List<ChunkServer> list = Lists.newArrayList(this.loaded);
for(int n = 0; n < list.size(); ++n) {
Chunk chunk = list.get(n);
ChunkServer chunk = list.get(n);
if(chunk.isDirty(this.time)) {
this.saveChunkData(chunk);
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)) {
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) {
return this.chunkExists(x, z) && super.isLoaded(x, z, allowEmpty);
return this.chunkExists(x, z);
}
public Chunk getChunk(int x, int z) {
Chunk chunk = this.chunks.getValueByKey(LongHashMap.packInt(x, z));
public ChunkServer getChunk(int x, int z) {
ChunkServer chunk = this.chunks.getValueByKey(LongHashMap.packInt(x, z));
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) {
return this.chunks.containsItem(LongHashMap.packInt(x, z));
}
@ -1350,15 +1352,15 @@ public final class WorldServer extends AWorldServer {
}
public void unloadAllChunks() {
for(Chunk chunk : this.loaded) {
for(ChunkServer chunk : this.loaded) {
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);
this.dropped.remove(Long.valueOf(id));
Chunk chunk = (Chunk)this.chunks.getValueByKey(id);
ChunkServer chunk = this.chunks.getValueByKey(id);
if(chunk == null) {
if(!this.debug)
@ -1377,7 +1379,7 @@ public final class WorldServer extends AWorldServer {
return chunk;
}
private Chunk loadChunkFromFile(int x, int z) {
private ChunkServer loadChunkFromFile(int x, int z) {
try {
ChunkPos coord = new ChunkPos(x, z);
NBTTagCompound tag = this.toRemove.get(coord);
@ -1389,7 +1391,7 @@ public final class WorldServer extends AWorldServer {
}
// tag = CompressedStreamTools.read(in);
}
Chunk chunk = Region.readNbt(this, x, z, tag);
ChunkServer chunk = Region.readNbt(this, x, z, tag);
if(chunk != null) {
chunk.setSaved(this.time);
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 {
chunk.setSaved(this.time);
// this.lock.check();
@ -1424,7 +1426,7 @@ public final class WorldServer extends AWorldServer {
// NBTTagCompound ltag = new NBTTagCompound();
// tag.setTag("Level", ltag);
NBTTagCompound tag = Region.writeNbt(this, chunk);
ChunkPos coord = chunk.getPos();
ChunkPos coord = new ChunkPos(chunk.xPos, chunk.zPos);
if(!this.pending.contains(coord)) {
this.toRemove.put(coord, tag);
}
@ -1533,7 +1535,7 @@ public final class WorldServer extends AWorldServer {
}
private void populate(int x, int z) {
Chunk chunk = this.getChunk(x, z);
ChunkServer chunk = this.getChunk(x, z);
if(!chunk.isTerrainPopulated()) {
chunk.checkLight();
BlockFalling.fallInstantly = true;
@ -1602,11 +1604,11 @@ public final class WorldServer extends AWorldServer {
}
// }
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);
ChunkPrimer primer = new ChunkPrimer(this.height);
this.generator.generateChunk(this, x, z, primer);
@ -1638,7 +1640,7 @@ public final class WorldServer extends AWorldServer {
if(this.scatteredGen != null) {
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() {
@ -1673,7 +1675,7 @@ public final class WorldServer extends AWorldServer {
this.exterminated = true;
// this.dataModified = true;
for(Long v : this.dropped) {
Chunk chunk = this.chunks.getValueByKey(v.longValue());
ChunkServer chunk = this.chunks.getValueByKey(v.longValue());
if(chunk != null) {
chunk.onChunkUnload();
this.chunks.remove(v.longValue());
@ -1681,10 +1683,10 @@ public final class WorldServer extends AWorldServer {
}
}
this.dropped.clear();
List<Chunk> loaded = Lists.<Chunk>newArrayList(this.loaded);
List<ChunkServer> loaded = Lists.<ChunkServer>newArrayList(this.loaded);
this.loaded.clear();
this.setExterminatedGen();
for(Chunk chunk : loaded) {
for(ChunkServer chunk : loaded) {
long pos = LongHashMap.packInt(chunk.xPos, chunk.zPos);
chunk.onChunkUnload();
this.chunks.remove(pos);
@ -1693,9 +1695,9 @@ public final class WorldServer extends AWorldServer {
this.loaded.add(chunk);
chunk.onChunkLoad();
chunk.checkLight();
chunk.setModified();
chunk.setModified(true);
}
for(Chunk chunk : this.loaded) {
for(ChunkServer chunk : this.loaded) {
chunk.update(false);
}
this.entities.removeAll(this.unloaded);
@ -1877,8 +1879,8 @@ public final class WorldServer extends AWorldServer {
PlayerInstance ins = this.instances.getValueByKey(v);
if(ins == null)
return false;
Chunk chunk = this.getChunk(chunkX, chunkZ);
chunk.setModified();
ChunkServer chunk = this.getChunk(chunkX, chunkZ);
chunk.setModified(true);
ins.sendToAllPlayersWatchingChunk(new SPacketBiomes(chunkX, chunkZ, chunk.getBiomes()));
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) {
if(entitytrackerentry.trackedEntity != player && entitytrackerentry.trackedEntity.chunkCoordX == chunk.xPos
&& entitytrackerentry.trackedEntity.chunkCoordZ == chunk.zPos) {
@ -2189,7 +2191,7 @@ public final class WorldServer extends AWorldServer {
// int x = position.getBlockX();
// int y = position.getBlockY();
// 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);
State old = chunk.getState(pos);
State newState = block.getState();
@ -2249,7 +2251,7 @@ public final class WorldServer extends AWorldServer {
// }
private final boolean setChunkBiome(BlockPos position, Biome biome) {
Chunk chunk = this.getChunk(position);
ChunkServer chunk = this.getChunk(position);
if((chunk != null) && (chunk.isLoaded())) {
chunk.getBiomes()[((position.getZ() & 0xF) << 4 | position.getX() & 0xF)] = (byte)biome.id;
return true;
@ -2437,7 +2439,7 @@ public final class WorldServer extends AWorldServer {
}
public BlockPos getTopSolidOrLiquidBlock(BlockPos pos) {
Chunk chunk = this.getChunk(pos);
ChunkServer chunk = this.getChunk(pos);
int h = chunk.getTopSegment();
if(h == Integer.MIN_VALUE)
return new BlockPos(pos.getX(), 0, pos.getZ());
@ -2792,6 +2794,11 @@ public final class WorldServer extends AWorldServer {
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 EventList() {
}
@ -2808,6 +2815,15 @@ public final class WorldServer extends AWorldServer {
this.tag = tag;
}
}
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 final List<EntityNPC> watching = Lists.<EntityNPC>newArrayList();
@ -2841,10 +2857,10 @@ public final class WorldServer extends AWorldServer {
public void removePlayer(EntityNPC 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()) {
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);
@ -2876,7 +2892,7 @@ public final class WorldServer extends AWorldServer {
this.biomes = true;
}
private void increaseInhabitedTime(Chunk chunk) {
private void increaseInhabitedTime(ChunkServer chunk) {
chunk.setInhabited(chunk.getInhabited() + WorldServer.this.time - this.prevTime);
this.prevTime = WorldServer.this.time;
}
@ -2935,8 +2951,8 @@ public final class WorldServer extends AWorldServer {
extend[n++] = i;
}
}
this.sendToAllPlayersWatchingChunk(new SPacketChunkData(WorldServer.this.getChunk(this.position.x, this.position.z),
this.biomes, extend));
this.sendToAllPlayersWatchingChunk(Player.getPacket(WorldServer.this.getChunk(this.position.x, this.position.z),
this.biomes, extend, !WorldServer.this.dimension.hasNoLight()));
if(this.biomes) {
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 {
this.sendToAllPlayersWatchingChunk(new SPacketMultiBlockChange(this.updates, this.changes,
this.sendToAllPlayersWatchingChunk(getPacket(this.updates, this.changes,
WorldServer.this.getChunk(this.position.x, this.position.z)));
for(int n = 0; n < this.updates; ++n) {

View file

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

View file

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

View file

@ -0,0 +1,16 @@
package server.worldgen;
import java.util.Set;
import common.biome.Biome;
import common.util.BlockPos;
public interface BiomeGenerator {
public void genFactors(double[] factors, int xPos, int zPos, int sizeX, int sizeZ);
public Biome getBiomeGenerator(BlockPos pos, Biome def);
public void getGenBiomes(Biome[] biomes, int x, int z, int width, int height);
public void getChunkBiomes(Biome[] oldBiomeList, int x, int z, int width, int depth);
public void getBiomes(Biome[] listToReuse, int x, int z, int width, int length, boolean cacheFlag);
public boolean areBiomesViable(int x, int z, int size, Set<Biome> allowed);
public void cleanupCache();
}

View file

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

View file

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