Archived
0

генератор плоской карты

This commit is contained in:
2021-07-18 12:15:10 +03:00
parent f280e9beaa
commit ee82930426
14 changed files with 241 additions and 14 deletions

View File

@@ -26,7 +26,7 @@ public final class ChunkSerializeUtil {
for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++) {
Block block = section.getBlock(x, y, z);
int blockState = (block.getId() << 4) | block.getMeta();
int blockState = blockIdMetaSerialize(block.getId(), block.getMeta());
blockArray.put(blockState);
blockLight.put(block.getLight());
@@ -45,4 +45,15 @@ public final class ChunkSerializeUtil {
return result;
}
public static int blockIdMetaSerialize(int id, int meta) {
return (id << 4) | meta;
}
public static int[] blockIdMetaDeserialize(int blockState) {
return new int[]{
blockState >> 4,
blockState & 0b1111
};
}
}

View File

@@ -1,13 +1,13 @@
package mc.protocol.world;
import mc.protocol.model.Location;
import mc.protocol.model.BlockLocation;
public interface Block {
int getId();
int getMeta();
Location getLocation();
BlockLocation getLocation();
int getLight();
void setLight(int value);

View File

@@ -5,6 +5,6 @@ public interface Chunk {
int getX();
int getZ();
ChunkSection getSection(int index);
ChunkSection getSection(int height);
byte getBiome(int x, int z);
}

View File

@@ -1,9 +1,14 @@
package mc.protocol.world;
import mc.protocol.model.BlockLocation;
public interface ChunkSection {
int getY();
Block getBlock(int x, int y, int z);
Block getBlock(BlockLocation blockLocation);
int getSkyLight(int x, int y, int z);
int getSkyLight(BlockLocation blockLocation);
}

View File

@@ -68,7 +68,7 @@ public class Main {
ServerComponent serverComponent = DaggerServerComponent.builder()
.scenarioModule(new ScenarioModule(configComponent.getConfig()))
.worldModule(new WorldModule(configComponent.getConfig()))
.worldModule(new FlatWorldModule(configComponent.getConfig()))
.build();
serverComponent.getPacketScenarios().forEach(scenario -> scenario.setup(serverComponent.getProtocolHandlersBus()));

View File

@@ -0,0 +1,61 @@
package mc.server.di;
import com.typesafe.config.Config;
import mc.protocol.model.Location;
import mc.protocol.utils.ChunkSerializeUtil;
import mc.protocol.world.World;
import mc.server.world.FlatWorld;
import mc.utils.array.BitArray;
import mc.utils.array.BitLongArray;
public class FlatWorldModule extends WorldModule {
public FlatWorldModule(Config config) {
super(config);
}
@Override
World provideWorld() {
String[] rawConfigParts = this.config.getString("world.flat-generator").split(";");
byte biome = Byte.parseByte(rawConfigParts[0]);
return new FlatWorld(spawn(), flatConfig(rawConfigParts), biome);
}
private Location spawn() {
Location spawn = new Location();
spawn.set(
config.getDouble("world.spawn.x"),
config.getDouble("world.spawn.y"),
config.getDouble("world.spawn.z")
);
return spawn;
}
private BitArray flatConfig(String[] rawConfigParts) {
BitArray flatConfig = new BitLongArray(13, 256);
int k = 0;
for (int i = 1; i < rawConfigParts.length; i++) {
String[] part1 = rawConfigParts[i].split(",");
String[] part2 = part1[1].split(":");
int count = Integer.parseInt(part1[0]);
int blockId = Integer.parseInt(part2[0]);
int blockMeta = Integer.parseInt(part2[1]);
k += count;
for (int j = 0; j < count; j++) {
flatConfig.put(ChunkSerializeUtil.blockIdMetaSerialize(blockId, blockMeta));
}
}
if (k < 256) {
for (int i = 0; i < (256 - k); i++) {
flatConfig.put(0);
}
}
return flatConfig;
}
}

View File

@@ -14,7 +14,7 @@ import javax.inject.Singleton;
@RequiredArgsConstructor
public class WorldModule {
private final Config config;
protected final Config config;
@Provides
@Singleton

View File

@@ -0,0 +1,33 @@
package mc.server.world;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import mc.protocol.world.Chunk;
import mc.protocol.world.ChunkSection;
import mc.utils.array.BitArray;
import java.util.HashMap;
import java.util.Map;
@RequiredArgsConstructor
@Getter
public class FlatChunk implements Chunk {
private final Map<Integer, ChunkSection> sections = new HashMap<>();
private final BitArray chunkConfig;
private final int x;
private final int z;
private final byte biome;
@Override
public ChunkSection getSection(int height) {
return sections.computeIfAbsent(height, h -> new FlatChunkSection(chunkConfig, h));
}
@Override
public byte getBiome(int x, int z) {
return biome;
}
}

View File

@@ -0,0 +1,61 @@
package mc.server.world;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import mc.protocol.model.BlockLocation;
import mc.protocol.utils.ChunkSerializeUtil;
import mc.protocol.world.Block;
import mc.protocol.world.ChunkSection;
import mc.utils.array.BitArray;
import java.util.HashMap;
import java.util.Map;
@RequiredArgsConstructor
public class FlatChunkSection implements ChunkSection {
private final Map<Integer, Block> blocks = new HashMap<>();
private final Map<Integer, Integer> sky = new HashMap<>();
private final BitArray chunkConfig;
@Getter
private final int y;
@Override
public Block getBlock(int x, int y, int z) {
return blocks.computeIfAbsent(y, y0 -> {
int blockState = chunkConfig.get((this.y << 4) + y);
int[] blockIdMeta = ChunkSerializeUtil.blockIdMetaDeserialize(blockState);
SomeBlock block = new SomeBlock();
block.setId(blockIdMeta[0]);
block.setMeta(blockIdMeta[1]);
return block;
});
}
@Override
public Block getBlock(BlockLocation blockLocation) {
return getBlock(blockLocation.getX(), blockLocation.getY(), blockLocation.getZ());
}
@Override
public int getSkyLight(int x, int y, int z) {
return sky.computeIfAbsent(y, y0 -> {
int blockState = chunkConfig.get((this.y << 4) + y);
int[] blockIdMeta = ChunkSerializeUtil.blockIdMetaDeserialize(blockState);
if (blockIdMeta[0] != 0/*AIR*/) {
return 0;
} else {
return 15;
}
});
}
@Override
public int getSkyLight(BlockLocation blockLocation) {
return getSkyLight(blockLocation.getX(), blockLocation.getY(), blockLocation.getZ());
}
}

View File

@@ -0,0 +1,46 @@
package mc.server.world;
import lombok.RequiredArgsConstructor;
import mc.protocol.model.ChunkSectionLocation;
import mc.protocol.model.Location;
import mc.protocol.utils.LevelType;
import mc.protocol.world.Chunk;
import mc.protocol.world.World;
import mc.utils.Table;
import mc.utils.array.BitArray;
@RequiredArgsConstructor
public class FlatWorld implements World {
private final Table<Integer, Integer, Chunk> chunkTable = new Table<>();
private final Location spawn;
private final BitArray flatConfig;
private final byte biome;
@Override
public LevelType getLevelType() {
return LevelType.FLAT;
}
@Override
public Location getSpawn() {
return this.spawn;
}
@Override
public Chunk getChunk(int x, int z) {
Chunk chunk = chunkTable.getColumnAndRow(x, z);
if (chunk == null) {
chunk = new FlatChunk(flatConfig, x, z, biome);
chunkTable.put(x, z, chunk);
}
return chunk;
}
@Override
public Chunk getChunk(ChunkSectionLocation chunkSectionLocation) {
return getChunk(chunkSectionLocation.getX(), chunkSectionLocation.getZ());
}
}

View File

@@ -1,7 +1,7 @@
package mc.server.world;
import lombok.Data;
import mc.protocol.model.Location;
import mc.protocol.model.BlockLocation;
import mc.protocol.world.Block;
@Data
@@ -10,5 +10,5 @@ public class SomeBlock implements Block {
private int id;
private int meta;
private int light;
private Location location;
private BlockLocation location;
}

View File

@@ -2,6 +2,7 @@ package mc.server.world;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import mc.protocol.model.BlockLocation;
import mc.protocol.model.Location;
import mc.protocol.world.Block;
import mc.protocol.world.ChunkSection;
@@ -24,7 +25,6 @@ public class SomeChunkSection implements ChunkSection {
location1.set(x, y, z);
return blocks.computeIfAbsent(location1, location -> {
SomeBlock block = new SomeBlock();
block.setLocation(location);
block.setId(3);
return block;
});
@@ -33,7 +33,6 @@ public class SomeChunkSection implements ChunkSection {
location1.set(x, y, z);
return blocks.computeIfAbsent(location1, location -> {
SomeBlock block = new SomeBlock();
block.setLocation(location);
block.setId(0);
return block;
});
@@ -43,13 +42,17 @@ public class SomeChunkSection implements ChunkSection {
location1.set(x, y, z);
return blocks.computeIfAbsent(location1, location -> {
SomeBlock block = new SomeBlock();
block.setLocation(location);
block.setId(1);
return block;
});
}
}
@Override
public Block getBlock(BlockLocation blockLocation) {
return getBlock(blockLocation.getX(), blockLocation.getY(), blockLocation.getZ());
}
@Override
public int getSkyLight(int x, int y, int z) {
if (this.y == 15 && y != 0) {
@@ -59,4 +62,9 @@ public class SomeChunkSection implements ChunkSection {
}
}
@Override
public int getSkyLight(BlockLocation blockLocation) {
return getSkyLight(blockLocation.getX(), blockLocation.getY(), blockLocation.getZ());
}
}

View File

@@ -29,4 +29,6 @@ world {
y: 256
z: -247
}
// biome_id;count,id:meta;count,id:meta;...
flat-generator: "1;240,1:0;1,2:0"
}

View File

@@ -1,12 +1,12 @@
package mc.utils.pool;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class PassivableMultiObjectPool<T extends Passivable> implements MultiObjectPool<T> {
@SuppressWarnings("rawtypes")
private final Map<Class, ObjectPool> mapPool = new HashMap<>();
private final ConcurrentMap<Class, ObjectPool> mapPool = new ConcurrentHashMap<>();
@SuppressWarnings("unchecked")
@Override