Introduced WorldGenerators
This commit is contained in:
parent
6e6701d2e5
commit
77599e857d
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user