forked from SteamWar/SteamWar
Allow removing hulls and resend their chunks
HullHider#removeHull stops hiding a hull: it shows the entities and REntities the hull hid and resends its chunks to everybody who could not view it. A hull is enabled again by adding and initialising it. Hull#resendChunks only resends chunks the player has loaded. HullHider now resends the chunks to non-viewers after initialising a hull itself, so FightHullHider no longer does it.
This commit is contained in:
@@ -32,7 +32,6 @@ import de.steamwar.fightsystem.states.StateDependentListener;
|
||||
import de.steamwar.fightsystem.states.StateDependentTask;
|
||||
import de.steamwar.hullhider.Hull;
|
||||
import de.steamwar.hullhider.HullHider;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -68,14 +67,6 @@ public class FightHullHider {
|
||||
public void initialize(FightTeam team) {
|
||||
if (!TechHiderWrapper.ENABLED) return;
|
||||
hullHider.initialize(team);
|
||||
|
||||
// Chunks encoded while the hull was filled as hidden contain obfuscated blocks that are visible now, but no block update is generated for them
|
||||
Hull hull = hullHider.getHull(team);
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (!hull.isViewer(player)) {
|
||||
FightSystem.getTechHider().reloadChunks(player, team.getExtendRegion(), Region.EMPTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void fill(FightTeam team, boolean visible) {
|
||||
|
||||
@@ -21,6 +21,7 @@ package de.steamwar.hullhider;
|
||||
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import de.steamwar.core.CraftbukkitWrapper;
|
||||
import de.steamwar.core.ProtocolWrapper;
|
||||
import de.steamwar.entity.REntity;
|
||||
import it.unimi.dsi.fastutil.shorts.Short2ObjectArrayMap;
|
||||
@@ -32,6 +33,7 @@ import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@@ -180,6 +182,38 @@ public class Hull {
|
||||
rentities.remove(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows all entities hidden by this hull again, used when the hull is removed.
|
||||
*/
|
||||
public void reveal() {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (isViewer(player)) continue;
|
||||
|
||||
for (Entity entity : entities) {
|
||||
if (!player.equals(entity)) trackEntity(player, entity);
|
||||
}
|
||||
}
|
||||
entities.clear();
|
||||
|
||||
for (REntity entity : rentities) {
|
||||
entity.hide(false);
|
||||
}
|
||||
rentities.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resends the chunks of this hull the player has loaded, so they are encoded with the current visibility.
|
||||
*/
|
||||
public void resendChunks(Player player) {
|
||||
if (player.getWorld() != world) return;
|
||||
|
||||
region.forEachChunk((chunkX, chunkZ) -> {
|
||||
if (player.isChunkSent(Chunk.getChunkKey(chunkX, chunkZ))) {
|
||||
CraftbukkitWrapper.sendChunk(player, chunkX, chunkZ);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void fill(boolean visible) {
|
||||
visibility.set(0, visibility.size(), visible);
|
||||
occluding.set(0, occluding.size(), !visible);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
package de.steamwar.hullhider;
|
||||
|
||||
import de.steamwar.entity.REntity;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
@@ -45,11 +46,30 @@ public class HullHider<K> implements Listener {
|
||||
// Read on netty threads, replaced on every change
|
||||
private volatile Hull[] hulls = new Hull[0];
|
||||
|
||||
/**
|
||||
* The hull hides everything from non-viewers until it is initialised.
|
||||
*/
|
||||
public void addHull(K key, Hull hull) {
|
||||
hullMap.put(key, hull);
|
||||
hulls = hullMap.values().toArray(new Hull[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops hiding the hull: shows the entities it hid and resends its chunks to everybody who could not view it.
|
||||
*/
|
||||
public void removeHull(K key) {
|
||||
Hull hull = hullMap.remove(key);
|
||||
if (hull == null) return;
|
||||
hulls = hullMap.values().toArray(new Hull[0]);
|
||||
|
||||
hull.reveal();
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (!hull.isViewer(player)) {
|
||||
hull.resendChunks(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Hull getHull(K key) {
|
||||
return hullMap.get(key);
|
||||
}
|
||||
@@ -59,7 +79,22 @@ public class HullHider<K> implements Listener {
|
||||
}
|
||||
|
||||
public void initialize(K key) {
|
||||
hullMap.get(key).initialize();
|
||||
Hull hull = hullMap.get(key);
|
||||
hull.initialize();
|
||||
|
||||
// Chunks encoded while the hull was filled as hidden contain obfuscated blocks that are visible now, but no block update is generated for them
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (!hull.isViewer(player)) {
|
||||
hull.resendChunks(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Has to be called after the player became a viewer of the hull or stopped being one.
|
||||
*/
|
||||
public void resendChunks(Player player, K key) {
|
||||
hullMap.get(key).resendChunks(player);
|
||||
}
|
||||
|
||||
public void fill(K key, boolean visible) {
|
||||
|
||||
@@ -90,10 +90,22 @@ public final class HullRegion {
|
||||
}
|
||||
}
|
||||
|
||||
public void forEachChunk(ChunkConsumer executor) {
|
||||
for (int chunkX = minX >> 4; chunkX <= (maxX - 1) >> 4; chunkX++) {
|
||||
for (int chunkZ = minZ >> 4; chunkZ <= (maxZ - 1) >> 4; chunkZ++) {
|
||||
executor.accept(chunkX, chunkZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface BlockConsumer {
|
||||
void accept(int x, int y, int z);
|
||||
}
|
||||
|
||||
public interface ChunkConsumer {
|
||||
void accept(int chunkX, int chunkZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return minX + "," + minY + "," + minZ + "->" + maxX + "," + maxY + "," + maxZ;
|
||||
|
||||
Reference in New Issue
Block a user