adding support for equipment inventories as well as horse and pillager item inventories.

This commit is contained in:
gnembon committed 2020-11-25 17:52:17 -04:00
1 parent 1e7457c27f
commit 201654ff44
7 files changed
+175 -1

No files matched your search

+13
View File
@@ -8,6 +8,18 @@ two arguments, keyword `'enderchest'`, followed by the player entity argument, o
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.
You can also use `'equipment'` as a keyword preceeding an entity indicating the need of access that entity as a mob.
Equipment inventory
consists of its armour and hand items, and a few living entites can have both, their regular inventory, and their equipment inventory. For some
entities (players) their regular inventory already contains the equipment. For entity types that only have
their equipment inventory, the equipment is returned by default.
<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
an inventory, they typically do nothing and return null.
@@ -91,6 +103,7 @@ have an inventory
<pre>
inventory_size(player()) => 41
inventory_size('enderchest', player()) => 27 // enderchest
inventory_size('equipment', player()) => 6 // equipment
inventory_size(x,y,z) => 27 // chest
inventory_size(block(pos)) => 5 // hopper
</pre>
@@ -0,0 +1,8 @@
package carpet.fakes;
import net.minecraft.inventory.Inventory;
public interface InventoryBearerInterface
{
Inventory getCMInventory();
}
@@ -0,0 +1,21 @@
package carpet.mixins;
import carpet.fakes.InventoryBearerInterface;
import net.minecraft.entity.passive.HorseBaseEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.SimpleInventory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(HorseBaseEntity.class)
public class HorseBaseEntity_scarpetMixin implements InventoryBearerInterface
{
@Shadow protected SimpleInventory items;
@Override
public Inventory getCMInventory()
{
return items;
}
}
@@ -0,0 +1,21 @@
package carpet.mixins;
import carpet.fakes.InventoryBearerInterface;
import net.minecraft.entity.mob.PillagerEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.SimpleInventory;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(PillagerEntity.class)
public class PillagerEntity_scarpetMixin implements InventoryBearerInterface
{
@Shadow @Final private SimpleInventory inventory;
@Override
public Inventory getCMInventory()
{
return inventory;
}
}
@@ -0,0 +1,96 @@
package carpet.script.utils;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
public class LivingInventory implements Inventory
{
private static final Int2ObjectMap<EquipmentSlot> slotToSlot = new Int2ObjectOpenHashMap<EquipmentSlot>(){{
put(0, EquipmentSlot.MAINHAND);
put(1, EquipmentSlot.FEET);
put(2, EquipmentSlot.LEGS);
put(3, EquipmentSlot.CHEST);
put(4, EquipmentSlot.HEAD);
put(5, EquipmentSlot.OFFHAND);
}};
LivingEntity mob;
public LivingInventory(LivingEntity mob)
{
this.mob = mob;
}
@Override
public int size()
{
return 6;
}
@Override
public boolean isEmpty()
{
for (EquipmentSlot slot: EquipmentSlot.values())
if (!mob.getEquippedStack(slot).isEmpty()) return false;
return true;
}
@Override
public ItemStack getStack(int slot)
{
EquipmentSlot slotSlot = slotToSlot.getOrDefault(slot, null);
if (slotSlot == null) return null;
return mob.getEquippedStack(slotToSlot.get(slot));
}
@Override
public ItemStack removeStack(int slot, int amount)
{
EquipmentSlot slotSlot = slotToSlot.getOrDefault(slot, null);
if (slotSlot == null) return null;
ItemStack stack = mob.getEquippedStack(slotSlot);
stack.decrement(amount);
return stack;
}
@Override
public ItemStack removeStack(int slot)
{
EquipmentSlot slotSlot = slotToSlot.getOrDefault(slot, null);
if (slotSlot == null) return null;
ItemStack previous = mob.getEquippedStack(slotSlot);
mob.equipStack(slotSlot, ItemStack.EMPTY);
return previous;
}
@Override
public void setStack(int slot, ItemStack stack)
{
EquipmentSlot slotSlot = slotToSlot.getOrDefault(slot, null);
if (slotSlot == null) return;
mob.equipStack(slotSlot, stack);
}
@Override
public void markDirty()
{
}
@Override
public boolean canPlayerUse(PlayerEntity player)
{
return false;
}
@Override
public void clear()
{
for (EquipmentSlot slot: EquipmentSlot.values())
mob.equipStack(slot, ItemStack.EMPTY);
}
}
@@ -1,8 +1,10 @@
package carpet.script.value;
import carpet.fakes.InventoryBearerInterface;
import carpet.script.CarpetContext;
import carpet.script.LazyValue;
import carpet.script.exception.InternalExpressionException;
import carpet.script.utils.LivingInventory;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.block.Block;
@@ -15,6 +17,8 @@ import net.minecraft.command.argument.ItemStackArgument;
import net.minecraft.command.argument.ItemStringReader;
import net.minecraft.command.argument.NbtPathArgumentType;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.passive.VillagerEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventory;
@@ -184,7 +188,8 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
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) inv = new LivingInventory((MobEntity) e);
if (inv == null)
return null;
@@ -222,6 +227,14 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
if (player == null) throw new InternalExpressionException("enderchest inventory requires player argument");
return new InventoryLocator(player, player.getBlockPos(), player.getEnderChestInventory(), offset + 2, true);
}
else if (strVal.equals("equipment"))
{
Value v2 = params.get(1 + offset).evalValue(c);
if (!(v2 instanceof EntityValue)) throw new InternalExpressionException("mob inventory requires a mob argument");
Entity e = ((EntityValue) v2).getEntity();
if (!(e instanceof LivingEntity)) throw new InternalExpressionException("mob inventory requires a mob argument");
return new InventoryLocator(e, e.getBlockPos(), new LivingInventory((LivingEntity) e), offset + 2, false);
}
else
{
boolean isEnder = strVal.startsWith("enderchest_");
+2
View File
@@ -174,6 +174,8 @@
"RecipeManager_scarpetMixin",
"Ingredient_scarpetMixin",
"BlockStateArgument_scarpetMixin",
"HorseBaseEntity_scarpetMixin",
"PillagerEntity_scarpetMixin",
"PistonBlock_movableTEMixin",
"PistonBlockEntity_movableTEMixin",