diff --git a/client/src/main/resources/shader/chunk/fragment.glsl b/client/src/main/resources/shader/chunk/fragment.glsl index 497c2a2..9c0a671 100644 --- a/client/src/main/resources/shader/chunk/fragment.glsl +++ b/client/src/main/resources/shader/chunk/fragment.glsl @@ -7,7 +7,7 @@ in vec3 vertexNormal; out vec4 fragmentColor; void main() { - vec3 lightDirection = normalize(vec3(0.1, -1.0, -0.5));// TODO: Add this via a uniform. + vec3 lightDirection = normalize(vec3(0.5, -1.0, -0.5));// TODO: Add this via a uniform. vec3 lightColor = vec3(1.0, 1.0, 0.9); // TODO: Add this via a uniform. vec3 ambientComponent = vec3(0.1, 0.1, 0.1); diff --git a/core/src/main/java/nl/andrewl/aos_core/model/World.java b/core/src/main/java/nl/andrewl/aos_core/model/World.java index 050d7f6..987bea4 100644 --- a/core/src/main/java/nl/andrewl/aos_core/model/World.java +++ b/core/src/main/java/nl/andrewl/aos_core/model/World.java @@ -8,6 +8,10 @@ import org.joml.Vector3ic; import java.util.HashMap; import java.util.Map; +/** + * A world is just a collection of chunks that together form the environment + * that players can interact in. + */ public class World { private final Map chunkMap = new HashMap<>(); diff --git a/core/src/main/java/nl/andrewl/aos_core/model/WorldIO.java b/core/src/main/java/nl/andrewl/aos_core/model/WorldIO.java new file mode 100644 index 0000000..10b1813 --- /dev/null +++ b/core/src/main/java/nl/andrewl/aos_core/model/WorldIO.java @@ -0,0 +1,44 @@ +package nl.andrewl.aos_core.model; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +/** + * Utility class for reading and writing worlds to files. + */ +public final class WorldIO { + public static void write(World world, Path path) throws IOException { + var chunks = world.getChunkMap().values(); + try (var os = Files.newOutputStream(path)) { + var out = new DataOutputStream(os); + out.writeInt(chunks.size()); + for (var chunk : chunks) { + out.writeInt(chunk.getPosition().x); + out.writeInt(chunk.getPosition().y); + out.writeInt(chunk.getPosition().z); + out.write(chunk.getBlocks()); + } + } + } + + public static World read(Path path) throws IOException { + World world = new World(); + try (var is = Files.newInputStream(path)) { + var in = new DataInputStream(is); + int chunkCount = in.readInt(); + for (int i = 0; i < chunkCount; i++) { + Chunk chunk = new Chunk( + in.readInt(), + in.readInt(), + in.readInt(), + in.readNBytes(Chunk.TOTAL_SIZE) + ); + world.addChunk(chunk); + } + } + return world; + } +} diff --git a/server/src/main/java/nl/andrewl/aos2_server/Server.java b/server/src/main/java/nl/andrewl/aos2_server/Server.java index 850d4a5..810f111 100644 --- a/server/src/main/java/nl/andrewl/aos2_server/Server.java +++ b/server/src/main/java/nl/andrewl/aos2_server/Server.java @@ -1,20 +1,19 @@ package nl.andrewl.aos2_server; -import nl.andrewl.aos_core.model.Chunk; import nl.andrewl.aos_core.model.World; +import nl.andrewl.aos_core.model.WorldIO; import nl.andrewl.aos_core.net.UdpReceiver; import nl.andrewl.aos_core.net.udp.ClientInputState; import nl.andrewl.aos_core.net.udp.ClientOrientationState; import nl.andrewl.aos_core.net.udp.DatagramInit; import nl.andrewl.aos_core.net.udp.PlayerUpdateMessage; import nl.andrewl.record_net.Message; -import org.joml.Vector3f; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.*; -import java.util.Random; +import java.nio.file.Path; import java.util.concurrent.ForkJoinPool; public class Server implements Runnable { @@ -37,24 +36,26 @@ public class Server implements Runnable { this.worldUpdater = new WorldUpdater(this, 20); // Generate world. TODO: do this elsewhere. - Random rand = new Random(1); - this.world = new World(); - for (int x = -5; x <= 5; x++) { - for (int y = 0; y <= 5; y++) { - for (int z = -3; z <= 3; z++) { - Chunk chunk = new Chunk(x, y, z); - if (y <= 3) { - for (int i = 0; i < Chunk.TOTAL_SIZE; i++) { - chunk.getBlocks()[i] = (byte) rand.nextInt(20, 40); - } - } - world.addChunk(chunk); - } - } - } - world.setBlockAt(new Vector3f(5, 64, 5), (byte) 50); - world.setBlockAt(new Vector3f(5, 65, 6), (byte) 50); - world.setBlockAt(new Vector3f(5, 66, 7), (byte) 50); +// Random rand = new Random(1); +// this.world = new World(); +// for (int x = -5; x <= 5; x++) { +// for (int y = 0; y <= 5; y++) { +// for (int z = -3; z <= 3; z++) { +// Chunk chunk = new Chunk(x, y, z); +// if (y <= 3) { +// for (int i = 0; i < Chunk.TOTAL_SIZE; i++) { +// chunk.getBlocks()[i] = (byte) rand.nextInt(20, 40); +// } +// } +// world.addChunk(chunk); +// } +// } +// } +// world.setBlockAt(new Vector3f(5, 64, 5), (byte) 50); +// world.setBlockAt(new Vector3f(5, 65, 6), (byte) 50); +// world.setBlockAt(new Vector3f(5, 66, 7), (byte) 50); +// WorldIO.write(world, Path.of("testworld")); + this.world = WorldIO.read(Path.of("testworld")); } @Override diff --git a/server/src/main/java/nl/andrewl/aos2_server/WorldUpdater.java b/server/src/main/java/nl/andrewl/aos2_server/WorldUpdater.java index f688bba..cbcfb6c 100644 --- a/server/src/main/java/nl/andrewl/aos2_server/WorldUpdater.java +++ b/server/src/main/java/nl/andrewl/aos2_server/WorldUpdater.java @@ -89,7 +89,7 @@ public class WorldUpdater implements Runnable { } // Apply horizontal deceleration to the player before computing any input-derived acceleration. - if (hv.length() > 0) { + if (grounded && hv.length() > 0) { Vector3f deceleration = new Vector3f(hv).negate().normalize().mul(0.1f); hv.add(deceleration); if (hv.length() < 0.1f) { @@ -107,30 +107,29 @@ public class WorldUpdater implements Runnable { } // Compute horizontal motion separately. - if (inputState.forward()) a.z -= 1; - if (inputState.backward()) a.z += 1; - if (inputState.left()) a.x -= 1; - if (inputState.right()) a.x += 1; -// if (inputState.crouching()) a.y -= 1; // TODO: do crouching instead of down. - if (a.lengthSquared() > 0) { - a.normalize(); - Matrix4f moveTransform = new Matrix4f(); - moveTransform.rotate(player.getOrientation().x, new Vector3f(0, 1, 0)); - moveTransform.transformDirection(a); - hv.add(a); + if (grounded) { + if (inputState.forward()) a.z -= 1; + if (inputState.backward()) a.z += 1; + if (inputState.left()) a.x -= 1; + if (inputState.right()) a.x += 1; +// if (inputState.crouching()) a.y -= 1; // TODO: do crouching instead of down. + if (a.lengthSquared() > 0) { + a.normalize(); + Matrix4f moveTransform = new Matrix4f(); + moveTransform.rotate(player.getOrientation().x, new Vector3f(0, 1, 0)); + moveTransform.transformDirection(a); + hv.add(a); - final float maxSpeed = 0.25f; // Blocks per tick. - if (hv.length() > maxSpeed) { - hv.normalize(maxSpeed); + final float maxSpeed = 0.25f; // Blocks per tick. + if (hv.length() > maxSpeed) { + hv.normalize(maxSpeed); + } + v.x = hv.x; + v.z = hv.z; + updated = true; } - v.x = hv.x; - v.z = hv.z; - updated = true; } - // Check if the player is colliding with the world. - - // Apply velocity to the player's position. if (v.lengthSquared() > 0) { p.add(v);