diff --git a/docs/scarpet/api/Auxiliary.md b/docs/scarpet/api/Auxiliary.md index 399d5fc1..cede1808 100644 --- a/docs/scarpet/api/Auxiliary.md +++ b/docs/scarpet/api/Auxiliary.md @@ -540,3 +540,9 @@ Available options in the scarpet app space: Scarpet related properties * `scarpet_version` - returns the version of the carpet your scarpet comes with. + +## NBT Storage + +### `nbt_storage()`, `nbt_storage(key)`, `nbt_storage(key, nbt)` +Displays or modifies individual storage NBT tags. With no arguments, returns the list of current NBT storages. With specified `key`, returns the `nbt` associated with current `key`, or `null` if storage does not exist. With specified `key` and `nbt`, sets a new `nbt` value, returning previous value associated with the `key`. +NOTE: This NBT storage is shared with all vanilla datapacks and scripts of the entire server and is persistent between restarts and reloads. You can also access this NBT storage with vanilla `/data storage ...` command. diff --git a/docs/scarpet/resources/editors/idea/2.txt b/docs/scarpet/resources/editors/idea/2.txt index 25f4e954..4186fa25 100644 --- a/docs/scarpet/resources/editors/idea/2.txt +++ b/docs/scarpet/resources/editors/idea/2.txt @@ -67,6 +67,7 @@ map_colour material modify nbt +nbt_storage neighbours opacity parse_nbt diff --git a/docs/scarpet/resources/editors/npp/scarpet.xml b/docs/scarpet/resources/editors/npp/scarpet.xml index 83cceb54..eeb7ca64 100644 --- a/docs/scarpet/resources/editors/npp/scarpet.xml +++ b/docs/scarpet/resources/editors/npp/scarpet.xml @@ -86,6 +86,8 @@ load_app_data store_app_data read_file write_file delete_file list_files escape_nbt parse_nbt encode_nbt tag_matches statistic + + nbt_storage euler pi null true false x y z p diff --git a/src/main/java/carpet/script/api/Auxiliary.java b/src/main/java/carpet/script/api/Auxiliary.java index 7625ea94..a0268cc7 100644 --- a/src/main/java/carpet/script/api/Auxiliary.java +++ b/src/main/java/carpet/script/api/Auxiliary.java @@ -36,12 +36,14 @@ import carpet.script.value.Value; import carpet.script.value.ValueConversions; import carpet.utils.Messenger; import net.minecraft.block.BlockState; +import net.minecraft.command.DataCommandStorage; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.decoration.ArmorStandEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtHelper; import net.minecraft.nbt.StringTag; import net.minecraft.nbt.Tag; @@ -86,6 +88,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import java.util.stream.Stream; +import static carpet.script.value.NBTSerializableValue.nameFromRegistryId; import static java.lang.Math.max; import static java.lang.Math.min; @@ -1022,6 +1025,29 @@ public class Auxiliary { Value ret = new NumericValue(counts); return (c_, t_) -> ret; }); + + // nbt_storage() + // nbt_storage(key) + // nbt_storage(key, nbt) + expression.addLazyFunction("nbt_storage", -1, (c, t, lv) -> { + if (lv.size() > 2) throw new InternalExpressionException("'nbt_storage' requires 0, 1 or 2 arguments."); + CarpetContext cc = (CarpetContext) c; + DataCommandStorage storage = cc.s.getMinecraftServer().getDataCommandStorage(); + if (lv.size() == 0) { + Value ret = ListValue.wrap(storage.getIds().map(i -> new StringValue(nameFromRegistryId(i))).collect(Collectors.toList())); + return (_c, _t) -> ret; + } + String key = lv.get(0).evalValue(c).getString(); + CompoundTag old_nbt = storage.get(new Identifier(key)); + if (lv.size() == 2) { + Value nbt = lv.get(1).evalValue(c); + NBTSerializableValue new_nbt = (nbt instanceof NBTSerializableValue) ? (NBTSerializableValue) nbt + : NBTSerializableValue.parseString(nbt.getString(), true); + storage.set(new Identifier(key), new_nbt.getCompoundTag()); + } + if (old_nbt == null) return LazyValue.NULL; + return (_c, _t) -> new NBTSerializableValue(old_nbt); + }); } private static Stat getStat(StatType type, Identifier id)