From dd28c78a366032cf5393fbeee709d04b56a0a543 Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Sat, 6 Apr 2019 14:45:39 +1100 Subject: [PATCH] trimflatfilter --- .../boydti/fawe/command/AnvilCommands.java | 12 +++ .../jnbt/anvil/filters/TrimFlatFilter.java | 73 +++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 core/src/main/java/com/boydti/fawe/jnbt/anvil/filters/TrimFlatFilter.java diff --git a/core/src/main/java/com/boydti/fawe/command/AnvilCommands.java b/core/src/main/java/com/boydti/fawe/command/AnvilCommands.java index 1eb6ab67..83fc1e97 100644 --- a/core/src/main/java/com/boydti/fawe/command/AnvilCommands.java +++ b/core/src/main/java/com/boydti/fawe/command/AnvilCommands.java @@ -310,6 +310,18 @@ public class AnvilCommands { } + @Command( + aliases = {"trimallflat", }, + desc = "Trim all flat chunks" + ) + @CommandPermissions("worldedit.anvil.trimallflat") + public void trimAllAir(Player player, String folder, @Switch('u') boolean unsafe) throws WorldEditException { + TrimFlatFilter filter = new TrimFlatFilter(); + TrimFlatFilter result = runWithWorld(player, folder, filter, true, unsafe); + if (result != null) player.print(BBC.getPrefix() + BBC.VISITOR_BLOCK.format(result.getTotal())); + } + + @Command( aliases = {"debugfixair", }, desc = "debug - do not use" diff --git a/core/src/main/java/com/boydti/fawe/jnbt/anvil/filters/TrimFlatFilter.java b/core/src/main/java/com/boydti/fawe/jnbt/anvil/filters/TrimFlatFilter.java new file mode 100644 index 00000000..c619406d --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/jnbt/anvil/filters/TrimFlatFilter.java @@ -0,0 +1,73 @@ +package com.boydti.fawe.jnbt.anvil.filters; + +import com.boydti.fawe.jnbt.anvil.MCAChunk; +import com.boydti.fawe.jnbt.anvil.MCAFile; +import com.boydti.fawe.jnbt.anvil.MCAFilterCounter; +import com.boydti.fawe.object.RunnableVal; +import com.boydti.fawe.object.number.MutableLong; + +public class TrimFlatFilter extends MCAFilterCounter { + @Override + public MCAChunk applyChunk(MCAChunk chunk, MutableLong cache) { + // Check other layers + for (int layer = 1; layer < chunk.ids.length; layer++) { + byte[] idLayer = chunk.ids[layer]; + if (idLayer == null) continue; + for (int i = 0; i < 4096; i++) { + if (idLayer[i] != 0) { + return null; + } + } + { // Possibly dead code depending on the generator + chunk.ids[layer] = null; + chunk.data[layer] = null; + chunk.setModified(); + } + } + byte[] layer0 = chunk.ids[0]; + int index = 0; + for (int y = 0; y <= 3; y++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++, index++) { + int id = layer0[index] & 0xFF; + switch (id) { + case 2: // grass + case 3: // dirt + case 7: // bedrock + continue; + default: + return; + } + } + } + } + for (int y = 4; y < 16; y++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++, index++) { + if (layer0[index] != 0) return; + } + } + } + + // Check floor layers + cache.add(Character.MAX_VALUE); + chunk.setDeleted(true); + return null; + } + + @Override + public void finishFile(MCAFile file, MutableLong cache) { + boolean[] deleteFile = { true }; + file.forEachCachedChunk(new RunnableVal() { + @Override + public void run(MCAChunk value) { + if (!value.isDeleted()) { + deleteFile[0] = false; + } + } + }); + if (deleteFile[0]) { + file.setDeleted(true); + } + } +} \ No newline at end of file