diff --git a/src/main/java/us/tss3/blockparty/arena/Arena.java b/src/main/java/us/tss3/blockparty/arena/Arena.java index 29ed9ce..6078952 100644 --- a/src/main/java/us/tss3/blockparty/arena/Arena.java +++ b/src/main/java/us/tss3/blockparty/arena/Arena.java @@ -348,8 +348,11 @@ public class Arena { World world = config.getWorld(); if (world != null) { powerupManager.expireOld(world, round + 1); - powerupManager.maybeSpawn(world, random, round + 1); + PowerupType spawned = powerupManager.maybeSpawn(world, random, round + 1); powerupManager.applyMarkers(world); + if (spawned != null) { + announcePowerupSpawn(spawned); + } } onComplete.run(); }); @@ -585,6 +588,19 @@ public class Arena { } } + /** Announces a freshly-spawned powerup to everyone currently in the arena, so players know + * to go look for it instead of relying on spotting the marker block by chance. */ + private void announcePowerupSpawn(PowerupType type) { + Map ph = Map.of("type", type.displayName()); + for (UUID uuid : allParticipants()) { + Player p = plugin.getServer().getPlayer(uuid); + if (p != null) { + p.sendMessage(plugin.getMessages().get("powerup.spawned", ph)); + } + } + playToParticipants("powerup-spawn"); + } + /** Plays a configured sound directly to every current player/spectator (each at their own * location), instead of once at a single world coordinate — Bukkit's location-based * playSound falls off with distance, so anyone far from that one spot would hear nothing. */ diff --git a/src/main/java/us/tss3/blockparty/powerup/PowerupManager.java b/src/main/java/us/tss3/blockparty/powerup/PowerupManager.java index 5624800..6f4feb7 100644 --- a/src/main/java/us/tss3/blockparty/powerup/PowerupManager.java +++ b/src/main/java/us/tss3/blockparty/powerup/PowerupManager.java @@ -57,25 +57,28 @@ public class PowerupManager { } /** Rolls whether a new powerup should appear this round and, if so, places one above a - * random free floor cell. No-op while powerups are disabled or the floor has no free cells. */ - public void maybeSpawn(World world, Random random, int currentRound) { + * random free floor cell. No-op while powerups are disabled or the floor has no free cells. + * + * @return the type that spawned, or null if nothing spawned this call (so the caller can + * decide whether to announce it - see Arena). */ + public PowerupType maybeSpawn(World world, Random random, int currentRound) { if (!configManager.isPowerupsEnabled() || world == null) { - return; + return null; } if (active.size() >= configManager.getPowerupMaxActive()) { - return; + return null; } if (random.nextDouble() >= configManager.getPowerupSpawnChance()) { - return; + return null; } List floorKeys = floorManager.layoutKeys(); if (floorKeys.isEmpty()) { - return; + return null; } String floorKey = floorKeys.get(random.nextInt(floorKeys.size())); String markerKey = aboveKey(floorKey); if (markerKey == null || active.containsKey(markerKey)) { - return; + return null; } PowerupType[] types = PowerupType.values(); PowerupType type = types[random.nextInt(types.length)]; @@ -84,6 +87,7 @@ public class PowerupManager { int lifetime = min + (max > min ? random.nextInt(max - min + 1) : 0); active.put(markerKey, new ActivePowerup(type, markerKey, currentRound, lifetime)); placeMarkerBlock(world, markerKey, markerMaterial(type)); + return type; } /** (Re-)places every currently active powerup's marker block in the world. Only strictly diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 60a3ecb..54d6866 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -20,6 +20,7 @@ sounds: eliminate: ENTITY_VILLAGER_NO round-complete: BLOCK_NOTE_BLOCK_BELL victory: UI_TOAST_CHALLENGE_COMPLETE + powerup-spawn: ENTITY_PLAYER_LEVELUP music: # Optional background music for the duration of a match, played on the client's MUSIC