feat(notification): announce earned tree unlocks

This commit is contained in:
dmg
2026-08-11 17:33:54 -04:00
parent 8c7c008ca0
commit 2664f7c68b
6 changed files with 142 additions and 9 deletions
@@ -0,0 +1,18 @@
package games.dmg.treefeller;
import java.util.List;
import org.bukkit.entity.Player;
/** Delivers one persisted progress update to each presentation observer in order. */
public final class CompositeProgressObserver implements ProgressObserver {
private final List<ProgressObserver> observers;
public CompositeProgressObserver(ProgressObserver... observers) {
this.observers = List.of(observers);
}
@Override
public void onProgress(Player player, ProgressUpdate update) {
observers.forEach(observer -> observer.onProgress(player, update));
}
}
@@ -42,7 +42,9 @@ public final class TreeFellerPlugin extends JavaPlugin {
playerStateRepository,
species -> settingsService.current().threshold(species),
automaticBreakRegistry,
progressBossBarObserver,
new CompositeProgressObserver(
progressBossBarObserver,
new TreeUnlockAnnouncement(settingsService::current)),
exception -> getLogger().log(
Level.SEVERE, "Unable to persist Tree Feller progress", exception));
getServer().getPluginManager().registerEvents(progressListener, this);
@@ -0,0 +1,36 @@
package games.dmg.treefeller;
import java.util.function.Supplier;
import org.bukkit.entity.Player;
/** Presents the one-time earned unlock title and safety guidance. */
public final class TreeUnlockAnnouncement implements ProgressObserver {
private final Supplier<TreeFellerSettings> settings;
public TreeUnlockAnnouncement(Supplier<TreeFellerSettings> settings) {
this.settings = settings;
}
@Override
public void onProgress(Player player, ProgressUpdate update) {
if (!update.newlyUnlocked()) {
return;
}
TreeFellerSettings current = settings.get();
player.sendTitle(
format(current.titleText(), update),
format(current.subtitleText(), update),
current.titleFadeInTicks(),
current.titleStayTicks(),
current.titleFadeOutTicks());
player.sendMessage(format(current.message("unlock-guidance"), update));
}
private String format(String template, ProgressUpdate update) {
return template
.replace("{species}", update.species().displayName())
.replace("{progress}", Long.toString(update.progress()))
.replace("{threshold}", Integer.toString(update.threshold()))
.replace('&', '\u00a7');
}
}