SteamWar/BauSystem
Archiviert
13
0
Dieses Repository wurde am 2024-08-04 archiviert. Du kannst Dateien ansehen und es klonen, aber nicht pushen oder Issues/Pull-Requests öffnen.
BauSystem/BauSystem_Main/src/de/steamwar/bausystem/tracer/TraceCache.java

171 Zeilen
5.6 KiB
Java

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