2020-09-03 20:10:01 +02:00
|
|
|
/*
|
|
|
|
This file is a part of the SteamWar software.
|
|
|
|
|
|
|
|
Copyright (C) 2020 SteamWar.de-Serverteam
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU Affero General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU Affero General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2020-08-30 02:23:23 +02:00
|
|
|
package de.steamwar.bausystem.tracer;
|
|
|
|
|
|
|
|
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 12:01:47 +02:00
|
|
|
displayMode = 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 12:01:47 +02:00
|
|
|
updatePoints(player).forEach(loc -> {
|
2020-08-30 02:23:23 +02:00
|
|
|
loc.updatePoint = true;
|
|
|
|
locSet.add(loc);
|
|
|
|
});
|
2020-08-30 12:01:47 +02:00
|
|
|
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 12:01:47 +02:00
|
|
|
ShowManager.DisplayType currentMode = 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;
|
|
|
|
}
|
|
|
|
|
2020-08-30 12:01:47 +02:00
|
|
|
private Set<TraceCache.Loc> updateLocations(Player player) {
|
|
|
|
Iterator<TNTTrace> traces = ShowManager.get(player).getTraces().descendingIterator();
|
|
|
|
Set<TraceCache.Loc> locSet = new HashSet<>();
|
|
|
|
while (traces.hasNext()) {
|
|
|
|
locSet.addAll(traces.next().locs());
|
|
|
|
}
|
|
|
|
double radius = ShowManager.get(player).getShowRadius();
|
|
|
|
locSet.removeIf(loc -> loc.remove(player, radius));
|
|
|
|
return locSet;
|
|
|
|
}
|
|
|
|
|
|
|
|
private Set<TraceCache.Loc> updatePoints(Player player) {
|
|
|
|
Iterator<TNTTrace> traces = ShowManager.get(player).getTraces().descendingIterator();
|
|
|
|
Set<TraceCache.Loc> locSet = new HashSet<>();
|
|
|
|
while (traces.hasNext()) {
|
|
|
|
locSet.addAll(traces.next().locsUpdate(ShowManager.get(player).getDisplayMode()));
|
|
|
|
}
|
|
|
|
double radius = ShowManager.get(player).getShowRadius();
|
|
|
|
locSet.removeIf(loc -> loc.remove(player, radius));
|
|
|
|
return locSet;
|
|
|
|
}
|
|
|
|
|
|
|
|
private ShowManager.DisplayType getDisplayType(Player player) {
|
|
|
|
return ShowManager.get(player).getDisplayType();
|
|
|
|
}
|
2020-08-30 02:23:23 +02:00
|
|
|
}
|