extend biome ids, remove biome id saving

This commit is contained in:
Sen 2025-06-29 20:03:00 +02:00
parent f613bd2122
commit 15459fc627
Signed by: sen
GPG key ID: 3AC50A6F47D1B722
7 changed files with 119 additions and 37 deletions

View file

@ -105,7 +105,10 @@ public class ChunkClient extends Chunk {
}
if(biomes) {
System.arraycopy(data, pos, this.biomes, 0, this.biomes.length);
for(int k = 0; k < this.biomes.length; ++k) {
this.biomes[k] = (char)((data[pos + 1] & 255) << 8 | data[pos] & 255);
pos += 2;
}
}
for(int cy : extend) {
@ -128,14 +131,8 @@ public class ChunkClient extends Chunk {
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 void setBiome(BlockPos pos, Biome biome) {
this.biomes[((pos.getZ() & 15) << 4 | pos.getX() & 15)] = (byte)biome.id;
this.biomes[((pos.getZ() & 15) << 4 | pos.getX() & 15)] = (char)biome.id;
}
public boolean isDummy() {

View file

@ -73,7 +73,7 @@ public class SPacketChunkData implements Packet<IClientPlayer>
int i = segments * 2 * 16 * 16 * 16;
int j = segments * 16 * 16 * 16 / 2;
int k = overworld ? segments * 16 * 16 * 16 / 2 : 0;
int l = biomes ? 256 : 0;
int l = biomes ? 256 * 2 : 0;
return i + j + k + l;
}

View file

@ -7,6 +7,7 @@ import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.function.Predicate;
import common.biome.Biome;
import common.block.Block;
import common.block.ITileEntityProvider;
import common.block.Material;
@ -31,7 +32,7 @@ public abstract class Chunk {
protected final Block fillerBlock;
protected final IntHashMap<BlockArray> blocks = new IntHashMap();
protected final Set<BlockArray> blockList = Sets.newHashSet();
protected final byte[] biomes = new byte[256];
protected final char[] biomes = new char[256];
protected final int[] precHeight = new int[256];
protected final boolean[] updateSky = new boolean[256];
protected final int[] height = new int[256];
@ -61,7 +62,6 @@ public abstract class Chunk {
this.entities[y] = new InheritanceMultiMap(Entity.class);
}
Arrays.fill(this.precHeight, -99999999);
Arrays.fill(this.biomes, (byte)-1);
}
public int getHeight(int x, int z) {
@ -839,4 +839,10 @@ public abstract class Chunk {
public int getLowest() {
return this.minHeight;
}
public Biome getBiome(BlockPos pos) {
int x = pos.getX() & 15;
int z = pos.getZ() & 15;
return Biome.getBiomeDef(this.biomes[z << 4 | x]);
}
}

View file

@ -921,7 +921,13 @@ public class Player extends User implements ICrafting, Executor, IPlayer
if (biomes)
{
copyTo(chunk.getBiomes(), s21packetchunkdata$extracted.data, j);
char[] achar = chunk.getBiomes();
for (char c0 : achar)
{
s21packetchunkdata$extracted.data[j++] = (byte)(c0 & 255);
s21packetchunkdata$extracted.data[j++] = (byte)(c0 >> 8 & 255);
}
}
return s21packetchunkdata$extracted;

View file

@ -1,5 +1,6 @@
package server.world;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import common.biome.Biome;
@ -15,7 +16,6 @@ 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;
@ -86,7 +86,7 @@ public class ChunkServer extends Chunk {
}
}
for(int n = 0; n < this.biomes.length; ++n) {
this.biomes[n] = (byte)biomes[n].id;
this.biomes[n] = (char)biomes[n].id;
}
if(ceil)
this.resetRelight();
@ -140,27 +140,14 @@ public class ChunkServer extends Chunk {
}
}
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() {
public char[] getBiomes() {
return this.biomes;
}
public void setBiomes(byte[] biomes) {
public void setBiomes(char[] biomes) {
if(this.biomes.length != biomes.length) {
Log.IO.warn("Konnte Biome des Chunks nicht setzen, Länge des Arrays ist " + biomes.length + " statt " + this.biomes.length);
Arrays.fill(this.biomes, (char)Biome.DEF_BIOME.id);
}
else {
for(int n = 0; n < this.biomes.length; ++n) {

View file

@ -10,6 +10,7 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@ -19,6 +20,7 @@ import java.util.Set;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;
import common.biome.Biome;
import common.block.Block;
import common.collect.Lists;
import common.collect.Maps;
@ -113,8 +115,73 @@ public class Region {
return false;
}
private static boolean makeBiomeMap(TagObject tag) {
Map<Character, String> biomes = Maps.newTreeMap();
Map<String, Character> assign = Maps.newHashMap();
if(tag.hasStringArray("biomes")) {
String[] ids = tag.getStringArray("biomes");
for(char bid = 1; bid < ids.length; bid++) {
String id = ids[bid];
if(!id.isEmpty()) {
biomes.put(bid, id);
assign.put(id, bid);
}
}
}
Map<Character, String> mapping = Maps.newHashMap();
List<String> missing = Lists.newArrayList();
char highest = 0;
for(Biome state : Biome.values()) {
if(state == Biome.NONE)
continue;
String id = state.getName();
if(assign.containsKey(id)) {
char bid = assign.get(id);
if(bid == 0) {
missing.add(id);
continue;
}
mapping.put(bid, id);
highest = bid > highest ? bid : highest;
biomes.remove(bid);
Log.IO.debug("Bestehende Biom-ID %d = %s", (int)bid, id);
}
else {
missing.add(id);
}
}
for(Entry<Character, String> entry : biomes.entrySet()) {
Log.IO.debug("Entfernte Biom-ID %d = %s", (int)entry.getKey(), entry.getValue());
}
char bid = 1;
for(String id : missing) {
while(mapping.containsKey(bid)) {
++bid;
}
mapping.put(bid, id);
highest = bid > highest ? bid : highest;
Log.IO.debug("Neue Biom-ID %d = %s", (int)bid, id);
}
for(Entry<Character, String> entry : mapping.entrySet()) {
bid = entry.getKey();
char ids = (char)Biome.findByName(entry.getValue()).id;
BDECODE_MAP[bid] = ids;
BENCODE_MAP[ids] = bid;
}
if(!missing.isEmpty() || !biomes.isEmpty()) {
String[] ids = new String[highest + 1];
ids[0] = Biome.NONE.getName();
for(bid = 1; bid < ids.length; bid++) {
ids[bid] = mapping.getOrDefault(bid, "");
}
tag.setStringArray("biomes", ids);
return true;
}
return false;
}
public static void loadMap() {
File mapFile = new File("blocks.cdt");
File mapFile = new File("datamap.cdt");
TagObject tag;
if(mapFile.exists()) {
try {
@ -128,8 +195,10 @@ public class Region {
else {
tag = new TagObject();
}
if(makeMap(tag)) {
Log.IO.info("Block-IDs haben sich geändert, schreibe %s", mapFile);
boolean states = makeMap(tag);
boolean biomes = makeBiomeMap(tag);
if(states || biomes) {
Log.IO.info((states ? "Block-IDs" : "") + (states && biomes ? " und " : "") + (biomes ? "Biom-IDs" : "") + " haben sich geändert, schreibe %s", mapFile);
try {
TagObject.writeGZip(tag, mapFile);
}
@ -169,6 +238,8 @@ public class Region {
private static final List<WorldServer> QUEUE = Collections.<WorldServer>synchronizedList(Lists.<WorldServer>newArrayList());
private static final char[] DECODE_MAP = new char[65536];
private static final char[] ENCODE_MAP = new char[65536];
private static final char[] BDECODE_MAP = new char[65536];
private static final char[] BENCODE_MAP = new char[65536];
private static volatile long queued;
private static volatile long saved;
@ -519,7 +590,15 @@ public class Region {
chunk.setStorage(sections);
if(tag.hasByteArray("Biomes")) {
chunk.setBiomes(tag.getByteArray("Biomes"));
byte[] bdata = tag.getByteArray("Biomes");
char[] biomes = new char[bdata.length / 2];
for(int n = 0; n < biomes.length; n++) {
biomes[n] = BDECODE_MAP[(char)((bdata[n * 2] & 255) << 8 | bdata[n * 2 + 1] & 255)];
}
chunk.setBiomes(biomes);
}
else {
Arrays.fill(chunk.getBiomes(), (char)Biome.DEF_BIOME.id);
}
List<TagObject> entities = tag.getList("Entities");
@ -645,7 +724,14 @@ public class Region {
}
tag.setList("Sections", sects);
tag.setByteArray("Biomes", chunk.getBiomes());
char[] biomes = chunk.getBiomes();
byte[] bdata = new byte[biomes.length * 2];
for(int n = 0; n < biomes.length; n++) {
char biome = BENCODE_MAP[biomes[n]];
bdata[n * 2] = (byte)(biome >> 8 & 255);
bdata[n * 2 + 1] = (byte)(biome & 255);
}
tag.setByteArray("Biomes", bdata);
chunk.setHasEntities(false);
List<TagObject> entities = Lists.newArrayList();

View file

@ -601,7 +601,7 @@ public final class WorldServer extends AWorldServer {
public Biome getBiomeGenForCoords(final BlockPos pos) {
if(this.isBlockLoaded(pos))
return this.getChunk(pos).getBiome(pos, this.biomeGen);
return this.getChunk(pos).getBiome(pos);
else
return this.biomeGen.getBiomeGenerator(pos, Biome.DEF_BIOME);
}
@ -1854,7 +1854,7 @@ public final class WorldServer extends AWorldServer {
ChunkServer chunk = this.getChunk(pos);
if(chunk == null || !chunk.isLoaded())
return;
chunk.getBiomes()[((pos.getZ() & 0xF) << 4 | pos.getX() & 0xF)] = (byte)biome.id;
chunk.getBiomes()[((pos.getZ() & 0xF) << 4 | pos.getX() & 0xF)] = (char)biome.id;
chunk.setModified(true);
int chunkX = pos.getX() >> 4;
int chunkZ = pos.getZ() >> 4;