2020-08-30 02:23:23 +02:00
|
|
|
package de.steamwar.bausystem.tracer;
|
|
|
|
|
2020-08-30 07:45:32 +02:00
|
|
|
import de.steamwar.bausystem.tracer.manager.ShowManager;
|
2020-08-30 02:23:23 +02:00
|
|
|
import org.bukkit.entity.Player;
|
|
|
|
|
|
|
|
import java.util.*;
|
|
|
|
|
|
|
|
public class TraceCache {
|
|
|
|
|
2020-08-30 07:45:32 +02:00
|
|
|
private static final Set<Loc> empty = new HashSet<>();
|
2020-08-30 02:23:23 +02:00
|
|
|
private Map<String, Set<Loc>> playerMap = new HashMap<>();
|
2020-08-30 07:45:32 +02:00
|
|
|
private Map<String, ShowManager.DisplayType> playerDisplayMap = new HashMap<>();
|
2020-08-30 02:23:23 +02:00
|
|
|
|
|
|
|
public Set<Loc> get(Player player) {
|
|
|
|
return playerMap.getOrDefault(player.getUniqueId().toString(), empty);
|
|
|
|
}
|
|
|
|
|
2020-08-30 07:45:32 +02:00
|
|
|
Set<Loc> update(Player player, boolean dirty) {
|
2020-08-30 02:23:23 +02:00
|
|
|
if (!dirty) return empty;
|
|
|
|
String key = player.getUniqueId().toString();
|
|
|
|
Set<Loc> locOld;
|
2020-08-30 07:45:32 +02:00
|
|
|
ShowManager.DisplayType displayMode;
|
2020-08-30 02:23:23 +02:00
|
|
|
if (!playerMap.containsKey(key)) {
|
|
|
|
locOld = new HashSet<>();
|
2020-08-30 07:45:32 +02:00
|
|
|
displayMode = TracerUpdater.getDisplayType(player);
|
2020-08-30 02:23:23 +02:00
|
|
|
} else {
|
|
|
|
locOld = playerMap.get(key);
|
|
|
|
displayMode = playerDisplayMap.get(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
Set<Loc> locSet = new HashSet<>();
|
2020-08-30 07:45:32 +02:00
|
|
|
TracerUpdater.updatePoints(player).forEach(loc -> {
|
2020-08-30 02:23:23 +02:00
|
|
|
loc.updatePoint = true;
|
|
|
|
locSet.add(loc);
|
|
|
|
});
|
2020-08-30 07:45:32 +02:00
|
|
|
TracerUpdater.updateLocations(player).forEach(loc -> {
|
2020-08-30 02:23:23 +02:00
|
|
|
loc.updatePoint = false;
|
|
|
|
locSet.add(loc);
|
|
|
|
});
|
|
|
|
|
|
|
|
playerMap.put(key, locSet);
|
2020-08-30 07:45:32 +02:00
|
|
|
ShowManager.DisplayType currentMode = TracerUpdater.getDisplayType(player);
|
2020-08-30 02:23:23 +02:00
|
|
|
playerDisplayMap.put(key, currentMode);
|
|
|
|
|
2020-08-30 07:45:32 +02:00
|
|
|
if (currentMode == ShowManager.DisplayType.Particle && displayMode == ShowManager.DisplayType.Block) return locOld;
|
|
|
|
if (currentMode == ShowManager.DisplayType.Block) return diff(locOld, locSet);
|
2020-08-30 02:23:23 +02:00
|
|
|
return empty;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static class Loc {
|
2020-08-30 07:45:32 +02:00
|
|
|
final float x;
|
|
|
|
final float y;
|
|
|
|
final float z;
|
2020-08-30 02:23:23 +02:00
|
|
|
|
|
|
|
private final float dx;
|
|
|
|
private final float dy;
|
|
|
|
private final float dz;
|
|
|
|
|
2020-08-30 07:45:32 +02:00
|
|
|
boolean updatePoint = false;
|
2020-08-30 02:23:23 +02:00
|
|
|
|
|
|
|
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 float round(float toRound) {
|
2020-08-30 07:45:32 +02:00
|
|
|
final int roundNumber = 10;
|
2020-08-30 02:23:23 +02:00
|
|
|
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<Loc> diff(Set<Loc> locOld, Set<Loc> locNew) {
|
|
|
|
if (locOld.isEmpty()) return empty;
|
|
|
|
if (locNew.isEmpty()) return locOld;
|
|
|
|
for (Loc l : locNew) {
|
|
|
|
locOld.remove(l);
|
|
|
|
}
|
|
|
|
return locOld;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|