Changed worldgen and made some minor changes in code

This commit is contained in:
OLEGSHA 2020-12-22 10:57:39 +03:00
parent fc48928c66
commit a582727cc0
9 changed files with 217 additions and 47 deletions

View File

@ -25,6 +25,7 @@ import glm.vec._3.i.Vec3i;
import gnu.trove.impl.sync.TSynchronizedLongObjectMap;
import gnu.trove.map.TLongObjectMap;
import gnu.trove.map.hash.TLongObjectHashMap;
import gnu.trove.set.TLongSet;
import ru.windcorp.progressia.common.collision.CollisionModel;
import ru.windcorp.progressia.common.util.CoordinatePacker;
import ru.windcorp.progressia.common.world.block.BlockData;
@ -55,17 +56,19 @@ public class WorldData {
}
public void tmp_generate() {
final int size = 6;
final int size = 10;
Vec3i cursor = new Vec3i(0, 0, 0);
for (cursor.x = -(size / 2); cursor.x <= (size / 2); ++cursor.x) {
for (cursor.y = -(size / 2); cursor.y <= (size / 2); ++cursor.y) {
for (cursor.z = -(size / 2); cursor.z <= (size / 2); ++cursor.z) {
ChunkData chunk = new ChunkData(cursor, this);
TestContent.generateChunk(chunk);
addChunk(chunk);
}
}
}
}
private void addChunkListeners(ChunkData chunk) {
getListeners().forEach(l -> l.getChunkListeners(this, chunk.getPosition(), chunk::addListener));
@ -140,6 +143,10 @@ public class WorldData {
return chunks;
}
public TLongSet getChunkKeys() {
return chunksByPos.keySet();
}
public EntityData getEntity(long entityId) {
return entitiesById.get(entityId);
}

View File

@ -2,9 +2,11 @@ package ru.windcorp.progressia.common.world.entity;
import glm.vec._2.Vec2;
import glm.vec._3.Vec3;
import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.collision.Collideable;
import ru.windcorp.progressia.common.collision.CollisionModel;
import ru.windcorp.progressia.common.state.StatefulObject;
import ru.windcorp.progressia.common.world.Coordinates;
public class EntityData extends StatefulObject implements Collideable {
@ -27,6 +29,16 @@ public class EntityData extends StatefulObject implements Collideable {
return position;
}
public Vec3i getBlockInWorld(Vec3i output) {
if (output == null) output = new Vec3i();
return position.round(output);
}
public Vec3i getChunkCoords(Vec3i output) {
output = getBlockInWorld(output);
return Coordinates.convertInWorldToChunk(output, output);
}
public void setPosition(Vec3 position) {
move(position.sub_(getPosition()));
}

View File

@ -0,0 +1,92 @@
package ru.windcorp.progressia.server;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import glm.vec._3.i.Vec3i;
import gnu.trove.set.TLongSet;
import gnu.trove.set.hash.TLongHashSet;
import ru.windcorp.progressia.common.util.CoordinatePacker;
import ru.windcorp.progressia.common.world.ChunkData;
import ru.windcorp.progressia.test.TestContent;
public class ChunkLoadManager {
private final Server server;
private final Collection<Collection<? extends ChunkLoader>> allChunkLoaders =
Collections.synchronizedCollection(new ArrayList<>());
private final TLongSet requested = new TLongHashSet();
private final TLongSet toLoad = new TLongHashSet();
private final TLongSet toUnload = new TLongHashSet();
public ChunkLoadManager(Server server) {
this.server = server;
allChunkLoaders.add(server.getPlayerManager().getPlayers());
}
public void tick() {
gatherRequests();
updateQueues();
processQueues();
}
private void gatherRequests() {
requested.clear();
allChunkLoaders.forEach(collection -> {
collection.forEach(this::gatherRequests);
});
}
private void gatherRequests(ChunkLoader loader) {
loader.requestChunksToLoad(v -> requested.add(CoordinatePacker.pack3IntsIntoLong(v)));
}
private void updateQueues() {
TLongSet loaded = getServer().getWorld().getData().getChunkKeys();
toLoad.clear();
toLoad.addAll(requested);
toLoad.removeAll(loaded);
toUnload.clear();
toUnload.addAll(loaded);
toUnload.removeAll(requested);
}
private void processQueues() {
Vec3i v = new Vec3i();
toLoad.forEach(key -> {
loadChunk(CoordinatePacker.unpack3IntsFromLong(key, v));
return true;
});
toUnload.forEach(key -> {
unloadChunk(CoordinatePacker.unpack3IntsFromLong(key, v));
return true;
});
}
public Server getServer() {
return server;
}
public void loadChunk(Vec3i pos) {
ChunkData chunk = new ChunkData(pos, getServer().getWorld().getData());
TestContent.generateChunk(chunk);
getServer().getWorld().getData().addChunk(chunk);
}
public void unloadChunk(Vec3i pos) {
getServer().getWorld().getData().removeChunk(getServer().getWorld().getData().getChunk(pos));
}
}

View File

@ -0,0 +1,11 @@
package ru.windcorp.progressia.server;
import java.util.function.Consumer;
import glm.vec._3.i.Vec3i;
public interface ChunkLoader {
void requestChunksToLoad(Consumer<Vec3i> output);
}

View File

@ -9,7 +9,7 @@ import ru.windcorp.progressia.common.world.PlayerData;
import ru.windcorp.progressia.common.world.entity.EntityData;
import ru.windcorp.progressia.server.comms.ClientPlayer;
public class Player extends PlayerData {
public class Player extends PlayerData implements ChunkLoader {
private final Server server;
private final ClientPlayer client;
@ -28,7 +28,8 @@ public class Player extends PlayerData {
return client;
}
public void getRequestedChunks(Consumer<Vec3i> chunkConsumer) {
@Override
public void requestChunksToLoad(Consumer<Vec3i> chunkConsumer) {
Vec3i start = getEntity().getPosition().round_();
Coordinates.convertInWorldToChunk(start, start);

View File

@ -112,8 +112,12 @@ public class Server {
taskQueue.waitAndInvoke(task);
}
public void schedule(Runnable task) {
taskQueue.schedule(task);
}
public void schedule(Consumer<Server> task) {
taskQueue.schedule(() -> task.accept(this));
schedule(() -> task.accept(this));
}
public void requestChange(Change change) {

View File

@ -5,6 +5,7 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.apache.logging.log4j.LogManager;
import ru.windcorp.progressia.common.util.crash.CrashReports;
import ru.windcorp.progressia.server.world.ticking.TickerCoordinator;
public class ServerThread implements Runnable {
@ -56,7 +57,7 @@ public class ServerThread implements Runnable {
server.tick();
ticker.runOneTick();
} catch (Exception e) {
LogManager.getLogger(getClass()).error("Got an exception in server thread", e);
CrashReports.report(e, "Got an exception in the server thread");
}
}

View File

@ -2,12 +2,15 @@ package ru.windcorp.progressia.test;
import java.io.IOException;
import glm.Glm;
import ru.windcorp.progressia.common.comms.packets.PacketLoadChunk;
import ru.windcorp.progressia.common.comms.packets.PacketSetLocalPlayer;
import ru.windcorp.progressia.common.io.ChunkIO;
import ru.windcorp.progressia.common.util.crash.CrashReports;
import ru.windcorp.progressia.common.world.ChunkData;
import ru.windcorp.progressia.common.world.WorldData;
import ru.windcorp.progressia.common.world.WorldDataListener;
import ru.windcorp.progressia.common.world.entity.EntityData;
import ru.windcorp.progressia.server.Server;
public class TestChunkSender implements WorldDataListener {
@ -21,12 +24,32 @@ public class TestChunkSender implements WorldDataListener {
@Override
public void onChunkLoaded(WorldData world, ChunkData chunk) {
PacketLoadChunk packet = new PacketLoadChunk("Core:LoadChunk");
packet.getPosition().set(
chunk.getPosition().x,
chunk.getPosition().y,
chunk.getPosition().z
);
try {
ChunkIO.save(chunk, packet.getData().getOutputStream());
} catch (IOException e) {
CrashReports.report(e, "TestChunkSender fjcked up. javahorse stupid");
}
server.getClientManager().broadcastGamePacket(packet);
tmp_sendPlayerIfPossible(world, chunk);
}
private void tmp_sendPlayerIfPossible(WorldData world, ChunkData chunk) {
EntityData e = world.getEntity(TestContent.PLAYER_ENTITY_ID);
if (e == null) return;
if (Glm.equals(e.getChunkCoords(null), chunk.getPosition())) {
System.out.printf("TestChunkSender: player found in (%d; %d; %d)\n", e.getChunkCoords(null).x, e.getChunkCoords(null).y, e.getChunkCoords(null).z);
server.getClientManager().broadcastGamePacket(new PacketSetLocalPlayer(e.getEntityId()));
}
}
}

View File

@ -28,6 +28,7 @@ import ru.windcorp.progressia.common.io.ChunkIO;
import ru.windcorp.progressia.common.state.StatefulObjectRegistry.Factory;
import ru.windcorp.progressia.common.util.Vectors;
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.*;
@ -258,20 +259,32 @@ public class TestContent {
TileData flowers = TileDataRegistry.getInstance().get("Test:YellowFlowers");
TileData sand = TileDataRegistry.getInstance().get("Test:Sand");
Vec3i aPoint = new Vec3i(5, 0, bpc + bpc/4).sub(chunk.getPosition().mul_(ChunkData.BLOCKS_PER_CHUNK));
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 (int x = 0; x < bpc; ++x) {
for (int y = 0; y < bpc; ++y) {
for (int z = 0; z < bpc; ++z) {
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) {
pos.set(x, y, z);
float f = aPoint.sub(pos, pos).length();
pos.set(x, y, z);
int layer = pos.z - heightMap[pos.x][pos.y];
if (f > 17) {
if (layer < -4) {
chunk.setBlock(pos, stone, false);
} else if (f > 14) {
} else if (layer < 0) {
chunk.setBlock(pos, dirt, false);
} else {
chunk.setBlock(pos, air, false);
@ -283,11 +296,15 @@ public class TestContent {
for (int x = 0; x < bpc; ++x) {
for (int y = 0; y < bpc; ++y) {
pos.set(x, y, 0);
for (pos.z = bpc - 1; pos.z >= 0 && chunk.getBlock(pos) == air; --pos.z);
if (pos.z < 0) continue;
// 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;
@ -317,11 +334,13 @@ public class TestContent {
}
}
}
}
}
if (Glm.equals(chunk.getPosition(), Vectors.ZERO_3i)) {
EntityData player = EntityDataRegistry.getInstance().create("Test:Player");
player.setEntityId(PLAYER_ENTITY_ID);
player.setPosition(new Vec3(-6, -6, 20));
player.setPosition(new Vec3(8, 8, 8));
player.setDirection(new Vec2(
(float) Math.toRadians(40), (float) Math.toRadians(45)
));