Introduced WorldGenerators

This commit is contained in:
OLEGSHA 2020-12-31 15:36:21 +03:00
parent 6e6701d2e5
commit 77599e857d
6 changed files with 150 additions and 97 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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<ChunkData, ChunkLogic> chunks = new HashMap<>();
private final Evaluation tickEntitiesTask = new TickEntitiesTask();
public WorldLogic(WorldData data, Server server) {
public WorldLogic(WorldData data, Server server, Function<WorldLogic, WorldGenerator> 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);
}

View File

@ -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);
}

View File

@ -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());
}

View File

@ -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;
}
}