Changed worldgen and made some minor changes in code
This commit is contained in:
parent
fc48928c66
commit
a582727cc0
@ -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);
|
||||
}
|
||||
|
@ -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()));
|
||||
}
|
||||
|
@ -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));
|
||||
|
||||
}
|
||||
|
||||
}
|
11
src/main/java/ru/windcorp/progressia/server/ChunkLoader.java
Normal file
11
src/main/java/ru/windcorp/progressia/server/ChunkLoader.java
Normal 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);
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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)
|
||||
));
|
||||
|
Reference in New Issue
Block a user