fill in inventory calls

This commit is contained in:
gnembon committed 2019-06-24 14:38:00 -03:00
1 parent 037321ccfd
commit 7534c4b061
2 files changed
+166 -21

No files matched your search

+117 -11
View File
@@ -19,11 +19,14 @@ import carpet.script.value.StringValue;
import carpet.script.value.Value;
import carpet.utils.BlockInfo;
import carpet.utils.Messenger;
import com.google.common.collect.Sets;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
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.entity.EntityType;
import net.minecraft.entity.EquipmentSlot;
@@ -50,10 +53,7 @@ import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.text.LiteralText;
import net.minecraft.util.Identifier;
import net.minecraft.sound.SoundCategory;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.EulerRotation;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.*;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.LightType;
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
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>)
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
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 (slot > -1)
if (lv.size() <= inventoryLocator.offset+1)
throw new InternalExpressionException("inventory_set requires at least an item to be removed");
ItemStackArgument searchItem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset).evalValue(c).getString());
int amount = 1;
if (lv.size() > inventoryLocator.offset+2)
{
if (slot >= inv.getInvSize())
throw new InternalExpressionException("Inventory of "+e+" has "+inv.getInvSize()+" slots only");
itemstack = inv.getInvStack(slot);
amount = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset+2).evalValue(c)).getLong();
}
*/
// 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.LazyValue;
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.command.arguments.ItemStackArgument;
import net.minecraft.command.arguments.ItemStackArgumentType;
import net.minecraft.command.arguments.ItemStringReader;
import net.minecraft.entity.Entity;
import net.minecraft.entity.passive.AbstractTraderEntity;
import net.minecraft.entity.passive.VillagerEntity;
@@ -12,8 +17,11 @@ import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
public class NBTSerializableValue extends Value
@@ -26,7 +34,7 @@ public class NBTSerializableValue extends Value
public NBTSerializableValue(ItemStack 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)
@@ -39,13 +47,13 @@ public class NBTSerializableValue extends Value
{
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 Inventory) inv = (Inventory) e;
else if (e instanceof VillagerEntity) inv = ((VillagerEntity) e).getInventory();
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)
{
@@ -54,8 +62,8 @@ public class NBTSerializableValue extends Value
throw new InternalExpressionException("Block to acess inventory needs to be positioned in the world");
inv = HopperBlockEntity.getInventoryAt(c.s.getWorld(), pos);
if (inv == null)
throw new InternalExpressionException("Block at "+pos+" has no inventory");
return new InventoryLocator(pos, pos, inv, offset+1);
throw new InternalExpressionException("Block at " + pos + " has no inventory");
return new InventoryLocator(pos, pos, inv, offset + 1);
}
else if (v1 instanceof ListValue)
{
@@ -66,8 +74,8 @@ public class NBTSerializableValue extends Value
NumericValue.asNumber(args.get(2)).getDouble());
inv = HopperBlockEntity.getInventoryAt(c.s.getWorld(), pos);
if (inv == null)
throw new InternalExpressionException("Block at "+pos+" has no inventory");
return new InventoryLocator(pos, pos, inv, offset+1);
throw new InternalExpressionException("Block at " + pos + " has no inventory");
return new InventoryLocator(pos, pos, inv, offset + 1);
}
BlockPos pos = new BlockPos(
NumericValue.asNumber(v1).getDouble(),
@@ -75,8 +83,8 @@ public class NBTSerializableValue extends Value
NumericValue.asNumber(params.get(2 + offset).evalValue(c)).getDouble());
inv = HopperBlockEntity.getInventoryAt(c.s.getWorld(), pos);
if (inv == null)
throw new InternalExpressionException("Block at "+pos+" has no inventory");
return new InventoryLocator(pos, pos, inv, offset+3);
throw new InternalExpressionException("Block at " + pos + " has no inventory");
return new InventoryLocator(pos, pos, inv, offset + 3);
}
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()
{
if (nbtTag == null)