forked from SteamWar/SteamWar
Add /hullhider to BauSystem
/hullhider hides the inside of the build area hull of a region from the players who toggle it, like the hull hider of a fight. Each region gets its own hull while somebody uses it; it is rebuilt every time somebody enables it, as WorldEdit and Axiom changes do not update it. /techhider, /xray and /hullhider exclude each other per player and region. Which players may see the hull contents is now decided by Viewers, a sealed class with HiddenByDefault (fight) and VisibleByDefault (bau). Added players are stored in a set; isViewer alone defines what being added means.
This commit is contained in:
@@ -45,7 +45,6 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.IntStream;
|
||||
@@ -67,21 +66,22 @@ public class Hull {
|
||||
private final HashMap<IntVector, BitSet> visibilityDirections = new HashMap<>(); // Contains the visible directions of each occluding visible block
|
||||
private final HashSet<IntVector> uncoveredSurface = new HashSet<>();
|
||||
|
||||
// Players that may see the hull contents (viewers). Everybody else is hidden from it (default deny). Concurrent as it is read on netty threads.
|
||||
private final Set<UUID> viewers = ConcurrentHashMap.newKeySet();
|
||||
private final Viewers viewers;
|
||||
private final HashSet<Entity> entities = new HashSet<>();
|
||||
private final HashSet<REntity> rentities = new HashSet<>();
|
||||
|
||||
/**
|
||||
* @param groundVisible whether the bottom layer of the region is uncovered (if the region does not reach the ground)
|
||||
* @param hiddenBlocks blocks that occlude like solid blocks, as the techhider replaces them by an occluding block
|
||||
* @param viewers which players may see the hull contents, a new instance for every hull
|
||||
*/
|
||||
public Hull(Plugin plugin, World world, HullRegion region, boolean groundVisible, Set<Material> hiddenBlocks) {
|
||||
public Hull(Plugin plugin, World world, HullRegion region, boolean groundVisible, Set<Material> hiddenBlocks, Viewers viewers) {
|
||||
this.plugin = plugin;
|
||||
this.world = world;
|
||||
this.region = region;
|
||||
this.groundVisible = groundVisible;
|
||||
this.hiddenBlocks = hiddenBlocks;
|
||||
this.viewers = viewers;
|
||||
this.occluding = new BitSet(region.volume());
|
||||
this.visibility = new BitSet(region.volume());
|
||||
|
||||
@@ -103,33 +103,48 @@ public class Hull {
|
||||
}
|
||||
|
||||
public boolean isViewer(Player player) {
|
||||
return player != null && viewers.contains(player.getUniqueId());
|
||||
return player != null && viewers.isViewer(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the hull from this player (removes the viewer), also hiding all entities currently inside it.
|
||||
*/
|
||||
public void removeViewer(Player player) {
|
||||
viewers.remove(player.getUniqueId());
|
||||
for (Entity entity : entities) {
|
||||
if (!player.equals(entity)) untrackEntity(player, entity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows this player to see the hull (adds a viewer).
|
||||
* Adds the player to the {@link Viewers}, which decide whether the player may see the hull contents afterwards.
|
||||
*/
|
||||
public void addViewer(Player player) {
|
||||
if (viewers.add(player.getUniqueId())) {
|
||||
for (Entity entity : entities) {
|
||||
trackEntity(player, entity);
|
||||
}
|
||||
// techhider triggers block change sending
|
||||
}
|
||||
boolean wasViewer = isViewer(player);
|
||||
viewers.addViewer(player);
|
||||
updateEntities(player, wasViewer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the player from the {@link Viewers}, which decide whether the player may see the hull contents afterwards.
|
||||
*/
|
||||
public void removeViewer(Player player) {
|
||||
boolean wasViewer = isViewer(player);
|
||||
viewers.removeViewer(player);
|
||||
updateEntities(player, wasViewer);
|
||||
}
|
||||
|
||||
private void updateEntities(Player player, boolean wasViewer) {
|
||||
if (isViewer(player)) {
|
||||
if (!wasViewer) {
|
||||
for (Entity entity : entities) {
|
||||
trackEntity(player, entity);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Also hides the entities from players that joined after they were hidden
|
||||
for (Entity entity : entities) {
|
||||
if (!player.equals(entity)) untrackEntity(player, entity);
|
||||
}
|
||||
}
|
||||
// techhider triggers block change sending
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the player to the default viewer state, e.g. when leaving.
|
||||
*/
|
||||
public void forgetViewer(Player player) {
|
||||
viewers.remove(player.getUniqueId());
|
||||
viewers.removeViewer(player);
|
||||
}
|
||||
|
||||
public void checkEntity(Entity entity) {
|
||||
|
||||
@@ -107,13 +107,18 @@ public class HullHider<K> implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
public void setViewer(Player player, K key, boolean viewer) {
|
||||
Hull hull = hullMap.get(key);
|
||||
if (viewer) {
|
||||
hull.addViewer(player);
|
||||
} else {
|
||||
hull.removeViewer(player);
|
||||
}
|
||||
/**
|
||||
* @see Viewers
|
||||
*/
|
||||
public void addViewer(Player player, K key) {
|
||||
hullMap.get(key).addViewer(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Viewers
|
||||
*/
|
||||
public void removeViewer(Player player, K key) {
|
||||
hullMap.get(key).removeViewer(player);
|
||||
}
|
||||
|
||||
public void forgetViewer(Player player) {
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2026 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.hullhider;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* The players of a {@link Hull}. Whether an added player may see the hull contents or sees the hull blocks instead is decided by {@link #isViewer(Player)}.
|
||||
* Stores the players, so every hull needs its own instance.
|
||||
*/
|
||||
public abstract sealed class Viewers {
|
||||
|
||||
// Concurrent as it is read on netty threads
|
||||
protected final Set<UUID> players = ConcurrentHashMap.newKeySet();
|
||||
|
||||
/**
|
||||
* @return whether the player may see the hull contents instead of the hull blocks
|
||||
*/
|
||||
public abstract boolean isViewer(Player player);
|
||||
|
||||
/**
|
||||
* @return whether the player was not added before
|
||||
*/
|
||||
public boolean addViewer(Player player) {
|
||||
return players.add(player.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether the player was added before
|
||||
*/
|
||||
public boolean removeViewer(Player player) {
|
||||
return players.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Hidden from everybody, only added players may see the hull contents.
|
||||
*/
|
||||
public static final class HiddenByDefault extends Viewers {
|
||||
@Override
|
||||
public boolean isViewer(Player player) {
|
||||
return players.contains(player.getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Visible to everybody, only added players see the hull blocks instead of the hull contents.
|
||||
*/
|
||||
public static final class VisibleByDefault extends Viewers {
|
||||
@Override
|
||||
public boolean isViewer(Player player) {
|
||||
return !players.contains(player.getUniqueId());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user