Added hit stuff, but it doesn't work yet.

This commit is contained in:
Andrew Lalis 2022-07-15 20:40:56 +02:00
parent 2ebf5ad1bf
commit 236a421296
5 changed files with 71 additions and 15 deletions

View File

@ -0,0 +1,13 @@
package nl.andrewl.aos_core;
import org.joml.Vector3i;
import org.joml.Vector3ic;
public class Directions {
public static final Vector3ic UP = new Vector3i(0, 1, 0);
public static final Vector3ic DOWN = new Vector3i(0, -1, 0);
public static final Vector3ic NEGATIVE_X = new Vector3i(-1, 0, 0);
public static final Vector3ic POSITIVE_X = new Vector3i(1, 0, 0);
public static final Vector3ic NEGATIVE_Z = new Vector3i(0, 0, -1);
public static final Vector3ic POSITIVE_Z = new Vector3i(0, 0, 1);
}

View File

@ -0,0 +1,13 @@
package nl.andrewl.aos_core.model;
import org.joml.Vector3i;
import org.joml.Vector3ic;
/**
* Represents the point at which a ray hits a block, often used when casting a
* ray from a player's location to see if they break or place a block.
*/
public record Hit (
Vector3i pos,
Vector3ic norm
) {}

View File

@ -1,5 +1,6 @@
package nl.andrewl.aos_core.model;
import nl.andrewl.aos_core.Directions;
import org.joml.Math;
import org.joml.Vector3f;
import org.joml.Vector3i;
@ -95,7 +96,7 @@ public class World {
* @return The location of the block that is looked at, or null if none
* could be found.
*/
public Vector3i getLookingAtPos(Vector3f eyePos, Vector3f eyeDir, float limit) {
public Hit getLookingAtPos(Vector3f eyePos, Vector3f eyeDir, float limit) {
if (eyeDir.lengthSquared() == 0 || limit <= 0) return null;
Vector3f pos = new Vector3f(eyePos);
Vector3f movement = new Vector3f(); // Pre-allocate this vector.
@ -120,11 +121,22 @@ public class World {
movement.set(eyeDir).mul(minFactor);
pos.add(movement);
if (getBlockAt(pos) > 0) {
return new Vector3i(
Vector3f prevPos = new Vector3f(pos).sub(movement);
Vector3i hitPos = new Vector3i(
(int) Math.floor(pos.x),
(int) Math.floor(pos.y),
(int) Math.floor(pos.z)
);
Vector3ic hitNorm = null;
if (prevPos.y > hitPos.y + 1) hitNorm = Directions.UP;
else if (prevPos.y < hitPos.y) hitNorm = Directions.DOWN;
else if (prevPos.x > hitPos.x + 1) hitNorm = Directions.POSITIVE_X;
else if (prevPos.x < hitPos.x) hitNorm = Directions.NEGATIVE_X;
else if (prevPos.z > hitPos.z + 1) hitNorm = Directions.POSITIVE_Z;
else if (prevPos.z < hitPos.z) hitNorm = Directions.NEGATIVE_Z;
return new Hit(hitPos, hitNorm);
}
}
return null;

View File

@ -1,6 +1,8 @@
package nl.andrewl.aos_core.net.udp;
import nl.andrewl.aos_core.model.World;
import nl.andrewl.record_net.Message;
import org.joml.Vector3i;
/**
* A message that's sent to clients when a block in a chunk is updated.
@ -16,4 +18,14 @@ public record ChunkUpdateMessage(
int cx, int cy, int cz,
int lx, int ly, int lz,
byte newBlock
) implements Message {}
) implements Message {
public static ChunkUpdateMessage fromWorld(Vector3i worldPos, World world) {
Vector3i chunkPos = World.getChunkPosAt(worldPos);
Vector3i localPos = World.getLocalPosAt(worldPos);
return new ChunkUpdateMessage(
chunkPos.x, chunkPos.y, chunkPos.z,
localPos.x, localPos.y, localPos.z,
world.getBlockAt(worldPos.x, worldPos.y, worldPos.z)
);
}
}

View File

@ -1,6 +1,5 @@
package nl.andrewl.aos2_server;
import nl.andrewl.aos_core.model.Chunk;
import nl.andrewl.aos_core.model.Player;
import nl.andrewl.aos_core.model.World;
import nl.andrewl.aos_core.net.udp.ChunkUpdateMessage;
@ -63,18 +62,25 @@ public class ServerPlayer extends Player {
if (lastInputState.hitting() && now - lastBlockRemovedAt > BLOCK_REMOVE_COOLDOWN) {
Vector3f eyePos = new Vector3f(position);
eyePos.y += getEyeHeight();
Vector3i targetPos = world.getLookingAtPos(eyePos, viewVector, 10);
System.out.println(targetPos);
if (targetPos != null) {
Vector3i chunkPos = World.getChunkPosAt(targetPos);
Vector3i localPos = World.getLocalPosAt(targetPos);
world.setBlockAt(targetPos.x, targetPos.y, targetPos.z, (byte) 0);
var hit = world.getLookingAtPos(eyePos, viewVector, 10);
System.out.println(hit);
if (hit != null) {
world.setBlockAt(hit.pos().x, hit.pos().y, hit.pos().z, (byte) 0);
lastBlockRemovedAt = now;
server.getPlayerManager().broadcastUdpMessage(new ChunkUpdateMessage(
chunkPos.x, chunkPos.y, chunkPos.z,
localPos.x, localPos.y, localPos.z,
(byte) 0
));
server.getPlayerManager().broadcastUdpMessage(ChunkUpdateMessage.fromWorld(hit.pos(), world));
}
}
if (lastInputState.interacting() && now - lastBlockRemovedAt > BLOCK_REMOVE_COOLDOWN) {
Vector3f eyePos = new Vector3f(position);
eyePos.y += getEyeHeight();
var hit = world.getLookingAtPos(eyePos, viewVector, 10);
System.out.println(hit);
if (hit != null) {
Vector3i placePos = new Vector3i(hit.pos());
placePos.add(hit.norm());
world.setBlockAt(placePos.x, placePos.y, placePos.z, (byte) 1);
lastBlockRemovedAt = now;
server.getPlayerManager().broadcastUdpMessage(ChunkUpdateMessage.fromWorld(placePos, world));
}
}
tickMovement(dt, world);