refactor for inventories, allowing for null types.
This commit is contained in:
1 parent
2d92a82ed0
commit
79cb4a20d8
3 files changed
+88
-74
No files matched your search
@@ -3,29 +3,30 @@
|
|||||||
## Manipulating inventories of blocks and entities
|
## Manipulating inventories of blocks and entities
|
||||||
|
|
||||||
Most functions in this category require inventory as the first argument. Inventory could be specified by an entity,
|
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
|
or a block, or position (three coordinates) of a potential block with inventory, or can be preceded with inventory
|
||||||
two arguments, keyword `'enderchest'`, followed by the player entity argument, or a single argument as a string of a
|
type.
|
||||||
form: `'enderchest_steve'`. If your player name starts with enderchest, it can be always accessed by passing a player
|
Inventory type can be `null` (default), `'enderchest'` denoting player enderchest storage, or `'equipment'` applying to
|
||||||
|
entities hand and armour pieces. Then the type can be followed by entity, block or position coordinates.
|
||||||
|
For instance, player enderchest inventory requires
|
||||||
|
two arguments, keyword `'enderchest'`, followed by the player entity argument, (or a single argument as a string of a
|
||||||
|
form: `'enderchest_steve'` for legacy support). If your player name starts with `'enderchest_'`, first of all, tough luck,
|
||||||
|
but then 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
|
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.
|
a block inventory. Player inventories can also be called by their name.
|
||||||
|
|
||||||
You can also use `'equipment'` as a keyword preceeding an entity indicating the need of access that entity as a mob.
|
A few living entities can have both: their regular inventory, and their equipment inventory.
|
||||||
Equipment inventory
|
Player's regular inventory already contains the equipment, but you can access the equipment part as well, as well as
|
||||||
consists of its armour and hand items, and a few living entites can have both, their regular inventory, and their equipment inventory. For some
|
their enderchest separately. For entity types that only have
|
||||||
entities (players) their regular inventory already contains the equipment. For entity types that only have
|
their equipment inventory, the equipment is returned by default (`null` type).
|
||||||
their equipment inventory, the equipment is returned by default.
|
|
||||||
|
If that's confusing see examples under `inventory_size` on how to access inventories. All other `inventory_...()` functions
|
||||||
|
use the same scheme.
|
||||||
|
|
||||||
<pre>
|
|
||||||
inventory_size(player()) => 41 // items
|
|
||||||
inventory_size('enderchest', player()) => 27 // equipment
|
|
||||||
inventory_size('equipment', player()) => 6 // equipment
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
If the entity or a block doesn't have
|
If the entity or a block doesn't have
|
||||||
an inventory, they typically do nothing and return null.
|
an inventory, all API functions 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.
|
Most items returned are in the form of a triple of item name, count, and nbt or the extra data associated with an item.
|
||||||
Manipulating of the nbt data can be costly, but retrieving them from the tuple to match other aspects is cheap
|
|
||||||
|
|
||||||
### `stack_limit(item)`
|
### `stack_limit(item)`
|
||||||
|
|
||||||
@@ -98,14 +99,26 @@ item name that serves as a replacement after crafting is done. Currently it can
|
|||||||
### `inventory_size(inventory)`
|
### `inventory_size(inventory)`
|
||||||
|
|
||||||
Returns the size of the inventory for the entity or block in question. Returns null if the block or entity don't
|
Returns the size of the inventory for the entity or block in question. Returns null if the block or entity don't
|
||||||
have an inventory
|
have an inventory.
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
inventory_size(player()) => 41
|
inventory_size(player()) => 41
|
||||||
inventory_size('enderchest', player()) => 27 // enderchest
|
inventory_size('enderchest', player()) => 27 // enderchest
|
||||||
inventory_size('equipment', player()) => 6 // equipment
|
inventory_size('equipment', player()) => 6 // equipment
|
||||||
|
inventory_size(null, player()) => 41 // default inventory for players
|
||||||
|
|
||||||
inventory_size(x,y,z) => 27 // chest
|
inventory_size(x,y,z) => 27 // chest
|
||||||
inventory_size(block(pos)) => 5 // hopper
|
inventory_size(block(pos)) => 5 // hopper
|
||||||
|
|
||||||
|
horse = spawn('horse', x, y, z);
|
||||||
|
inventory_size(horse); => 2 // default horse inventory
|
||||||
|
inventory_size('equipment', horse); => 6 // unused horse equipment inventory
|
||||||
|
inventory_size(null, horse); => 2 // default horse
|
||||||
|
|
||||||
|
creeper = spawn('creeper', x, y, z);
|
||||||
|
inventory_size(creeper); => 6 // default creeper inventory is equipment since it has no other
|
||||||
|
inventory_size('equipment', creeper); => 6 // unused horse equipment inventory
|
||||||
|
inventory_size(null, creeper); => 6 // creeper default is its equipment
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
### `inventory_has_items(inventory)`
|
### `inventory_has_items(inventory)`
|
||||||
|
|||||||
+2
-2
@@ -9,7 +9,7 @@ import net.minecraft.item.ItemStack;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class LivingInventory implements Inventory
|
public class EquipmentInventory implements Inventory
|
||||||
{
|
{
|
||||||
private static final List<EquipmentSlot> slotToSlot = Arrays.asList(
|
private static final List<EquipmentSlot> slotToSlot = Arrays.asList(
|
||||||
EquipmentSlot.MAINHAND,
|
EquipmentSlot.MAINHAND,
|
||||||
@@ -18,7 +18,7 @@ public class LivingInventory implements Inventory
|
|||||||
);
|
);
|
||||||
|
|
||||||
LivingEntity mob;
|
LivingEntity mob;
|
||||||
public LivingInventory(LivingEntity mob)
|
public EquipmentInventory(LivingEntity mob)
|
||||||
{
|
{
|
||||||
this.mob = mob;
|
this.mob = mob;
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,7 @@ import carpet.fakes.InventoryBearerInterface;
|
|||||||
import carpet.script.CarpetContext;
|
import carpet.script.CarpetContext;
|
||||||
import carpet.script.LazyValue;
|
import carpet.script.LazyValue;
|
||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
import carpet.script.utils.LivingInventory;
|
import carpet.script.utils.EquipmentInventory;
|
||||||
import com.mojang.brigadier.StringReader;
|
import com.mojang.brigadier.StringReader;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
@@ -175,47 +175,15 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
return inventory;
|
return inventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static InventoryLocator locateInventory(CarpetContext c, List<LazyValue> params, int offset)
|
public static InventoryLocator locateInventory(CarpetContext c, List<LazyValue> params, int offset)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Inventory inv = null;
|
Value v1 = params.get(offset).evalValue(c);
|
||||||
Value v1 = params.get(0 + offset).evalValue(c);
|
if (v1.isNull())
|
||||||
if (v1 instanceof EntityValue)
|
|
||||||
{
|
{
|
||||||
Entity e = ((EntityValue) v1).getEntity();
|
offset ++;
|
||||||
if (e instanceof PlayerEntity) inv = ((PlayerEntity) e).inventory;
|
v1 = params.get(offset).evalValue(c);
|
||||||
else if (e instanceof Inventory) inv = (Inventory) e;
|
|
||||||
else if (e instanceof VillagerEntity) inv = ((VillagerEntity) e).getInventory();
|
|
||||||
else if (e instanceof InventoryBearerInterface) inv = ((InventoryBearerInterface)e).getCMInventory();
|
|
||||||
else if (e instanceof LivingEntity) inv = new LivingInventory((MobEntity) e);
|
|
||||||
if (inv == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return new InventoryLocator(e, e.getBlockPos(), inv, offset + 1);
|
|
||||||
}
|
|
||||||
else if (v1 instanceof BlockValue)
|
|
||||||
{
|
|
||||||
BlockPos pos = ((BlockValue) v1).getPos();
|
|
||||||
if (pos == null)
|
|
||||||
throw new InternalExpressionException("Block to access inventory needs to be positioned in the world");
|
|
||||||
inv = getInventoryAt(c.s.getWorld(), pos);
|
|
||||||
if (inv == null)
|
|
||||||
return null;
|
|
||||||
return new InventoryLocator(pos, pos, inv, offset + 1);
|
|
||||||
}
|
|
||||||
else if (v1 instanceof ListValue)
|
|
||||||
{
|
|
||||||
List<Value> args = ((ListValue) v1).getItems();
|
|
||||||
BlockPos pos = new BlockPos(
|
|
||||||
NumericValue.asNumber(args.get(0)).getDouble(),
|
|
||||||
NumericValue.asNumber(args.get(1)).getDouble(),
|
|
||||||
NumericValue.asNumber(args.get(2)).getDouble());
|
|
||||||
inv = getInventoryAt(c.s.getWorld(), pos);
|
|
||||||
if (inv == null)
|
|
||||||
return null;
|
|
||||||
return new InventoryLocator(pos, pos, inv, offset + 1);
|
|
||||||
}
|
}
|
||||||
else if (v1 instanceof StringValue)
|
else if (v1 instanceof StringValue)
|
||||||
{
|
{
|
||||||
@@ -227,34 +195,67 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
if (player == null) throw new InternalExpressionException("enderchest inventory requires player argument");
|
if (player == null) throw new InternalExpressionException("enderchest inventory requires player argument");
|
||||||
return new InventoryLocator(player, player.getBlockPos(), player.getEnderChestInventory(), offset + 2, true);
|
return new InventoryLocator(player, player.getBlockPos(), player.getEnderChestInventory(), offset + 2, true);
|
||||||
}
|
}
|
||||||
else if (strVal.equals("equipment"))
|
if (strVal.equals("equipment"))
|
||||||
{
|
{
|
||||||
Value v2 = params.get(1 + offset).evalValue(c);
|
Value v2 = params.get(1 + offset).evalValue(c);
|
||||||
if (!(v2 instanceof EntityValue)) throw new InternalExpressionException("mob inventory requires a mob argument");
|
if (!(v2 instanceof EntityValue)) throw new InternalExpressionException("Equipment inventory requires a living entity argument");
|
||||||
Entity e = ((EntityValue) v2).getEntity();
|
Entity e = ((EntityValue) v2).getEntity();
|
||||||
if (!(e instanceof LivingEntity)) throw new InternalExpressionException("mob inventory requires a mob argument");
|
if (!(e instanceof LivingEntity)) throw new InternalExpressionException("Equipment inventory requires a living entity argument");
|
||||||
return new InventoryLocator(e, e.getBlockPos(), new LivingInventory((LivingEntity) e), offset + 2, false);
|
return new InventoryLocator(e, e.getBlockPos(), new EquipmentInventory((LivingEntity) e), offset + 2);
|
||||||
}
|
|
||||||
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
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (v1 instanceof EntityValue)
|
||||||
|
{
|
||||||
|
Inventory inv = null;
|
||||||
|
Entity e = ((EntityValue) v1).getEntity();
|
||||||
|
if (e instanceof PlayerEntity) inv = ((PlayerEntity) e).inventory;
|
||||||
|
else if (e instanceof Inventory) inv = (Inventory) e;
|
||||||
|
else if (e instanceof VillagerEntity) inv = ((VillagerEntity) e).getInventory();
|
||||||
|
else if (e instanceof InventoryBearerInterface) inv = ((InventoryBearerInterface)e).getCMInventory();
|
||||||
|
else if (e instanceof LivingEntity) return new InventoryLocator(e, e.getBlockPos(), new EquipmentInventory((MobEntity) e), offset+1);
|
||||||
|
if (inv == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new InventoryLocator(e, e.getBlockPos(), inv, offset+1);
|
||||||
|
}
|
||||||
|
if (v1 instanceof BlockValue)
|
||||||
|
{
|
||||||
|
BlockPos pos = ((BlockValue) v1).getPos();
|
||||||
|
if (pos == null)
|
||||||
|
throw new InternalExpressionException("Block to access inventory needs to be positioned in the world");
|
||||||
|
Inventory inv = getInventoryAt(c.s.getWorld(), pos);
|
||||||
|
if (inv == null)
|
||||||
|
return null;
|
||||||
|
return new InventoryLocator(pos, pos, inv, offset+1);
|
||||||
|
}
|
||||||
|
if (v1 instanceof ListValue)
|
||||||
|
{
|
||||||
|
List<Value> args = ((ListValue) v1).getItems();
|
||||||
|
BlockPos pos = new BlockPos(
|
||||||
|
NumericValue.asNumber(args.get(0)).getDouble(),
|
||||||
|
NumericValue.asNumber(args.get(1)).getDouble(),
|
||||||
|
NumericValue.asNumber(args.get(2)).getDouble());
|
||||||
|
Inventory inv = getInventoryAt(c.s.getWorld(), pos);
|
||||||
|
if (inv == null)
|
||||||
|
return null;
|
||||||
|
return new InventoryLocator(pos, pos, inv, offset+1);
|
||||||
}
|
}
|
||||||
BlockPos pos = new BlockPos(
|
BlockPos pos = new BlockPos(
|
||||||
NumericValue.asNumber(v1).getDouble(),
|
NumericValue.asNumber(v1).getDouble(),
|
||||||
NumericValue.asNumber(params.get(1 + offset).evalValue(c)).getDouble(),
|
NumericValue.asNumber(params.get(1 + offset).evalValue(c)).getDouble(),
|
||||||
NumericValue.asNumber(params.get(2 + offset).evalValue(c)).getDouble());
|
NumericValue.asNumber(params.get(2 + offset).evalValue(c)).getDouble());
|
||||||
inv = getInventoryAt(c.s.getWorld(), pos);
|
Inventory inv = getInventoryAt(c.s.getWorld(), pos);
|
||||||
if (inv == null)
|
if (inv == null)
|
||||||
return null;
|
return null;
|
||||||
return new InventoryLocator(pos, pos, inv, offset + 3);
|
return new InventoryLocator(pos, pos, inv, offset + 3);
|
||||||
|
|||||||
Reference in new issue
Block a user