package de.steamwar.bausystem.tracer; import de.steamwar.bausystem.BauSystem; import de.steamwar.core.Core; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.TextComponent; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Particle; import org.bukkit.entity.Player; import java.util.Set; public class TNTTracer { private TNTTracer(){} static final boolean DEBUG = false; private static final Object synchronizer = new Object(); private static final TraceCache traceCache = new TraceCache(); public static void init(){ Bukkit.getScheduler().runTaskTimer(BauSystem.getPlugin(), () -> { synchronized (synchronizer) { synchronizer.notifyAll(); } }, 1, 20); Bukkit.getScheduler().runTaskAsynchronously(BauSystem.getPlugin(), () -> { while (true) { synchronized (synchronizer) { try { synchronizer.wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } run(); } }); } private static void run(){ for (Player p : Bukkit.getOnlinePlayers()) { if (DEBUG) { String actionBar = "§e" + TraceManager.getAllTraces().size() + " §cTraces §e" + ShowManager.get(p).getShowRadius() + " §cRadius"; p.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(actionBar)); } boolean dirty = ShowManager.get(p).isDirty(); if (ShowManager.get(p).getDisplayType() == ShowManager.DisplayType.Block && !dirty) { continue; } Set toHide = traceCache.update(p, dirty); Set toShow = traceCache.get(p); hideBlockTraces(toHide, p); showTraces(toShow, ShowManager.get(p).getDisplayType(), p); } } private static void hideBlockTraces(Set locs, Player player) { if (locs.isEmpty()) return; for (TraceCache.Loc l : locs) { hideBlock(player, l.x, l.y - 0.49F, l.z); } } private static void showTraces(Set locs, ShowManager.DisplayType displayMode, Player player) { if (locs.isEmpty()) return; for (TraceCache.Loc l : locs) { if (displayMode == ShowManager.DisplayType.Block) { showBlock(player, l.x, l.y - 0.49F, l.z, getMaterial(l), (l.updatePoint ? (byte) 5 : (byte) 14)); } else { showCorner(player, l.x - 0.49F, l.y, l.z - 0.49F, (l.updatePoint ? Particle.FLAME : Particle.VILLAGER_HAPPY)); } } } private static Material getMaterial(TraceCache.Loc l){ switch(Core.getVersion()){ case 15: return TNTTracer_15.getMaterial(l.updatePoint); default: return TNTTracer_12.getMaterial(); } } private static void showCorner(Player player, float x, float y, float z, Particle particle) { player.spawnParticle(particle, makeLocation(x + 0.00F, y + 0.00F, z + 0.00F), 1, 0F, 0F, 0F, 0.001); player.spawnParticle(particle, makeLocation(x + 0.98F, y + 0.00F, z + 0.00F), 1, 0F, 0F, 0F, 0.001); player.spawnParticle(particle, makeLocation(x + 0.00F, y + 0.00F, z + 0.98F), 1, 0F, 0F, 0F, 0.001); player.spawnParticle(particle, makeLocation(x + 0.98F, y + 0.00F, z + 0.98F), 1, 0F, 0F, 0F, 0.001); player.spawnParticle(particle, makeLocation(x + 0.00F, y + 0.98F, z + 0.00F), 1, 0F, 0F, 0F, 0.001); player.spawnParticle(particle, makeLocation(x + 0.98F, y + 0.98F, z + 0.00F), 1, 0F, 0F, 0F, 0.001); player.spawnParticle(particle, makeLocation(x + 0.00F, y + 0.98F, z + 0.98F), 1, 0F, 0F, 0F, 0.001); player.spawnParticle(particle, makeLocation(x + 0.98F, y + 0.98F, z + 0.98F), 1, 0F, 0F, 0F, 0.001); } private static void showBlock(Player p, float x, float y, float z, Material block, byte b) { if (makeLocation(x, y, z).getBlock().getType() == Material.AIR) { p.sendBlockChange(makeLocation(x, y, z), block, b); } } private static void hideBlock(Player p, float x, float y, float z) { if (makeLocation(x, y, z).getBlock().getType() == Material.AIR) { p.sendBlockChange(makeLocation(x, y, z), Material.AIR, (byte) 0); } } private static final Location location = new Location(Bukkit.getWorlds().get(0), 0, 0, 0); private static Location makeLocation(float x, float y, float z) { location.setX(x); location.setY(y); location.setZ(z); return location; } }