fix: use stable full-volume zone playback
Build / maven (push) Successful in 42s
Build and publish release / Build and publish Ambient Audio Zone (push) Successful in 44s

This commit is contained in:
root
2026-08-04 06:15:13 +02:00
parent 247aa3cc90
commit 6e6a94c146
5 changed files with 11 additions and 10 deletions
@@ -21,11 +21,13 @@ public record AudioZone(String name, String worldName, String sound, Point origi
public Location originLocation(World world) { return new Location(world, origin.x(), origin.y(), origin.z()); }
public String normalizedName() { return name.toLowerCase(Locale.ROOT); }
public double distanceToAudibleAreaSquared(Location location) { return region.distanceSquared(location.getX(), location.getY(), location.getZ()); }
public boolean isAudible(Location location) { return belongsTo(location.getWorld()) && distanceToAudibleAreaSquared(location) <= fadeDistance * fadeDistance; }
/** Returns true only while the listener is inside the configured cuboid. */
public boolean isInside(Location location) { return belongsTo(location.getWorld()) && region.contains(location.getX(), location.getY(), location.getZ()); }
public record Point(double x, double y, double z) { }
/** Inclusive axis-aligned cuboid. */
public record Cuboid(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) {
public Cuboid { if (minX > maxX || minY > maxY || minZ > maxZ) throw new IllegalArgumentException("Cuboid minimum exceeds maximum"); }
public boolean contains(double x, double y, double z) { return x >= minX && x <= maxX && y >= minY && y <= maxY && z >= minZ && z <= maxZ; }
public double distanceSquared(double x, double y, double z) {
double dx = delta(x, minX, maxX), dy = delta(y, minY, maxY), dz = delta(z, minZ, maxZ);
return dx * dx + dy * dy + dz * dz;
@@ -26,7 +26,7 @@ public final class PlaybackService {
private void tick() { Bukkit.getOnlinePlayers().forEach(this::update); }
private void update(Player player) {
long now = Bukkit.getCurrentTick();
List<AudioZone> audible = index.candidates(player.getLocation()).stream().filter(zone -> zone.isAudible(player.getLocation())).sorted(Comparator.comparingInt(AudioZone::priority).reversed()).toList();
List<AudioZone> audible = index.candidates(player.getLocation()).stream().filter(zone -> zone.isInside(player.getLocation())).sorted(Comparator.comparingInt(AudioZone::priority).reversed()).toList();
if (!blending && !audible.isEmpty()) audible = List.of(audible.getFirst());
Set<String> desired = audible.stream().map(AudioZone::normalizedName).collect(Collectors.toSet());
Map<String, ActiveSound> current = active.computeIfAbsent(player.getUniqueId(), unused -> new HashMap<>());
@@ -18,5 +18,5 @@ public final class ZoneService {
public AudioZone get(String name) { return zones.get(name.toLowerCase(Locale.ROOT)); }
public void put(AudioZone zone) throws IOException { zones.put(zone.normalizedName(), zone); store.save(zones.values()); refreshPlayback(); }
public AudioZone remove(String name) throws IOException { AudioZone removed = zones.remove(name.toLowerCase(Locale.ROOT)); if (removed != null) { store.save(zones.values()); refreshPlayback(); } return removed; }
private void refreshPlayback() { FileConfiguration c = plugin.getConfig(); playback.configure(zones.values(), Math.max(1, c.getInt("playback.check-interval-ticks", 10)), Math.max(0, c.getLong("playback.leave-grace-ticks", 100)), c.getBoolean("playback.blend-overlapping-zones", false), c.getBoolean("playback.follow-player", true), c.getBoolean("playback.fade-volume-updates", false), Math.max(0, c.getLong("playback.loop-restart-ticks", 2680))); }
private void refreshPlayback() { FileConfiguration c = plugin.getConfig(); playback.configure(zones.values(), Math.max(1, c.getInt("playback.check-interval-ticks", 10)), 0, c.getBoolean("playback.blend-overlapping-zones", false), true, false, Math.max(0, c.getLong("playback.loop-restart-ticks", 2680))); }
}