Merge branch 'master' into 1.15
# Conflicts: # src/main/java/carpet/mixins/ServerPlayNetworkHandler_scarpetEventsMixin.java # src/main/java/carpet/script/CarpetExpression.java
This commit is contained in:
commit
dc9532cf05
24 files changed
+1695
-655
No files matched your search
@@ -1,9 +1,15 @@
|
||||
package carpet.script.value;
|
||||
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public abstract class AbstractListValue extends Value
|
||||
{
|
||||
public abstract Iterator<Value> iterator();
|
||||
public void fatality() { }
|
||||
public void append(Value v)
|
||||
{
|
||||
throw new InternalExpressionException("Cannot append a value to abstract list");
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import net.minecraft.item.ItemPlacementContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.GlobalPos;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@@ -254,6 +255,14 @@ public class BlockValue extends Value
|
||||
return new BlockValue(blockState, world, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
if (world != null && pos != null )
|
||||
return GlobalPos.create(world.getDimension().getType(), pos).hashCode();
|
||||
return ("b"+getString()).hashCode();
|
||||
}
|
||||
|
||||
public BlockPos getPos()
|
||||
{
|
||||
return pos;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package carpet.script.value;
|
||||
|
||||
public interface ContainerValueInterface
|
||||
{
|
||||
public Value put(Value where, Value value);
|
||||
default Value put(Value where, Value value, Value conditions)
|
||||
{
|
||||
return put(where, value);
|
||||
}
|
||||
public Value get(Value where);
|
||||
public boolean has(Value where);
|
||||
public Value delete(Value where);
|
||||
}
|
||||
@@ -101,13 +101,13 @@ public class EntityValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Value v)
|
||||
public boolean equals(Object v)
|
||||
{
|
||||
if (v instanceof EntityValue)
|
||||
{
|
||||
return entity.getEntityId()==((EntityValue) v).entity.getEntityId();
|
||||
}
|
||||
return super.equals(v);
|
||||
return super.equals((Value)v);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -138,6 +138,13 @@ public class EntityValue extends Value
|
||||
return "entity";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return entity.hashCode();
|
||||
}
|
||||
|
||||
public static Pair<EntityType<?>, Predicate<? super Entity>> getPredicate(String who)
|
||||
{
|
||||
Pair<EntityType<?>, Predicate<? super Entity>> res = entityPredicates.get(who);
|
||||
@@ -386,21 +393,11 @@ public class EntityValue extends Value
|
||||
put("nbt",(e, a) -> {
|
||||
CompoundTag nbttagcompound = e.toTag((new CompoundTag()));
|
||||
if (a==null)
|
||||
return new NBTSerializableValue(nbttagcompound);//StringValue(nbttagcompound.toString());
|
||||
NbtPathArgumentType.NbtPath path = NBTSerializableValue.cachePath(a.getString());
|
||||
try
|
||||
{
|
||||
List<Tag> tags = path.get(nbttagcompound);
|
||||
if (tags.size()==0)
|
||||
return Value.NULL;
|
||||
if (tags.size()==1)
|
||||
return NBTSerializableValue.decodeTag(tags.get(0));
|
||||
return ListValue.wrap(tags.stream().map(NBTSerializableValue::decodeTag).collect(Collectors.toList()));
|
||||
}
|
||||
catch (CommandSyntaxException ignored) { }
|
||||
return Value.NULL;
|
||||
return new NBTSerializableValue(nbttagcompound);
|
||||
return new NBTSerializableValue(nbttagcompound).get(a);
|
||||
});
|
||||
}};
|
||||
|
||||
private static <Req extends Entity> Req assertEntityArgType(Class<Req> klass, Value arg)
|
||||
{
|
||||
if (!(arg instanceof EntityValue))
|
||||
@@ -728,6 +725,6 @@ public class EntityValue extends Value
|
||||
put("on_death", (c, e, f, l) -> ((EntityInterface)e).setDeathCallback(c, f, l));
|
||||
put("on_removed", (c, e, f, l) -> ((EntityInterface)e).setRemovedCallback(c, f, l));
|
||||
put("on_tick", (c, e, f, l) -> ((EntityInterface)e).setTickCallback(c, f, l));
|
||||
put("on_damage", (c, e, f, l) -> ((EntityInterface)e).setDamageCallback(c, f, l));
|
||||
put("on_damaged", (c, e, f, l) -> ((EntityInterface)e).setDamageCallback(c, f, l));
|
||||
}};
|
||||
}
|
||||
@@ -43,5 +43,11 @@ public class FunctionSignatureValue extends Value
|
||||
}
|
||||
public List<String> getGlobals() {return globals;}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
throw new UnsupportedOperationException("function signature value cannot be used as map key");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -19,4 +19,10 @@ public class GlobalValue extends Value
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
throw new UnsupportedOperationException("global value cannot be used as map key");
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,12 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
||||
{
|
||||
return stepp > 0?(current < limit):(current > limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString()
|
||||
{
|
||||
return String.format("[%d, %d, ..., %d]",start, start+stepp, limit);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -115,16 +121,11 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Value o)
|
||||
public boolean equals(final Object o)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value getElementAt(Value v2)
|
||||
{
|
||||
throw new InternalExpressionException("get element can only be obtained for regular lists");
|
||||
}
|
||||
@Override
|
||||
public String getTypeString()
|
||||
{
|
||||
@@ -145,4 +146,10 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
||||
((LazyListValue)copy).reset();
|
||||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return ("i"+getString()).hashCode();
|
||||
}
|
||||
}
|
||||
@@ -4,16 +4,13 @@ import carpet.script.exception.InternalExpressionException;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import static java.lang.Math.abs;
|
||||
|
||||
public class ListValue extends AbstractListValue
|
||||
public class ListValue extends AbstractListValue implements ContainerValueInterface
|
||||
{
|
||||
protected List<Value> items;
|
||||
@Override
|
||||
@@ -102,6 +99,7 @@ public class ListValue extends AbstractListValue
|
||||
}
|
||||
return output;
|
||||
}
|
||||
@Override
|
||||
public void append(Value v)
|
||||
{
|
||||
items.add(v);
|
||||
@@ -215,18 +213,11 @@ public class ListValue extends AbstractListValue
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Value o)
|
||||
public boolean equals(final Object o)
|
||||
{
|
||||
if (o instanceof ListValue)
|
||||
{
|
||||
ListValue ol = (ListValue)o;
|
||||
int this_size = this.getItems().size();
|
||||
int o_size = ol.getItems().size();
|
||||
if (this_size != o_size) return false;
|
||||
if (this_size == 0) return true;
|
||||
for (int i = 0; i < this_size; i++)
|
||||
if (!this.items.get(i).equals(ol.items.get(i))) return false;
|
||||
return true;
|
||||
return getItems().equals(((ListValue) o).getItems());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -275,6 +266,8 @@ public class ListValue extends AbstractListValue
|
||||
super(list);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length()
|
||||
{
|
||||
return items.size();
|
||||
@@ -313,7 +306,69 @@ public class ListValue extends AbstractListValue
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value getElementAt(Value value)
|
||||
public Value put(Value where, Value value, Value conditionValue)
|
||||
{
|
||||
String condition = conditionValue.getString();
|
||||
if (condition.equalsIgnoreCase("insert"))
|
||||
return put(where, value, false, false);
|
||||
if (condition.equalsIgnoreCase("extend"))
|
||||
return put(where, value, false, true);
|
||||
if (condition.equalsIgnoreCase("replace"))
|
||||
return put(where, value, true, false);
|
||||
throw new InternalExpressionException("list put modifier could be either insert, or replace");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value put(Value ind, Value value)
|
||||
{
|
||||
return put(ind, value, true, false);
|
||||
}
|
||||
private Value put(Value ind, Value value, boolean replace, boolean extend)
|
||||
{
|
||||
if (ind == Value.NULL)
|
||||
{
|
||||
if (extend && value instanceof AbstractListValue)
|
||||
{
|
||||
((AbstractListValue) value).iterator().forEachRemaining((v)-> items.add(v));
|
||||
}
|
||||
else
|
||||
{
|
||||
items.add(value);
|
||||
}
|
||||
return items.get(items.size()-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
int numitems = items.size();
|
||||
int index = (int) NumericValue.asNumber(ind).getLong();
|
||||
if (index < 0)
|
||||
{
|
||||
long range = abs(index) / numitems;
|
||||
index += (range + 2) * numitems;
|
||||
index = index % numitems;
|
||||
}
|
||||
if (replace)
|
||||
{
|
||||
while (index >= items.size()) items.add(Value.NULL);
|
||||
return items.set(index, value);
|
||||
}
|
||||
while (index > items.size()) items.add(Value.NULL);
|
||||
|
||||
if (extend && value instanceof AbstractListValue)
|
||||
{
|
||||
Iterable<Value> iterable = ((AbstractListValue) value)::iterator;
|
||||
List<Value> appendix = StreamSupport.stream( iterable.spliterator(), false).collect(Collectors.toList());
|
||||
items.addAll(index, appendix );
|
||||
return items.get(index+appendix.size()-1);
|
||||
}
|
||||
items.add(index, value);
|
||||
return value;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value get(Value value)
|
||||
{
|
||||
long index = NumericValue.asNumber(value).getLong();
|
||||
int numitems = items.size();
|
||||
@@ -322,9 +377,34 @@ public class ListValue extends AbstractListValue
|
||||
index = index % numitems;
|
||||
return items.get((int)index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(Value where)
|
||||
{
|
||||
long index = NumericValue.asNumber(where).getLong();
|
||||
return index >= 0 && index < items.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value delete(Value where)
|
||||
{
|
||||
long index = NumericValue.asNumber(where).getLong();
|
||||
int numitems = items.size();
|
||||
long range = abs(index)/numitems;
|
||||
index += (range+2)*numitems;
|
||||
index = index % numitems;
|
||||
return items.remove((int)index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeString()
|
||||
{
|
||||
return "list";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return items.hashCode();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
package carpet.script.value;
|
||||
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MapValue extends AbstractListValue implements ContainerValueInterface
|
||||
{
|
||||
private Map<Value, Value> map;
|
||||
|
||||
private MapValue()
|
||||
{
|
||||
map = new HashMap<>();
|
||||
}
|
||||
|
||||
public MapValue(List<Value> kvPairs)
|
||||
{
|
||||
this();
|
||||
for (Value v : kvPairs)
|
||||
{
|
||||
put(v);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Value> iterator()
|
||||
{
|
||||
return map.keySet().iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString()
|
||||
{
|
||||
return "{"+map.entrySet().stream().map((p) -> p.getKey().getString()+": "+p.getValue().getString()).collect(Collectors.joining(", "))+"}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrettyString()
|
||||
{
|
||||
if (map.size()<6)
|
||||
return "{"+map.entrySet().stream().map((p) -> p.getKey().getPrettyString()+": "+p.getValue().getPrettyString()).collect(Collectors.joining(", "))+"}";
|
||||
List<Value> keys = new ArrayList<>(map.keySet());
|
||||
int max = keys.size();
|
||||
return "{"+keys.get(0).getPrettyString()+": "+map.get(keys.get(0)).getPrettyString()+", "+
|
||||
keys.get(1).getPrettyString()+": "+map.get(keys.get(1)).getPrettyString()+", ..., "+
|
||||
keys.get(max-2).getPrettyString()+": "+map.get(keys.get(max-2)).getPrettyString()+", "+
|
||||
keys.get(max-1).getPrettyString()+": "+map.get(keys.get(max-1)).getPrettyString()+"}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean()
|
||||
{
|
||||
return !map.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value clone()
|
||||
{
|
||||
return new MapValue(map);
|
||||
}
|
||||
public MapValue(Map<Value,Value> other)
|
||||
{
|
||||
map = new HashMap<>(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value add(Value o)
|
||||
{
|
||||
throw new InternalExpressionException("cannot add to a map value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value subtract(Value v)
|
||||
{
|
||||
throw new InternalExpressionException("cannot subtract to a map value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value multiply(Value v)
|
||||
{
|
||||
throw new InternalExpressionException("cannot multiply to a map value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value divide(Value v)
|
||||
{
|
||||
throw new InternalExpressionException("cannot divide to a map value");
|
||||
}
|
||||
|
||||
public void put(Value v)
|
||||
{
|
||||
if (!(v instanceof ListValue))
|
||||
{
|
||||
map.put(v, Value.NULL);
|
||||
return;
|
||||
}
|
||||
ListValue pair = (ListValue)v;
|
||||
if (pair.getItems().size() != 2)
|
||||
{
|
||||
throw new InternalExpressionException("map constructor requires elements that have two elements");
|
||||
}
|
||||
map.put(pair.getItems().get(0), pair.getItems().get(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void append(Value v)
|
||||
{
|
||||
put(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Value o)
|
||||
{
|
||||
throw new InternalExpressionException("cannot compare to a map value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o)
|
||||
{
|
||||
if (o instanceof MapValue)
|
||||
{
|
||||
return map.equals(((MapValue) o).map);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Map<Value, Value> getMap()
|
||||
{
|
||||
return map;
|
||||
}
|
||||
|
||||
public void extend(List<Value> subList)
|
||||
{
|
||||
for (Value v: subList) put(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length()
|
||||
{
|
||||
return map.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value in(Value value1)
|
||||
{
|
||||
if (map.containsKey(value1)) return value1;
|
||||
return Value.NULL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value slice(long from, long to)
|
||||
{
|
||||
throw new InternalExpressionException("cannot slice a map value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double readNumber()
|
||||
{
|
||||
return (double)map.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value get(Value v2)
|
||||
{
|
||||
return map.getOrDefault(v2, Value.NULL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(Value where)
|
||||
{
|
||||
return map.containsKey(where);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value delete(Value where)
|
||||
{
|
||||
Value ret = map.remove(where);
|
||||
if (ret == null)
|
||||
return Value.NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value put(Value key, Value value)
|
||||
{
|
||||
Value ret = map.put(key, value);
|
||||
if (ret == null)
|
||||
return Value.NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeString()
|
||||
{
|
||||
return "map";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return map.hashCode();
|
||||
}
|
||||
}
|
||||
@@ -14,23 +14,28 @@ import net.minecraft.entity.passive.VillagerEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.AbstractListTag;
|
||||
import net.minecraft.nbt.AbstractNumberTag;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.StringNbtReader;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class NBTSerializableValue extends Value
|
||||
public class NBTSerializableValue extends Value implements ContainerValueInterface
|
||||
{
|
||||
private String nbtString = null;
|
||||
private Tag nbtTag = null;
|
||||
private Supplier<CompoundTag> nbtSupplier = null;
|
||||
private Supplier<Tag> nbtSupplier = null;
|
||||
|
||||
public NBTSerializableValue(ItemStack stack)
|
||||
{
|
||||
@@ -43,7 +48,7 @@ public class NBTSerializableValue extends Value
|
||||
{
|
||||
try
|
||||
{
|
||||
return (new StringNbtReader(new StringReader(nbtString))).parseCompoundTag();
|
||||
return (new StringNbtReader(new StringReader(nbtString))).parseTag();
|
||||
}
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
@@ -52,6 +57,26 @@ public class NBTSerializableValue extends Value
|
||||
};
|
||||
}
|
||||
|
||||
public static NBTSerializableValue parseString(String nbtString)
|
||||
{
|
||||
Tag tag;
|
||||
try
|
||||
{
|
||||
tag = (new StringNbtReader(new StringReader(nbtString))).parseTag();
|
||||
}
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
NBTSerializableValue value = new NBTSerializableValue(tag);
|
||||
value.nbtString = nbtString;
|
||||
return value;
|
||||
}
|
||||
|
||||
public Value clone()
|
||||
{
|
||||
return new NBTSerializableValue(getTag().copy());
|
||||
}
|
||||
public NBTSerializableValue(Tag tag)
|
||||
{
|
||||
nbtTag = tag;
|
||||
@@ -156,7 +181,7 @@ public class NBTSerializableValue extends Value
|
||||
return slot;
|
||||
}
|
||||
|
||||
public static Value decodeTag(Tag t)
|
||||
private static Value decodeTag(Tag t)
|
||||
{
|
||||
if (t instanceof CompoundTag)
|
||||
return new NBTSerializableValue(t);
|
||||
@@ -166,19 +191,26 @@ public class NBTSerializableValue extends Value
|
||||
return new StringValue(t.asString());
|
||||
}
|
||||
|
||||
public Tag getTag()
|
||||
private Tag getTag()
|
||||
{
|
||||
if (nbtTag == null)
|
||||
nbtTag = nbtSupplier.get();
|
||||
return nbtTag;
|
||||
}
|
||||
|
||||
private void replaceTag(Tag newTag)
|
||||
{
|
||||
nbtTag = newTag;
|
||||
nbtString = null;
|
||||
nbtSupplier = null; // just to be sure
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Value o)
|
||||
public boolean equals(final Object o)
|
||||
{
|
||||
if (o instanceof NBTSerializableValue)
|
||||
return getTag().equals(((NBTSerializableValue) o).getTag());
|
||||
return super.equals(o);
|
||||
return super.equals((Value)o);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -207,6 +239,188 @@ public class NBTSerializableValue extends Value
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value put(Value where, Value value)
|
||||
{
|
||||
return put(where, value, new StringValue("replace"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value put(Value where, Value value, Value conditions)
|
||||
{
|
||||
/// WIP
|
||||
|
||||
NbtPathArgumentType.NbtPath path = cachePath(where.getString());
|
||||
Tag tagToInsert = value instanceof NBTSerializableValue ?
|
||||
((NBTSerializableValue) value).getTag() :
|
||||
new NBTSerializableValue(value.getString()).getTag();
|
||||
Tag modifiedTag;
|
||||
if (conditions instanceof NumericValue)
|
||||
{
|
||||
modifiedTag = modify_insert((int)((NumericValue) conditions).getLong(), path, tagToInsert);
|
||||
}
|
||||
else
|
||||
{
|
||||
String ops = conditions.getString();
|
||||
if (ops.equalsIgnoreCase("merge"))
|
||||
{
|
||||
modifiedTag = modify_merge(path, tagToInsert);
|
||||
}
|
||||
else if (ops.equalsIgnoreCase("replace"))
|
||||
{
|
||||
modifiedTag = modify_replace(path, tagToInsert);
|
||||
}
|
||||
else
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
if (modifiedTag != null)
|
||||
{
|
||||
replaceTag(modifiedTag);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Tag modify_insert(int index, NbtPathArgumentType.NbtPath nbtPath, Tag newElement)
|
||||
{
|
||||
return modify_insert(index, nbtPath, newElement, this.getTag().copy());
|
||||
}
|
||||
|
||||
private Tag modify_insert(int index, NbtPathArgumentType.NbtPath nbtPath, Tag newElement, Tag currentTag)
|
||||
{
|
||||
Collection<Tag> targets;
|
||||
try
|
||||
{
|
||||
targets = nbtPath.putIfAbsent(currentTag, ListTag::new);
|
||||
}
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean modified = false;
|
||||
for (Tag target : targets)
|
||||
{
|
||||
if (!(target instanceof AbstractListTag))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
AbstractListTag<?> targetList = (AbstractListTag) target;
|
||||
if (!targetList.addTag(index < 0 ? targetList.size() + index + 1 : index, newElement.copy()))
|
||||
return null;
|
||||
modified = true;
|
||||
}
|
||||
catch (IndexOutOfBoundsException ignored)
|
||||
{
|
||||
}
|
||||
}
|
||||
return modified?currentTag:null;
|
||||
}
|
||||
|
||||
|
||||
private Tag modify_merge(NbtPathArgumentType.NbtPath nbtPath, Tag replacement) //nbtPathArgumentType$NbtPath_1, list_1)
|
||||
{
|
||||
if (!(replacement instanceof CompoundTag))
|
||||
{
|
||||
return getTag();
|
||||
}
|
||||
Tag originalTag = getTag().copy();
|
||||
try
|
||||
{
|
||||
for (Tag target : nbtPath.putIfAbsent(originalTag, CompoundTag::new))
|
||||
{
|
||||
if (!(target instanceof CompoundTag))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
((CompoundTag) target).copyFrom((CompoundTag) replacement);
|
||||
}
|
||||
}
|
||||
catch (CommandSyntaxException ignored) { }
|
||||
return originalTag;
|
||||
}
|
||||
|
||||
private Tag modify_replace(NbtPathArgumentType.NbtPath nbtPath, Tag replacement) //nbtPathArgumentType$NbtPath_1, list_1)
|
||||
{
|
||||
Tag originalTag = getTag().copy();
|
||||
String pathText = nbtPath.toString();
|
||||
if (pathText.endsWith("]")) // workaround for array replacement or item in the array replacement
|
||||
{
|
||||
if (nbtPath.remove(originalTag)==0)
|
||||
return null;
|
||||
Pattern pattern = Pattern.compile("\\[[^\\[]*]$");
|
||||
Matcher matcher = pattern.matcher(pathText);
|
||||
if (!matcher.find()) // malformed path
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String arrAccess = matcher.group();
|
||||
int pos;
|
||||
if (arrAccess.length()==2) // we just removed entire array
|
||||
pos = 0;
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
pos = Integer.parseInt(arrAccess.substring(1, arrAccess.length() - 1));
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
NbtPathArgumentType.NbtPath newPath = cachePath(pathText.substring(0, pathText.length()-arrAccess.length()));
|
||||
return modify_insert(pos,newPath,replacement, originalTag);
|
||||
}
|
||||
try
|
||||
{
|
||||
nbtPath.put(originalTag, () -> replacement);
|
||||
}
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return originalTag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value get(Value value)
|
||||
{
|
||||
NbtPathArgumentType.NbtPath path = cachePath(value.getString());
|
||||
try
|
||||
{
|
||||
List<Tag> tags = path.get(getTag());
|
||||
if (tags.size()==0)
|
||||
return Value.NULL;
|
||||
if (tags.size()==1)
|
||||
return NBTSerializableValue.decodeTag(tags.get(0));
|
||||
return ListValue.wrap(tags.stream().map(NBTSerializableValue::decodeTag).collect(Collectors.toList()));
|
||||
}
|
||||
catch (CommandSyntaxException ignored) { }
|
||||
return Value.NULL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(Value where)
|
||||
{
|
||||
return cachePath(where.getString()).count(getTag()) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value delete(Value where)
|
||||
{
|
||||
NbtPathArgumentType.NbtPath path = cachePath(where.getString());
|
||||
Tag tag = getTag().copy();
|
||||
int removed = path.remove(tag);
|
||||
if (removed > 0) replaceTag(tag);
|
||||
return new NumericValue(removed);
|
||||
}
|
||||
|
||||
public static class InventoryLocator
|
||||
{
|
||||
public Object owner;
|
||||
@@ -223,7 +437,7 @@ public class NBTSerializableValue extends Value
|
||||
}
|
||||
|
||||
private static Map<String, NbtPathArgumentType.NbtPath> pathCache = new HashMap<>();
|
||||
public static NbtPathArgumentType.NbtPath cachePath(String arg)
|
||||
private static NbtPathArgumentType.NbtPath cachePath(String arg)
|
||||
{
|
||||
NbtPathArgumentType.NbtPath res = pathCache.get(arg);
|
||||
if (res != null)
|
||||
@@ -242,23 +456,6 @@ public class NBTSerializableValue extends Value
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value getElementAt(Value value)
|
||||
{
|
||||
NbtPathArgumentType.NbtPath path = cachePath(value.getString());
|
||||
try
|
||||
{
|
||||
List<Tag> tags = path.get(getTag());
|
||||
if (tags.size()==0)
|
||||
return Value.NULL;
|
||||
if (tags.size()==1)
|
||||
return NBTSerializableValue.decodeTag(tags.get(0));
|
||||
return ListValue.wrap(tags.stream().map(NBTSerializableValue::decodeTag).collect(Collectors.toList()));
|
||||
}
|
||||
catch (CommandSyntaxException ignored) { }
|
||||
return Value.NULL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeString()
|
||||
{
|
||||
|
||||
@@ -28,7 +28,7 @@ public class NullValue extends NumericValue // TODO check nonsingleton code
|
||||
public NullValue() {super(0.0D);}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Value o)
|
||||
public boolean equals(final Object o)
|
||||
{
|
||||
return o instanceof NullValue;
|
||||
}
|
||||
@@ -44,4 +44,10 @@ public class NullValue extends NumericValue // TODO check nonsingleton code
|
||||
{
|
||||
return "null";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -125,7 +125,7 @@ public class NumericValue extends Value
|
||||
return getString().compareTo(o.getString());
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Value o)
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (o instanceof NullValue)
|
||||
{
|
||||
@@ -133,7 +133,7 @@ public class NumericValue extends Value
|
||||
}
|
||||
if (o instanceof NumericValue)
|
||||
{
|
||||
return !this.subtract(o).getBoolean();
|
||||
return !this.subtract((Value) o).getBoolean();
|
||||
}
|
||||
return super.equals(o);
|
||||
}
|
||||
@@ -179,4 +179,13 @@ public class NumericValue extends Value
|
||||
return "number";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
if (Math.abs(Math.floor(value + 0.5D)-value) < epsilon) // is sufficiently close to the integer value
|
||||
return Long.hashCode(getLong());
|
||||
return Double.hashCode(value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -115,6 +115,16 @@ public abstract class Value implements Comparable<Value>, Cloneable
|
||||
}
|
||||
return getString().compareTo(o.getString());
|
||||
}
|
||||
|
||||
@Override // for hashmap key access
|
||||
public boolean equals(final Object o)
|
||||
{
|
||||
if (o instanceof Value)
|
||||
return this.compareTo((Value) o)==0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// for general use
|
||||
public boolean equals(final Value o)
|
||||
{
|
||||
return this.compareTo(o)==0;
|
||||
@@ -173,13 +183,16 @@ public abstract class Value implements Comparable<Value>, Cloneable
|
||||
return (long)readNumber();
|
||||
}
|
||||
|
||||
public Value getElementAt(Value v2)
|
||||
{
|
||||
throw new InternalExpressionException("get element can only be obtained for lists and nbt values");
|
||||
}
|
||||
|
||||
public String getTypeString()
|
||||
{
|
||||
throw new InternalExpressionException("How did you get here? Cannot get type of an intenal type.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
String stringVal = getString();
|
||||
if (stringVal.isEmpty()) return 0;
|
||||
return ("s"+stringVal).hashCode();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user