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:
+27
-7
@@ -19,6 +19,7 @@
|
||||
|
||||
package de.steamwar.bausystem.features.techhider;
|
||||
|
||||
import de.steamwar.bausystem.features.hullhider.HullHiderCommand;
|
||||
import de.steamwar.bausystem.features.world.SpectatorListener;
|
||||
import de.steamwar.bausystem.features.xray.XrayCommand;
|
||||
import de.steamwar.linkage.Linked;
|
||||
@@ -29,18 +30,20 @@ import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The single TechHider of the server. It combines the hiding rules of the spectator techhider, /techhider and /xray per player.
|
||||
* The single TechHider of the server. It combines the hiding rules of the spectator techhider, /techhider and /xray and the hulls of /hullhider per player.
|
||||
*/
|
||||
@Linked
|
||||
public class BauTechHider implements AccessPrivilegeProvider {
|
||||
|
||||
private static final HidingRule[] NO_RULES = new HidingRule[0];
|
||||
private static final HiddenHull[] NO_HULLS = new HiddenHull[0];
|
||||
|
||||
// Injected after construction, until then nothing is hidden
|
||||
@LinkedInstance
|
||||
@@ -49,6 +52,8 @@ public class BauTechHider implements AccessPrivilegeProvider {
|
||||
public TechHiderCommand techHiderCommand;
|
||||
@LinkedInstance
|
||||
public SpectatorListener spectatorListener;
|
||||
@LinkedInstance
|
||||
public HullHiderCommand hullHiderCommand;
|
||||
|
||||
public BauTechHider() {
|
||||
new TechHider(this);
|
||||
@@ -56,8 +61,8 @@ public class BauTechHider implements AccessPrivilegeProvider {
|
||||
|
||||
@Override
|
||||
public ForPlayer forPlayer(Player p) {
|
||||
if (xrayCommand == null || techHiderCommand == null || spectatorListener == null) {
|
||||
return new BauPlayerAccess(p, NO_RULES);
|
||||
if (xrayCommand == null || techHiderCommand == null || spectatorListener == null || hullHiderCommand == null) {
|
||||
return new BauPlayerAccess(p, NO_RULES, NO_HULLS);
|
||||
}
|
||||
|
||||
// Region rules first: where rules overlap, the first one decides the obfuscation block
|
||||
@@ -65,7 +70,10 @@ public class BauTechHider implements AccessPrivilegeProvider {
|
||||
xrayCommand.addHidingRules(p, rules);
|
||||
techHiderCommand.addHidingRules(p, rules);
|
||||
spectatorListener.addHidingRules(p, rules);
|
||||
return new BauPlayerAccess(p, rules.toArray(NO_RULES));
|
||||
|
||||
List<HiddenHull> hulls = new ArrayList<>();
|
||||
hullHiderCommand.addHiddenHulls(p, hulls);
|
||||
return new BauPlayerAccess(p, rules.toArray(NO_RULES), hulls.toArray(NO_HULLS));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -76,7 +84,7 @@ public class BauTechHider implements AccessPrivilegeProvider {
|
||||
/**
|
||||
* Snapshot of the hiding rules of one player, taken once per outgoing packet on the netty thread.
|
||||
*/
|
||||
private record BauPlayerAccess(Player player, HidingRule[] rules) implements ForPlayer {
|
||||
private record BauPlayerAccess(Player player, HidingRule[] rules, HiddenHull[] hulls) implements ForPlayer {
|
||||
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
@@ -88,11 +96,17 @@ public class BauTechHider implements AccessPrivilegeProvider {
|
||||
for (HidingRule rule : rules) {
|
||||
if (rule.coversChunk(chunkX, chunkZ)) return false;
|
||||
}
|
||||
for (HiddenHull hull : hulls) {
|
||||
if (!hull.hull().getRegion().chunkOutside(chunkX, chunkZ)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAccessPosition(int blockX, int blockY, int blockZ) {
|
||||
for (HiddenHull hull : hulls) {
|
||||
if (hull.hull().isBlockHidden(player, blockX, blockY, blockZ)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -114,7 +128,10 @@ public class BauTechHider implements AccessPrivilegeProvider {
|
||||
|
||||
@Override
|
||||
public boolean canAccessEntity(int entityId) {
|
||||
return true;
|
||||
if (hulls.length == 0) return true;
|
||||
|
||||
net.minecraft.world.entity.Entity nmsEntity = ((CraftWorld) player.getWorld()).getHandle().moonrise$getEntityLookup().get(entityId);
|
||||
return nmsEntity == null || canAccessPosition(nmsEntity.getBlockX(), nmsEntity.getBlockY(), nmsEntity.getBlockZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -130,7 +147,10 @@ public class BauTechHider implements AccessPrivilegeProvider {
|
||||
for (HidingRule rule : rules) {
|
||||
if (rule.covers(blockX, blockY, blockZ)) return rule.obfuscation().getObfuscationState();
|
||||
}
|
||||
// Only asked for positions a rule hides
|
||||
for (HiddenHull hull : hulls) {
|
||||
if (hull.hull().getRegion().contains(blockX, blockY, blockZ)) return hull.obfuscation();
|
||||
}
|
||||
// Only asked for positions a rule or hull hides
|
||||
return Blocks.END_STONE.defaultBlockState();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.bausystem.features.techhider;
|
||||
|
||||
import de.steamwar.hullhider.Hull;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
/**
|
||||
* A hull a player may not view, and the block sent instead of its hidden blocks.
|
||||
*/
|
||||
public record HiddenHull(Hull hull, BlockState obfuscation) {
|
||||
}
|
||||
+5
@@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.techhider;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.Permission;
|
||||
import de.steamwar.bausystem.features.hullhider.HullHiderCommand;
|
||||
import de.steamwar.bausystem.features.world.SpectatorListener;
|
||||
import de.steamwar.bausystem.features.xray.XrayCommand;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
@@ -58,6 +59,9 @@ public class TechHiderCommand extends SWCommand implements Listener, ScoreboardE
|
||||
@LinkedInstance
|
||||
public XrayCommand xrayCommand;
|
||||
|
||||
@LinkedInstance
|
||||
public HullHiderCommand hullHiderCommand;
|
||||
|
||||
@Register(description = "TECHHIDER_HELP")
|
||||
public void toggleHider(@Validator Player player) {
|
||||
Region region = Region.getRegion(player.getLocation());
|
||||
@@ -79,6 +83,7 @@ public class TechHiderCommand extends SWCommand implements Listener, ScoreboardE
|
||||
}
|
||||
|
||||
xrayCommand.disable(region, player);
|
||||
hullHiderCommand.disable(region, player);
|
||||
if (hidden.get(region).contains(player)) {
|
||||
hidden.get(region).remove(player);
|
||||
BauSystem.MESSAGE.sendPrefixless("TECHHIDER_OFF", player, ChatMessageType.ACTION_BAR);
|
||||
|
||||
Reference in New Issue
Block a user