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();
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<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
* 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. */
@@ -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<String> 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
+1
View File
@@ -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