diff --git a/client/src/main/java/nl/andrewl/aos2_client/Client.java b/client/src/main/java/nl/andrewl/aos2_client/Client.java index f4c62b1..1cf99f5 100644 --- a/client/src/main/java/nl/andrewl/aos2_client/Client.java +++ b/client/src/main/java/nl/andrewl/aos2_client/Client.java @@ -9,7 +9,6 @@ import nl.andrewl.aos2_client.model.ClientPlayer; import nl.andrewl.aos2_client.model.OtherPlayer; import nl.andrewl.aos2_client.render.GameRenderer; import nl.andrewl.aos2_client.sound.SoundManager; -import nl.andrewl.aos2_client.sound.SoundSource; import nl.andrewl.aos_core.config.Config; import nl.andrewl.aos_core.model.Player; import nl.andrewl.aos_core.model.Projectile; @@ -38,14 +37,13 @@ public class Client implements Runnable { private final InputHandler inputHandler; private GameRenderer gameRenderer; private SoundManager soundManager; - private SoundSource playerSource; private long lastPlayerUpdate = 0; private ClientWorld world; private ClientPlayer myPlayer; private final Map players; private final Map projectiles; - private Map teams; + private final Map teams; public Client(ClientConfig config) { this.config = config; @@ -89,17 +87,18 @@ public class Client implements Runnable { new PlayerInputMouseClickCallback(inputHandler) ); soundManager = new SoundManager(); - soundManager.load("rifle", "sound/m1garand-shot1.wav"); - playerSource = new SoundSource(); + log.debug("Sound system initialized."); long lastFrameAt = System.currentTimeMillis(); while (!gameRenderer.windowShouldClose() && !communicationHandler.isDone()) { long now = System.currentTimeMillis(); float dt = (now - lastFrameAt) / 1000f; world.processQueuedChunkUpdates(); + soundManager.updateListener(myPlayer.getPosition(), myPlayer.getVelocity()); gameRenderer.getCamera().interpolatePosition(dt); - interpolatePlayers(dt); + interpolatePlayers(now, dt); interpolateProjectiles(dt); + soundManager.playWalkingSounds(myPlayer, now); gameRenderer.draw(); lastFrameAt = now; } @@ -156,7 +155,7 @@ public class Client implements Runnable { } else if (msg instanceof PlayerLeaveMessage leaveMessage) { players.remove(leaveMessage.id()); } else if (msg instanceof SoundMessage soundMessage) { - playerSource.play(soundManager.getSoundBuffer(soundMessage.name())); + soundManager.play(soundMessage.name(), soundMessage.gain(), new Vector3f(soundMessage.px(), soundMessage.py(), soundMessage.pz())); } else if (msg instanceof ProjectileMessage pm) { Projectile p = projectiles.get(pm.id()); if (p == null && !pm.destroyed()) { @@ -186,10 +185,6 @@ public class Client implements Runnable { return teams; } - public void setTeams(Map teams) { - this.teams = teams; - } - public Map getPlayers() { return players; } @@ -198,12 +193,13 @@ public class Client implements Runnable { return projectiles; } - public void interpolatePlayers(float dt) { + public void interpolatePlayers(long now, float dt) { Vector3f movement = new Vector3f(); for (var player : players.values()) { movement.set(player.getVelocity()).mul(dt); player.getPosition().add(movement); player.updateModelTransform(); + soundManager.playWalkingSounds(player, now); } } 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 d23ce29..8711744 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,31 +1,81 @@ package nl.andrewl.aos2_client.sound; +import nl.andrewl.aos_core.model.Player; import org.joml.Vector3f; import org.lwjgl.openal.AL; import org.lwjgl.openal.ALC; import org.lwjgl.openal.ALCCapabilities; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.nio.ByteBuffer; import java.nio.IntBuffer; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ThreadLocalRandom; -import static org.lwjgl.openal.AL10.*; +import static org.lwjgl.openal.AL11.*; import static org.lwjgl.openal.ALC10.*; /** * Main class for managing the OpenAL audio interface. */ public class SoundManager { + private static final Logger log = LoggerFactory.getLogger(SoundManager.class); + + private static final int SOURCE_COUNT = 16; + private final long alContext; private final Map audioBuffers = new HashMap<>(); + /** + * A set of pre-allocated sound sources that can be utilized when short + * sounds need to be played. + */ + private final List availableSources = new ArrayList<>(SOURCE_COUNT); + + private final Map lastPlayerWalkingSounds = new ConcurrentHashMap<>(); + public SoundManager() { long device = alcOpenDevice((ByteBuffer) null); ALCCapabilities capabilities = ALC.createCapabilities(device); alContext = alcCreateContext(device, (IntBuffer) null); alcMakeContextCurrent(alContext); AL.createCapabilities(capabilities); + + alDistanceModel(AL_EXPONENT_DISTANCE); + + for (int i = 0; i < SOURCE_COUNT; i++) { + SoundSource source = new SoundSource(); + alSourcef(source.getId(), AL_ROLLOFF_FACTOR, 1); + alSourcef(source.getId(), AL_REFERENCE_DISTANCE, 10); + alSourcef(source.getId(), AL_MAX_DISTANCE, 20); + availableSources.add(source); + } + + loadSounds(); + } + + private void loadSounds() { + load("footsteps_1", "sound/m_footsteps_1.wav"); + load("footsteps_2", "sound/m_footsteps_2.wav"); + load("footsteps_3", "sound/m_footsteps_3.wav"); + load("footsteps_4", "sound/m_footsteps_4.wav"); + load("shot_m1-garand_1", "sound/m_shot_m1-garand_1.wav"); + load("shot_ak-47_1", "sound/m_shot_ak-47_1.wav"); + load("bullet_impact_1", "sound/m_bullet_impact_1.wav"); + load("bullet_impact_2", "sound/m_bullet_impact_2.wav"); + load("bullet_impact_3", "sound/m_bullet_impact_3.wav"); + load("bullet_impact_4", "sound/m_bullet_impact_4.wav"); + load("bullet_impact_5", "sound/m_bullet_impact_5.wav"); + load("reload", "sound/m_reload.wav"); + load("death", "sound/m_death.wav"); + load("hurt_1", "sound/m_hurt_1.wav"); + load("hurt_2", "sound/m_hurt_2.wav"); + load("hurt_3", "sound/m_hurt_3.wav"); } public void load(String name, String resource) { @@ -41,14 +91,58 @@ public class SoundManager { alListener3f(AL_VELOCITY, velocity.x(), velocity.y(), velocity.z()); } - public int getSoundBuffer(String name) { + public Integer getSoundBuffer(String name) { return audioBuffers.get(name); } + public void play(String soundName, float gain, Vector3f position, Vector3f velocity) { + Integer bufferId = getSoundBuffer(soundName); + if (bufferId == null) { + log.warn("Attempted to play unknown sound \"{}\"", soundName); + } else { + SoundSource source = getNextAvailableSoundSource(); + if (source != null) { + source.setPosition(position); + source.setVelocity(velocity); + source.setGain(gain); + source.play(bufferId); + } else { + log.warn("Couldn't get an available sound source to play sound \"{}\"", soundName); + } + } + } + + public void play(String soundName, float gain, Vector3f position) { + play(soundName, gain, position, new Vector3f(0, 0, 0)); + } + + public void playWalkingSounds(Player player, long now) { + if (player.getVelocity().length() <= 0) return; + long lastSoundAt = lastPlayerWalkingSounds.computeIfAbsent(player, p -> 0L); + long delay = 500; // Delay in ms between footfalls. + if (player.getVelocity().length() > 5) delay -= 150; + if (player.getVelocity().length() < 3) delay += 150; + if (lastSoundAt + delay < now) { + int choice = ThreadLocalRandom.current().nextInt(1, 5); + play("footsteps_" + choice, 0.5f, player.getPosition(), player.getVelocity()); + lastPlayerWalkingSounds.put(player, now); + } + } + + private SoundSource getNextAvailableSoundSource() { + for (var source : availableSources) { + if (!source.isPlaying()) return source; + } + return null; + } + public void free() { for (var bufferId : audioBuffers.values()) { alDeleteBuffers(bufferId); } + for (var source : availableSources) { + source.free(); + } alcDestroyContext(alContext); } } diff --git a/client/src/main/java/nl/andrewl/aos2_client/sound/SoundSource.java b/client/src/main/java/nl/andrewl/aos2_client/sound/SoundSource.java index c2b782f..8b9eee0 100644 --- a/client/src/main/java/nl/andrewl/aos2_client/sound/SoundSource.java +++ b/client/src/main/java/nl/andrewl/aos2_client/sound/SoundSource.java @@ -1,5 +1,7 @@ package nl.andrewl.aos2_client.sound; +import org.joml.Vector3f; + import static org.lwjgl.openal.AL10.*; public class SoundSource { @@ -17,6 +19,30 @@ public class SoundSource { alSourcePlay(sourceId); } + public void setPosition(Vector3f pos) { + alSource3f(sourceId, AL_POSITION, pos.x, pos.y, pos.z); + } + + public void setVelocity(Vector3f vel) { + alSource3f(sourceId, AL_VELOCITY, vel.x, vel.y, vel.z); + } + + public void setDirection(Vector3f dir) { + alSource3f(sourceId, AL_DIRECTION, dir.x, dir.y, dir.z); + } + + public void setGain(float gain) { + alSourcef(sourceId, AL_GAIN, gain); + } + + public int getId() { + return sourceId; + } + + public boolean isPlaying() { + return alGetSourcei(sourceId, AL_SOURCE_STATE) == AL_PLAYING; + } + public void free() { alDeleteSources(sourceId); } diff --git a/client/src/main/resources/sound/block_break_1.wav b/client/src/main/resources/sound/block_break_1.wav new file mode 100644 index 0000000..2c3a1a0 Binary files /dev/null and b/client/src/main/resources/sound/block_break_1.wav differ diff --git a/client/src/main/resources/sound/block_place_1.wav b/client/src/main/resources/sound/block_place_1.wav new file mode 100644 index 0000000..c174a45 Binary files /dev/null and b/client/src/main/resources/sound/block_place_1.wav differ diff --git a/client/src/main/resources/sound/bullet_impact_1.wav b/client/src/main/resources/sound/bullet_impact_1.wav new file mode 100644 index 0000000..79de43e Binary files /dev/null and b/client/src/main/resources/sound/bullet_impact_1.wav differ diff --git a/client/src/main/resources/sound/bullet_impact_2.wav b/client/src/main/resources/sound/bullet_impact_2.wav new file mode 100644 index 0000000..156fe5f Binary files /dev/null and b/client/src/main/resources/sound/bullet_impact_2.wav differ diff --git a/client/src/main/resources/sound/bullet_impact_3.wav b/client/src/main/resources/sound/bullet_impact_3.wav new file mode 100644 index 0000000..14684cd Binary files /dev/null and b/client/src/main/resources/sound/bullet_impact_3.wav differ diff --git a/client/src/main/resources/sound/bullet_impact_4.wav b/client/src/main/resources/sound/bullet_impact_4.wav new file mode 100644 index 0000000..67ce995 Binary files /dev/null and b/client/src/main/resources/sound/bullet_impact_4.wav differ diff --git a/client/src/main/resources/sound/bullet_impact_5.wav b/client/src/main/resources/sound/bullet_impact_5.wav new file mode 100644 index 0000000..7cfe1fa Binary files /dev/null and b/client/src/main/resources/sound/bullet_impact_5.wav differ diff --git a/client/src/main/resources/sound/death.wav b/client/src/main/resources/sound/death.wav new file mode 100644 index 0000000..8f5f2d1 Binary files /dev/null and b/client/src/main/resources/sound/death.wav differ diff --git a/client/src/main/resources/sound/footsteps_1.wav b/client/src/main/resources/sound/footsteps_1.wav new file mode 100644 index 0000000..2cb729f Binary files /dev/null and b/client/src/main/resources/sound/footsteps_1.wav differ diff --git a/client/src/main/resources/sound/footsteps_2.wav b/client/src/main/resources/sound/footsteps_2.wav new file mode 100644 index 0000000..542d079 Binary files /dev/null and b/client/src/main/resources/sound/footsteps_2.wav differ diff --git a/client/src/main/resources/sound/footsteps_3.wav b/client/src/main/resources/sound/footsteps_3.wav new file mode 100644 index 0000000..3a7e97f Binary files /dev/null and b/client/src/main/resources/sound/footsteps_3.wav differ diff --git a/client/src/main/resources/sound/footsteps_4.wav b/client/src/main/resources/sound/footsteps_4.wav new file mode 100644 index 0000000..3b6d4d3 Binary files /dev/null and b/client/src/main/resources/sound/footsteps_4.wav differ diff --git a/client/src/main/resources/sound/hurt_1.wav b/client/src/main/resources/sound/hurt_1.wav new file mode 100644 index 0000000..b40c79b Binary files /dev/null and b/client/src/main/resources/sound/hurt_1.wav differ diff --git a/client/src/main/resources/sound/hurt_2.wav b/client/src/main/resources/sound/hurt_2.wav new file mode 100644 index 0000000..c6b3318 Binary files /dev/null and b/client/src/main/resources/sound/hurt_2.wav differ diff --git a/client/src/main/resources/sound/hurt_3.wav b/client/src/main/resources/sound/hurt_3.wav new file mode 100644 index 0000000..08c60fa Binary files /dev/null and b/client/src/main/resources/sound/hurt_3.wav differ diff --git a/client/src/main/resources/sound/m_block_break_1.wav b/client/src/main/resources/sound/m_block_break_1.wav new file mode 100644 index 0000000..b255e95 Binary files /dev/null and b/client/src/main/resources/sound/m_block_break_1.wav differ diff --git a/client/src/main/resources/sound/m_block_place_1.wav b/client/src/main/resources/sound/m_block_place_1.wav new file mode 100644 index 0000000..f2e919e Binary files /dev/null and b/client/src/main/resources/sound/m_block_place_1.wav differ diff --git a/client/src/main/resources/sound/m_bullet_impact_1.wav b/client/src/main/resources/sound/m_bullet_impact_1.wav new file mode 100644 index 0000000..3beb0d0 Binary files /dev/null and b/client/src/main/resources/sound/m_bullet_impact_1.wav differ diff --git a/client/src/main/resources/sound/m_bullet_impact_2.wav b/client/src/main/resources/sound/m_bullet_impact_2.wav new file mode 100644 index 0000000..50ed38e Binary files /dev/null and b/client/src/main/resources/sound/m_bullet_impact_2.wav differ diff --git a/client/src/main/resources/sound/m_bullet_impact_3.wav b/client/src/main/resources/sound/m_bullet_impact_3.wav new file mode 100644 index 0000000..4c927a5 Binary files /dev/null and b/client/src/main/resources/sound/m_bullet_impact_3.wav differ diff --git a/client/src/main/resources/sound/m_bullet_impact_4.wav b/client/src/main/resources/sound/m_bullet_impact_4.wav new file mode 100644 index 0000000..a6dfb64 Binary files /dev/null and b/client/src/main/resources/sound/m_bullet_impact_4.wav differ diff --git a/client/src/main/resources/sound/m_bullet_impact_5.wav b/client/src/main/resources/sound/m_bullet_impact_5.wav new file mode 100644 index 0000000..73627e8 Binary files /dev/null and b/client/src/main/resources/sound/m_bullet_impact_5.wav differ diff --git a/client/src/main/resources/sound/m_death.wav b/client/src/main/resources/sound/m_death.wav new file mode 100644 index 0000000..66a7073 Binary files /dev/null and b/client/src/main/resources/sound/m_death.wav differ diff --git a/client/src/main/resources/sound/m_footsteps_1.wav b/client/src/main/resources/sound/m_footsteps_1.wav new file mode 100644 index 0000000..72cf15a Binary files /dev/null and b/client/src/main/resources/sound/m_footsteps_1.wav differ diff --git a/client/src/main/resources/sound/m_footsteps_2.wav b/client/src/main/resources/sound/m_footsteps_2.wav new file mode 100644 index 0000000..247f2d4 Binary files /dev/null and b/client/src/main/resources/sound/m_footsteps_2.wav differ diff --git a/client/src/main/resources/sound/m_footsteps_3.wav b/client/src/main/resources/sound/m_footsteps_3.wav new file mode 100644 index 0000000..b36ca70 Binary files /dev/null and b/client/src/main/resources/sound/m_footsteps_3.wav differ diff --git a/client/src/main/resources/sound/m_footsteps_4.wav b/client/src/main/resources/sound/m_footsteps_4.wav new file mode 100644 index 0000000..d5e214b Binary files /dev/null and b/client/src/main/resources/sound/m_footsteps_4.wav differ diff --git a/client/src/main/resources/sound/m_hurt_1.wav b/client/src/main/resources/sound/m_hurt_1.wav new file mode 100644 index 0000000..a231b9a Binary files /dev/null and b/client/src/main/resources/sound/m_hurt_1.wav differ diff --git a/client/src/main/resources/sound/m_hurt_2.wav b/client/src/main/resources/sound/m_hurt_2.wav new file mode 100644 index 0000000..f9857b3 Binary files /dev/null and b/client/src/main/resources/sound/m_hurt_2.wav differ diff --git a/client/src/main/resources/sound/m_hurt_3.wav b/client/src/main/resources/sound/m_hurt_3.wav new file mode 100644 index 0000000..8a87078 Binary files /dev/null and b/client/src/main/resources/sound/m_hurt_3.wav differ diff --git a/client/src/main/resources/sound/m_reload.wav b/client/src/main/resources/sound/m_reload.wav new file mode 100644 index 0000000..eeb1341 Binary files /dev/null and b/client/src/main/resources/sound/m_reload.wav differ diff --git a/client/src/main/resources/sound/m_shot_ak-47_1.wav b/client/src/main/resources/sound/m_shot_ak-47_1.wav new file mode 100644 index 0000000..960474a Binary files /dev/null and b/client/src/main/resources/sound/m_shot_ak-47_1.wav differ diff --git a/client/src/main/resources/sound/m_shot_m1-garand_1.wav b/client/src/main/resources/sound/m_shot_m1-garand_1.wav new file mode 100644 index 0000000..39743be Binary files /dev/null and b/client/src/main/resources/sound/m_shot_m1-garand_1.wav differ diff --git a/client/src/main/resources/sound/m_shot_winchester_1.wav b/client/src/main/resources/sound/m_shot_winchester_1.wav new file mode 100644 index 0000000..785ea43 Binary files /dev/null and b/client/src/main/resources/sound/m_shot_winchester_1.wav differ diff --git a/client/src/main/resources/sound/reload.wav b/client/src/main/resources/sound/reload.wav new file mode 100644 index 0000000..54608dc Binary files /dev/null and b/client/src/main/resources/sound/reload.wav differ diff --git a/client/src/main/resources/sound/shot_ak-47_1.wav b/client/src/main/resources/sound/shot_ak-47_1.wav new file mode 100644 index 0000000..fe9a259 Binary files /dev/null and b/client/src/main/resources/sound/shot_ak-47_1.wav differ diff --git a/client/src/main/resources/sound/m1garand-shot1.wav b/client/src/main/resources/sound/shot_m1-garand_1.wav similarity index 100% rename from client/src/main/resources/sound/m1garand-shot1.wav rename to client/src/main/resources/sound/shot_m1-garand_1.wav diff --git a/client/src/main/resources/sound/shot_winchester_1.wav b/client/src/main/resources/sound/shot_winchester_1.wav new file mode 100644 index 0000000..e60c709 Binary files /dev/null and b/client/src/main/resources/sound/shot_winchester_1.wav differ 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 fef4eb3..398877b 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 @@ -84,6 +84,16 @@ public class World { setBlockAt(new Vector3f(x, y, z), block); } + public void setBlocksAt(int x1, int y1, int z1, int x2, int y2, int z2, byte block) { + for (int x = x1; x <= x2; x++) { + for (int y = y1; y <= y2; y++) { + for (int z = z1; z <= z2; z++) { + setBlockAt(x, y, z, block); + } + } + } + } + public Chunk getChunkAt(Vector3i chunkPos) { return chunkMap.get(chunkPos); } diff --git a/core/src/main/java/nl/andrewl/aos_core/model/world/Worlds.java b/core/src/main/java/nl/andrewl/aos_core/model/world/Worlds.java index d68b33a..eab21d9 100644 --- a/core/src/main/java/nl/andrewl/aos_core/model/world/Worlds.java +++ b/core/src/main/java/nl/andrewl/aos_core/model/world/Worlds.java @@ -134,4 +134,21 @@ public final class Worlds { return world; } + + public static World flatWorld() { + World world = new World(ColorPalette.rainbow()); + for (int x = 0; x < 5; x++) { + for (int y = 0; y < 5; y++) { + for (int z = 0; z < 12; z++) { + world.addChunk(new Chunk(x, y, z)); + } + } + } + world.setBlocksAt(0, 0, 0, 5 * Chunk.SIZE, 2 * Chunk.SIZE, 12 * Chunk.SIZE, (byte) 80); + + world.setSpawnPoint("A", new Vector3f(5, 34, 5)); + world.setSpawnPoint("B", new Vector3f(5 * Chunk.SIZE - 5, 34, 12 * Chunk.SIZE - 5)); + + return world; + } } diff --git a/core/src/main/java/nl/andrewl/aos_core/net/client/SoundMessage.java b/core/src/main/java/nl/andrewl/aos_core/net/client/SoundMessage.java index c0ccb5f..715687b 100644 --- a/core/src/main/java/nl/andrewl/aos_core/net/client/SoundMessage.java +++ b/core/src/main/java/nl/andrewl/aos_core/net/client/SoundMessage.java @@ -1,6 +1,7 @@ package nl.andrewl.aos_core.net.client; import nl.andrewl.record_net.Message; +import org.joml.Vector3f; /** * A message that indicates that a sound has been emitted somewhere in the @@ -8,5 +9,28 @@ import nl.andrewl.record_net.Message; */ public record SoundMessage( String name, - float px, float py, float pz -) implements Message {} + float gain, + float px, float py, float pz, + float vx, float vy, float vz +) implements Message { + public SoundMessage(String name, float gain, Vector3f position, Vector3f velocity) { + this( + name, + gain, + position.x, position.y, position.z, + velocity.x, velocity.y, velocity.z + ); + } + + public SoundMessage(String name, float gain, Vector3f position) { + this(name, gain, position.x, position.y, position.z, 0, 0, 0); + } + + public Vector3f positionAsVec() { + return new Vector3f(px, py, pz); + } + + public Vector3f velocityAsVec() { + return new Vector3f(vx, vy, vz); + } +} diff --git a/server/src/main/java/nl/andrewl/aos2_server/PlayerManager.java b/server/src/main/java/nl/andrewl/aos2_server/PlayerManager.java index 1ee674a..2180d8e 100644 --- a/server/src/main/java/nl/andrewl/aos2_server/PlayerManager.java +++ b/server/src/main/java/nl/andrewl/aos2_server/PlayerManager.java @@ -7,10 +7,7 @@ import nl.andrewl.aos_core.model.item.BlockItemStack; import nl.andrewl.aos_core.model.item.Gun; import nl.andrewl.aos_core.model.item.GunItemStack; import nl.andrewl.aos_core.model.item.ItemStack; -import nl.andrewl.aos_core.net.client.ClientHealthMessage; -import nl.andrewl.aos_core.net.client.ItemStackMessage; -import nl.andrewl.aos_core.net.client.PlayerJoinMessage; -import nl.andrewl.aos_core.net.client.PlayerLeaveMessage; +import nl.andrewl.aos_core.net.client.*; import nl.andrewl.aos_core.net.connect.DatagramInit; import nl.andrewl.record_net.Message; import org.joml.Vector3f; @@ -154,6 +151,7 @@ public class PlayerManager { * @param player The player that died. */ public void playerKilled(ServerPlayer player) { + Vector3f deathPosition = new Vector3f(player.getPosition()); player.setPosition(getBestSpawnPoint(player)); player.setVelocity(new Vector3f(0)); player.setHealth(1); @@ -171,6 +169,7 @@ public class PlayerManager { } handler.sendDatagramPacket(new ClientHealthMessage(player.getHealth())); broadcastUdpMessage(player.getUpdateMessage(System.currentTimeMillis())); + broadcastUdpMessage(new SoundMessage("death", 1, deathPosition)); // TODO: Team points or something. } diff --git a/server/src/main/java/nl/andrewl/aos2_server/ProjectileManager.java b/server/src/main/java/nl/andrewl/aos2_server/ProjectileManager.java index 0d492e6..6c19262 100644 --- a/server/src/main/java/nl/andrewl/aos2_server/ProjectileManager.java +++ b/server/src/main/java/nl/andrewl/aos2_server/ProjectileManager.java @@ -7,6 +7,7 @@ import nl.andrewl.aos_core.model.Player; import nl.andrewl.aos_core.model.Projectile; import nl.andrewl.aos_core.model.world.Hit; import nl.andrewl.aos_core.net.client.ClientHealthMessage; +import nl.andrewl.aos_core.net.client.SoundMessage; import nl.andrewl.aos_core.net.world.ChunkUpdateMessage; import org.joml.Matrix4f; import org.joml.Vector3f; @@ -15,6 +16,7 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Queue; +import java.util.concurrent.ThreadLocalRandom; /** * Component that manages the set of all active projectiles in the world, and @@ -112,14 +114,16 @@ public class ProjectileManager { // Bullet struck the world first. server.getWorld().setBlockAt(hit.pos().x, hit.pos().y, hit.pos().z, (byte) 0); server.getPlayerManager().broadcastUdpMessage(ChunkUpdateMessage.fromWorld(hit.pos(), server.getWorld())); + int soundVariant = ThreadLocalRandom.current().nextInt(1, 6); + server.getPlayerManager().broadcastUdpMessage(new SoundMessage("bullet_impact_" + soundVariant, 1, hit.rawPos())); deleteProjectile(projectile); } else if (playerHit != null && (hit == null || playerHitDist < worldHitDist)) { // Bullet struck the player first. - System.out.println("Player hit: " + playerHitType); float damage = 0.4f; if (playerHitType == 1) damage *= 2; hitPlayer.setHealth(hitPlayer.getHealth() - damage); - System.out.println(hitPlayer.getHealth()); + int soundVariant = ThreadLocalRandom.current().nextInt(1, 4); + server.getPlayerManager().broadcastUdpMessage(new SoundMessage("hurt_" + soundVariant, 1, hitPlayer.getPosition(), hitPlayer.getVelocity())); if (hitPlayer.getHealth() == 0) { System.out.println("Player killed!!!"); server.getPlayerManager().playerKilled(hitPlayer); 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 69b75b7..caee45e 100644 --- a/server/src/main/java/nl/andrewl/aos2_server/Server.java +++ b/server/src/main/java/nl/andrewl/aos2_server/Server.java @@ -45,7 +45,7 @@ public class Server implements Runnable { this.teamManager = new TeamManager(this); this.projectileManager = new ProjectileManager(this); this.worldUpdater = new WorldUpdater(this, config.ticksPerSecond); - this.world = Worlds.testingWorld(); + this.world = Worlds.flatWorld(); // TODO: Add some way to configure teams with config files or commands. teamManager.addTeam("Red", new Vector3f(0.8f, 0, 0), "A"); 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 b2206b4..824c456 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 @@ -1,9 +1,14 @@ package nl.andrewl.aos2_server.logic; import nl.andrewl.aos2_server.Server; -import nl.andrewl.aos2_server.model.ServerPlayer; import nl.andrewl.aos2_server.config.ServerConfig; -import nl.andrewl.aos_core.model.item.*; +import nl.andrewl.aos2_server.model.ServerPlayer; +import nl.andrewl.aos_core.model.item.BlockItemStack; +import nl.andrewl.aos_core.model.item.Gun; +import nl.andrewl.aos_core.model.item.GunItemStack; +import nl.andrewl.aos_core.model.item.ItemStack; +import nl.andrewl.aos_core.model.item.gun.Ak47; +import nl.andrewl.aos_core.model.item.gun.Rifle; import nl.andrewl.aos_core.model.world.World; import nl.andrewl.aos_core.net.client.ClientInputState; import nl.andrewl.aos_core.net.client.InventorySelectedStackMessage; @@ -18,7 +23,7 @@ import org.joml.Vector3i; import java.util.ArrayList; import java.util.List; -import static nl.andrewl.aos2_server.model.ServerPlayer.*; +import static nl.andrewl.aos2_server.model.ServerPlayer.RADIUS; /** * Component that manages a server player's current actions and movement. @@ -106,7 +111,13 @@ public class PlayerActionManager { gunNeedsReCock = true; } server.getPlayerManager().getHandler(player.getId()).sendDatagramPacket(new ItemStackMessage(player.getInventory())); - server.getPlayerManager().broadcastUdpMessage(new SoundMessage("rifle", player.getPosition().x(), player.getPosition().y(), player.getPosition().z())); + String shotSound = null; + if (gun instanceof Rifle) { + shotSound = "shot_m1-garand_1"; + } else if (gun instanceof Ak47) { + shotSound = "shot_ak-47_1"; + } + server.getPlayerManager().broadcastUdpMessage(new SoundMessage(shotSound, 1, player.getPosition(), player.getVelocity())); } if (// Check to see if the player is reloading. @@ -118,6 +129,7 @@ public class PlayerActionManager { gunReloadingStartedAt = now; gunReloading = true; server.getPlayerManager().getHandler(player.getId()).sendDatagramPacket(new ItemStackMessage(player.getInventory())); + server.getPlayerManager().broadcastUdpMessage(new SoundMessage("reload", 1, player.getPosition(), player.getVelocity())); } if (// Check to see if reloading is done.