мелкий рефакторинг + указываем точно где локальные, а где глобальные координаты
This commit is contained in:
@@ -24,10 +24,10 @@ public class CoreEventListener {
|
|||||||
log.trace("(GameLoop) playerMoveEventHandler()");
|
log.trace("(GameLoop) playerMoveEventHandler()");
|
||||||
|
|
||||||
Chunk chunk;
|
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 ccX = chunk.getX();
|
||||||
int ccZ = chunk.getZ();
|
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 ncX = chunk.getX();
|
||||||
int ncZ = chunk.getZ();
|
int ncZ = chunk.getZ();
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package mc.core;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import mc.core.world.block.BlockLocation;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@@ -44,6 +45,10 @@ public class EntityLocation implements Cloneable {
|
|||||||
return (int) Math.floor(z);
|
return (int) Math.floor(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BlockLocation toBlockLocation() {
|
||||||
|
return new BlockLocation(getBlockX(), getBlockY(), getBlockZ());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityLocation clone() {
|
public EntityLocation clone() {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,34 +1,57 @@
|
|||||||
/*
|
|
||||||
* DmitriyMX <dimon550@gmail.com>
|
|
||||||
* 2018-04-15
|
|
||||||
*/
|
|
||||||
package mc.core.world;
|
package mc.core.world;
|
||||||
|
|
||||||
import mc.core.EntityLocation;
|
import mc.core.EntityLocation;
|
||||||
|
import mc.core.world.block.Block;
|
||||||
import mc.core.world.block.BlockLocation;
|
import mc.core.world.block.BlockLocation;
|
||||||
import mc.core.world.chunk.Chunk;
|
import mc.core.world.chunk.Chunk;
|
||||||
|
|
||||||
public interface World {
|
public interface World {
|
||||||
String getName();
|
String getName();
|
||||||
WorldType getWorldType();
|
WorldType getType();
|
||||||
|
|
||||||
EntityLocation getSpawn();
|
EntityLocation getSpawn();
|
||||||
|
|
||||||
void setSpawn(EntityLocation location);
|
void setSpawn(EntityLocation location);
|
||||||
|
|
||||||
default void setSpawn(double x, double y, double z, float yaw, float pitch) {
|
default void setSpawn(double x, double y, double z, float yaw, float pitch) {
|
||||||
setSpawn(new EntityLocation(x, y, z, yaw, pitch));
|
setSpawn(new EntityLocation(x, y, z, yaw, pitch));
|
||||||
}
|
}
|
||||||
|
|
||||||
default void setSpawn(double x, double y, double z) {
|
default void setSpawn(double x, double y, double z) {
|
||||||
setSpawn(x, y, z, 0f, 0f);
|
setSpawn(x, y, z, 0f, 0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Получить чанк по его координатам
|
||||||
|
* @param x chunk X
|
||||||
|
* @param z chunk Z
|
||||||
|
* @return {@link Chunk}
|
||||||
|
*/
|
||||||
Chunk getChunk(int x, int z);
|
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) {
|
default Chunk getChunk(BlockLocation location) {
|
||||||
return getChunk(location.getX() >> 4, location.getZ() >> 4);
|
return getChunk(location.getX() >> 4, location.getZ() >> 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
default Chunk getChunk(EntityLocation location) {
|
void setChunk(int x, int z, Chunk chunk);
|
||||||
return getChunk(location.getBlockX() >> 4, location.getBlockZ() >> 4);
|
|
||||||
|
/**
|
||||||
|
* Получить блок по его координатам
|
||||||
|
* @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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ public abstract class AbstractBlock implements Block {
|
|||||||
@Getter
|
@Getter
|
||||||
private int light = 0;
|
private int light = 0;
|
||||||
@Getter
|
@Getter
|
||||||
private final BlockType blockType;
|
private final BlockType type;
|
||||||
|
|
||||||
protected AbstractBlock(BlockType type) {
|
protected AbstractBlock(BlockType type) {
|
||||||
this.blockType = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mc.core.world.chunk;
|
package mc.core.world.chunk;
|
||||||
|
|
||||||
import mc.core.world.Biome;
|
import mc.core.world.Biome;
|
||||||
|
import mc.core.world.block.Block;
|
||||||
|
|
||||||
public interface Chunk {
|
public interface Chunk {
|
||||||
int getX();
|
int getX();
|
||||||
@@ -9,6 +10,28 @@ public interface Chunk {
|
|||||||
ChunkSection getChunkSection(int height);
|
ChunkSection getChunkSection(int height);
|
||||||
void setChunkSection(int height, ChunkSection chunkSection);
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,29 @@
|
|||||||
/*
|
|
||||||
* DmitriyMX <dimon550@gmail.com>
|
|
||||||
* 2018-04-15
|
|
||||||
*/
|
|
||||||
package mc.core.world.chunk;
|
package mc.core.world.chunk;
|
||||||
|
|
||||||
import mc.core.world.Biome;
|
|
||||||
import mc.core.world.block.Block;
|
import mc.core.world.block.Block;
|
||||||
|
|
||||||
/* 16x16x16 */
|
/**
|
||||||
|
* Секция чанка размером 16x16x16 блоков
|
||||||
|
*/
|
||||||
public interface ChunkSection {
|
public interface ChunkSection {
|
||||||
int getX();
|
Chunk getParent();
|
||||||
|
void setParent(Chunk chunk);
|
||||||
|
|
||||||
int getY();
|
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);
|
void setBlock(Block block);
|
||||||
Block getBlock(int x, int y, int z);
|
|
||||||
|
|
||||||
int getSkyLight(int x, int y, int z);
|
int getSkyLight(int localX, int localY, int localZ);
|
||||||
void setSkyLight(int x, int y, int z, int lightLevel);
|
void setSkyLight(int localX, int localY, int localZ, int lightLevel);
|
||||||
|
|
||||||
int getAddition(int x, int y, int z);
|
int getAddition(int localX, int localY, int localZ);
|
||||||
void setAddition(int x, int y, int z, int value);
|
void setAddition(int localX, int localY, int localZ, int value);
|
||||||
|
|
||||||
Biome getBiome(int localX, int localZ);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ public class ChunkDataPacket implements SCPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!biomeFinally) {
|
if (!biomeFinally) {
|
||||||
biomes.writeByte(chunkSection.getBiome(x, z).getId());
|
biomes.writeByte(chunk.getBiome(x, z).getId());
|
||||||
if (x == 15 && z == 15) {
|
if (x == 15 && z == 15) {
|
||||||
biomeFinally = true;
|
biomeFinally = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ class ChunkdataPacketTest {
|
|||||||
if (y <= 3) return 0;
|
if (y <= 3) return 0;
|
||||||
else return 15;
|
else return 15;
|
||||||
});
|
});
|
||||||
when(chunkSection.getBiome(anyInt(), anyInt())).thenReturn(Biome.PLAINS);
|
|
||||||
when(chunkSection.getBlock(anyInt(), anyInt(), anyInt())).thenAnswer(invocation -> {
|
when(chunkSection.getBlock(anyInt(), anyInt(), anyInt())).thenAnswer(invocation -> {
|
||||||
Object[] args = invocation.getArguments();
|
Object[] args = invocation.getArguments();
|
||||||
int x = (int) args[0];
|
int x = (int) args[0];
|
||||||
@@ -57,7 +56,7 @@ class ChunkdataPacketTest {
|
|||||||
});
|
});
|
||||||
|
|
||||||
world = mock(World.class);
|
world = mock(World.class);
|
||||||
when(world.getWorldType()).thenReturn(WorldType.FLAT);
|
when(world.getType()).thenReturn(WorldType.FLAT);
|
||||||
when(world.getChunk(anyInt(), anyInt())).thenAnswer(invocation -> {
|
when(world.getChunk(anyInt(), anyInt())).thenAnswer(invocation -> {
|
||||||
Object[] args = invocation.getArguments();
|
Object[] args = invocation.getArguments();
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ public class LoginHandler extends AbstractStateHandler implements LoginStateHand
|
|||||||
pkt1.setMode(PlayerMode.CREATIVE); //TODO перенести в Config
|
pkt1.setMode(PlayerMode.CREATIVE); //TODO перенести в Config
|
||||||
pkt1.setDimension(0/*Overworld*/); //TODO перенести в World
|
pkt1.setDimension(0/*Overworld*/); //TODO перенести в World
|
||||||
pkt1.setDifficulty(0/*Peaceful*/); //TODO перенести в Config
|
pkt1.setDifficulty(0/*Peaceful*/); //TODO перенести в Config
|
||||||
pkt1.setLevelType(world.getWorldType().getName());
|
pkt1.setLevelType(world.getType().getName());
|
||||||
channel.write(pkt1);
|
channel.write(pkt1);
|
||||||
|
|
||||||
// Spawn Position
|
// Spawn Position
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import lombok.Getter;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import mc.core.world.Biome;
|
import mc.core.world.Biome;
|
||||||
|
import mc.core.world.block.Block;
|
||||||
import mc.core.world.chunk.Chunk;
|
import mc.core.world.chunk.Chunk;
|
||||||
import mc.core.world.chunk.ChunkSection;
|
import mc.core.world.chunk.ChunkSection;
|
||||||
|
|
||||||
@@ -13,7 +14,6 @@ public class SimpleChunk implements Chunk {
|
|||||||
@Getter
|
@Getter
|
||||||
private final int x, z;
|
private final int x, z;
|
||||||
private ChunkSection chunkSection;
|
private ChunkSection chunkSection;
|
||||||
private final Biome biome = Biome.PLAINS;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChunkSection getChunkSection(int height) {
|
public ChunkSection getChunkSection(int height) {
|
||||||
@@ -23,15 +23,58 @@ public class SimpleChunk implements Chunk {
|
|||||||
@Override
|
@Override
|
||||||
public void setChunkSection(int height, ChunkSection chunkSection) {
|
public void setChunkSection(int height, ChunkSection chunkSection) {
|
||||||
this.chunkSection = chunkSection;
|
this.chunkSection = chunkSection;
|
||||||
|
this.chunkSection.setParent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Biome getBiome(int localX, int localZ) {
|
public Block getBlock(int x, int y, int z) {
|
||||||
return biome;
|
return chunkSection.getBlock(
|
||||||
|
x - (x >> 4) << 4,
|
||||||
|
y - (y >> 4) << 4,
|
||||||
|
z - (z >> 4) << 4
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,19 @@
|
|||||||
package mc.world.simple;
|
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.Block;
|
||||||
import mc.core.world.block.BlockFactory;
|
import mc.core.world.block.BlockFactory;
|
||||||
import mc.core.world.block.BlockType;
|
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.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SimpleChunkSection implements ChunkSection {
|
public class SimpleChunkSection implements ChunkSection {
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private Chunk parent;
|
||||||
private final BlockFactory blockFactory = new BlockFactory();
|
private final BlockFactory blockFactory = new BlockFactory();
|
||||||
private final List<BlockType> layersBlock;
|
private final List<BlockType> layersBlock;
|
||||||
|
|
||||||
@@ -17,32 +22,22 @@ public class SimpleChunkSection implements ChunkSection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSkyLight(int x, int y, int z) {
|
public int getSkyLight(int localX, int localY, int localZ) {
|
||||||
if (y <= 3) return 0;
|
if (localY <= 3) return 0;
|
||||||
else return 15;
|
else return 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setSkyLight(int x, int y, int z, int lightLevel) {
|
public void setSkyLight(int localX, int localY, int localZ, int lightLevel) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAddition(int x, int y, int z) {
|
public int getAddition(int localX, int localY, int localZ) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAddition(int x, int y, int z, int value) {
|
public void setAddition(int localX, int localY, int localZ, int value) {
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Biome getBiome(int localX, int localZ) {
|
|
||||||
return Biome.PLAINS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getX() {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -50,31 +45,26 @@ public class SimpleChunkSection implements ChunkSection {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getZ() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBlock(Block block) {
|
public void setBlock(Block block) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Block getBlock(int x, int y, int z) {
|
public Block getBlock(int localX, int localY, int localZ) {
|
||||||
if (x < 0) x = 0;
|
if (localX < 0) localX = 0;
|
||||||
else if (x > 15) x = 15;
|
else if (localX > 15) localX = 15;
|
||||||
if (y < 0) y = 0;
|
if (localY < 0) localY = 0;
|
||||||
else if (y > 15) y = 15;
|
else if (localY > 15) localY = 15;
|
||||||
if (z < 0) z = 0;
|
if (localZ < 0) localZ = 0;
|
||||||
else if (z > 15) z = 15;
|
else if (localZ > 15) localZ = 15;
|
||||||
|
|
||||||
if (y >= layersBlock.size()) {
|
if (localY >= layersBlock.size()) {
|
||||||
return blockFactory.create(BlockType.AIR, x, y, z);
|
return blockFactory.create(BlockType.AIR, localX, localY, localZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockType blockType = layersBlock.get(y);
|
BlockType blockType = layersBlock.get(localY);
|
||||||
if (blockType == null) return blockFactory.create(BlockType.AIR, x, y, z);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import mc.core.EntityLocation;
|
import mc.core.EntityLocation;
|
||||||
import mc.core.world.World;
|
import mc.core.world.World;
|
||||||
import mc.core.world.WorldType;
|
import mc.core.world.WorldType;
|
||||||
|
import mc.core.world.block.Block;
|
||||||
import mc.core.world.chunk.Chunk;
|
import mc.core.world.chunk.Chunk;
|
||||||
import mc.core.world.chunk.ChunkProvider;
|
import mc.core.world.chunk.ChunkProvider;
|
||||||
import org.springframework.beans.factory.BeanNameAware;
|
import org.springframework.beans.factory.BeanNameAware;
|
||||||
@@ -19,7 +20,7 @@ public class SimpleWorld implements World, BeanNameAware {
|
|||||||
@Getter
|
@Getter
|
||||||
private String name;
|
private String name;
|
||||||
@Getter
|
@Getter
|
||||||
private final WorldType worldType = WorldType.FLAT;
|
private final WorldType type = WorldType.FLAT;
|
||||||
private EntityLocation spawn;
|
private EntityLocation spawn;
|
||||||
@Setter
|
@Setter
|
||||||
private ChunkProvider chunkProvider;
|
private ChunkProvider chunkProvider;
|
||||||
@@ -49,6 +50,16 @@ public class SimpleWorld implements World, BeanNameAware {
|
|||||||
throw new UnsupportedOperationException();
|
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
|
@Override
|
||||||
public void setBeanName(@Nonnull String name) {
|
public void setBeanName(@Nonnull String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|||||||
Reference in New Issue
Block a user