From 48de3a50498f2d056ecb95dbc1d3902990e5baeb Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Tue, 25 Dec 2018 14:55:14 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BC=D0=B5=D0=BB=D0=BA=D0=B8=D0=B9=20=D1=80?= =?UTF-8?q?=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE=D1=80=D0=B8=D0=BD=D0=B3=20?= =?UTF-8?q?+=20=D1=83=D0=BA=D0=B0=D0=B7=D1=8B=D0=B2=D0=B0=D0=B5=D0=BC=20?= =?UTF-8?q?=D1=82=D0=BE=D1=87=D0=BD=D0=BE=20=D0=B3=D0=B4=D0=B5=20=D0=BB?= =?UTF-8?q?=D0=BE=D0=BA=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5,=20=D0=B0=20?= =?UTF-8?q?=D0=B3=D0=B4=D0=B5=20=D0=B3=D0=BB=D0=BE=D0=B1=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D1=8B=D0=B5=20=D0=BA=D0=BE=D0=BE=D1=80=D0=B4=D0=B8=D0=BD?= =?UTF-8?q?=D0=B0=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/mc/core/CoreEventListener.java | 4 +- .../src/main/java/mc/core/EntityLocation.java | 5 ++ core/src/main/java/mc/core/world/World.java | 39 ++++++++++--- .../mc/core/world/block/AbstractBlock.java | 4 +- .../main/java/mc/core/world/chunk/Chunk.java | 27 ++++++++- .../mc/core/world/chunk/ChunkSection.java | 33 ++++++----- .../proto_1_12_2/packets/ChunkDataPacket.java | 2 +- .../packets/ChunkdataPacketTest.java | 3 +- .../netty/handlers/LoginHandler.java | 2 +- .../java/mc/world/simple/SimpleChunk.java | 51 +++++++++++++++-- .../mc/world/simple/SimpleChunkSection.java | 56 ++++++++----------- .../java/mc/world/simple/SimpleWorld.java | 13 ++++- 12 files changed, 168 insertions(+), 71 deletions(-) diff --git a/core/src/main/java/mc/core/CoreEventListener.java b/core/src/main/java/mc/core/CoreEventListener.java index 201b60e..134e071 100644 --- a/core/src/main/java/mc/core/CoreEventListener.java +++ b/core/src/main/java/mc/core/CoreEventListener.java @@ -24,10 +24,10 @@ public class CoreEventListener { log.trace("(GameLoop) playerMoveEventHandler()"); Chunk chunk; - chunk = event.getPlayer().getWorld().getChunk(event.getOldLocation()); // Old chunk + chunk = event.getPlayer().getWorld().getChunk(event.getOldLocation().toBlockLocation()); // Old chunk int ccX = chunk.getX(); int ccZ = chunk.getZ(); - chunk = event.getPlayer().getWorld().getChunk(event.getNewLocation()); // Next chunk + chunk = event.getPlayer().getWorld().getChunk(event.getNewLocation().toBlockLocation()); // Next chunk int ncX = chunk.getX(); int ncZ = chunk.getZ(); diff --git a/core/src/main/java/mc/core/EntityLocation.java b/core/src/main/java/mc/core/EntityLocation.java index 735c50b..e0dc571 100644 --- a/core/src/main/java/mc/core/EntityLocation.java +++ b/core/src/main/java/mc/core/EntityLocation.java @@ -3,6 +3,7 @@ package mc.core; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import mc.core.world.block.BlockLocation; import org.springframework.lang.Nullable; @NoArgsConstructor @@ -44,6 +45,10 @@ public class EntityLocation implements Cloneable { return (int) Math.floor(z); } + public BlockLocation toBlockLocation() { + return new BlockLocation(getBlockX(), getBlockY(), getBlockZ()); + } + @Override public EntityLocation clone() { try { diff --git a/core/src/main/java/mc/core/world/World.java b/core/src/main/java/mc/core/world/World.java index 37d35e0..8c91eac 100644 --- a/core/src/main/java/mc/core/world/World.java +++ b/core/src/main/java/mc/core/world/World.java @@ -1,34 +1,57 @@ -/* - * DmitriyMX - * 2018-04-15 - */ package mc.core.world; import mc.core.EntityLocation; +import mc.core.world.block.Block; import mc.core.world.block.BlockLocation; import mc.core.world.chunk.Chunk; public interface World { String getName(); - WorldType getWorldType(); + WorldType getType(); EntityLocation getSpawn(); + void setSpawn(EntityLocation location); + default void setSpawn(double x, double y, double z, float yaw, float pitch) { setSpawn(new EntityLocation(x, y, z, yaw, pitch)); } + default void setSpawn(double x, double y, double z) { setSpawn(x, y, z, 0f, 0f); } + /** + * Получить чанк по его координатам + * @param x chunk X + * @param z chunk Z + * @return {@link Chunk} + */ Chunk getChunk(int x, int z); - void setChunk(int x, int z, Chunk chunkSection); + /** + * Получить чанк по глобальным координатам блока + * @param location {@link BlockLocation} + * @return {@link Chunk} + */ default Chunk getChunk(BlockLocation location) { return getChunk(location.getX() >> 4, location.getZ() >> 4); } - default Chunk getChunk(EntityLocation location) { - return getChunk(location.getBlockX() >> 4, location.getBlockZ() >> 4); + void setChunk(int x, int z, Chunk chunk); + + /** + * Получить блок по его координатам + * @param x X + * @param y Y + * @param z Z + * @return {@link Block} + */ + Block getBlock(int x, int y, int z); + + default Block getBlock(BlockLocation location) { + return getBlock(location.getX(), location.getY(), location.getZ()); } + + void setBlock(Block block); } diff --git a/core/src/main/java/mc/core/world/block/AbstractBlock.java b/core/src/main/java/mc/core/world/block/AbstractBlock.java index 6bf8445..1795d8e 100644 --- a/core/src/main/java/mc/core/world/block/AbstractBlock.java +++ b/core/src/main/java/mc/core/world/block/AbstractBlock.java @@ -10,10 +10,10 @@ public abstract class AbstractBlock implements Block { @Getter private int light = 0; @Getter - private final BlockType blockType; + private final BlockType type; protected AbstractBlock(BlockType type) { - this.blockType = type; + this.type = type; } @Override diff --git a/core/src/main/java/mc/core/world/chunk/Chunk.java b/core/src/main/java/mc/core/world/chunk/Chunk.java index 0ee2e28..d096646 100644 --- a/core/src/main/java/mc/core/world/chunk/Chunk.java +++ b/core/src/main/java/mc/core/world/chunk/Chunk.java @@ -1,6 +1,7 @@ package mc.core.world.chunk; import mc.core.world.Biome; +import mc.core.world.block.Block; public interface Chunk { int getX(); @@ -9,6 +10,28 @@ public interface Chunk { ChunkSection getChunkSection(int height); void setChunkSection(int height, ChunkSection chunkSection); - Biome getBiome(int localX, int localZ); - void setBiome(int localX, int localZ, Biome biome); + /** + * Получить блок по глобальным координатам секции чанка + * @param x global X + * @param y global Y + * @param z global Z + * @return {@link Block} + */ + Block getBlock(int x, int y, int z); + void setBlock(Block block); + + 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); + + /** + * Получить тип биома по глобальным координатам + * @param x global X + * @param z global Z + * @return + */ + Biome getBiome(int x, int z); + void setBiome(int x, int z, Biome biome); } diff --git a/core/src/main/java/mc/core/world/chunk/ChunkSection.java b/core/src/main/java/mc/core/world/chunk/ChunkSection.java index ae65a8b..194f520 100644 --- a/core/src/main/java/mc/core/world/chunk/ChunkSection.java +++ b/core/src/main/java/mc/core/world/chunk/ChunkSection.java @@ -1,26 +1,29 @@ -/* - * DmitriyMX - * 2018-04-15 - */ package mc.core.world.chunk; -import mc.core.world.Biome; import mc.core.world.block.Block; -/* 16x16x16 */ +/** + * Секция чанка размером 16x16x16 блоков + */ public interface ChunkSection { - int getX(); + Chunk getParent(); + void setParent(Chunk chunk); + int getY(); - int getZ(); + /** + * Получить блок по локальным координатам секции чанка + * @param localX local X (0-15) + * @param localY local Y (0-15) + * @param localZ local Z (0-15) + * @return {@link Block} + */ + Block getBlock(int localX, int localY, int localZ); void setBlock(Block block); - Block getBlock(int x, int y, int z); - int getSkyLight(int x, int y, int z); - void setSkyLight(int x, int y, int z, int lightLevel); + int getSkyLight(int localX, int localY, int localZ); + void setSkyLight(int localX, int localY, int localZ, int lightLevel); - int getAddition(int x, int y, int z); - void setAddition(int x, int y, int z, int value); - - Biome getBiome(int localX, int localZ); + int getAddition(int localX, int localY, int localZ); + void setAddition(int localX, int localY, int localZ, int value); } diff --git a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java index 233548a..a57e323 100644 --- a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java +++ b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java @@ -207,7 +207,7 @@ public class ChunkDataPacket implements SCPacket { } if (!biomeFinally) { - biomes.writeByte(chunkSection.getBiome(x, z).getId()); + biomes.writeByte(chunk.getBiome(x, z).getId()); if (x == 15 && z == 15) { biomeFinally = true; } diff --git a/proto_1.12.2/src/test/java/mc/core/network/proto_1_12_2/packets/ChunkdataPacketTest.java b/proto_1.12.2/src/test/java/mc/core/network/proto_1_12_2/packets/ChunkdataPacketTest.java index 5060676..6b21626 100644 --- a/proto_1.12.2/src/test/java/mc/core/network/proto_1_12_2/packets/ChunkdataPacketTest.java +++ b/proto_1.12.2/src/test/java/mc/core/network/proto_1_12_2/packets/ChunkdataPacketTest.java @@ -41,7 +41,6 @@ class ChunkdataPacketTest { if (y <= 3) return 0; else return 15; }); - when(chunkSection.getBiome(anyInt(), anyInt())).thenReturn(Biome.PLAINS); when(chunkSection.getBlock(anyInt(), anyInt(), anyInt())).thenAnswer(invocation -> { Object[] args = invocation.getArguments(); int x = (int) args[0]; @@ -57,7 +56,7 @@ class ChunkdataPacketTest { }); world = mock(World.class); - when(world.getWorldType()).thenReturn(WorldType.FLAT); + when(world.getType()).thenReturn(WorldType.FLAT); when(world.getChunk(anyInt(), anyInt())).thenAnswer(invocation -> { Object[] args = invocation.getArguments(); diff --git a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java index 0f8332c..19afb32 100644 --- a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java +++ b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java @@ -73,7 +73,7 @@ public class LoginHandler extends AbstractStateHandler implements LoginStateHand pkt1.setMode(PlayerMode.CREATIVE); //TODO перенести в Config pkt1.setDimension(0/*Overworld*/); //TODO перенести в World pkt1.setDifficulty(0/*Peaceful*/); //TODO перенести в Config - pkt1.setLevelType(world.getWorldType().getName()); + pkt1.setLevelType(world.getType().getName()); channel.write(pkt1); // Spawn Position diff --git a/simple_world/src/main/java/mc/world/simple/SimpleChunk.java b/simple_world/src/main/java/mc/world/simple/SimpleChunk.java index aadf810..7a6fbb5 100644 --- a/simple_world/src/main/java/mc/world/simple/SimpleChunk.java +++ b/simple_world/src/main/java/mc/world/simple/SimpleChunk.java @@ -4,6 +4,7 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import mc.core.world.Biome; +import mc.core.world.block.Block; import mc.core.world.chunk.Chunk; import mc.core.world.chunk.ChunkSection; @@ -13,7 +14,6 @@ public class SimpleChunk implements Chunk { @Getter private final int x, z; private ChunkSection chunkSection; - private final Biome biome = Biome.PLAINS; @Override public ChunkSection getChunkSection(int height) { @@ -23,15 +23,58 @@ public class SimpleChunk implements Chunk { @Override public void setChunkSection(int height, ChunkSection chunkSection) { this.chunkSection = chunkSection; + this.chunkSection.setParent(this); } @Override - public Biome getBiome(int localX, int localZ) { - return biome; + public Block getBlock(int x, int y, int z) { + return chunkSection.getBlock( + x - (x >> 4) << 4, + y - (y >> 4) << 4, + z - (z >> 4) << 4 + ); } @Override - public void setBiome(int localX, int localZ, Biome biome) { + public void setBlock(Block block) { + // ignore + } + + @Override + public int getSkyLight(int x, int y, int z) { + return chunkSection.getSkyLight( + x - (x >> 4) << 4, + y - (y >> 4) << 4, + z - (z >> 4) << 4 + ); + } + + @Override + public void setSkyLight(int x, int y, int z, int lightLevel) { + // ignore + } + + @Override + public int getAddition(int x, int y, int z) { + return chunkSection.getAddition( + x - (x >> 4) << 4, + y - (y >> 4) << 4, + z - (z >> 4) << 4 + ); + } + + @Override + public void setAddition(int x, int y, int z, int value) { + // ignore + } + + @Override + public Biome getBiome(int x, int z) { + return Biome.PLAINS; + } + + @Override + public void setBiome(int x, int z, Biome biome) { // ignore } } diff --git a/simple_world/src/main/java/mc/world/simple/SimpleChunkSection.java b/simple_world/src/main/java/mc/world/simple/SimpleChunkSection.java index 4674ac7..cde4005 100644 --- a/simple_world/src/main/java/mc/world/simple/SimpleChunkSection.java +++ b/simple_world/src/main/java/mc/world/simple/SimpleChunkSection.java @@ -1,14 +1,19 @@ package mc.world.simple; -import mc.core.world.Biome; +import lombok.Getter; +import lombok.Setter; import mc.core.world.block.Block; import mc.core.world.block.BlockFactory; import mc.core.world.block.BlockType; +import mc.core.world.chunk.Chunk; import mc.core.world.chunk.ChunkSection; import java.util.List; public class SimpleChunkSection implements ChunkSection { + @Getter + @Setter + private Chunk parent; private final BlockFactory blockFactory = new BlockFactory(); private final List layersBlock; @@ -17,32 +22,22 @@ public class SimpleChunkSection implements ChunkSection { } @Override - public int getSkyLight(int x, int y, int z) { - if (y <= 3) return 0; + public int getSkyLight(int localX, int localY, int localZ) { + if (localY <= 3) return 0; else return 15; } @Override - public void setSkyLight(int x, int y, int z, int lightLevel) { + public void setSkyLight(int localX, int localY, int localZ, int lightLevel) { } @Override - public int getAddition(int x, int y, int z) { + public int getAddition(int localX, int localY, int localZ) { return 0; } @Override - public void setAddition(int x, int y, int z, int value) { - } - - @Override - public Biome getBiome(int localX, int localZ) { - return Biome.PLAINS; - } - - @Override - public int getX() { - return 0; + public void setAddition(int localX, int localY, int localZ, int value) { } @Override @@ -50,31 +45,26 @@ public class SimpleChunkSection implements ChunkSection { return 0; } - @Override - public int getZ() { - return 0; - } - @Override public void setBlock(Block block) { } @Override - public Block getBlock(int x, int y, int z) { - if (x < 0) x = 0; - else if (x > 15) x = 15; - if (y < 0) y = 0; - else if (y > 15) y = 15; - if (z < 0) z = 0; - else if (z > 15) z = 15; + public Block getBlock(int localX, int localY, int localZ) { + if (localX < 0) localX = 0; + else if (localX > 15) localX = 15; + if (localY < 0) localY = 0; + else if (localY > 15) localY = 15; + if (localZ < 0) localZ = 0; + else if (localZ > 15) localZ = 15; - if (y >= layersBlock.size()) { - return blockFactory.create(BlockType.AIR, x, y, z); + if (localY >= layersBlock.size()) { + return blockFactory.create(BlockType.AIR, localX, localY, localZ); } - BlockType blockType = layersBlock.get(y); - if (blockType == null) return blockFactory.create(BlockType.AIR, x, y, z); + BlockType blockType = layersBlock.get(localY); + if (blockType == null) return blockFactory.create(BlockType.AIR, localX, localY, localZ); - return blockFactory.create(blockType, x, y, z); + return blockFactory.create(blockType, localX, localY, localZ); } } diff --git a/simple_world/src/main/java/mc/world/simple/SimpleWorld.java b/simple_world/src/main/java/mc/world/simple/SimpleWorld.java index b4ac9e4..4a6e345 100644 --- a/simple_world/src/main/java/mc/world/simple/SimpleWorld.java +++ b/simple_world/src/main/java/mc/world/simple/SimpleWorld.java @@ -6,6 +6,7 @@ import lombok.extern.slf4j.Slf4j; import mc.core.EntityLocation; import mc.core.world.World; import mc.core.world.WorldType; +import mc.core.world.block.Block; import mc.core.world.chunk.Chunk; import mc.core.world.chunk.ChunkProvider; import org.springframework.beans.factory.BeanNameAware; @@ -19,7 +20,7 @@ public class SimpleWorld implements World, BeanNameAware { @Getter private String name; @Getter - private final WorldType worldType = WorldType.FLAT; + private final WorldType type = WorldType.FLAT; private EntityLocation spawn; @Setter private ChunkProvider chunkProvider; @@ -49,6 +50,16 @@ public class SimpleWorld implements World, BeanNameAware { throw new UnsupportedOperationException(); } + @Override + public Block getBlock(int x, int y, int z) { + return chunkProvider.getChunk(x >> 4, z >> 4).getBlock(x, y, z); + } + + @Override + public void setBlock(Block block) { + // nope... + } + @Override public void setBeanName(@Nonnull String name) { this.name = name;