From 3d695e03122f79c01cbe150dcc5a571264f117ac Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Wed, 20 Jul 2022 18:51:24 +0200 Subject: [PATCH] Added gunshot raytracing for environmental damage. --- .../aos2_client/sound/SoundManager.java | 7 +-- .../andrewl/aos2_client/sound/WaveData.java | 5 +- .../nl/andrewl/aos_core/model/item/Gun.java | 2 +- .../andrewl/aos_core/model/world/World.java | 47 ++++++------------- .../logic/PlayerActionManager.java | 5 ++ 5 files changed, 27 insertions(+), 39 deletions(-) diff --git a/client/src/main/java/nl/andrewl/aos2_client/sound/SoundManager.java b/client/src/main/java/nl/andrewl/aos2_client/sound/SoundManager.java index d6420a7..d23ce29 100644 --- a/client/src/main/java/nl/andrewl/aos2_client/sound/SoundManager.java +++ b/client/src/main/java/nl/andrewl/aos2_client/sound/SoundManager.java @@ -1,6 +1,5 @@ package nl.andrewl.aos2_client.sound; -import nl.andrewl.aos2_client.model.ClientPlayer; import org.joml.Vector3f; import org.lwjgl.openal.AL; import org.lwjgl.openal.ALC; @@ -11,9 +10,12 @@ import java.nio.IntBuffer; import java.util.HashMap; import java.util.Map; -import static org.lwjgl.openal.ALC10.*; import static org.lwjgl.openal.AL10.*; +import static org.lwjgl.openal.ALC10.*; +/** + * Main class for managing the OpenAL audio interface. + */ public class SoundManager { private final long alContext; private final Map audioBuffers = new HashMap<>(); @@ -24,7 +26,6 @@ public class SoundManager { alContext = alcCreateContext(device, (IntBuffer) null); alcMakeContextCurrent(alContext); AL.createCapabilities(capabilities); - } public void load(String name, String resource) { diff --git a/client/src/main/java/nl/andrewl/aos2_client/sound/WaveData.java b/client/src/main/java/nl/andrewl/aos2_client/sound/WaveData.java index 079270d..5f6b8c8 100644 --- a/client/src/main/java/nl/andrewl/aos2_client/sound/WaveData.java +++ b/client/src/main/java/nl/andrewl/aos2_client/sound/WaveData.java @@ -44,7 +44,7 @@ public class WaveData { } } - private ByteBuffer loadData() { + private void loadData() { try { int bytesRead = audioStream.read(dataArray, 0, totalBytes); data.clear(); @@ -54,7 +54,6 @@ public class WaveData { e.printStackTrace(); System.err.println("Couldn't read bytes from audio stream!"); } - return data; } @@ -62,7 +61,7 @@ public class WaveData { InputStream stream = WaveData.class.getClassLoader().getResourceAsStream(file); if (stream == null) { System.err.println("Couldn't find file: " + file); - return null; + throw new RuntimeException(); } InputStream bufferedInput = new BufferedInputStream(stream); AudioInputStream audioStream; diff --git a/core/src/main/java/nl/andrewl/aos_core/model/item/Gun.java b/core/src/main/java/nl/andrewl/aos_core/model/item/Gun.java index 6ae92d1..127b34a 100644 --- a/core/src/main/java/nl/andrewl/aos_core/model/item/Gun.java +++ b/core/src/main/java/nl/andrewl/aos_core/model/item/Gun.java @@ -14,7 +14,7 @@ public class Gun extends Item { private final float reloadTime; private final float baseDamage; private final float recoil; - private boolean automatic; + private final boolean automatic; public Gun( int id, diff --git a/core/src/main/java/nl/andrewl/aos_core/model/world/World.java b/core/src/main/java/nl/andrewl/aos_core/model/world/World.java index 8a9fbd7..fd9cdf2 100644 --- a/core/src/main/java/nl/andrewl/aos_core/model/world/World.java +++ b/core/src/main/java/nl/andrewl/aos_core/model/world/World.java @@ -180,43 +180,26 @@ public class World { float factorY = Float.MAX_VALUE; float factorZ = Float.MAX_VALUE; - if (dir.x != 0) { - float nextValue; - if (dir.x > 0) { - nextValue = (Math.ceil(pos.x) == pos.x) ? pos.x + 1 : Math.ceil(pos.x); - } else { - nextValue = Math.floor(pos.x) - DELTA; - } - float diff = nextValue - pos.x; - factorX = Math.abs(diff / dir.x); - } - - if (dir.y != 0) { - float nextValue; - if (dir.y > 0) { - nextValue = (Math.ceil(pos.y) == pos.y) ? pos.y + 1 : Math.ceil(pos.y); - } else { - nextValue = Math.floor(pos.y) - DELTA; - } - float diff = nextValue - pos.y; - factorY = Math.abs(diff / dir.y); - } - - if (dir.z != 0) { - float nextValue; - if (dir.z > 0) { - nextValue = (Math.ceil(pos.z) == pos.z) ? pos.z + 1 : Math.ceil(pos.z); - } else { - nextValue = Math.floor(pos.z) - DELTA; - } - float diff = nextValue - pos.z; - factorZ = Math.abs(diff / dir.z); - } + if (dir.x != 0) factorX = factorToNextValue(pos.x, dir.x); + if (dir.y != 0) factorY = factorToNextValue(pos.y, dir.y); + if (dir.z != 0) factorZ = factorToNextValue(pos.z, dir.z); float minFactor = Math.min(factorX, Math.min(factorY, factorZ)); dir.mulAdd(minFactor, pos, pos); } + private static float factorToNextValue(float n, float dir) { + if (dir == 0) return 0; + float nextValue; + if (dir > 0) { + nextValue = (Math.ceil(n) == n) ? n + 1 : Math.ceil(n); + } else { + nextValue = Math.floor(n) - DELTA; + } + float diff = nextValue - n; + return Math.abs(diff / dir); + } + /** * Gets the chunk position at the specified world position. * @param x The x coordinate. diff --git a/server/src/main/java/nl/andrewl/aos2_server/logic/PlayerActionManager.java b/server/src/main/java/nl/andrewl/aos2_server/logic/PlayerActionManager.java index 23ed622..b3f484d 100644 --- a/server/src/main/java/nl/andrewl/aos2_server/logic/PlayerActionManager.java +++ b/server/src/main/java/nl/andrewl/aos2_server/logic/PlayerActionManager.java @@ -101,6 +101,11 @@ public class PlayerActionManager { (gun.isAutomatic() || !gunNeedsReCock) ) { // TODO: trace a ray from gun to see if players intersect with it. + var hit = world.getLookingAtPos(player.getEyePosition(), player.getViewVector(), 100); + if (hit != null) { + world.setBlockAt(hit.pos().x, hit.pos().y, hit.pos().z, (byte) 0); + server.getPlayerManager().broadcastUdpMessage(ChunkUpdateMessage.fromWorld(hit.pos(), world)); + } g.setBulletCount(g.getBulletCount() - 1); gunLastShotAt = now; if (!gun.isAutomatic()) {