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.impl.sync.TSynchronizedLongObjectMap;
|
||||||
import gnu.trove.map.TLongObjectMap;
|
import gnu.trove.map.TLongObjectMap;
|
||||||
import gnu.trove.map.hash.TLongObjectHashMap;
|
import gnu.trove.map.hash.TLongObjectHashMap;
|
||||||
|
import gnu.trove.set.TLongSet;
|
||||||
import ru.windcorp.progressia.common.collision.CollisionModel;
|
import ru.windcorp.progressia.common.collision.CollisionModel;
|
||||||
import ru.windcorp.progressia.common.util.CoordinatePacker;
|
import ru.windcorp.progressia.common.util.CoordinatePacker;
|
||||||
import ru.windcorp.progressia.common.world.block.BlockData;
|
import ru.windcorp.progressia.common.world.block.BlockData;
|
||||||
@ -55,17 +56,19 @@ public class WorldData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void tmp_generate() {
|
public void tmp_generate() {
|
||||||
final int size = 6;
|
final int size = 10;
|
||||||
Vec3i cursor = new Vec3i(0, 0, 0);
|
Vec3i cursor = new Vec3i(0, 0, 0);
|
||||||
|
|
||||||
for (cursor.x = -(size / 2); cursor.x <= (size / 2); ++cursor.x) {
|
for (cursor.x = -(size / 2); cursor.x <= (size / 2); ++cursor.x) {
|
||||||
for (cursor.y = -(size / 2); cursor.y <= (size / 2); ++cursor.y) {
|
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);
|
ChunkData chunk = new ChunkData(cursor, this);
|
||||||
TestContent.generateChunk(chunk);
|
TestContent.generateChunk(chunk);
|
||||||
addChunk(chunk);
|
addChunk(chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void addChunkListeners(ChunkData chunk) {
|
private void addChunkListeners(ChunkData chunk) {
|
||||||
getListeners().forEach(l -> l.getChunkListeners(this, chunk.getPosition(), chunk::addListener));
|
getListeners().forEach(l -> l.getChunkListeners(this, chunk.getPosition(), chunk::addListener));
|
||||||
@ -140,6 +143,10 @@ public class WorldData {
|
|||||||
return chunks;
|
return chunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TLongSet getChunkKeys() {
|
||||||
|
return chunksByPos.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
public EntityData getEntity(long entityId) {
|
public EntityData getEntity(long entityId) {
|
||||||
return entitiesById.get(entityId);
|
return entitiesById.get(entityId);
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,11 @@ package ru.windcorp.progressia.common.world.entity;
|
|||||||
|
|
||||||
import glm.vec._2.Vec2;
|
import glm.vec._2.Vec2;
|
||||||
import glm.vec._3.Vec3;
|
import glm.vec._3.Vec3;
|
||||||
|
import glm.vec._3.i.Vec3i;
|
||||||
import ru.windcorp.progressia.common.collision.Collideable;
|
import ru.windcorp.progressia.common.collision.Collideable;
|
||||||
import ru.windcorp.progressia.common.collision.CollisionModel;
|
import ru.windcorp.progressia.common.collision.CollisionModel;
|
||||||
import ru.windcorp.progressia.common.state.StatefulObject;
|
import ru.windcorp.progressia.common.state.StatefulObject;
|
||||||
|
import ru.windcorp.progressia.common.world.Coordinates;
|
||||||
|
|
||||||
public class EntityData extends StatefulObject implements Collideable {
|
public class EntityData extends StatefulObject implements Collideable {
|
||||||
|
|
||||||
@ -27,6 +29,16 @@ public class EntityData extends StatefulObject implements Collideable {
|
|||||||
return position;
|
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) {
|
public void setPosition(Vec3 position) {
|
||||||
move(position.sub_(getPosition()));
|
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.common.world.entity.EntityData;
|
||||||
import ru.windcorp.progressia.server.comms.ClientPlayer;
|
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 Server server;
|
||||||
private final ClientPlayer client;
|
private final ClientPlayer client;
|
||||||
@ -28,7 +28,8 @@ public class Player extends PlayerData {
|
|||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getRequestedChunks(Consumer<Vec3i> chunkConsumer) {
|
@Override
|
||||||
|
public void requestChunksToLoad(Consumer<Vec3i> chunkConsumer) {
|
||||||
Vec3i start = getEntity().getPosition().round_();
|
Vec3i start = getEntity().getPosition().round_();
|
||||||
Coordinates.convertInWorldToChunk(start, start);
|
Coordinates.convertInWorldToChunk(start, start);
|
||||||
|
|
||||||
|
@ -112,8 +112,12 @@ public class Server {
|
|||||||
taskQueue.waitAndInvoke(task);
|
taskQueue.waitAndInvoke(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void schedule(Runnable task) {
|
||||||
|
taskQueue.schedule(task);
|
||||||
|
}
|
||||||
|
|
||||||
public void schedule(Consumer<Server> task) {
|
public void schedule(Consumer<Server> task) {
|
||||||
taskQueue.schedule(() -> task.accept(this));
|
schedule(() -> task.accept(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void requestChange(Change change) {
|
public void requestChange(Change change) {
|
||||||
|
@ -5,6 +5,7 @@ import java.util.concurrent.ScheduledExecutorService;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||||
import ru.windcorp.progressia.server.world.ticking.TickerCoordinator;
|
import ru.windcorp.progressia.server.world.ticking.TickerCoordinator;
|
||||||
|
|
||||||
public class ServerThread implements Runnable {
|
public class ServerThread implements Runnable {
|
||||||
@ -56,7 +57,7 @@ public class ServerThread implements Runnable {
|
|||||||
server.tick();
|
server.tick();
|
||||||
ticker.runOneTick();
|
ticker.runOneTick();
|
||||||
} catch (Exception e) {
|
} 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 java.io.IOException;
|
||||||
|
|
||||||
|
import glm.Glm;
|
||||||
import ru.windcorp.progressia.common.comms.packets.PacketLoadChunk;
|
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.io.ChunkIO;
|
||||||
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||||
import ru.windcorp.progressia.common.world.ChunkData;
|
import ru.windcorp.progressia.common.world.ChunkData;
|
||||||
import ru.windcorp.progressia.common.world.WorldData;
|
import ru.windcorp.progressia.common.world.WorldData;
|
||||||
import ru.windcorp.progressia.common.world.WorldDataListener;
|
import ru.windcorp.progressia.common.world.WorldDataListener;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||||
import ru.windcorp.progressia.server.Server;
|
import ru.windcorp.progressia.server.Server;
|
||||||
|
|
||||||
public class TestChunkSender implements WorldDataListener {
|
public class TestChunkSender implements WorldDataListener {
|
||||||
@ -21,12 +24,32 @@ public class TestChunkSender implements WorldDataListener {
|
|||||||
@Override
|
@Override
|
||||||
public void onChunkLoaded(WorldData world, ChunkData chunk) {
|
public void onChunkLoaded(WorldData world, ChunkData chunk) {
|
||||||
PacketLoadChunk packet = new PacketLoadChunk("Core:LoadChunk");
|
PacketLoadChunk packet = new PacketLoadChunk("Core:LoadChunk");
|
||||||
|
|
||||||
|
packet.getPosition().set(
|
||||||
|
chunk.getPosition().x,
|
||||||
|
chunk.getPosition().y,
|
||||||
|
chunk.getPosition().z
|
||||||
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ChunkIO.save(chunk, packet.getData().getOutputStream());
|
ChunkIO.save(chunk, packet.getData().getOutputStream());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
CrashReports.report(e, "TestChunkSender fjcked up. javahorse stupid");
|
CrashReports.report(e, "TestChunkSender fjcked up. javahorse stupid");
|
||||||
}
|
}
|
||||||
|
|
||||||
server.getClientManager().broadcastGamePacket(packet);
|
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.state.StatefulObjectRegistry.Factory;
|
||||||
import ru.windcorp.progressia.common.util.Vectors;
|
import ru.windcorp.progressia.common.util.Vectors;
|
||||||
import ru.windcorp.progressia.common.world.ChunkData;
|
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.block.*;
|
||||||
import ru.windcorp.progressia.common.world.entity.*;
|
import ru.windcorp.progressia.common.world.entity.*;
|
||||||
import ru.windcorp.progressia.common.world.tile.*;
|
import ru.windcorp.progressia.common.world.tile.*;
|
||||||
@ -258,20 +259,32 @@ public class TestContent {
|
|||||||
TileData flowers = TileDataRegistry.getInstance().get("Test:YellowFlowers");
|
TileData flowers = TileDataRegistry.getInstance().get("Test:YellowFlowers");
|
||||||
TileData sand = TileDataRegistry.getInstance().get("Test:Sand");
|
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();
|
Vec3i pos = new Vec3i();
|
||||||
|
|
||||||
for (int x = 0; x < bpc; ++x) {
|
for (pos.x = 0; pos.x < bpc; ++pos.x) {
|
||||||
for (int y = 0; y < bpc; ++y) {
|
for (pos.y = 0; pos.y < bpc; ++pos.y) {
|
||||||
for (int z = 0; z < bpc; ++z) {
|
for (pos.z = 0; pos.z < bpc; ++pos.z) {
|
||||||
|
|
||||||
pos.set(x, y, z);
|
int layer = pos.z - heightMap[pos.x][pos.y];
|
||||||
float f = aPoint.sub(pos, pos).length();
|
|
||||||
pos.set(x, y, z);
|
|
||||||
|
|
||||||
if (f > 17) {
|
if (layer < -4) {
|
||||||
chunk.setBlock(pos, stone, false);
|
chunk.setBlock(pos, stone, false);
|
||||||
} else if (f > 14) {
|
} else if (layer < 0) {
|
||||||
chunk.setBlock(pos, dirt, false);
|
chunk.setBlock(pos, dirt, false);
|
||||||
} else {
|
} else {
|
||||||
chunk.setBlock(pos, air, false);
|
chunk.setBlock(pos, air, false);
|
||||||
@ -283,11 +296,15 @@ public class TestContent {
|
|||||||
|
|
||||||
for (int x = 0; x < bpc; ++x) {
|
for (int x = 0; x < bpc; ++x) {
|
||||||
for (int y = 0; y < bpc; ++y) {
|
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);
|
// int z = heightMap[x][y];
|
||||||
if (pos.z < 0) continue;
|
|
||||||
|
|
||||||
|
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);
|
chunk.getTiles(pos, BlockFace.TOP).add(grass);
|
||||||
for (BlockFace face : BlockFace.getFaces()) {
|
for (BlockFace face : BlockFace.getFaces()) {
|
||||||
if (face.getVector().z != 0) continue;
|
if (face.getVector().z != 0) continue;
|
||||||
@ -317,11 +334,13 @@ public class TestContent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Glm.equals(chunk.getPosition(), Vectors.ZERO_3i)) {
|
if (Glm.equals(chunk.getPosition(), Vectors.ZERO_3i)) {
|
||||||
EntityData player = EntityDataRegistry.getInstance().create("Test:Player");
|
EntityData player = EntityDataRegistry.getInstance().create("Test:Player");
|
||||||
player.setEntityId(PLAYER_ENTITY_ID);
|
player.setEntityId(PLAYER_ENTITY_ID);
|
||||||
player.setPosition(new Vec3(-6, -6, 20));
|
player.setPosition(new Vec3(8, 8, 8));
|
||||||
player.setDirection(new Vec2(
|
player.setDirection(new Vec2(
|
||||||
(float) Math.toRadians(40), (float) Math.toRadians(45)
|
(float) Math.toRadians(40), (float) Math.toRadians(45)
|
||||||
));
|
));
|
||||||
|
Reference in New Issue
Block a user