package de.steamwar.bausystem.tracer; import org.bukkit.entity.Player; import java.util.*; public class TraceCache { private static final Set empty = new HashSet(); private Map> playerMap = new HashMap<>(); private Map playerDisplayMap = new HashMap<>(); public Set get(Player player) { return playerMap.getOrDefault(player.getUniqueId().toString(), empty); } public Set update(Player player, TracerUpdater tracerUpdater, boolean dirty) { if (!dirty) return empty; String key = player.getUniqueId().toString(); Set locOld; TracerUpdater.DisplayMode displayMode; if (!playerMap.containsKey(key)) { locOld = new HashSet<>(); displayMode = tracerUpdater.getDisplayType(player); } else { locOld = playerMap.get(key); displayMode = playerDisplayMap.get(key); } Set locSet = new HashSet<>(); tracerUpdater.updatePoints(player).forEach(loc -> { loc.updatePoint = true; locSet.add(loc); }); tracerUpdater.updateLocations(player).forEach(loc -> { loc.updatePoint = false; locSet.add(loc); }); playerMap.put(key, locSet); TracerUpdater.DisplayMode currentMode = tracerUpdater.getDisplayType(player); playerDisplayMap.put(key, currentMode); if (currentMode == TracerUpdater.DisplayMode.Particle && displayMode == TracerUpdater.DisplayMode.Block) return locOld; if (currentMode == TracerUpdater.DisplayMode.Block) return diff(locOld, locSet); return empty; } public static class Loc { public final float x; public final float y; public final float z; private final float dx; private final float dy; private final float dz; public boolean updatePoint = false; public Loc(float x, float y, float z) { this.x = x; this.y = y; this.z = z; this.dx = round(x); this.dy = round(y); this.dz = round(z); } private static int roundNumber = 10; private static float round(float toRound) { float r = (toRound * roundNumber); float t = r - (int) r; if (t >= 0.5) { return (((float)(int)r) + 1) / roundNumber; } else { return (((float)(int)r) + 0) / roundNumber; } } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Loc)) return false; Loc loc = (Loc) o; return Float.compare(loc.dx, dx) == 0 && Float.compare(loc.dy, dy) == 0 && Float.compare(loc.dz, dz) == 0; } @Override public int hashCode() { return Objects.hash(dx, dy, dz); } @Override public String toString() { return "Loc{" + "x=" + x + ", y=" + y + ", z=" + z + '}'; } public boolean remove(Player player, double radius) { double x = player.getLocation().getX(); double y = player.getLocation().getY(); double z = player.getLocation().getZ(); double dx = (this.x - x) * (this.x - x); double dy = (this.y - y) * (this.y - y); double dz = (this.z - z) * (this.z - z); return (dx + dy + dz) > radius * radius; } } private Set diff(Set locOld, Set locNew) { if (locOld.isEmpty()) return empty; if (locNew.isEmpty()) return locOld; for (Loc l : locNew) { locOld.remove(l); } return locOld; } }