fill in inventory calls
This commit is contained in:
1 parent
037321ccfd
commit
7534c4b061
2 files changed
+166
-21
No files matched your search
@@ -19,11 +19,14 @@ import carpet.script.value.StringValue;
|
|||||||
import carpet.script.value.Value;
|
import carpet.script.value.Value;
|
||||||
import carpet.utils.BlockInfo;
|
import carpet.utils.BlockInfo;
|
||||||
import carpet.utils.Messenger;
|
import carpet.utils.Messenger;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
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;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.command.arguments.ItemStackArgument;
|
||||||
|
import net.minecraft.command.arguments.ItemStringReader;
|
||||||
import net.minecraft.enchantment.Enchantments;
|
import net.minecraft.enchantment.Enchantments;
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraft.entity.EquipmentSlot;
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
@@ -50,10 +53,7 @@ import net.minecraft.predicate.entity.EntityPredicates;
|
|||||||
import net.minecraft.text.LiteralText;
|
import net.minecraft.text.LiteralText;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.sound.SoundCategory;
|
import net.minecraft.sound.SoundCategory;
|
||||||
import net.minecraft.util.math.Box;
|
import net.minecraft.util.math.*;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.EulerRotation;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.util.registry.Registry;
|
||||||
import net.minecraft.world.LightType;
|
import net.minecraft.world.LightType;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
@@ -899,19 +899,125 @@ public class CarpetExpression
|
|||||||
});
|
});
|
||||||
|
|
||||||
//inventory_find(<b, e>, <item> or null (first empty slot), <start_from=0> ) -> <N> or null
|
//inventory_find(<b, e>, <item> or null (first empty slot), <start_from=0> ) -> <N> or null
|
||||||
|
this.expr.addLazyFunction("inventory_find", -1, (c, t, lv) -> {
|
||||||
|
//long stime = System.nanoTime();
|
||||||
|
CarpetContext cc = (CarpetContext) c;
|
||||||
|
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||||
|
ItemStackArgument itemArg = null;
|
||||||
|
if (lv.size() > inventoryLocator.offset)
|
||||||
|
{
|
||||||
|
Value secondArg = lv.get(inventoryLocator.offset+0).evalValue(c);
|
||||||
|
if (!(secondArg instanceof NullValue))
|
||||||
|
{
|
||||||
|
itemArg = NBTSerializableValue.parseItem(secondArg.getString());
|
||||||
|
if (itemArg == null)
|
||||||
|
throw new InternalExpressionException("Incorrect item format: "+secondArg.getString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int startIndex = 0;
|
||||||
|
if (lv.size() > inventoryLocator.offset+1)
|
||||||
|
{
|
||||||
|
startIndex = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset+1).evalValue(c)).getLong();
|
||||||
|
}
|
||||||
|
startIndex = NBTSerializableValue.validateSlot(startIndex, inventoryLocator.inventory);
|
||||||
|
for (int i = startIndex, maxi = inventoryLocator.inventory.getInvSize(); i < maxi; i++)
|
||||||
|
{
|
||||||
|
ItemStack stack = inventoryLocator.inventory.getInvStack(i);
|
||||||
|
if ( (itemArg == null && stack.isEmpty()) || (itemArg != null && itemArg.getItem().equals(stack.getItem())) )
|
||||||
|
{
|
||||||
|
Value res = new NumericValue(i);
|
||||||
|
return (_c, _t) -> res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//long etime = System.nanoTime();
|
||||||
|
//CarpetSettings.LOG.error("took "+(etime-stime)/1000);
|
||||||
|
return (_c, _t) -> Value.NULL;
|
||||||
|
});
|
||||||
|
|
||||||
//inventory_set(<b,e>, <n>, <count>, <item>)
|
//inventory_set(<b,e>, <n>, <count>, <item>)
|
||||||
|
this.expr.addLazyFunction("inventory_set", -1, (c, t, lv) -> {
|
||||||
|
//long stime = System.nanoTime();
|
||||||
|
CarpetContext cc = (CarpetContext) c;
|
||||||
|
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||||
|
|
||||||
|
if (lv.size() <= inventoryLocator.offset+2)
|
||||||
|
throw new InternalExpressionException("inventory_set requires at least slot number and new stack size, and optional new item");
|
||||||
|
int slot = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset+0).evalValue(c)).getLong();
|
||||||
|
slot = NBTSerializableValue.validateSlot(slot, inventoryLocator.inventory);
|
||||||
|
int count = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset+1).evalValue(c)).getLong();
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
// clear slot
|
||||||
|
ItemStack removedStack = inventoryLocator.inventory.removeInvStack(slot);
|
||||||
|
//Value res = ListValue.fromItemStack(removedStack);
|
||||||
|
return (_c, _t) -> ListValue.fromItemStack(removedStack); // that tuple will be read only but cheaper if noone cares
|
||||||
|
}
|
||||||
|
if (lv.size() <= inventoryLocator.offset+3)
|
||||||
|
{
|
||||||
|
ItemStack previousStack = inventoryLocator.inventory.getInvStack(slot);
|
||||||
|
ItemStack newStack = previousStack.copy();
|
||||||
|
newStack.setCount(count);
|
||||||
|
inventoryLocator.inventory.setInvStack(slot, newStack);
|
||||||
|
return (_c, _t) -> ListValue.fromItemStack(previousStack);
|
||||||
|
}
|
||||||
|
ItemStackArgument newitem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset+2).evalValue(c).getString());
|
||||||
|
ItemStack previousStack = inventoryLocator.inventory.getInvStack(slot);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
inventoryLocator.inventory.setInvStack(slot, newitem.createStack(count, false));
|
||||||
|
}
|
||||||
|
catch (CommandSyntaxException e)
|
||||||
|
{
|
||||||
|
throw new InternalExpressionException(e.getMessage());
|
||||||
|
}
|
||||||
|
return (_c, _t) -> ListValue.fromItemStack(previousStack);
|
||||||
|
});
|
||||||
|
|
||||||
//inventory_remove(<b, e>, <item>, <amount=1>) -> bool
|
//inventory_remove(<b, e>, <item>, <amount=1>) -> bool
|
||||||
|
|
||||||
|
this.expr.addLazyFunction("inventory_remove", -1, (c, t, lv) -> {
|
||||||
|
//long stime = System.nanoTime();
|
||||||
|
CarpetContext cc = (CarpetContext) c;
|
||||||
|
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||||
|
|
||||||
|
if (lv.size() <= inventoryLocator.offset+1)
|
||||||
/*
|
throw new InternalExpressionException("inventory_set requires at least an item to be removed");
|
||||||
if (slot > -1)
|
ItemStackArgument searchItem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset).evalValue(c).getString());
|
||||||
|
int amount = 1;
|
||||||
|
if (lv.size() > inventoryLocator.offset+2)
|
||||||
{
|
{
|
||||||
if (slot >= inv.getInvSize())
|
amount = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset+2).evalValue(c)).getLong();
|
||||||
throw new InternalExpressionException("Inventory of "+e+" has "+inv.getInvSize()+" slots only");
|
|
||||||
itemstack = inv.getInvStack(slot);
|
|
||||||
}
|
}
|
||||||
*/
|
// not enough
|
||||||
|
if ( (amount == 1) && (inventoryLocator.inventory.containsAnyInInv(Sets.newHashSet(searchItem.getItem()))) ||
|
||||||
|
inventoryLocator.inventory.getInvAmountOf(searchItem.getItem()) >= amount )
|
||||||
|
return (_c, _t) -> Value.FALSE;
|
||||||
|
for (int i = 0, maxi = inventoryLocator.inventory.getInvSize(); i < maxi; i++)
|
||||||
|
{
|
||||||
|
ItemStack stack = inventoryLocator.inventory.getInvStack(i);
|
||||||
|
if (stack.isEmpty())
|
||||||
|
continue;
|
||||||
|
if (!stack.getItem().equals(searchItem.getItem()))
|
||||||
|
continue;
|
||||||
|
int left = stack.getCount()-amount;
|
||||||
|
if (left > 0)
|
||||||
|
{
|
||||||
|
stack.setCount(left);
|
||||||
|
inventoryLocator.inventory.setInvStack(i, stack);
|
||||||
|
return (_c, _t) -> Value.TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inventoryLocator.inventory.removeInvStack(i);
|
||||||
|
amount -= stack.getCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (amount > 0)
|
||||||
|
throw new InternalExpressionException("Something bad happened - cannot pull all items from inventory");
|
||||||
|
return (_c, _t) -> Value.TRUE;
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,7 +3,12 @@ package carpet.script.value;
|
|||||||
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 com.mojang.brigadier.StringReader;
|
||||||
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import net.minecraft.block.entity.HopperBlockEntity;
|
import net.minecraft.block.entity.HopperBlockEntity;
|
||||||
|
import net.minecraft.command.arguments.ItemStackArgument;
|
||||||
|
import net.minecraft.command.arguments.ItemStackArgumentType;
|
||||||
|
import net.minecraft.command.arguments.ItemStringReader;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.passive.AbstractTraderEntity;
|
import net.minecraft.entity.passive.AbstractTraderEntity;
|
||||||
import net.minecraft.entity.passive.VillagerEntity;
|
import net.minecraft.entity.passive.VillagerEntity;
|
||||||
@@ -12,8 +17,11 @@ import net.minecraft.inventory.Inventory;
|
|||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class NBTSerializableValue extends Value
|
public class NBTSerializableValue extends Value
|
||||||
@@ -26,7 +34,7 @@ public class NBTSerializableValue extends Value
|
|||||||
public NBTSerializableValue(ItemStack stack)
|
public NBTSerializableValue(ItemStack stack)
|
||||||
{
|
{
|
||||||
what = stack;
|
what = stack;
|
||||||
nbtSupplier = () -> ((ItemStack)what).toTag(new CompoundTag());
|
nbtSupplier = () -> ((ItemStack) what).toTag(new CompoundTag());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static InventoryLocator locateInventory(CarpetContext c, List<LazyValue> params, int offset)
|
public static InventoryLocator locateInventory(CarpetContext c, List<LazyValue> params, int offset)
|
||||||
@@ -39,13 +47,13 @@ public class NBTSerializableValue extends Value
|
|||||||
{
|
{
|
||||||
Entity e = ((EntityValue) v1).getEntity();
|
Entity e = ((EntityValue) v1).getEntity();
|
||||||
if (e instanceof PlayerEntity) inv = ((PlayerEntity) e).inventory;
|
if (e instanceof PlayerEntity) inv = ((PlayerEntity) e).inventory;
|
||||||
else if (e instanceof Inventory) inv = (Inventory)e;
|
else if (e instanceof Inventory) inv = (Inventory) e;
|
||||||
else if (e instanceof VillagerEntity) inv = ((VillagerEntity) e).getInventory();
|
else if (e instanceof VillagerEntity) inv = ((VillagerEntity) e).getInventory();
|
||||||
|
|
||||||
if (inv == null)
|
if (inv == null)
|
||||||
throw new InternalExpressionException("Entity "+e+" has no inventory");
|
throw new InternalExpressionException("Entity " + e + " has no inventory");
|
||||||
|
|
||||||
return new InventoryLocator(e, e.getBlockPos(), inv, offset+1);
|
return new InventoryLocator(e, e.getBlockPos(), inv, offset + 1);
|
||||||
}
|
}
|
||||||
else if (v1 instanceof BlockValue)
|
else if (v1 instanceof BlockValue)
|
||||||
{
|
{
|
||||||
@@ -54,8 +62,8 @@ public class NBTSerializableValue extends Value
|
|||||||
throw new InternalExpressionException("Block to acess inventory needs to be positioned in the world");
|
throw new InternalExpressionException("Block to acess inventory needs to be positioned in the world");
|
||||||
inv = HopperBlockEntity.getInventoryAt(c.s.getWorld(), pos);
|
inv = HopperBlockEntity.getInventoryAt(c.s.getWorld(), pos);
|
||||||
if (inv == null)
|
if (inv == null)
|
||||||
throw new InternalExpressionException("Block at "+pos+" has no inventory");
|
throw new InternalExpressionException("Block at " + pos + " has no inventory");
|
||||||
return new InventoryLocator(pos, pos, inv, offset+1);
|
return new InventoryLocator(pos, pos, inv, offset + 1);
|
||||||
}
|
}
|
||||||
else if (v1 instanceof ListValue)
|
else if (v1 instanceof ListValue)
|
||||||
{
|
{
|
||||||
@@ -66,8 +74,8 @@ public class NBTSerializableValue extends Value
|
|||||||
NumericValue.asNumber(args.get(2)).getDouble());
|
NumericValue.asNumber(args.get(2)).getDouble());
|
||||||
inv = HopperBlockEntity.getInventoryAt(c.s.getWorld(), pos);
|
inv = HopperBlockEntity.getInventoryAt(c.s.getWorld(), pos);
|
||||||
if (inv == null)
|
if (inv == null)
|
||||||
throw new InternalExpressionException("Block at "+pos+" has no inventory");
|
throw new InternalExpressionException("Block at " + pos + " has no inventory");
|
||||||
return new InventoryLocator(pos, pos, inv, offset+1);
|
return new InventoryLocator(pos, pos, inv, offset + 1);
|
||||||
}
|
}
|
||||||
BlockPos pos = new BlockPos(
|
BlockPos pos = new BlockPos(
|
||||||
NumericValue.asNumber(v1).getDouble(),
|
NumericValue.asNumber(v1).getDouble(),
|
||||||
@@ -75,8 +83,8 @@ public class NBTSerializableValue extends Value
|
|||||||
NumericValue.asNumber(params.get(2 + offset).evalValue(c)).getDouble());
|
NumericValue.asNumber(params.get(2 + offset).evalValue(c)).getDouble());
|
||||||
inv = HopperBlockEntity.getInventoryAt(c.s.getWorld(), pos);
|
inv = HopperBlockEntity.getInventoryAt(c.s.getWorld(), pos);
|
||||||
if (inv == null)
|
if (inv == null)
|
||||||
throw new InternalExpressionException("Block at "+pos+" has no inventory");
|
throw new InternalExpressionException("Block at " + pos + " has no inventory");
|
||||||
return new InventoryLocator(pos, pos, inv, offset+3);
|
return new InventoryLocator(pos, pos, inv, offset + 3);
|
||||||
}
|
}
|
||||||
catch (IndexOutOfBoundsException e)
|
catch (IndexOutOfBoundsException e)
|
||||||
{
|
{
|
||||||
@@ -84,6 +92,37 @@ public class NBTSerializableValue extends Value
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Map<String,ItemStackArgument> itemCache = new HashMap<>();
|
||||||
|
public static ItemStackArgument parseItem(String itemString)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ItemStackArgument res = itemCache.get(itemString);
|
||||||
|
if (res != null)
|
||||||
|
return res;
|
||||||
|
ItemStringReader parser = (new ItemStringReader(new StringReader(itemString), false)).consume();
|
||||||
|
res = new ItemStackArgument(parser.getItem(), parser.getTag());
|
||||||
|
itemCache.put(itemString, res);
|
||||||
|
if (itemCache.size()>64000)
|
||||||
|
itemCache.clear();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
catch (CommandSyntaxException e)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int validateSlot(int slot, Inventory inv)
|
||||||
|
{
|
||||||
|
int invSize = inv.getInvSize();
|
||||||
|
if (slot < 0)
|
||||||
|
slot = invSize + slot;
|
||||||
|
if (slot < 0 || slot >= invSize)
|
||||||
|
throw new InternalExpressionException("Slot for inventory should be between 0 and "+(invSize-1));
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
|
||||||
private CompoundTag getTag()
|
private CompoundTag getTag()
|
||||||
{
|
{
|
||||||
if (nbtTag == null)
|
if (nbtTag == null)
|
||||||
|
|||||||
Reference in new issue
Block a user