diff --git a/src/main/java/ru/windcorp/progressia/server/ChunkManager.java b/src/main/java/ru/windcorp/progressia/server/ChunkManager.java index 2705c8e..e7f4f00 100644 --- a/src/main/java/ru/windcorp/progressia/server/ChunkManager.java +++ b/src/main/java/ru/windcorp/progressia/server/ChunkManager.java @@ -11,7 +11,6 @@ import ru.windcorp.progressia.common.world.PacketSendChunk; import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.generic.ChunkSet; import ru.windcorp.progressia.common.world.generic.ChunkSets; -import ru.windcorp.progressia.test.TestContent; import ru.windcorp.progressia.test.TestWorldDiskIO; public class ChunkManager { @@ -123,8 +122,7 @@ public class ChunkManager { ChunkData chunk = TestWorldDiskIO.tryToLoad(chunkPos, world); if (chunk == null) { - chunk = new ChunkData(chunkPos, world); - TestContent.generateChunk(chunk); + chunk = getServer().getWorld().generate(chunkPos); } world.addChunk(chunk); diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index 40df32b..9d0b12e 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -13,6 +13,7 @@ import ru.windcorp.progressia.server.world.WorldLogic; import ru.windcorp.progressia.server.world.tasks.WorldAccessor; import ru.windcorp.progressia.server.world.ticking.Change; import ru.windcorp.progressia.server.world.ticking.Evaluation; +import ru.windcorp.progressia.test.gen.TestWorldGenerator; public class Server { @@ -39,7 +40,7 @@ public class Server { private final TickingSettings tickingSettings = new TickingSettings(); public Server(WorldData world) { - this.world = new WorldLogic(world, this); + this.world = new WorldLogic(world, this, TestWorldGenerator::new); this.serverThread = new ServerThread(this); this.clientManager = new ClientManager(this); diff --git a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java index e5ec697..2c8cc48 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java @@ -3,6 +3,7 @@ package ru.windcorp.progressia.server.world; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.function.Function; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.ChunkData; @@ -13,6 +14,7 @@ import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.GenericWorld; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.block.BlockLogic; +import ru.windcorp.progressia.server.world.generation.WorldGenerator; import ru.windcorp.progressia.server.world.tasks.TickEntitiesTask; import ru.windcorp.progressia.server.world.ticking.Evaluation; import ru.windcorp.progressia.server.world.tile.TileLogic; @@ -30,13 +32,16 @@ implements GenericWorld< private final WorldData data; private final Server server; + private final WorldGenerator generator; + private final Map chunks = new HashMap<>(); private final Evaluation tickEntitiesTask = new TickEntitiesTask(); - public WorldLogic(WorldData data, Server server) { + public WorldLogic(WorldData data, Server server, Function worldGeneratorConstructor) { this.data = data; this.server = server; + this.generator = worldGeneratorConstructor.apply(this); data.addListener(new WorldDataListener() { @Override @@ -80,6 +85,14 @@ implements GenericWorld< return data; } + public WorldGenerator getGenerator() { + return generator; + } + + public ChunkData generate(Vec3i chunkPos) { + return getGenerator().generate(chunkPos, getData()); + } + public ChunkLogic getChunk(ChunkData chunkData) { return chunks.get(chunkData); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java new file mode 100644 index 0000000..45d0a12 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java @@ -0,0 +1,16 @@ +package ru.windcorp.progressia.server.world.generation; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.namespaces.Namespaced; +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.WorldData; + +public abstract class WorldGenerator extends Namespaced { + + public WorldGenerator(String id) { + super(id); + } + + public abstract ChunkData generate(Vec3i chunkPos, WorldData world); + +} diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index ee6bedb..352f288 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -23,7 +23,6 @@ import ru.windcorp.progressia.common.comms.controls.*; import ru.windcorp.progressia.common.io.ChunkIO; import ru.windcorp.progressia.common.state.StatefulObjectRegistry.Factory; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.block.*; import ru.windcorp.progressia.common.world.entity.*; import ru.windcorp.progressia.common.world.tile.*; @@ -239,97 +238,6 @@ public class TestContent { server.getWorldAccessor().setBlock(blockInWorld, BlockDataRegistry.getInstance().get("Test:Stone")); } - public static void generateChunk(ChunkData chunk) { - final int bpc = ChunkData.BLOCKS_PER_CHUNK; - - BlockData dirt = BlockDataRegistry.getInstance().get("Test:Dirt"); - BlockData stone = BlockDataRegistry.getInstance().get("Test:Stone"); - BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); - - TileData grass = TileDataRegistry.getInstance().get("Test:Grass"); - TileData stones = TileDataRegistry.getInstance().get("Test:Stones"); - TileData flowers = TileDataRegistry.getInstance().get("Test:YellowFlowers"); - TileData sand = TileDataRegistry.getInstance().get("Test:Sand"); - - final float maxHeight = 32; - final float rho = 2000; - - int[][] heightMap = new int[bpc][bpc]; - - for (int yic = 0; yic < heightMap.length; ++yic) { - int yiw = Coordinates.getInWorld(chunk.getY(), yic); - for (int xic = 0; xic < heightMap[yic].length; ++xic) { - int xiw = Coordinates.getInWorld(chunk.getX(), xic); - - int rsq = (xiw*xiw + yiw*yiw); - heightMap[xic][yic] = (int) (rsq / (rho + rsq) * maxHeight) - chunk.getZ()*bpc; - } - } - - Vec3i pos = new Vec3i(); - - for (pos.x = 0; pos.x < bpc; ++pos.x) { - for (pos.y = 0; pos.y < bpc; ++pos.y) { - for (pos.z = 0; pos.z < bpc; ++pos.z) { - - int layer = pos.z - heightMap[pos.x][pos.y]; - - if (layer < -4) { - chunk.setBlock(pos, stone, false); - } else if (layer < 0) { - chunk.setBlock(pos, dirt, false); - } else { - chunk.setBlock(pos, air, false); - } - - } - } - } - - for (int x = 0; x < bpc; ++x) { - for (int y = 0; y < bpc; ++y) { - -// int z = heightMap[x][y]; - - for (int z = 0; z < bpc; ++z) { - - pos.set(x, y, z); - int layer = pos.z - heightMap[x][y]; - - if (layer == -1) { - chunk.getTiles(pos, BlockFace.TOP).add(grass); - for (BlockFace face : BlockFace.getFaces()) { - if (face.getVector().z != 0) continue; - pos.add(face.getVector()); - - if (!ChunkData.isInBounds(pos) || (chunk.getBlock(pos) == air)) { - pos.sub(face.getVector()); - chunk.getTiles(pos, face).add(grass); - } else { - pos.sub(face.getVector()); - } - } - - int hash = x*x * 19 ^ y*y * 41 ^ pos.z*pos.z * 147; - if (hash % 5 == 0) { - chunk.getTiles(pos, BlockFace.TOP).addFarthest(sand); - } - - hash = x*x * 13 ^ y*y * 37 ^ pos.z*pos.z * 129; - if (hash % 5 == 0) { - chunk.getTiles(pos, BlockFace.TOP).addFarthest(stones); - } - - hash = x*x * 17 ^ y*y * 39 ^ pos.z*pos.z * 131; - if (hash % 9 == 0) { - chunk.getTiles(pos, BlockFace.TOP).addFarthest(flowers); - } - } - } - } - } - } - private static void registerMisc() { ChunkIO.registerCodec(new TestChunkCodec()); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java new file mode 100644 index 0000000..e680fa2 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java @@ -0,0 +1,117 @@ +package ru.windcorp.progressia.test.gen; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.Coordinates; +import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.block.BlockDataRegistry; +import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.tile.TileData; +import ru.windcorp.progressia.common.world.tile.TileDataRegistry; +import ru.windcorp.progressia.server.world.WorldLogic; +import ru.windcorp.progressia.server.world.generation.WorldGenerator; + +public class TestWorldGenerator extends WorldGenerator { + + public TestWorldGenerator(WorldLogic world) { + super("Test:WorldGenerator"); + } + + @Override + public ChunkData generate(Vec3i chunkPos, WorldData world) { + ChunkData chunk = new ChunkData(chunkPos, world); + + final int bpc = ChunkData.BLOCKS_PER_CHUNK; + + BlockData dirt = BlockDataRegistry.getInstance().get("Test:Dirt"); + BlockData stone = BlockDataRegistry.getInstance().get("Test:Stone"); + BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); + + TileData grass = TileDataRegistry.getInstance().get("Test:Grass"); + TileData stones = TileDataRegistry.getInstance().get("Test:Stones"); + TileData flowers = TileDataRegistry.getInstance().get("Test:YellowFlowers"); + TileData sand = TileDataRegistry.getInstance().get("Test:Sand"); + + final float maxHeight = 32; + final float rho = 2000; + + int[][] heightMap = new int[bpc][bpc]; + + for (int yic = 0; yic < heightMap.length; ++yic) { + int yiw = Coordinates.getInWorld(chunk.getY(), yic); + for (int xic = 0; xic < heightMap[yic].length; ++xic) { + int xiw = Coordinates.getInWorld(chunk.getX(), xic); + + int rsq = (xiw*xiw + yiw*yiw); + heightMap[xic][yic] = (int) (rsq / (rho + rsq) * maxHeight) - chunk.getZ()*bpc; + } + } + + Vec3i pos = new Vec3i(); + + for (pos.x = 0; pos.x < bpc; ++pos.x) { + for (pos.y = 0; pos.y < bpc; ++pos.y) { + for (pos.z = 0; pos.z < bpc; ++pos.z) { + + int layer = pos.z - heightMap[pos.x][pos.y]; + + if (layer < -4) { + chunk.setBlock(pos, stone, false); + } else if (layer < 0) { + chunk.setBlock(pos, dirt, false); + } else { + chunk.setBlock(pos, air, false); + } + + } + } + } + + for (int x = 0; x < bpc; ++x) { + for (int y = 0; y < bpc; ++y) { + +// int z = heightMap[x][y]; + + for (int z = 0; z < bpc; ++z) { + + pos.set(x, y, z); + int layer = pos.z - heightMap[x][y]; + + if (layer == -1) { + chunk.getTiles(pos, BlockFace.TOP).add(grass); + for (BlockFace face : BlockFace.getFaces()) { + if (face.getVector().z != 0) continue; + pos.add(face.getVector()); + + if (!ChunkData.isInBounds(pos) || (chunk.getBlock(pos) == air)) { + pos.sub(face.getVector()); + chunk.getTiles(pos, face).add(grass); + } else { + pos.sub(face.getVector()); + } + } + + int hash = x*x * 19 ^ y*y * 41 ^ pos.z*pos.z * 147; + if (hash % 5 == 0) { + chunk.getTiles(pos, BlockFace.TOP).addFarthest(sand); + } + + hash = x*x * 13 ^ y*y * 37 ^ pos.z*pos.z * 129; + if (hash % 5 == 0) { + chunk.getTiles(pos, BlockFace.TOP).addFarthest(stones); + } + + hash = x*x * 17 ^ y*y * 39 ^ pos.z*pos.z * 131; + if (hash % 9 == 0) { + chunk.getTiles(pos, BlockFace.TOP).addFarthest(flowers); + } + } + } + } + } + + return chunk; + } + +}