From 2f08ee8c0149518b79f67c672838779ed62776a0 Mon Sep 17 00:00:00 2001 From: gnembon Date: Sun, 7 Jun 2020 19:32:08 -0300 Subject: [PATCH] player inventories can be specified as strings player enderchest inventories can also be specified as a single string. --- docs/scarpet/api/Inventories.md | 7 ++++- .../script/value/NBTSerializableValue.java | 30 ++++++++++++++----- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/docs/scarpet/api/Inventories.md b/docs/scarpet/api/Inventories.md index 972cf5b5..5ef96c7a 100644 --- a/docs/scarpet/api/Inventories.md +++ b/docs/scarpet/api/Inventories.md @@ -4,7 +4,12 @@ Most functions in this category require inventory as the first argument. Inventory could be specified by an entity, or a block, or position (three coordinates) of a potential block with inventory. Player enderchest inventory require -two arguments, keyword `'enderchest'`, followed by the player entity argument. If the entity or a block doesn't have +two arguments, keyword `'enderchest'`, followed by the player entity argument, or a single argument as a string of a +form: `'enderchest_steve'`. If your player name starts with enderchest, it can be always accessed by passing a player +entity value. If all else fails, it will try to identify first three arguments as coordinates of a block position of +a block inventory. Player inventories can also be called by their name. + + If the entity or a block doesn't have an inventory, they typically do nothing and return null. Most items returned are in the form of a triple of item name, count, and nbt or the extra data associated with an item. diff --git a/src/main/java/carpet/script/value/NBTSerializableValue.java b/src/main/java/carpet/script/value/NBTSerializableValue.java index 07256909..b4ce70b5 100644 --- a/src/main/java/carpet/script/value/NBTSerializableValue.java +++ b/src/main/java/carpet/script/value/NBTSerializableValue.java @@ -27,6 +27,7 @@ import net.minecraft.nbt.StringNbtReader; import net.minecraft.nbt.StringTag; import net.minecraft.nbt.Tag; import net.minecraft.predicate.entity.EntityPredicates; +import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; @@ -35,6 +36,7 @@ import net.minecraft.util.math.Box; import java.util.Collection; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.function.Supplier; import java.util.regex.Matcher; @@ -201,16 +203,30 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa return null; return new InventoryLocator(pos, pos, inv, offset + 1); } - else if (v1.getString().equalsIgnoreCase("enderchest")) + else if (v1 instanceof StringValue) { - Value v2 = params.get(1 + offset).evalValue(c); - if (!(v2 instanceof EntityValue) || !(((EntityValue) v2).getEntity() instanceof PlayerEntity)) + String strVal = v1.getString().toLowerCase(Locale.ROOT); + if (strVal.equals("enderchest")) { - throw new InternalExpressionException("enderchest inventory requires player argument"); + Value v2 = params.get(1 + offset).evalValue(c); + ServerPlayerEntity player = EntityValue.getPlayerByValue(c.s.getMinecraftServer(), v2); + if (player == null) throw new InternalExpressionException("enderchest inventory requires player argument"); + return new InventoryLocator(player, player.getBlockPos(), player.getEnderChestInventory(), offset + 2, true); + } + else + { + boolean isEnder = strVal.startsWith("enderchest_"); + if (isEnder) strVal = strVal.substring(11); // len("enderchest_") + ServerPlayerEntity player = c.s.getMinecraftServer().getPlayerManager().getPlayer(strVal); + if (player == null) throw new InternalExpressionException("String description of an inventory should either denote a player or player's enderchest"); + return new InventoryLocator( + player, + player.getBlockPos(), + isEnder ? player.getEnderChestInventory() : player.inventory, + offset + 1, + isEnder + ); } - PlayerEntity e = (PlayerEntity)((EntityValue) v2).getEntity(); - inv = e.getEnderChestInventory(); - return new InventoryLocator(e, e.getBlockPos(), inv, offset + 2, true); } BlockPos pos = new BlockPos( NumericValue.asNumber(v1).getDouble(),