Add a way to manipulate nbt of blocks in selection
The Problem
It is extremely tiresome to use worldedit to set LootTables for chests in an area, without destroying their other NBT data.
Or to fix up decorated pot patterns without touching their content.
Or to basically do any non-destructive nbt operation
A Solution
Add a command/commands to basically mass execute /data merge block {nbt], /data set block {nbt} and /data modify block ...
e.g.:
//nbtmerge chest {LootTable:"chests/simple_dungeon"}
//nbtset {}
//nbtmodify decorated_pot shards[0] set "minecraft:skull_pottery_sherd"
Maybe warn players that bad NBT may crash the game, especially with modded blocks when first using the command.
Alternatives
Alternatively just allow arbitrary commands to be executed for blocks in selection matching mask.
//execute [mask] command [arguments] §x §y §z [arguments]
Pro:
- more versatile
Con:
- less readable/intuitive commands
Anything Else?
No response
We should add nbtmerge / nbtmodify, but as a pattern, not a dedicated command. For syntax, ^{} should work just fine, as it will be similar to how type/state applying works already.
I'm not sure what exactly you were thinking of as the difference between the two, but I assume you want "merge" to merge lists and objects together, whereas ^{} would just be an overwrite. I'm not sure what kind of syntax would work for this case, but we should again keep it as just a pattern.
I don't see the value of nbtset as I think it's unlikely to be useful to apply to different types of blocks and you can just do chest{} already.
I thought nbtset might be useful to unset NBT for all blocks or to e.g. overwrite NBT for contents on all kinds of containers. This is already kinda doable with replace (just quite cumbersome in some cases).
But just having ^{...} would already be very useful. With merge, noted with e.g. a prepended comma ^{,...} it would solve my problems. I don't think modify is that useful outside specific edge cases (i.e. setting slot 1 of every container to a specific item), anyway.
As a Sidenote/idea/concept regarding ^ patterns, I would find it most intuitive to have a placeholder for keeping arbitrary parts of a block, instead. The benefit would be that one could replace or keep any combination of block, blockstates and NBT. e.g.
//replace #existing ^[^]{^} would be a no-op replacing every block with an identical copy,
//replace #existing ^[^]{} would purge NBT for all blocks (=^{}),
//replace #existing chest[^]{LootTable:"chests/simple_dungeon"} would replace everything with loot chests preserving block states if possible (=two runs ^chest and ^{LootTable:"chests/simple_dungeon"})
//replace chest ^[^]{^,LootTable:"chests/simple_dungeon"} would merge LootTable to all chests (=^{,LootTable:"chests/simple_dungeon"}),
//replace ##stairs ^[^,waterlogged=true] would waterlog all stairs, keeping other state.
For modify a syntax like this could be used:
set:
//replace decorated_pot ^[^]{^,shards[0]="minecraft:skull_pottery_sherd"} (=^{,shards[0]="minecraft:skull_pottery_sherd"})
append:
//replace decorated_pot ^[^]{^,shards=+"minecraft:skull_pottery_sherd"} (=^{,shards=+"minecraft:skull_pottery_sherd"})
prepend:
//replace decorated_pot ^[^]{^,shards+="minecraft:skull_pottery_sherd"} (=^{,shards+="minecraft:skull_pottery_sherd"})
insert:
//replace decorated_pot ^[^]{^,shards[3]+"minecraft:skull_pottery_sherd"} (=^{,shards[3]+"minecraft:skull_pottery_sherd"})
delete:
//replace decorated_pot ^[^]{^,LootTable-} (=^{,LootTable-})
//replace decorated_pot ^[^]{^,shards[0]-} (=^{,shards[0]-})
//replace decorated_pot ^[^]{^,shards[-1]-} (=^{,shards[-1]-})
merge in modify:
//replace example ^[^]{^,nested.example.pos^={x:12,y:1}} (=^{,nested.example.pos^={x:12,y:1}})
would appreciate a //wax command i mentioned in the duplicate issue; as well as affecting signs