Skip to content

Commit 373dfbc

Browse files
fix: don't write structure void blocks in Minecraft structure (#3092)
1 parent f86192c commit 373dfbc

File tree

2 files changed

+22
-11
lines changed

2 files changed

+22
-11
lines changed

worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ public Clipboard read(UUID clipboardId) throws IOException {
103103
size.get(0).valueAsInt(), size.get(1).valueAsInt(), size.get(2).value()
104104
).subtract(BlockVector3.ONE));
105105
final Clipboard clipboard = new BlockArrayClipboard(region, clipboardId);
106+
// fill clipboard with structure void blocks to represent empty entries.
107+
// known block data will be overridden with palette data.
108+
clipboard.setBlocks((Region) region, BlockTypes.STRUCTURE_VOID.getDefaultState());
106109

107110
// Palette
108111
final List<LinCompoundTag> paletteEntry = parent.getListTag("palette", LinTagType.compoundTag()).value();
@@ -204,6 +207,7 @@ public void write(Clipboard clipboard) throws IOException {
204207
Int2ObjectMap<BlockState> paletteIndexes = new Int2ObjectArrayMap<>();
205208
for (final BlockVector3 pos : clipboard) {
206209
final BlockState block = clipboard.getBlock(pos);
210+
// Structure Void Blocks are not part of the structure file and therefor not part of the palette
207211
if (block.getBlockType() == BlockTypes.STRUCTURE_VOID || ordinals.containsKey(block.getOrdinalChar())) {
208212
continue;
209213
}
@@ -225,20 +229,21 @@ public void write(Clipboard clipboard) throws IOException {
225229
// Blocks
226230
LinListTag.Builder<@org.jetbrains.annotations.NotNull LinCompoundTag> blocks = LinListTag.builder(LinTagType.compoundTag());
227231
for (final BlockVector3 pos : clipboard) {
228-
final BlockState block = clipboard.getBlock(pos);
232+
final BaseBlock block = clipboard.getFullBlock(pos);
233+
// Structure Void Blocks are not part of the structure file
234+
if (block.getBlockType() == BlockTypes.STRUCTURE_VOID) {
235+
continue;
236+
}
229237
LinCompoundTag.Builder entry = LinCompoundTag.builder()
230238
.putInt("state", ordinals.get(block.getOrdinalChar()))
231239
.put("pos", LinListTag.of(LinTagType.intTag(), List.of(
232240
LinIntTag.of(pos.x() - min.x()),
233241
LinIntTag.of(pos.y() - min.y()),
234242
LinIntTag.of(pos.z() - min.z())
235243
)));
236-
final BaseBlock baseBlock = clipboard.getFullBlock(pos);
237-
if (baseBlock != null) {
238-
final LinCompoundTag nbt = baseBlock.getNbt();
239-
if (nbt != null) {
240-
entry.put("nbt", nbt.toBuilder().remove("x").remove("y").remove("z").build());
241-
}
244+
final LinCompoundTag nbt = block.getNbt();
245+
if (nbt != null) {
246+
entry.put("nbt", nbt.toBuilder().remove("x").remove("y").remove("z").build());
242247
}
243248
blocks.add(entry.build());
244249
}

worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
5959
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
6060
import com.sk89q.worldedit.function.block.BlockReplace;
61+
import com.sk89q.worldedit.function.mask.InverseSingleBlockTypeMask;
6162
import com.sk89q.worldedit.function.mask.Mask;
6263
import com.sk89q.worldedit.function.mask.MaskIntersection;
6364
import com.sk89q.worldedit.function.mask.Masks;
@@ -85,6 +86,7 @@
8586
import com.sk89q.worldedit.util.formatting.text.TextComponent;
8687
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
8788
import com.sk89q.worldedit.world.World;
89+
import com.sk89q.worldedit.world.block.BlockTypes;
8890
import org.enginehub.piston.annotation.Command;
8991
import org.enginehub.piston.annotation.CommandContainer;
9092
import org.enginehub.piston.annotation.param.Arg;
@@ -526,14 +528,15 @@ public void paste(
526528
Mask sourceMask,
527529
//FAWE start - entity removal
528530
@Switch(name = 'x', desc = "Remove existing entities in the affected region")
529-
boolean removeEntities
531+
boolean removeEntities,
532+
@Switch(name = 'v', desc = "Don't paste structure void blocks and keep the target block state")
533+
boolean ignoreStructureVoidBlocks
530534
//FAWE end
531-
532535
) throws WorldEditException {
533536

534537
ClipboardHolder holder = session.getClipboard();
535538
//FAWE start - use place
536-
if (holder.getTransform().isIdentity() && sourceMask == null) {
539+
if (holder.getTransform().isIdentity() && sourceMask == null && !ignoreStructureVoidBlocks) {
537540
place(actor, world, session, editSession, ignoreAirBlocks, atOrigin, selectPasted, onlySelect,
538541
pasteEntities, pasteBiomes, removeEntities
539542
);
@@ -550,13 +553,16 @@ public void paste(
550553
//FAWE end
551554

552555
if (!onlySelect) {
556+
final Mask finalSourceMask = ignoreStructureVoidBlocks ?
557+
MaskIntersection.of(sourceMask, new InverseSingleBlockTypeMask(clipboard, BlockTypes.STRUCTURE_VOID)) :
558+
sourceMask;
553559
Operation operation = holder
554560
.createPaste(editSession)
555561
.to(to)
556562
.ignoreAirBlocks(ignoreAirBlocks)
557563
.copyBiomes(pasteBiomes)
558564
.copyEntities(pasteEntities)
559-
.maskSource(sourceMask)
565+
.maskSource(finalSourceMask)
560566
.build();
561567
Operations.completeLegacy(operation);
562568
messages.addAll(Lists.newArrayList(operation.getStatusMessages()));

0 commit comments

Comments
 (0)