forked from SteamWar/SteamWar
Fix Hullhider 1.15-, improve performance.
This commit is contained in:
@@ -24,7 +24,6 @@ import de.steamwar.entity.REntity;
|
|||||||
import de.steamwar.fightsystem.Config;
|
import de.steamwar.fightsystem.Config;
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
import de.steamwar.fightsystem.FightSystem;
|
||||||
import de.steamwar.fightsystem.fight.FightTeam;
|
import de.steamwar.fightsystem.fight.FightTeam;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@@ -52,7 +51,7 @@ public class Hull {
|
|||||||
|
|
||||||
private final BitSet occluding;
|
private final BitSet occluding;
|
||||||
private final BitSet visibility;
|
private final BitSet visibility;
|
||||||
private final Int2IntOpenHashMap visibilityDirections = new Int2IntOpenHashMap(); // Contains the visible directions of each occluding visible block
|
private final HashMap<IntVector, BitSet> visibilityDirections = new HashMap<>(); // Contains the visible directions of each occluding visible block
|
||||||
private final Set<IntVector> uncoveredSurface = new HashSet<>();
|
private final Set<IntVector> uncoveredSurface = new HashSet<>();
|
||||||
|
|
||||||
private final HashSet<Player> players = new HashSet<>();
|
private final HashSet<Player> players = new HashSet<>();
|
||||||
@@ -68,13 +67,14 @@ public class Hull {
|
|||||||
|
|
||||||
directions = IntStream.range(0, 27)
|
directions = IntStream.range(0, 27)
|
||||||
.mapToObj(v -> new IntVector(v%3 -1, (v/3)%3 -1, v/9 -1))
|
.mapToObj(v -> new IntVector(v%3 -1, (v/3)%3 -1, v/9 -1))
|
||||||
.filter(v -> v.sqLength() > 0)
|
.filter(v -> v.sqLength() == 1 || v.x*primaryDirection.x + v.y*primaryDirection.y + v.z*primaryDirection.z >= 1) // Not pointing away from primary direction
|
||||||
.filter(v -> v.sqLength() <= 2)
|
|
||||||
.toArray(IntVector[]::new);
|
.toArray(IntVector[]::new);
|
||||||
branchDirections = Arrays.stream(directions)
|
branchDirections = Arrays.stream(directions)
|
||||||
.filter(v -> v.x*primaryDirection.x + v.y*primaryDirection.y + v.z*primaryDirection.z >= 0) // Not pointing away from primary direction
|
.filter(v -> v.sqLength() >= 2) // Diagonal
|
||||||
.filter(v -> v.sqLength() == 2) // Diagonal
|
|
||||||
.toArray(IntVector[]::new);
|
.toArray(IntVector[]::new);
|
||||||
|
|
||||||
|
for(IntVector direction : directions)
|
||||||
|
visibilityDirections.put(direction, new BitSet(region.volume()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean blockPrecise(Player player, int chunkX, int chunkY, int chunkZ) {
|
public boolean blockPrecise(Player player, int chunkX, int chunkY, int chunkZ) {
|
||||||
@@ -141,7 +141,8 @@ public class Hull {
|
|||||||
public void initialize() {
|
public void initialize() {
|
||||||
visibility.clear();
|
visibility.clear();
|
||||||
occluding.clear();
|
occluding.clear();
|
||||||
visibilityDirections.clear();
|
for(BitSet directionalVisibility : visibilityDirections.values())
|
||||||
|
directionalVisibility.clear();
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
region.forEach((x, y, z) -> {
|
region.forEach((x, y, z) -> {
|
||||||
@@ -149,7 +150,7 @@ public class Hull {
|
|||||||
if (isOccluding(Config.world.getBlockAt(x, y, z).getType()))
|
if (isOccluding(Config.world.getBlockAt(x, y, z).getType()))
|
||||||
occluding.set(block.toId(region));
|
occluding.set(block.toId(region));
|
||||||
});
|
});
|
||||||
forEachBorder((root, direction) -> updateBlocks(new NullList<>(), root, direction));
|
forEachBorder((root, direction) -> updateBlocks(new NullList<>(), root, direction, visibilityDirections.get(direction)));
|
||||||
FightSystem.getPlugin().getLogger().log(Level.INFO, () -> "[HullHider] initialisation finished: " + (System.currentTimeMillis() - start) + " ms, visible blocks: " + visibility.cardinality());
|
FightSystem.getPlugin().getLogger().log(Level.INFO, () -> "[HullHider] initialisation finished: " + (System.currentTimeMillis() - start) + " ms, visible blocks: " + visibility.cardinality());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,10 +168,11 @@ public class Hull {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
List<IntVector> uncovered = new ArrayList<>();
|
List<IntVector> uncovered = new ArrayList<>();
|
||||||
int visibleDirections = visibilityDirections.remove(id);
|
for(Map.Entry<IntVector, BitSet> directionalVisibility : visibilityDirections.entrySet()) {
|
||||||
for(IntVector direction : directions) {
|
if(directionalVisibility.getValue().get(id)) {
|
||||||
if((directionId(direction) & visibleDirections) != 0)
|
directionalVisibility.getValue().clear(id);
|
||||||
updateBlocks(uncovered, root, direction);
|
updateBlocks(uncovered, root, directionalVisibility.getKey(), directionalVisibility.getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(uncovered.isEmpty())
|
if(uncovered.isEmpty())
|
||||||
@@ -241,27 +243,29 @@ public class Hull {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateBlocks(List<IntVector> uncovered, IntVector block, IntVector direction) {
|
private void updateBlocks(List<IntVector> uncovered, IntVector block, IntVector direction, BitSet directionalVisibility) {
|
||||||
if (block.notInRegion(region))
|
if (block.notInRegion(region))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int id = block.toId(region);
|
int id = block.toId(region);
|
||||||
|
if(directionalVisibility.get(id))
|
||||||
|
return;
|
||||||
|
directionalVisibility.set(id);
|
||||||
|
|
||||||
if (!visibility.get(id)) {
|
if (!visibility.get(id)) {
|
||||||
visibility.set(id);
|
visibility.set(id);
|
||||||
uncovered.add(block);
|
uncovered.add(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (occluding.get(id)) {
|
if (occluding.get(id))
|
||||||
visibilityDirections.compute(id, (pos, v) -> (v == null ? 0 : v) | directionId(direction));
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
updateBlocks(uncovered, block.add(direction), direction);
|
updateBlocks(uncovered, block.add(direction), direction, directionalVisibility);
|
||||||
if(!direction.equals(primaryDirection))
|
if(!direction.equals(primaryDirection))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for(IntVector branchDirection : branchDirections)
|
for(IntVector branchDirection : branchDirections)
|
||||||
updateBlocks(uncovered, block.add(branchDirection), branchDirection);
|
updateBlocks(uncovered, block.add(branchDirection), branchDirection, visibilityDirections.get(branchDirection));
|
||||||
}
|
}
|
||||||
|
|
||||||
private int directionId(IntVector v) {
|
private int directionId(IntVector v) {
|
||||||
|
|||||||
Reference in New Issue
Block a user