refactory world and clean classes
This commit is contained in:
10
build.gradle
10
build.gradle
@@ -59,13 +59,13 @@ task runApp(type: JavaExec) {
|
|||||||
classpath += prj.sourceSets.main.runtimeClasspath
|
classpath += prj.sourceSets.main.runtimeClasspath
|
||||||
}
|
}
|
||||||
/* Uncomment, if your Log Implements are folder '{workDir}/log-impl' */
|
/* Uncomment, if your Log Implements are folder '{workDir}/log-impl' */
|
||||||
//classpath += files(fileTree(dir: new File(workingDir, "log-impl")))
|
classpath += files(fileTree(dir: new File(workingDir, "log-impl")))
|
||||||
|
|
||||||
/* Uncomment, if you used VM args */
|
/* Uncomment, if you used VM args */
|
||||||
//jvmArgs = [
|
jvmArgs = [
|
||||||
// "-DspringConfig=app.xml",
|
"-DspringConfig=spring-flat.xml",
|
||||||
// "-Dlog4j.configurationFile=log4j2.xml"
|
"-Dlog4j.configurationFile=log4j2.xml"
|
||||||
//]
|
]
|
||||||
|
|
||||||
ignoreExitValue = true
|
ignoreExitValue = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
package mc.core;
|
|
||||||
|
|
||||||
public enum Direction {
|
|
||||||
NORTH,
|
|
||||||
EAST,
|
|
||||||
WEST,
|
|
||||||
SOUTH
|
|
||||||
}
|
|
||||||
@@ -11,11 +11,10 @@ import mc.core.world.World;
|
|||||||
import mc.core.world.chunk.Chunk;
|
import mc.core.world.chunk.Chunk;
|
||||||
import mc.core.world.chunk.ChunkSection;
|
import mc.core.world.chunk.ChunkSection;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.lang.ref.Reference;
|
import java.lang.ref.Reference;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
public class Location implements Serializable, Cloneable {
|
public class Location implements Cloneable {
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
private double x, y, z;
|
private double x, y, z;
|
||||||
@@ -63,21 +62,20 @@ public class Location implements Serializable, Cloneable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Chunk getChunk() {
|
public Chunk getChunk() {
|
||||||
World world;
|
World world = getWorld();
|
||||||
if ((world = getWorld()) == null) {
|
if (world == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return world.getRegion((int) (x / 256), (int) (z / 256))
|
return world.getChunk((int)(x / 16), (int)(z / 16));
|
||||||
.getChunk((int) ((x % 256) / 16), (int) ((z % 256) / 16));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkSection getChunkSection() {
|
public ChunkSection getChunkSection() {
|
||||||
World world;
|
Chunk chunk = getChunk();
|
||||||
if ((world = getWorld()) == null) {
|
if (chunk == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return world.getChunk(getBlockX(), getBlockY(), getBlockZ());
|
return chunk.getChunkSection((int)(y / 16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
package mc.core.serialization;
|
|
||||||
|
|
||||||
import mc.core.world.Region;
|
|
||||||
import mc.core.world.chunk.ChunkSection;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public interface IChunkReader {
|
|
||||||
ChunkSection read (Region region, int x, int y, int z) throws IOException;
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package mc.core.serialization;
|
|
||||||
|
|
||||||
import mc.core.world.Region;
|
|
||||||
import mc.core.world.World;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public interface IRegionReaderWriter {
|
|
||||||
|
|
||||||
Region read (int x, int z, World world) throws IOException;
|
|
||||||
void write (Region region) throws IOException;
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
package mc.core.world;
|
|
||||||
|
|
||||||
public interface IWorldType {
|
|
||||||
String name();
|
|
||||||
String description();
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package mc.core.world;
|
|
||||||
|
|
||||||
import mc.core.serialization.IRegionReaderWriter;
|
|
||||||
import mc.core.serialization.Serializer;
|
|
||||||
import mc.core.world.chunk.Chunk;
|
|
||||||
import mc.core.world.chunk.ChunkSection;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple world generation unit
|
|
||||||
* 16x16x16 chunks
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* +-------------+----------------+------------+
|
|
||||||
* | param | range | bits |
|
|
||||||
* +-------------+----------------+------------+
|
|
||||||
* | biome_map | 256x256 0-128 | 524288 |
|
|
||||||
* +-------------+----------------+------------+
|
|
||||||
*
|
|
||||||
* Total: 524288 bits (64 Kb)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface Region extends Serializable{
|
|
||||||
Chunk getChunk (int x, int z);
|
|
||||||
void setChunk(int x, int z, Chunk chunk);
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
ChunkSection getChunkAt(int x, int y, int z);
|
|
||||||
@Deprecated
|
|
||||||
void setChunk(int x, int y, int z, ChunkSection chunkSection);
|
|
||||||
|
|
||||||
int getX();
|
|
||||||
int getZ();
|
|
||||||
|
|
||||||
Biome getBiomeAt (int x, int z);
|
|
||||||
void setBiome (int x, int z, Biome biome);
|
|
||||||
|
|
||||||
World getWorld();
|
|
||||||
|
|
||||||
void save(Serializer<ChunkSection> chunkSerializer, IRegionReaderWriter regionReaderWritter) throws IOException;
|
|
||||||
}
|
|
||||||
@@ -5,58 +5,14 @@
|
|||||||
package mc.core.world;
|
package mc.core.world;
|
||||||
|
|
||||||
import mc.core.EntityLocation;
|
import mc.core.EntityLocation;
|
||||||
import mc.core.nbt.Taggable;
|
import mc.core.world.chunk.Chunk;
|
||||||
import mc.core.world.chunk.ChunkSection;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
public interface World {
|
||||||
import java.util.UUID;
|
WorldType getWorldType();
|
||||||
|
|
||||||
/**
|
|
||||||
* WorldInfo
|
|
||||||
* +-------------+----------------+------------+
|
|
||||||
* | param | range | bits |
|
|
||||||
* +-------------+----------------+------------+
|
|
||||||
* | worldId | uuid | 128 |
|
|
||||||
* +-------------+----------------+------------+
|
|
||||||
* | worldName | string [0-64] | 512 |
|
|
||||||
* +-------------+----------------+------------+
|
|
||||||
* | spawnX | -524288:524287 | 20 |
|
|
||||||
* +-------------+----------------+------------+
|
|
||||||
* | spawnY | 0:255 | 8 |
|
|
||||||
* +-------------+----------------+------------+
|
|
||||||
* | spawnZ | -524288:524287 | 20 |
|
|
||||||
* +-------------+----------------+------------+
|
|
||||||
* | seed | long | 64 |
|
|
||||||
* +-------------+----------------+------------+
|
|
||||||
* | type | 0-255 | 8 |
|
|
||||||
* +-------------+----------------+------------+
|
|
||||||
*
|
|
||||||
* /worlds/
|
|
||||||
* --> []/world_uuid/
|
|
||||||
* --> world.dat
|
|
||||||
* --> []/r.X.Z/
|
|
||||||
* --> biomes.dat
|
|
||||||
* --> []chunk_x_y_z.dat
|
|
||||||
* --> entities.dat
|
|
||||||
* --> /playerdata/
|
|
||||||
* --> []player_uuid.dat
|
|
||||||
*/
|
|
||||||
|
|
||||||
public interface World extends Taggable, Serializable{
|
|
||||||
UUID getWorldId();
|
|
||||||
IWorldType getWorldType();
|
|
||||||
|
|
||||||
EntityLocation getSpawn();
|
EntityLocation getSpawn();
|
||||||
void setSpawn(EntityLocation location);
|
void setSpawn(EntityLocation location);
|
||||||
|
|
||||||
ChunkSection getChunk(int x, int y, int z);
|
Chunk getChunk(int x, int z);
|
||||||
void setChunk(int x, int y, int z, ChunkSection chunkSection);
|
void setChunk(int x, int z, Chunk chunkSection);
|
||||||
|
|
||||||
Region getRegion(int x, int z);
|
|
||||||
void setRegion(int x, int z, Region region);
|
|
||||||
|
|
||||||
int getSeed();
|
|
||||||
|
|
||||||
String getName();
|
|
||||||
void setName(String name);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
package mc.core.world;
|
|
||||||
|
|
||||||
public interface WorldGenerator {
|
|
||||||
|
|
||||||
Region generateRegion (int x, int z, World world);
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,13 @@
|
|||||||
package mc.core.world;
|
package mc.core.world;
|
||||||
|
|
||||||
public enum WorldType implements IWorldType {
|
import lombok.Getter;
|
||||||
GENERAL("Standard world type"),
|
import lombok.RequiredArgsConstructor;
|
||||||
NETHER ("Nether world type"),
|
|
||||||
END ("End world type");
|
|
||||||
|
|
||||||
private final String description;
|
@RequiredArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public enum WorldType {
|
||||||
|
DEFAULT("default"),
|
||||||
|
FLAT("flat");
|
||||||
|
|
||||||
WorldType(String description) {
|
private final String name;
|
||||||
this.description = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String description() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,7 @@ public abstract class AbstractBlock implements Block {
|
|||||||
@Setter
|
@Setter
|
||||||
private Location location;
|
private Location location;
|
||||||
@Getter
|
@Getter
|
||||||
private int meta;
|
private int light = 15;
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private int light = 0; //TODO need to know range of values
|
|
||||||
@Getter
|
@Getter
|
||||||
private final BlockType blockType;
|
private final BlockType blockType;
|
||||||
private final Map<String, Tag<?>> nbtTagsMap = new HashMap<>();
|
private final Map<String, Tag<?>> nbtTagsMap = new HashMap<>();
|
||||||
@@ -26,14 +23,11 @@ public abstract class AbstractBlock implements Block {
|
|||||||
this.blockType = type;
|
this.blockType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AbstractBlock(BlockType type, int meta) {
|
|
||||||
this.blockType = type;
|
|
||||||
this.meta = meta;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getId() {
|
public void setLight(int light) {
|
||||||
return blockType.getId();
|
if (light > 15) this.light = 15;
|
||||||
|
else if (light < 0) this.light = 0;
|
||||||
|
else this.light = light;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -3,50 +3,9 @@ package mc.core.world.block;
|
|||||||
import mc.core.Location;
|
import mc.core.Location;
|
||||||
import mc.core.nbt.Taggable;
|
import mc.core.nbt.Taggable;
|
||||||
|
|
||||||
import java.io.Serializable;
|
public interface Block extends Taggable{
|
||||||
|
|
||||||
/**
|
|
||||||
* Serialization block info
|
|
||||||
*
|
|
||||||
* +------------+--------+------------+
|
|
||||||
* | param | range | bits |
|
|
||||||
* +------------+--------+------------+
|
|
||||||
* | id | 0:255 | 8 |
|
|
||||||
* +------------+--------+------------+
|
|
||||||
* | meta | 0:15 | 4 |
|
|
||||||
* +------------+--------+------------+
|
|
||||||
* | x | 0:15 | 4 |
|
|
||||||
* +------------+--------+------------+
|
|
||||||
* | y | 0:15 | 4 |
|
|
||||||
* +------------+--------+------------+
|
|
||||||
* | z | 0:15 | 4 |
|
|
||||||
* +------------+--------+------------+
|
|
||||||
*
|
|
||||||
* Total: 24 bits per block (3 bytes)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
public interface Block extends Taggable, Serializable{
|
|
||||||
|
|
||||||
/** Block id */
|
|
||||||
int getId();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Addition in 0-15
|
|
||||||
* F.e. 35:0 - white wool
|
|
||||||
* 35:15 - black wool
|
|
||||||
*/
|
|
||||||
int getMeta();
|
|
||||||
|
|
||||||
int getLight();
|
int getLight();
|
||||||
void setLight(int light);
|
void setLight(int light);
|
||||||
|
|
||||||
/**
|
|
||||||
* Getting block type
|
|
||||||
*/
|
|
||||||
BlockType getBlockType();
|
BlockType getBlockType();
|
||||||
|
|
||||||
/** Block location */
|
|
||||||
Location getLocation();
|
Location getLocation();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,19 @@
|
|||||||
package mc.core.world.block;
|
package mc.core.world.block;
|
||||||
|
|
||||||
import mc.core.Location;
|
import mc.core.Location;
|
||||||
|
import mc.core.world.World;
|
||||||
|
|
||||||
public class BlockFactory {
|
public class BlockFactory {
|
||||||
|
|
||||||
public Block create(BlockType blockType, int meta, int x, int y, int z) {
|
public Block create(BlockType blockType, int x, int y, int z, World world) {
|
||||||
return new EmbeddedBlock(blockType, meta, x, y, z);
|
return new EmbeddedBlock(blockType, x, y, z, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Block create(BlockType blockType, int meta) {
|
/** For first-time generation */
|
||||||
return new EmbeddedBlock(blockType, meta, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Block create(BlockType blockType) {
|
|
||||||
return create(blockType, 0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For first-time generation
|
|
||||||
*/
|
|
||||||
private class EmbeddedBlock extends AbstractBlock {
|
private class EmbeddedBlock extends AbstractBlock {
|
||||||
EmbeddedBlock(BlockType type, int meta, int x, int y, int z) {
|
EmbeddedBlock(BlockType type, int x, int y, int z, World world) {
|
||||||
super(type, meta);
|
super(type);
|
||||||
super.setLocation(new Location(x,y,z, null));
|
setLocation(new Location(x,y,z, world));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,31 @@
|
|||||||
package mc.core.world.block;
|
package mc.core.world.block;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
public enum BlockType {
|
public enum BlockType {
|
||||||
AIR(0, "Air"),
|
AIR(0, 0),
|
||||||
STONE(1, "Stone"),
|
STONE(1, 0),
|
||||||
GRASS(2, "Grass"),
|
GRASS(2, 0),
|
||||||
DIRT(3, "Dirt"),
|
DIRT(3, 0),
|
||||||
BEDROCK(7, "Bedrock"),
|
BEDROCK(7, 0),
|
||||||
WATER(8, "Water"),
|
WATER(9, 0),
|
||||||
SAND(12, "Sand"),
|
SAND(12, 0),
|
||||||
SNOW(32, "Snow");
|
SNOW(78, 0);
|
||||||
|
|
||||||
|
public static BlockType getByIdMeta(int id, int meta) {
|
||||||
|
Stream<BlockType> stream = Arrays.stream(BlockType.values());
|
||||||
|
return stream.filter(blockType -> blockType.id == id && blockType.meta == meta)
|
||||||
|
.findFirst()
|
||||||
|
.orElse(BlockType.AIR);
|
||||||
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final int id;
|
private final int id;
|
||||||
@Getter
|
@Getter
|
||||||
private final String name;
|
private final int meta;
|
||||||
|
|
||||||
BlockType(int id, String name) {
|
|
||||||
this.id = id;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
package mc.core.world.chunk;
|
package mc.core.world.chunk;
|
||||||
|
|
||||||
import mc.core.world.Region;
|
import mc.core.world.Biome;
|
||||||
import mc.core.world.World;
|
import mc.core.world.World;
|
||||||
|
|
||||||
public interface Chunk {
|
public interface Chunk {
|
||||||
|
|
||||||
World getWorld();
|
|
||||||
ChunkSection getChunkSection(int height);
|
|
||||||
ChunkSection setChunkSection(int height, ChunkSection chunkSection);
|
|
||||||
Region getRegion();
|
|
||||||
|
|
||||||
int getX();
|
int getX();
|
||||||
int getZ();
|
int getZ();
|
||||||
|
|
||||||
|
ChunkSection getChunkSection(int height);
|
||||||
|
void setChunkSection(int height, ChunkSection chunkSection);
|
||||||
|
|
||||||
|
Biome getBiome(int localX, int localZ);
|
||||||
|
void setBiome(int localX, int localZ, Biome biome);
|
||||||
|
|
||||||
|
World getWorld();
|
||||||
|
void setWorld(World world);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
package mc.core.world.chunk;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public interface ChunkLoader {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads chunk from cache. If chunk in cache doesn't exist, loads from file (or other storage)
|
|
||||||
*
|
|
||||||
* @param x chunk position
|
|
||||||
* @param y chunk position
|
|
||||||
* @param z chunk position
|
|
||||||
* @return optional of chunk (nullable)
|
|
||||||
*/
|
|
||||||
Optional<ChunkSection> loadChunk (int x, int y, int z);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tries to load chunk like {@link #loadChunk(int, int, int)}
|
|
||||||
* If chunk doesn't exist, generates it with selected world generator
|
|
||||||
*
|
|
||||||
* @param x chunk position
|
|
||||||
* @param y chunk position
|
|
||||||
* @param z chunk position
|
|
||||||
* @return chunk
|
|
||||||
*/
|
|
||||||
ChunkSection loadOrGenerateChunk (int x, int y, int z);
|
|
||||||
}
|
|
||||||
@@ -4,38 +4,11 @@
|
|||||||
*/
|
*/
|
||||||
package mc.core.world.chunk;
|
package mc.core.world.chunk;
|
||||||
|
|
||||||
import mc.core.world.Biome;
|
|
||||||
import mc.core.world.Region;
|
|
||||||
import mc.core.world.World;
|
import mc.core.world.World;
|
||||||
import mc.core.world.block.Block;
|
import mc.core.world.block.Block;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Serialization chunk info
|
|
||||||
*
|
|
||||||
* +-------------+----------------+------------+
|
|
||||||
* | param | range | bits |
|
|
||||||
* +-------------+----------------+------------+
|
|
||||||
* | blocks | array | 24*count |
|
|
||||||
* +-------------+----------------+------------+
|
|
||||||
*
|
|
||||||
* Total: 24 * block_count bits (3 * block_count bytes)
|
|
||||||
* Max size: 12288 bytes (~12 Kb per chunk)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/* 16x16x16 */
|
/* 16x16x16 */
|
||||||
public interface ChunkSection extends Serializable{
|
public interface ChunkSection {
|
||||||
|
|
||||||
int getSkyLight(int x, int y, int z);
|
|
||||||
void setSkyLight(int x, int y, int z, int lightLevel);
|
|
||||||
|
|
||||||
int getAddition(int x, int y, int z);
|
|
||||||
void setAddition(int x, int y, int z, int value);
|
|
||||||
|
|
||||||
Biome getBiome(int x, int z);
|
|
||||||
void setBiome(int x, int z, Biome biome);
|
|
||||||
|
|
||||||
int getX();
|
int getX();
|
||||||
int getY();
|
int getY();
|
||||||
int getZ();
|
int getZ();
|
||||||
@@ -43,6 +16,11 @@ public interface ChunkSection extends Serializable{
|
|||||||
void setBlock(Block block);
|
void setBlock(Block block);
|
||||||
Block getBlock(int x, int y, int z);
|
Block getBlock(int x, int y, int z);
|
||||||
|
|
||||||
Region getRegion();
|
int getSkyLight(int x, int y, int z);
|
||||||
|
void setSkyLight(int x, int y, int z, int lightLevel);
|
||||||
|
|
||||||
|
int getAddition(int x, int y, int z);
|
||||||
|
void setAddition(int x, int y, int z, int value);
|
||||||
|
|
||||||
World getWorld();
|
World getWorld();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,17 @@
|
|||||||
package mc.core;
|
package mc.core;
|
||||||
|
|
||||||
import com.flowpowered.nbt.Tag;
|
|
||||||
import mc.core.world.IWorldType;
|
|
||||||
import mc.core.world.Region;
|
|
||||||
import mc.core.world.World;
|
import mc.core.world.World;
|
||||||
import mc.core.world.chunk.ChunkSection;
|
import mc.core.world.WorldType;
|
||||||
|
import mc.core.world.chunk.Chunk;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.UUID;
|
public class TestEntityLocation {
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class EntityLocationTest {
|
|
||||||
@Test
|
@Test
|
||||||
public void cloneTest() {
|
public void cloneTest() {
|
||||||
World dummyWorld = new World() {
|
World dummyWorld = new World() {
|
||||||
@Override
|
@Override
|
||||||
public UUID getWorldId() {
|
public WorldType getWorldType() {
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IWorldType getWorldType() {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,54 +26,14 @@ public class EntityLocationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChunkSection getChunk(int x, int y, int z) {
|
public Chunk getChunk(int x, int z) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setChunk(int x, int y, int z, ChunkSection chunkSection) {
|
public void setChunk(int x, int z, Chunk chunk) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Region getRegion(int x, int z) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRegion(int x, int z, Region region) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSeed() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setName(String name) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Tag<?> getTag(String name) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setTag(Tag<?> tag) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<Tag<?>> tagStream() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
EntityLocation firstLocation = new EntityLocation(10, 20, 30, 40, 50, dummyWorld);
|
EntityLocation firstLocation = new EntityLocation(10, 20, 30, 40, 50, dummyWorld);
|
||||||
@@ -4,38 +4,21 @@
|
|||||||
*/
|
*/
|
||||||
package mc.world.flat;
|
package mc.world.flat;
|
||||||
|
|
||||||
import com.flowpowered.nbt.Tag;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import mc.core.EntityLocation;
|
import mc.core.EntityLocation;
|
||||||
import mc.core.world.IWorldType;
|
|
||||||
import mc.core.world.Region;
|
|
||||||
import mc.core.world.World;
|
import mc.core.world.World;
|
||||||
import mc.core.world.WorldType;
|
import mc.core.world.WorldType;
|
||||||
|
import mc.core.world.chunk.Chunk;
|
||||||
import mc.core.world.chunk.ChunkSection;
|
import mc.core.world.chunk.ChunkSection;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class FlatWorld implements World {
|
public class FlatWorld implements World {
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
private final WorldType worldType = WorldType.FLAT;
|
||||||
private UUID worldId = UUID.fromString("00000000-0000-0000-C000-000000000046");
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
private EntityLocation spawn;
|
private EntityLocation spawn;
|
||||||
private ChunkSection chunkSection = new SimpleChunkSection();
|
private ChunkSection chunkSection = new SimpleChunkSection();
|
||||||
|
|
||||||
@Override
|
|
||||||
public IWorldType getWorldType() {
|
|
||||||
return WorldType.GENERAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityLocation getSpawn() {
|
public EntityLocation getSpawn() {
|
||||||
if (this.spawn == null) {
|
if (this.spawn == null) {
|
||||||
@@ -53,42 +36,14 @@ public class FlatWorld implements World {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChunkSection getChunk(int x, int y, int z) {
|
public Chunk getChunk(int x, int z) {
|
||||||
return chunkSection;
|
Chunk chunk = new SimpleChunk(x, z, this);
|
||||||
|
chunk.setChunkSection(0, chunkSection);
|
||||||
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setChunk(int x, int y, int z, ChunkSection chunkSection) {
|
public void setChunk(int x, int z, Chunk chunk) {
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Region getRegion(int x, int z) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRegion(int x, int z, Region region) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSeed() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Tag<?> getTag(String name) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setTag(Tag<?> tag) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<Tag<?>> tagStream() {
|
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
61
flat_world/src/main/java/mc/world/flat/SimpleChunk.java
Normal file
61
flat_world/src/main/java/mc/world/flat/SimpleChunk.java
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
package mc.world.flat;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import mc.core.world.Biome;
|
||||||
|
import mc.core.world.World;
|
||||||
|
import mc.core.world.chunk.Chunk;
|
||||||
|
import mc.core.world.chunk.ChunkSection;
|
||||||
|
|
||||||
|
import java.lang.ref.Reference;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class SimpleChunk implements Chunk {
|
||||||
|
@Getter
|
||||||
|
private int x, z;
|
||||||
|
private Reference<World> refWorld;
|
||||||
|
private ChunkSection chunkSection;
|
||||||
|
private final Biome biome = Biome.PLAINS;
|
||||||
|
|
||||||
|
public SimpleChunk(int x, int z, World world) {
|
||||||
|
this.x = x;
|
||||||
|
this.z = z;
|
||||||
|
setWorld(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChunkSection getChunkSection(int height) {
|
||||||
|
return chunkSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setChunkSection(int height, ChunkSection chunkSection) {
|
||||||
|
this.chunkSection = chunkSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome getBiome(int localX, int localZ) {
|
||||||
|
return biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBiome(int localX, int localZ, Biome biome) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public World getWorld() {
|
||||||
|
if (refWorld.get() == null) {
|
||||||
|
log.error("World unloaded?");
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return refWorld.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setWorld(World world) {
|
||||||
|
this.refWorld = new WeakReference<>(world);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,8 +4,6 @@
|
|||||||
*/
|
*/
|
||||||
package mc.world.flat;
|
package mc.world.flat;
|
||||||
|
|
||||||
import mc.core.world.Biome;
|
|
||||||
import mc.core.world.Region;
|
|
||||||
import mc.core.world.World;
|
import mc.core.world.World;
|
||||||
import mc.core.world.block.Block;
|
import mc.core.world.block.Block;
|
||||||
import mc.core.world.block.BlockFactory;
|
import mc.core.world.block.BlockFactory;
|
||||||
@@ -34,16 +32,6 @@ public class SimpleChunkSection implements ChunkSection {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Biome getBiome(int x, int z) {
|
|
||||||
return Biome.PLAINS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBiome(int x, int z, Biome biome) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getX() {
|
public int getX() {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -68,15 +56,10 @@ public class SimpleChunkSection implements ChunkSection {
|
|||||||
public Block getBlock(int x, int y, int z) {
|
public Block getBlock(int x, int y, int z) {
|
||||||
BlockFactory blockFactory = new BlockFactory();
|
BlockFactory blockFactory = new BlockFactory();
|
||||||
|
|
||||||
if (y == 0) return blockFactory.create(BlockType.BEDROCK, 0);
|
if (y == 0) return blockFactory.create(BlockType.BEDROCK, x, y, z, getWorld());
|
||||||
else if (y >= 1 && y <= 2) return blockFactory.create(BlockType.DIRT, 0);
|
else if (y >= 1 && y <= 2) return blockFactory.create(BlockType.DIRT, x, y, z, getWorld());
|
||||||
else if (y == 3) return blockFactory.create(BlockType.GRASS, 0);
|
else if (y == 3) return blockFactory.create(BlockType.GRASS, x, y, z, getWorld());
|
||||||
else return blockFactory.create(BlockType.AIR, 0);
|
else return blockFactory.create(BlockType.AIR, x, y, z, getWorld());
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Region getRegion() {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import mc.core.network.NetOutputStream;
|
|||||||
import mc.core.network.SCPacket;
|
import mc.core.network.SCPacket;
|
||||||
import mc.core.network.proto_1_12_2.ByteArrayOutputNetStream;
|
import mc.core.network.proto_1_12_2.ByteArrayOutputNetStream;
|
||||||
import mc.core.world.block.Block;
|
import mc.core.world.block.Block;
|
||||||
|
import mc.core.world.block.BlockType;
|
||||||
|
import mc.core.world.chunk.Chunk;
|
||||||
import mc.core.world.chunk.ChunkSection;
|
import mc.core.world.chunk.ChunkSection;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -75,11 +77,11 @@ public class ChunkDataPacket implements SCPacket {
|
|||||||
private int z;
|
private int z;
|
||||||
@Setter
|
@Setter
|
||||||
private boolean initChunk = true; // "Ground-Up Continuous"
|
private boolean initChunk = true; // "Ground-Up Continuous"
|
||||||
@Getter
|
@Setter
|
||||||
private List<ChunkSection> chunks = new ArrayList<>();
|
private Chunk chunk;
|
||||||
|
|
||||||
private int serializeBlockState(int id, int meta) {
|
private int serializeBlockState(BlockType blockType) {
|
||||||
return (id << 4) | meta;
|
return (blockType.getId() << 4) | blockType.getMeta();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -91,9 +93,14 @@ public class ChunkDataPacket implements SCPacket {
|
|||||||
|
|
||||||
final ByteArrayOutputNetStream data = new ByteArrayOutputNetStream();
|
final ByteArrayOutputNetStream data = new ByteArrayOutputNetStream();
|
||||||
int dataItems = 0;
|
int dataItems = 0;
|
||||||
final int airBlockPalette = serializeBlockState(0, 0);
|
final int airBlockPalette = serializeBlockState(BlockType.AIR);
|
||||||
|
|
||||||
|
for (int h = 0; h < 1/*потому что у нас пока только единичная сейция*/; h++) {
|
||||||
|
ChunkSection chunkSection = chunk.getChunkSection(h);
|
||||||
|
if (chunkSection == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (ChunkSection chunk : chunks) {
|
|
||||||
final List<Integer> palette = new ArrayList<>();
|
final List<Integer> palette = new ArrayList<>();
|
||||||
palette.add(airBlockPalette);
|
palette.add(airBlockPalette);
|
||||||
final ByteArrayOutputNetStream dataArray = new ByteArrayOutputNetStream();
|
final ByteArrayOutputNetStream dataArray = new ByteArrayOutputNetStream();
|
||||||
@@ -112,8 +119,8 @@ public class ChunkDataPacket implements SCPacket {
|
|||||||
for (int y = 0; y < 16; y++) {
|
for (int y = 0; y < 16; y++) {
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = 0; z < 16; z++) {
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
Block block = chunk.getBlock(x, y, z);
|
Block block = chunkSection.getBlock(x, y, z);
|
||||||
int blockState = serializeBlockState(block.getId(), block.getMeta());
|
int blockState = serializeBlockState(block.getBlockType());
|
||||||
|
|
||||||
int currentIndexPaletteBlock;
|
int currentIndexPaletteBlock;
|
||||||
if (!palette.contains(blockState)) {
|
if (!palette.contains(blockState)) {
|
||||||
@@ -138,12 +145,12 @@ public class ChunkDataPacket implements SCPacket {
|
|||||||
|
|
||||||
if (idxHalfByte == 0) {
|
if (idxHalfByte == 0) {
|
||||||
blockLightCompacted = block.getLight();
|
blockLightCompacted = block.getLight();
|
||||||
skyLightCompacted = chunk.getSkyLight(x, y, z);
|
skyLightCompacted = chunkSection.getSkyLight(x, y, z);
|
||||||
idxHalfByte++;
|
idxHalfByte++;
|
||||||
} else {
|
} else {
|
||||||
blockLightCompacted = (blockLightCompacted << 4) | block.getLight();
|
blockLightCompacted = (blockLightCompacted << 4) | block.getLight();
|
||||||
blockLight.writeByte(blockLightCompacted);
|
blockLight.writeByte(blockLightCompacted);
|
||||||
skyLightCompacted = (skyLightCompacted << 4) | chunk.getSkyLight(x, y, z);
|
skyLightCompacted = (skyLightCompacted << 4) | chunkSection.getSkyLight(x, y, z);
|
||||||
skyLight.writeByte(skyLightCompacted);
|
skyLight.writeByte(skyLightCompacted);
|
||||||
idxHalfByte = 0;
|
idxHalfByte = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import mc.core.network.proto_1_12_2.TeleportManager;
|
|||||||
import mc.core.network.proto_1_12_2.packets.ChunkDataPacket;
|
import mc.core.network.proto_1_12_2.packets.ChunkDataPacket;
|
||||||
import mc.core.network.proto_1_12_2.packets.PlayerPositionAndLookPacket;
|
import mc.core.network.proto_1_12_2.packets.PlayerPositionAndLookPacket;
|
||||||
import mc.core.utils.CompactedCoords;
|
import mc.core.utils.CompactedCoords;
|
||||||
|
import mc.core.world.chunk.Chunk;
|
||||||
import mc.core.world.chunk.ChunkSection;
|
import mc.core.world.chunk.ChunkSection;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -29,13 +30,13 @@ class PlayerEventListener {
|
|||||||
|
|
||||||
for(Integer compressXZ : event.getNeedLoadChunks()) {
|
for(Integer compressXZ : event.getNeedLoadChunks()) {
|
||||||
int[] xz = CompactedCoords.uncompressXZ(compressXZ);
|
int[] xz = CompactedCoords.uncompressXZ(compressXZ);
|
||||||
ChunkSection chunkSection = event.getPlayer().getLocation().getWorld().getChunk(xz[0], 0, xz[1]);
|
Chunk chunk = event.getPlayer().getLocation().getWorld().getChunk(xz[0], xz[1]);
|
||||||
|
|
||||||
ChunkDataPacket packet = new ChunkDataPacket();
|
ChunkDataPacket packet = new ChunkDataPacket();
|
||||||
packet.setX(xz[0]);
|
packet.setX(xz[0]);
|
||||||
packet.setZ(xz[1]);
|
packet.setZ(xz[1]);
|
||||||
packet.setInitChunk(true);
|
packet.setInitChunk(true);
|
||||||
packet.getChunks().add(chunkSection);
|
packet.setChunk(chunk);
|
||||||
|
|
||||||
event.getPlayer().getChannel().write(packet);
|
event.getPlayer().getChannel().write(packet);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ public class LoginHandler extends AbstractStateHandler implements LoginStateHand
|
|||||||
ChunkDataPacket pkt8 = new ChunkDataPacket();
|
ChunkDataPacket pkt8 = new ChunkDataPacket();
|
||||||
pkt8.setX(0);
|
pkt8.setX(0);
|
||||||
pkt8.setZ(0);
|
pkt8.setZ(0);
|
||||||
pkt8.getChunks().add(world.getChunk(0, 0,0));
|
pkt8.setChunk(world.getChunk(0, 0));
|
||||||
pkt8.setInitChunk(true);
|
pkt8.setInitChunk(true);
|
||||||
channel.writeAndFlush(pkt8);
|
channel.writeAndFlush(pkt8);
|
||||||
player.getLoadedChunks().add(CompactedCoords.compressXZ(0, 0));
|
player.getLoadedChunks().add(CompactedCoords.compressXZ(0, 0));
|
||||||
|
|||||||
Reference in New Issue
Block a user