Announce powerup spawns to arena participants
Build / build (push) Successful in 1m18s

maybeSpawn() now returns the spawned type (or null) so Arena can broadcast
the existing but previously-unused powerup.spawned message plus a new
powerup-spawn sound cue whenever one actually appears on the floor.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
Michael Burgess
2026-08-08 17:19:38 -04:00
co-authored by Claude Sonnet 5
parent 039cfab92d
commit 61c09a5b4d
3 changed files with 29 additions and 8 deletions
@@ -348,8 +348,11 @@ public class Arena {
World world = config.getWorld(); World world = config.getWorld();
if (world != null) { if (world != null) {
powerupManager.expireOld(world, round + 1); powerupManager.expireOld(world, round + 1);
powerupManager.maybeSpawn(world, random, round + 1); PowerupType spawned = powerupManager.maybeSpawn(world, random, round + 1);
powerupManager.applyMarkers(world); powerupManager.applyMarkers(world);
if (spawned != null) {
announcePowerupSpawn(spawned);
}
} }
onComplete.run(); 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<String, String> 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 /** 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 * 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. */ * playSound falls off with distance, so anyone far from that one spot would hear nothing. */
@@ -57,25 +57,28 @@ public class PowerupManager {
} }
/** Rolls whether a new powerup should appear this round and, if so, places one above a /** 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. */ * 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) { *
* @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) { if (!configManager.isPowerupsEnabled() || world == null) {
return; return null;
} }
if (active.size() >= configManager.getPowerupMaxActive()) { if (active.size() >= configManager.getPowerupMaxActive()) {
return; return null;
} }
if (random.nextDouble() >= configManager.getPowerupSpawnChance()) { if (random.nextDouble() >= configManager.getPowerupSpawnChance()) {
return; return null;
} }
List<String> floorKeys = floorManager.layoutKeys(); List<String> floorKeys = floorManager.layoutKeys();
if (floorKeys.isEmpty()) { if (floorKeys.isEmpty()) {
return; return null;
} }
String floorKey = floorKeys.get(random.nextInt(floorKeys.size())); String floorKey = floorKeys.get(random.nextInt(floorKeys.size()));
String markerKey = aboveKey(floorKey); String markerKey = aboveKey(floorKey);
if (markerKey == null || active.containsKey(markerKey)) { if (markerKey == null || active.containsKey(markerKey)) {
return; return null;
} }
PowerupType[] types = PowerupType.values(); PowerupType[] types = PowerupType.values();
PowerupType type = types[random.nextInt(types.length)]; 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); int lifetime = min + (max > min ? random.nextInt(max - min + 1) : 0);
active.put(markerKey, new ActivePowerup(type, markerKey, currentRound, lifetime)); active.put(markerKey, new ActivePowerup(type, markerKey, currentRound, lifetime));
placeMarkerBlock(world, markerKey, markerMaterial(type)); placeMarkerBlock(world, markerKey, markerMaterial(type));
return type;
} }
/** (Re-)places every currently active powerup's marker block in the world. Only strictly /** (Re-)places every currently active powerup's marker block in the world. Only strictly
+1
View File
@@ -20,6 +20,7 @@ sounds:
eliminate: ENTITY_VILLAGER_NO eliminate: ENTITY_VILLAGER_NO
round-complete: BLOCK_NOTE_BLOCK_BELL round-complete: BLOCK_NOTE_BLOCK_BELL
victory: UI_TOAST_CHALLENGE_COMPLETE victory: UI_TOAST_CHALLENGE_COMPLETE
powerup-spawn: ENTITY_PLAYER_LEVELUP
music: music:
# Optional background music for the duration of a match, played on the client's MUSIC # Optional background music for the duration of a match, played on the client's MUSIC