138 lines
5.2 KiB
Java
138 lines
5.2 KiB
Java
package dev.loki.objective;
|
|
|
|
import dev.loki.mdbd;
|
|
import dev.loki.util.TextUtil;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.entity.ArmorStand;
|
|
import org.bukkit.entity.Display;
|
|
import org.bukkit.entity.EntityType;
|
|
import org.bukkit.entity.TextDisplay;
|
|
import org.bukkit.scheduler.BukkitTask;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* Floating labels above generators (name + repair progress).
|
|
* Uses TextDisplay (Paper 1.19.4+) with ArmorStand fallback for older versions.
|
|
*/
|
|
public class GeneratorHologram {
|
|
|
|
private final mdbd plugin;
|
|
private final GeneratorManager manager;
|
|
private final Map<Integer, Object> displays = new HashMap<>(); // TextDisplay or ArmorStand
|
|
private BukkitTask task;
|
|
private boolean useTextDisplay;
|
|
|
|
public GeneratorHologram(mdbd plugin, GeneratorManager manager) {
|
|
this.plugin = plugin;
|
|
this.manager = manager;
|
|
this.useTextDisplay = isTextDisplayAvailable();
|
|
}
|
|
|
|
private static boolean isTextDisplayAvailable() {
|
|
try {
|
|
EntityType.valueOf("TEXT_DISPLAY");
|
|
return true;
|
|
} catch (IllegalArgumentException e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public void start() {
|
|
stop();
|
|
spawnAll();
|
|
task = plugin.getServer().getScheduler().runTaskTimer(plugin, this::refresh, 20L, 20L);
|
|
plugin.getLogger().info("[GeneratorHologram] Started with " + displays.size() + " holograms (mode=" + (useTextDisplay ? "TextDisplay" : "ArmorStand") + ")");
|
|
}
|
|
|
|
public void stop() {
|
|
if (task != null) {
|
|
task.cancel();
|
|
task = null;
|
|
}
|
|
for (Object display : displays.values()) {
|
|
if (display instanceof TextDisplay td && td.isValid()) {
|
|
td.remove();
|
|
} else if (display instanceof ArmorStand as && as.isValid()) {
|
|
as.remove();
|
|
}
|
|
}
|
|
displays.clear();
|
|
}
|
|
|
|
private void spawnAll() {
|
|
double heightOffset = plugin.getConfigManager().getGame().getGeneratorHologramHeightOffset();
|
|
for (Generator gen : manager.getAllGenerators()) {
|
|
Location loc = gen.getLocation();
|
|
if (loc.getWorld() == null) continue;
|
|
|
|
Location holoLoc = loc.clone().add(0.5, 2.0 + heightOffset, 0.5);
|
|
try {
|
|
if (useTextDisplay) {
|
|
TextDisplay display = loc.getWorld().spawn(holoLoc, TextDisplay.class, d -> {
|
|
d.setBillboard(Display.Billboard.VERTICAL);
|
|
d.setSeeThrough(false);
|
|
d.setShadowed(true);
|
|
d.setDefaultBackground(false);
|
|
d.setPersistent(false);
|
|
d.setTextOpacity((byte) -1);
|
|
});
|
|
displays.put(gen.getId(), display);
|
|
} else {
|
|
ArmorStand stand = loc.getWorld().spawn(holoLoc, ArmorStand.class, as -> {
|
|
as.setInvisible(true);
|
|
as.setInvulnerable(true);
|
|
as.setGravity(false);
|
|
as.setMarker(true);
|
|
as.setCustomNameVisible(true);
|
|
as.setPersistent(false);
|
|
});
|
|
displays.put(gen.getId(), stand);
|
|
}
|
|
} catch (Exception e) {
|
|
plugin.getLogger().warning("[GeneratorHologram] Failed to spawn hologram for generator " + gen.getId() + ": " + e.getMessage());
|
|
}
|
|
}
|
|
}
|
|
|
|
private void refresh() {
|
|
double heightOffset = plugin.getConfigManager().getGame().getGeneratorHologramHeightOffset();
|
|
int total = manager.getTotalCount();
|
|
for (Generator gen : manager.getAllGenerators()) {
|
|
Object display = displays.get(gen.getId());
|
|
if (display == null) continue;
|
|
|
|
boolean valid = (display instanceof TextDisplay td && td.isValid()) ||
|
|
(display instanceof ArmorStand as && as.isValid());
|
|
if (!valid) continue;
|
|
|
|
int pct = (int) gen.getProgress();
|
|
String bar = buildBar(pct);
|
|
String text;
|
|
if (gen.isCompleted()) {
|
|
text = "§6⚙ Генератор §f#" + (gen.getId() + 1) + "/" + total + "\n§a✔ Починен!";
|
|
} else if (gen.isUnderRegression()) {
|
|
text = "§6⚙ Генератор §f#" + (gen.getId() + 1) + "/" + total + "\n§c↓ " + bar + " §f" + pct + "%";
|
|
} else {
|
|
text = "§6⚙ Генератор §f#" + (gen.getId() + 1) + "/" + total + "\n§e" + bar + " §f" + pct + "%";
|
|
}
|
|
|
|
Location base = gen.getLocation().clone().add(0.5, 2.0 + heightOffset, 0.5);
|
|
|
|
if (display instanceof TextDisplay td) {
|
|
td.text(TextUtil.color(text));
|
|
td.teleport(base);
|
|
} else if (display instanceof ArmorStand as) {
|
|
as.setCustomName(text);
|
|
as.teleport(base);
|
|
}
|
|
}
|
|
}
|
|
|
|
private String buildBar(int pct) {
|
|
int filled = pct / 10;
|
|
int empty = 10 - filled;
|
|
return "§e" + "█".repeat(Math.max(0, filled)) + "§7" + "░".repeat(Math.max(0, empty));
|
|
}
|
|
}
|