Merge branch 'master' into 1.17

# Conflicts:
#	src/main/java/carpet/script/api/Auxiliary.java
#	src/main/java/carpet/script/api/Entities.java
#	src/main/java/carpet/script/api/Inventories.java
#	src/main/java/carpet/script/api/Scoreboards.java
#	src/main/java/carpet/script/api/WorldAccess.java
#	src/main/java/carpet/script/value/FunctionValue.java
#	src/main/java/carpet/script/value/NBTSerializableValue.java
This commit is contained in:
gnembon committed 2021-04-23 01:46:11 -03:00
commit 5e3812e1f0
35 files changed
+1250 -1416

No files matched your search

+184 -265
View File
@@ -1,7 +1,6 @@
package carpet.script.api;
import carpet.CarpetServer;
import carpet.CarpetSettings;
import carpet.fakes.MinecraftServerInterface;
import carpet.fakes.ServerWorldInterface;
import carpet.fakes.StatTypeInterface;
@@ -15,7 +14,6 @@ import carpet.script.CarpetScriptHost;
import carpet.script.CarpetScriptServer;
import carpet.script.Context;
import carpet.script.Expression;
import carpet.script.LazyValue;
import carpet.script.argument.BlockArgument;
import carpet.script.argument.FunctionArgument;
import carpet.script.argument.Vector3Argument;
@@ -28,9 +26,9 @@ import carpet.script.utils.InputValidator;
import carpet.script.utils.ScarpetJsonDeserializer;
import carpet.script.utils.ShapeDispatcher;
import carpet.script.utils.WorldTools;
import carpet.script.value.BooleanValue;
import carpet.script.value.EntityValue;
import carpet.script.value.FormattedTextValue;
import carpet.script.value.FunctionValue;
import carpet.script.value.ListValue;
import carpet.script.value.MapValue;
import carpet.script.value.NBTSerializableValue;
@@ -155,16 +153,15 @@ public class Auxiliary {
public static void apply(Expression expression)
{
expression.addLazyFunction("sound", -1, (c, t, lv) -> {
expression.addContextFunction("sound", -1, (c, t, lv) -> {
CarpetContext cc = (CarpetContext)c;
if (lv.size() == 0)
{
Value ret = ListValue.wrap(Registry.SOUND_EVENT.getIds().stream().map(ValueConversions::of));
return (_c, _t) -> ret;
return ListValue.wrap(Registry.SOUND_EVENT.getIds().stream().map(ValueConversions::of));
}
String rawString = lv.get(0).evalValue(c).getString();
String rawString = lv.get(0).getString();
Identifier soundName = new Identifier(rawString);
Vector3Argument locator = Vector3Argument.findIn(cc, lv, 1);
Vector3Argument locator = Vector3Argument.findIn(lv, 1);
if (Registry.SOUND_EVENT.get(soundName) == null)
throw new ThrowStatement(rawString, Throwables.UNKNOWN_SOUND);
float volume = 1.0F;
@@ -172,13 +169,13 @@ public class Auxiliary {
SoundCategory mixer = SoundCategory.MASTER;
if (lv.size() > 0+locator.offset)
{
volume = (float) NumericValue.asNumber(lv.get(0+locator.offset).evalValue(c)).getDouble();
volume = (float) NumericValue.asNumber(lv.get(0+locator.offset)).getDouble();
if (lv.size() > 1+locator.offset)
{
pitch = (float) NumericValue.asNumber(lv.get(1+locator.offset).evalValue(c)).getDouble();
pitch = (float) NumericValue.asNumber(lv.get(1+locator.offset)).getDouble();
if (lv.size() > 2+locator.offset)
{
String mixerName = lv.get(2+locator.offset).evalValue(c).getString();
String mixerName = lv.get(2+locator.offset).getString();
mixer = mixerMap.get(mixerName.toLowerCase(Locale.ROOT));
if (mixer == null) throw new InternalExpressionException(mixerName +" is not a valid mixer name");
}
@@ -192,39 +189,33 @@ public class Auxiliary {
count++;
player.networkHandler.sendPacket(new PlaySoundIdS2CPacket(soundName, mixer, vec, volume, pitch));
}
int totalPlayed = count;
return (_c, _t) -> new NumericValue(totalPlayed);
return new NumericValue(count);
});
expression.addLazyFunction("particle", -1, (c, t, lv) ->
expression.addContextFunction("particle", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext)c;
if (lv.size() == 0)
{
Value ret = ListValue.wrap(Registry.PARTICLE_TYPE.getIds().stream().map(ValueConversions::of));
return (_c, _t) -> ret;
}
if (lv.size() == 0) return ListValue.wrap(Registry.PARTICLE_TYPE.getIds().stream().map(ValueConversions::of));
MinecraftServer ms = cc.s.getMinecraftServer();
ServerWorld world = cc.s.getWorld();
Vector3Argument locator = Vector3Argument.findIn(cc, lv, 1);
String particleName = lv.get(0).evalValue(c).getString();
Vector3Argument locator = Vector3Argument.findIn(lv, 1);
String particleName = lv.get(0).getString();
int count = 10;
double speed = 0;
float spread = 0.5f;
ServerPlayerEntity player = null;
if (lv.size() > locator.offset)
{
count = (int) NumericValue.asNumber(lv.get(locator.offset).evalValue(c)).getLong();
count = (int) NumericValue.asNumber(lv.get(locator.offset)).getLong();
if (lv.size() > 1+locator.offset)
{
spread = (float) NumericValue.asNumber(lv.get(1+locator.offset).evalValue(c)).getDouble();
spread = (float) NumericValue.asNumber(lv.get(1+locator.offset)).getDouble();
if (lv.size() > 2+locator.offset)
{
speed = NumericValue.asNumber(lv.get(2 + locator.offset).evalValue(c)).getDouble();
speed = NumericValue.asNumber(lv.get(2 + locator.offset)).getDouble();
if (lv.size() > 3 + locator.offset) // should accept entity as well as long as it is player
{
player = ms.getPlayerManager().getPlayer(lv.get(3 + locator.offset).evalValue(c).getString());
player = ms.getPlayerManager().getPlayer(lv.get(3 + locator.offset).getString());
}
}
}
@@ -246,29 +237,29 @@ public class Auxiliary {
spread, spread, spread, speed);
}
return (c_, t_) -> Value.TRUE;
return Value.TRUE;
});
expression.addLazyFunction("particle_line", -1, (c, t, lv) ->
expression.addContextFunction("particle_line", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext)c;
ServerWorld world = cc.s.getWorld();
String particleName = lv.get(0).evalValue(c).getString();
String particleName = lv.get(0).getString();
ParticleEffect particle = ShapeDispatcher.getParticleData(particleName);
Vector3Argument pos1 = Vector3Argument.findIn(cc, lv, 1);
Vector3Argument pos2 = Vector3Argument.findIn(cc, lv, pos1.offset);
Vector3Argument pos1 = Vector3Argument.findIn(lv, 1);
Vector3Argument pos2 = Vector3Argument.findIn(lv, pos1.offset);
double density = 1.0;
ServerPlayerEntity player = null;
if (lv.size() > pos2.offset+0 )
{
density = NumericValue.asNumber(lv.get(pos2.offset+0).evalValue(c)).getDouble();
density = NumericValue.asNumber(lv.get(pos2.offset+0)).getDouble();
if (density <= 0)
{
throw new InternalExpressionException("Particle density should be positive");
}
if (lv.size() > pos2.offset+1)
{
Value playerValue = lv.get(pos2.offset+1).evalValue(c);
Value playerValue = lv.get(pos2.offset+1);
if (playerValue instanceof EntityValue)
{
Entity e = ((EntityValue) playerValue).getEntity();
@@ -282,34 +273,33 @@ public class Auxiliary {
}
}
Value retval = new NumericValue(ShapeDispatcher.drawParticleLine(
return new NumericValue(ShapeDispatcher.drawParticleLine(
(player == null)?world.getPlayers(): Collections.singletonList(player),
particle, pos1.vec, pos2.vec, density));
return (c_, t_) -> retval;
particle, pos1.vec, pos2.vec, density
));
});
expression.addLazyFunction("particle_box", -1, (c, t, lv) ->
expression.addContextFunction("particle_box", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext)c;
ServerWorld world = cc.s.getWorld();
String particleName = lv.get(0).evalValue(c).getString();
String particleName = lv.get(0).getString();
ParticleEffect particle = ShapeDispatcher.getParticleData(particleName);
Vector3Argument pos1 = Vector3Argument.findIn(cc, lv, 1);
Vector3Argument pos2 = Vector3Argument.findIn(cc, lv, pos1.offset);
Vector3Argument pos1 = Vector3Argument.findIn(lv, 1);
Vector3Argument pos2 = Vector3Argument.findIn(lv, pos1.offset);
double density = 1.0;
ServerPlayerEntity player = null;
if (lv.size() > pos2.offset+0 )
{
density = NumericValue.asNumber(lv.get(pos2.offset+0).evalValue(c)).getDouble();
density = NumericValue.asNumber(lv.get(pos2.offset+0)).getDouble();
if (density <= 0)
{
throw new InternalExpressionException("Particle density should be positive");
}
if (lv.size() > pos2.offset+1)
{
Value playerValue = lv.get(pos2.offset+1).evalValue(c);
Value playerValue = lv.get(pos2.offset+1);
if (playerValue instanceof EntityValue)
{
Entity e = ((EntityValue) playerValue).getEntity();
@@ -330,13 +320,13 @@ public class Auxiliary {
player==null?world.getPlayers():Collections.singletonList(player),
particle, density, from, to
);
return (c_, t_) -> new NumericValue(particleCount);
return new NumericValue(particleCount);
});
// deprecated
expression.alias("particle_rect", "particle_box");
expression.addLazyFunction("draw_shape", -1, (c, t, lv) ->
expression.addContextFunction("draw_shape", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext)c;
ServerWorld world = cc.s.getWorld();
@@ -345,7 +335,7 @@ public class Auxiliary {
List<Pair<ShapeDispatcher.ExpiringShape, Map<String,Value>>> shapes = new ArrayList<>();
if (lv.size() == 1) // bulk
{
Value specLoad = lv.get(0).evalValue(c);
Value specLoad = lv.get(0);
if (!(specLoad instanceof ListValue)) throw new InternalExpressionException("In bulk mode - shapes need to be provided as a list of shape specs");
for (Value list : ((ListValue) specLoad).getItems())
{
@@ -355,19 +345,17 @@ public class Auxiliary {
}
else
{
List<Value> params = new ArrayList<>();
for (LazyValue v : lv) params.add(v.evalValue(c));
shapes.add(ShapeDispatcher.fromFunctionArgs(server, world, params, player));
shapes.add(ShapeDispatcher.fromFunctionArgs(server, world, lv, player));
}
ShapeDispatcher.sendShape(
(player[0]==null)?cc.s.getWorld().getPlayers():Collections.singletonList(player[0]),
shapes
);
return LazyValue.TRUE;
return Value.TRUE;
});
expression.addLazyFunction("create_marker", -1, (c, t, lv) ->{
expression.addContextFunction("create_marker", -1, (c, t, lv) ->{
CarpetContext cc = (CarpetContext)c;
BlockState targetBlock = null;
Vector3Argument pointLocator;
@@ -375,16 +363,16 @@ public class Auxiliary {
String name;
try
{
Value nameValue = lv.get(0).evalValue(c);
Value nameValue = lv.get(0);
name = nameValue instanceof NullValue ? "" : nameValue.getString();
pointLocator = Vector3Argument.findIn(cc, lv, 1, true, false);
pointLocator = Vector3Argument.findIn(lv, 1, true, false);
if (lv.size()>pointLocator.offset)
{
BlockArgument blockLocator = BlockArgument.findIn(cc, lv, pointLocator.offset, true, true, false);
if (blockLocator.block != null) targetBlock = blockLocator.block.getBlockState();
if (lv.size() > blockLocator.offset)
{
interactable = lv.get(blockLocator.offset).evalValue(c, Context.BOOLEAN).getBoolean();
interactable = lv.get(blockLocator.offset).getBoolean();
}
}
}
@@ -437,11 +425,10 @@ public class Auxiliary {
armorstand.setInvulnerable(true);
armorstand.getDataTracker().set(ArmorStandEntity.ARMOR_STAND_FLAGS, (byte)(interactable?8 : 16|8));
cc.s.getWorld().spawnEntity(armorstand);
EntityValue result = new EntityValue(armorstand);
return (_c, _t) -> result;
return new EntityValue(armorstand);
});
expression.addLazyFunction("remove_all_markers", 0, (c, t, lv) -> {
expression.addContextFunction("remove_all_markers", 0, (c, t, lv) -> {
CarpetContext cc = (CarpetContext)c;
int total = 0;
String markerName = MARKER_STRING+"_"+((cc.host.getName()==null)?"":cc.host.getName());
@@ -450,34 +437,18 @@ public class Auxiliary {
total ++;
e.discard(); // discard // remove();
}
int finalTotal = total;
return (_cc, _tt) -> new NumericValue(finalTotal);
return new NumericValue(total);
});
expression.addLazyFunction("nbt", 1, (c, t, lv) -> {
Value ret = NBTSerializableValue.fromValue(lv.get(0).evalValue(c));
return (cc, tt) -> ret;
});
expression.addUnaryFunction("nbt", NBTSerializableValue::fromValue);
expression.addLazyFunction("escape_nbt", 1, (c, t, lv) -> {
Value v = lv.get(0).evalValue(c);
String string = v.getString();
Value ret = new StringValue(NbtString.escape(string));
return (cc, tt) -> ret;
});
expression.addUnaryFunction("escape_nbt", v -> new StringValue(NbtString.escape(v.getString())));
expression.addLazyFunction("parse_nbt", 1, (c, t, lv) -> {
Value v = lv.get(0).evalValue(c);
if (v instanceof NBTSerializableValue)
{
Value parsed = ((NBTSerializableValue) v).toValue();
return (cc, tt) -> parsed;
}
expression.addUnaryFunction("parse_nbt", v -> {
if (v instanceof NBTSerializableValue) return ((NBTSerializableValue) v).toValue();
NBTSerializableValue ret = NBTSerializableValue.parseString(v.getString(), false);
if (ret == null)
return LazyValue.NULL;
Value parsed = ret.toValue();
return (cc, tt) -> parsed;
if (ret == null) return Value.NULL;
return ret.toValue();
});
expression.addFunction("tag_matches", (lv) -> {
@@ -490,11 +461,11 @@ public class Auxiliary {
return new NumericValue(NbtHelper.matches(match, source, numParam == 2 || lv.get(2).getBoolean()));
});
expression.addLazyFunction("encode_nbt", -1, (c, t, lv) -> {
expression.addFunction("encode_nbt", lv -> {
int argSize = lv.size();
if (argSize==0 || argSize > 2) throw new InternalExpressionException("'encode_nbt' requires 1 or 2 parameters");
Value v = lv.get(0).evalValue(c);
boolean force = (argSize > 1) && lv.get(1).evalValue(c).getBoolean();
Value v = lv.get(0);
boolean force = (argSize > 1) && lv.get(1).getBoolean();
NbtElement tag;
try
{
@@ -504,17 +475,16 @@ public class Auxiliary {
{
throw new InternalExpressionException("cannot reliably encode to a tag the value of '"+ignored.val.getPrettyString()+"'");
}
Value tagValue = new NBTSerializableValue(tag);
return (cc, tt) -> tagValue;
return new NBTSerializableValue(tag);
});
//"overridden" native call that prints to stderr
expression.addLazyFunction("print", -1, (c, t, lv) ->
expression.addContextFunction("print", -1, (c, t, lv) ->
{
if (lv.size() == 0 || lv.size() > 2) throw new InternalExpressionException("'print' takes one or two arguments");
ServerCommandSource s = ((CarpetContext)c).s;
MinecraftServer server = s.getMinecraftServer();
Value res = lv.get(0).evalValue(c);
Value res = lv.get(0);
List<ServerPlayerEntity> targets = null;
if (lv.size() == 2)
{
@@ -526,7 +496,7 @@ public class Auxiliary {
playerTargets.add(player);
});
targets = playerTargets;
res = lv.get(1).evalValue(c);
res = lv.get(1);
}
Text message = FormattedTextValue.getTextByValue(res);
if (targets == null)
@@ -537,13 +507,12 @@ public class Auxiliary {
{
targets.forEach(p -> p.getCommandSource().sendFeedback(message, false));
}
Value finalRes = res;
return (_c, _t) -> finalRes; // pass through for variables
return res; // pass through for variables
});
expression.addLazyFunction("display_title", -1, (c, t, lv) -> {
expression.addContextFunction("display_title", -1, (c, t, lv) -> {
if (lv.size() < 2) throw new InternalExpressionException("'display_title' needs at least a target, type and message, and optionally times");
Value pVal = lv.get(0).evalValue(c);
Value pVal = lv.get(0);
if (!(pVal instanceof ListValue)) pVal = ListValue.of(pVal);
MinecraftServer server = ((CarpetContext)c).s.getMinecraftServer();
Stream<ServerPlayerEntity> targets = ((ListValue) pVal).getItems().stream().map(v ->
@@ -554,7 +523,7 @@ public class Auxiliary {
});
Function<Text, Packet<?>> packetGetter = null;
//TitleS2CPacket.Action action;
String actionString = lv.get(1).evalValue(c).getString().toLowerCase(Locale.ROOT);
String actionString = lv.get(1).getString().toLowerCase(Locale.ROOT);
switch (actionString)
{
case "title":
@@ -594,7 +563,7 @@ public class Auxiliary {
boolean soundsTrue = false;
if (lv.size() > 2)
{
pVal = lv.get(2).evalValue(c);
pVal = lv.get(2);
title = FormattedTextValue.getTextByValue(pVal);
soundsTrue = pVal.getBoolean();
}
@@ -620,15 +589,15 @@ public class Auxiliary {
total.getAndIncrement();
});
HUDController.update_hud(((CarpetContext)c).s.getMinecraftServer(), targetList);
Value ret = NumericValue.of(total.get());
return (cc, tt) -> ret;
return NumericValue.of(total.get());
}
TitleFadeS2CPacket timesPacket; // TimesPacket
if (lv.size() > 3)
{
int in = NumericValue.asNumber(lv.get(3).evalValue(c),"fade in for display_title" ).getInt();
int stay = NumericValue.asNumber(lv.get(4).evalValue(c),"stay for display_title" ).getInt();
int out = NumericValue.asNumber(lv.get(5).evalValue(c),"fade out for display_title" ).getInt();
if (lv.size() != 6) throw new InternalExpressionException("'display_title' needs all fade-in, stay and fade-out times");
int in = NumericValue.asNumber(lv.get(3),"fade in for display_title" ).getInt();
int stay = NumericValue.asNumber(lv.get(4),"stay for display_title" ).getInt();
int out = NumericValue.asNumber(lv.get(5),"fade out for display_title" ).getInt();
timesPacket = new TitleFadeS2CPacket(in, stay, out);
//timesPacket = new TitleS2CPacket(Action.TIMES, null, in, stay, out);
}
@@ -642,20 +611,17 @@ public class Auxiliary {
p.networkHandler.sendPacket(packet);
total.getAndIncrement();
});
Value ret = NumericValue.of(total.get());
return (cc, tt) -> ret;
return NumericValue.of(total.get());
});
expression.addLazyFunction("format", -1, (c, t, lv) -> {
if (lv.size() == 0 ) throw new InternalExpressionException("'format' requires at least one component");
List<Value> values = lv.stream().map(lazy -> lazy.evalValue(c)).collect(Collectors.toList());
expression.addFunction("format", values -> {
if (values.size() == 0 ) throw new InternalExpressionException("'format' requires at least one component");
if (values.get(0) instanceof ListValue && values.size()==1)
values = ((ListValue) values.get(0)).getItems();
Value ret = new FormattedTextValue(Messenger.c(values.stream().map(Value::getString).toArray()));
return (cc, tt) -> ret;
return new FormattedTextValue(Messenger.c(values.stream().map(Value::getString).toArray()));
});
expression.addLazyFunction("run", 1, (c, t, lv) -> {
expression.addContextFunction("run", 1, (c, t, lv) -> {
BlockPos target = ((CarpetContext)c).origin;
Vec3d posf = new Vec3d((double)target.getX()+0.5D, target.getY(),(double)target.getZ()+0.5D);
ServerCommandSource s = ((CarpetContext)c).s;
@@ -665,56 +631,48 @@ public class Auxiliary {
List<Text> output = new ArrayList<>();
Value retval = new NumericValue(s.getMinecraftServer().getCommandManager().execute(
new SnoopyCommandSource(s, posf, error, output),
lv.get(0).evalValue(c).getString())
lv.get(0).getString())
);
Value ret = ListValue.of(
return ListValue.of(
retval,
ListValue.wrap(output.stream().map(FormattedTextValue::new).collect(Collectors.toList())),
FormattedTextValue.of(error[0])
);
return (c_, t_) -> ret;
}
catch (Exception exc)
{
Value ret = ListValue.of(Value.NULL, ListValue.of(), new FormattedTextValue(new LiteralText(exc.getMessage())));
return (c_, t_) -> ret;
return ListValue.of(Value.NULL, ListValue.of(), new FormattedTextValue(new LiteralText(exc.getMessage())));
}
});
expression.addLazyFunction("save", 0, (c, t, lv) -> {
expression.addContextFunction("save", 0, (c, t, lv) -> {
ServerCommandSource s = ((CarpetContext)c).s;
s.getMinecraftServer().getPlayerManager().saveAllPlayerData();
s.getMinecraftServer().save(true,true,true);
s.getWorld().getChunkManager().tick(() -> true);
CarpetSettings.LOG.warn("Saved chunks");
return (cc, tt) -> Value.TRUE;
CarpetScriptServer.LOG.warn("Saved chunks");
return Value.TRUE;
});
expression.addLazyFunction("tick_time", 0, (c, t, lv) ->
{
Value time = new NumericValue(((CarpetContext) c).s.getMinecraftServer().getTicks());
return (cc, tt) -> time;
});
expression.addContextFunction("tick_time", 0, (c, t, lv) ->
new NumericValue(((CarpetContext) c).s.getMinecraftServer().getTicks()));
expression.addLazyFunction("world_time", 0, (c, t, lv) ->
{
Value time = new NumericValue(((CarpetContext) c).s.getWorld().getTime());
return (cc, tt) -> time;
});
expression.addContextFunction("world_time", 0, (c, t, lv) ->
new NumericValue(((CarpetContext) c).s.getWorld().getTime()));
expression.addLazyFunction("day_time", -1, (c, t, lv) ->
expression.addContextFunction("day_time", -1, (c, t, lv) ->
{
Value time = new NumericValue(((CarpetContext) c).s.getWorld().getTimeOfDay());
if (lv.size() > 0)
{
long newTime = NumericValue.asNumber(lv.get(0).evalValue(c)).getLong();
long newTime = NumericValue.asNumber(lv.get(0)).getLong();
if (newTime < 0) newTime = 0;
((CarpetContext) c).s.getWorld().setTimeOfDay(newTime);// setTimeOfDay(newTime);
}
return (cc, tt) -> time;
return time;
});
expression.addLazyFunction("last_tick_times", -1, (c, t, lv) ->
expression.addContextFunction("last_tick_times", -1, (c, t, lv) ->
{
//assuming we are in the tick world section
// might be off one tick when run in the off tasks or asynchronously.
@@ -725,12 +683,11 @@ public class Auxiliary {
{
ticks.add(new NumericValue(((double)tickArray[i % 100])/1000000.0));
}
Value ret = ListValue.wrap(ticks);
return (cc, tt) -> ret;
return ListValue.wrap(ticks);
});
expression.addLazyFunction("game_tick", -1, (c, t, lv) -> {
expression.addContextFunction("game_tick", -1, (c, t, lv) -> {
CarpetContext cc = (CarpetContext)c;
ServerCommandSource s = cc.s;
if (!s.getMinecraftServer().isOnThread()) throw new InternalExpressionException("Unable to run ticks from threads");
@@ -741,7 +698,7 @@ public class Auxiliary {
((MinecraftServerInterface) s.getMinecraftServer()).forceTick(() -> System.nanoTime() - CarpetServer.scriptServer.tickStart < 50000000L);
if (lv.size() > 0)
{
long ms_total = NumericValue.asNumber(lv.get(0).evalValue(c)).getLong();
long ms_total = NumericValue.asNumber(lv.get(0)).getLong();
long end_expected = CarpetServer.scriptServer.tickStart + ms_total * 1000000L;
long wait = end_expected - System.nanoTime();
if (wait > 0L)
@@ -764,17 +721,16 @@ public class Auxiliary {
}
if(CarpetServer.scriptServer.stopAll)
throw new ExitStatement(Value.NULL);
return (_c, _t) -> Value.TRUE;
return Value.TRUE;
});
expression.addLazyFunction("seed", -1, (c, t, lv) -> {
expression.addContextFunction("seed", -1, (c, t, lv) -> {
ServerCommandSource s = ((CarpetContext)c).s;
c.host.issueDeprecation("seed()");
Value ret = new NumericValue(s.getWorld().getSeed());
return (cc, tt) -> ret;
return new NumericValue(s.getWorld().getSeed());
});
expression.addLazyFunction("relight", -1, (c, t, lv) ->
expression.addContextFunction("relight", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext) c;
BlockArgument locator = BlockArgument.findIn(cc, lv, 0);
@@ -782,21 +738,16 @@ public class Auxiliary {
ServerWorld world = cc.s.getWorld();
((ThreadedAnvilChunkStorageInterface) world.getChunkManager().threadedAnvilChunkStorage).relightChunk(new ChunkPos(pos));
WorldTools.forceChunkUpdate(pos, world);
return LazyValue.TRUE;
return Value.TRUE;
});
expression.addLazyFunction("current_dimension", 0, (c, t, lv) -> {
ServerCommandSource s = ((CarpetContext)c).s;
Value retval = ValueConversions.of(s.getWorld());
return (cc, tt) -> retval;
});
expression.addContextFunction("current_dimension", 0, (c, t, lv) ->
ValueConversions.of( ((CarpetContext)c).s.getWorld()));
expression.addLazyFunction("view_distance", 0, (c, t, lv) -> {
ServerCommandSource s = ((CarpetContext)c).s;
Value retval = new NumericValue(s.getMinecraftServer().getPlayerManager().getViewDistance());
return (cc, tt) -> retval;
});
expression.addContextFunction("view_distance", 0, (c, t, lv) ->
new NumericValue(((CarpetContext)c).s.getMinecraftServer().getPlayerManager().getViewDistance()));
// lazy due to passthrough and context changing ability
expression.addLazyFunction("in_dimension", 2, (c, t, lv) -> {
ServerCommandSource outerSource = ((CarpetContext)c).s;
Value dimensionValue = lv.get(0).evalValue(c);
@@ -810,7 +761,7 @@ public class Auxiliary {
return (cc, tt) -> retval;
});
expression.addLazyFunction("plop", -1, (c, t, lv) ->{
expression.addContextFunction("plop", -1, (c, t, lv) ->{
if (lv.size() == 0)
{
Map<Value, Value> plopData = new HashMap<>();
@@ -831,13 +782,12 @@ public class Auxiliary {
plopData.put(StringValue.of("configured_structures"),
ListValue.wrap(registryManager.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY).getIds().stream().sorted().map(ValueConversions::of).collect(Collectors.toList()))
);
Value ret = MapValue.wrap(plopData);
return (_c, _t) -> ret;
return MapValue.wrap(plopData);
}
BlockArgument locator = BlockArgument.findIn((CarpetContext)c, lv, 0);
if (lv.size() <= locator.offset)
throw new InternalExpressionException("'plop' needs extra argument indicating what to plop");
String what = lv.get(locator.offset).evalValue(c).getString();
String what = lv.get(locator.offset).getString();
Value [] result = new Value[]{Value.NULL};
((CarpetContext)c).s.getMinecraftServer().submitAndJoin( () ->
{
@@ -849,71 +799,67 @@ public class Auxiliary {
WorldTools.forceChunkUpdate(locator.block.getPos(), ((CarpetContext) c).s.getWorld());
result[0] = new NumericValue(res);
});
Value ret = result[0]; // preventing from lazy evaluating of the result in case a future completes later
return (_c, _t) -> ret;
return result[0];
});
expression.addLazyFunction("schedule", -1, (c, t, lv) -> {
expression.addContextFunction("schedule", -1, (c, t, lv) -> {
if (lv.size()<2)
throw new InternalExpressionException("'schedule' should have at least 2 arguments, delay and call name");
long delay = NumericValue.asNumber(lv.get(0).evalValue(c)).getLong();
FunctionArgument<LazyValue> functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, false, true);
long delay = NumericValue.asNumber(lv.get(0)).getLong();
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, false, false);
CarpetServer.scriptServer.events.scheduleCall(
(CarpetContext) c,
functionArgument.function,
FunctionValue.resolveArgs(functionArgument.args, c, t),
functionArgument.checkedArgs(),
delay
);
return (c_, t_) -> Value.TRUE;
return Value.TRUE;
});
expression.addLazyFunction("logger", -1, (c, t, lv) ->
expression.addFunction("logger", lv ->
{
//CarpetSettings.LOG.error(Registry.ENTITY_TYPE.getIds().stream().sorted().map(ValueConversions::simplify).collect(Collectors.joining("`, `")));
Value res;
if(lv.size()==1)
{
res = lv.get(0).evalValue(c);
CarpetSettings.LOG.info(res.getString());
res = lv.get(0);
CarpetScriptServer.LOG.info(res.getString());
}
else if(lv.size()==2)
{
String level = lv.get(0).evalValue(c).getString().toLowerCase(Locale.ROOT);
res = lv.get(1).evalValue(c);
String level = lv.get(0).getString().toLowerCase(Locale.ROOT);
res = lv.get(1);
switch(level){
case "error": CarpetSettings.LOG.error(res.getString()); break;
case "warn": CarpetSettings.LOG.warn(res.getString()); break;
case "debug": CarpetSettings.LOG.debug(res.getString()); break;
case "fatal": CarpetSettings.LOG.fatal(res.getString()); break;
case "info": CarpetSettings.LOG.info(res.getString()); break;
case "error": CarpetScriptServer.LOG.error(res.getString()); break;
case "warn": CarpetScriptServer.LOG.warn(res.getString()); break;
case "debug": CarpetScriptServer.LOG.debug(res.getString()); break;
case "fatal": CarpetScriptServer.LOG.fatal(res.getString()); break;
case "info": CarpetScriptServer.LOG.info(res.getString()); break;
default: throw new InternalExpressionException("Unknown log level for 'logger': "+level);
}
}
else throw new InternalExpressionException("logger takes 1 or 2 arguments");
return (_c, _t) -> res; // pass through for variables
return res; // pass through for variables
});
expression.addLazyFunction("list_files", 2, (c, t, lv) ->
expression.addContextFunction("list_files", 2, (c, t, lv) ->
{
FileArgument fdesc = FileArgument.from(lv, c, true, FileArgument.Reason.READ);
FileArgument fdesc = FileArgument.from(lv,true, FileArgument.Reason.READ);
Stream<String> files = ((CarpetScriptHost) c.host).listFolder(fdesc);
if (files == null) return LazyValue.NULL;
Value ret = ListValue.wrap(files.map(StringValue::of).collect(Collectors.toList()));
return (cc, tt) -> ret;
if (files == null) return Value.NULL;
return ListValue.wrap(files.map(StringValue::of).collect(Collectors.toList()));
});
expression.addLazyFunction("read_file", 2, (c, t, lv) ->
expression.addContextFunction("read_file", 2, (c, t, lv) ->
{
FileArgument fdesc = FileArgument.from(lv, c, false, FileArgument.Reason.READ);
FileArgument fdesc = FileArgument.from(lv,false, FileArgument.Reason.READ);
Value retVal;
if (fdesc.type == FileArgument.Type.NBT)
{
NbtElement state = ((CarpetScriptHost) c.host).readFileTag(fdesc);
if (state == null) return LazyValue.NULL;
if (state == null) return Value.NULL;
retVal = new NBTSerializableValue(state);
}
else if (fdesc.type == FileArgument.Type.JSON)
@@ -929,25 +875,23 @@ public class Auxiliary {
else
{
List<String> content = ((CarpetScriptHost) c.host).readTextResource(fdesc);
if (content == null) return LazyValue.NULL;
if (content == null) return Value.NULL;
retVal = ListValue.wrap(content.stream().map(StringValue::new).collect(Collectors.toList()));
}
return (cc, tt) -> retVal;
return retVal;
});
expression.addLazyFunction("delete_file", 2, (c, t, lv) -> {
FileArgument fdesc = FileArgument.from(lv, c, false, FileArgument.Reason.DELETE);
return ((CarpetScriptHost) c.host).removeResourceFile(fdesc) ? LazyValue.TRUE : LazyValue.FALSE;
});
expression.addContextFunction("delete_file", 2, (c, t, lv) ->
BooleanValue.of(((CarpetScriptHost) c.host).removeResourceFile(FileArgument.from(lv,false, FileArgument.Reason.DELETE))));
expression.addLazyFunction("write_file", -1, (c, t, lv) -> {
expression.addContextFunction("write_file", -1, (c, t, lv) -> {
if (lv.size() < 3) throw new InternalExpressionException("'write_file' requires three or more arguments");
FileArgument fdesc = FileArgument.from(lv, c, false, FileArgument.Reason.CREATE);
FileArgument fdesc = FileArgument.from(lv, false, FileArgument.Reason.CREATE);
boolean success;
if (fdesc.type == FileArgument.Type.NBT)
{
Value val = lv.get(2).evalValue(c);
Value val = lv.get(2);
NBTSerializableValue tagValue = (val instanceof NBTSerializableValue)
? (NBTSerializableValue) val
: new NBTSerializableValue(val.getString());
@@ -956,7 +900,7 @@ public class Auxiliary {
}
else if (fdesc.type == FileArgument.Type.JSON)
{
List<String> data = Collections.singletonList(GSON.toJson(lv.get(2).evalValue(c).toJson()));
List<String> data = Collections.singletonList(GSON.toJson(lv.get(2).toJson()));
((CarpetScriptHost) c.host).removeResourceFile(fdesc);
success = ((CarpetScriptHost) c.host).appendLogFile(fdesc, data);
}
@@ -965,7 +909,7 @@ public class Auxiliary {
List<String> data = new ArrayList<>();
if (lv.size()==3)
{
Value val = lv.get(2).evalValue(c);
Value val = lv.get(2);
if (val instanceof ListValue)
{
List<Value> lval = ((ListValue) val).getItems();
@@ -980,166 +924,144 @@ public class Auxiliary {
{
for(int i = 2; i < lv.size(); i++)
{
data.add(lv.get(i).evalValue(c).getString());
data.add(lv.get(i).getString());
}
}
success = ((CarpetScriptHost) c.host).appendLogFile(fdesc, data);
}
return success?LazyValue.TRUE:LazyValue.FALSE;
return BooleanValue.of(success);
});
expression.addLazyFunction("load_app_data", -1, (c, t, lv) ->
expression.addContextFunction("load_app_data", -1, (c, t, lv) ->
{
FileArgument fdesc = new FileArgument(null, FileArgument.Type.NBT, null, false, false, FileArgument.Reason.READ);
if (lv.size()>0)
{
c.host.issueDeprecation("load_app_data(...) with arguments");
String resource = recognizeResource(lv.get(0).evalValue(c), false);
boolean shared = lv.size() > 1 && lv.get(1).evalValue(c).getBoolean();
String resource = recognizeResource(lv.get(0), false);
boolean shared = lv.size() > 1 && lv.get(1).getBoolean();
fdesc = new FileArgument(resource, FileArgument.Type.NBT, null, false, shared, FileArgument.Reason.READ);
}
NbtElement state = ((CarpetScriptHost) c.host).readFileTag(fdesc);
if (state == null)
return (cc, tt) -> Value.NULL;
Value retVal = new NBTSerializableValue(state);
return (cc, tt) -> retVal;
return NBTSerializableValue.of(((CarpetScriptHost) c.host).readFileTag(fdesc));
});
expression.addLazyFunction("store_app_data", -1, (c, t, lv) ->
expression.addContextFunction("store_app_data", -1, (c, t, lv) ->
{
if (lv.size() == 0)
throw new InternalExpressionException("'store_app_data' needs NBT tag and an optional file");
Value val = lv.get(0).evalValue(c);
Value val = lv.get(0);
FileArgument fdesc = new FileArgument(null, FileArgument.Type.NBT, null, false, false, FileArgument.Reason.CREATE);
if (lv.size()>1)
{
c.host.issueDeprecation("store_app_data(...) with more than one argument");
String resource = recognizeResource(lv.get(1).evalValue(c), false);
boolean shared = lv.size() > 2 && lv.get(2).evalValue(c).getBoolean();
String resource = recognizeResource(lv.get(1), false);
boolean shared = lv.size() > 2 && lv.get(2).getBoolean();
fdesc = new FileArgument(resource, FileArgument.Type.NBT, null, false, shared, FileArgument.Reason.CREATE);
}
NBTSerializableValue tagValue = (val instanceof NBTSerializableValue)
? (NBTSerializableValue) val
: new NBTSerializableValue(val.getString());
NbtElement tag = tagValue.getTag();
boolean success = ((CarpetScriptHost) c.host).writeTagFile(tag, fdesc);
return success?LazyValue.TRUE:LazyValue.FALSE;
return BooleanValue.of(((CarpetScriptHost) c.host).writeTagFile(tagValue.getTag(), fdesc));
});
expression.addLazyFunction("statistic", 3, (c, t, lv) ->
expression.addContextFunction("statistic", 3, (c, t, lv) ->
{
Value playerValue = lv.get(0).evalValue(c);
CarpetContext cc = (CarpetContext)c;
ServerPlayerEntity player = EntityValue.getPlayerByValue(cc.s.getMinecraftServer(), playerValue);
if (player == null) return LazyValue.NULL;
ServerPlayerEntity player = EntityValue.getPlayerByValue(cc.s.getMinecraftServer(), lv.get(0));
if (player == null) return Value.NULL;
Identifier category;
Identifier statName;
try
{
category = new Identifier(lv.get(1).evalValue(c).getString());
statName = new Identifier(lv.get(2).evalValue(c).getString());
category = new Identifier(lv.get(1).getString());
statName = new Identifier(lv.get(2).getString());
}
catch (InvalidIdentifierException e)
{
return LazyValue.NULL;
return Value.NULL;
}
StatType<?> type = Registry.STAT_TYPE.get(category);
if (type == null)
return LazyValue.NULL;
if (type == null) return Value.NULL;
Stat<?> stat = getStat(type, statName);
if (stat == null)
return LazyValue.NULL;
return (_c, _t) -> new NumericValue(player.getStatHandler().getStat(stat));
if (stat == null) return Value.NULL;
return new NumericValue(player.getStatHandler().getStat(stat));
});
//handle_event('event', function...)
expression.addLazyFunction("handle_event", -1, (c, t, lv) ->
expression.addContextFunction("handle_event", -1, (c, t, lv) ->
{
if (lv.size() < 2)
throw new InternalExpressionException("'handle_event' requires at least two arguments, event name, and a callback");
String event = lv.get(0).evalValue(c).getString();
FunctionArgument<LazyValue> callback = FunctionArgument.findIn(c, expression.module, lv, 1, true, false);
String event = lv.get(0).getString();
FunctionArgument callback = FunctionArgument.findIn(c, expression.module, lv, 1, true, false);
CarpetScriptHost host = ((CarpetScriptHost)c.host);
Value success;
if (callback.function == null)
{
success = host.getScriptServer().events.removeBuiltInEvent(event, host)?Value.TRUE:Value.FALSE;
}
else
{
success = host.getScriptServer().events.handleCustomEvent(event, host, callback.function, FunctionValue.resolveArgs(callback.args, c, t) )?Value.TRUE:Value.FALSE;
}
return (cc, tt) -> success;
return BooleanValue.of(host.getScriptServer().events.removeBuiltInEvent(event, host));
// args don't need to be checked will be checked at the event
return BooleanValue.of( host.getScriptServer().events.handleCustomEvent(event, host, callback.function, callback.args ));
});
//signal_event('event', player or null, args.... ) -> number of apps notified
expression.addLazyFunction("signal_event", -1, (c, t, lv) ->
expression.addContextFunction("signal_event", -1, (c, t, lv) ->
{
if (lv.size() == 0)
throw new InternalExpressionException("'signal' requires at least one argument");
CarpetContext cc = (CarpetContext)c;
CarpetScriptServer server = ((CarpetScriptHost)c.host).getScriptServer();
String eventName = lv.get(0).evalValue(c).getString();
String eventName = lv.get(0).getString();
// no such event yet
if (CarpetEventServer.Event.getEvent(eventName, server) == null) return LazyValue.NULL;
if (CarpetEventServer.Event.getEvent(eventName, server) == null) return Value.NULL;
ServerPlayerEntity player = null;
List<Value> args = Collections.emptyList();
if (lv.size() > 1)
{
player = EntityValue.getPlayerByValue(server.server, lv.get(1).evalValue(c));
if (lv.size() > 2)
{
args = FunctionValue.resolveArgs(lv.subList(2, lv.size()), c, t);
}
player = EntityValue.getPlayerByValue(server.server, lv.get(1));
if (lv.size() > 2) args = lv.subList(2, lv.size());
}
int counts = ((CarpetScriptHost)c.host).getScriptServer().events.signalEvent(eventName, cc, player, args);
if (counts < 0) return LazyValue.NULL;
Value ret = new NumericValue(counts);
return (c_, t_) -> ret;
if (counts < 0) return Value.NULL;
return new NumericValue(counts);
});
// nbt_storage()
// nbt_storage(key)
// nbt_storage(key, nbt)
expression.addLazyFunction("nbt_storage", -1, (c, t, lv) -> {
expression.addContextFunction("nbt_storage", -1, (c, t, lv) -> {
if (lv.size() > 2) throw new InternalExpressionException("'nbt_storage' requires 0, 1 or 2 arguments.");
CarpetContext cc = (CarpetContext) c;
DataCommandStorage storage = cc.s.getMinecraftServer().getDataCommandStorage();
if (lv.size() == 0) {
Value ret = ListValue.wrap(storage.getIds().map(i -> new StringValue(nameFromRegistryId(i))).collect(Collectors.toList()));
return (_c, _t) -> ret;
}
String key = lv.get(0).evalValue(c).getString();
if (lv.size() == 0)
return ListValue.wrap(storage.getIds().map(i -> new StringValue(nameFromRegistryId(i))).collect(Collectors.toList()));
String key = lv.get(0).getString();
NbtCompound old_nbt = storage.get(new Identifier(key));
if (lv.size() == 2) {
Value nbt = lv.get(1).evalValue(c);
Value nbt = lv.get(1);
NBTSerializableValue new_nbt = (nbt instanceof NBTSerializableValue) ? (NBTSerializableValue) nbt
: NBTSerializableValue.parseString(nbt.getString(), true);
storage.set(new Identifier(key), new_nbt.getCompoundTag());
}
if (old_nbt == null) return LazyValue.NULL;
return (_c, _t) -> new NBTSerializableValue(old_nbt);
return NBTSerializableValue.of(old_nbt);
});
// script run create_datapack('foo', {'foo' -> {'bar.json' -> {'c' -> true,'d' -> false,'e' -> {'foo' -> [1,2,3]},'a' -> 'foobar','b' -> 5}}})
expression.addLazyFunction("create_datapack", 2, (c, t, lv) -> {
expression.addContextFunction("create_datapack", 2, (c, t, lv) -> {
CarpetContext cc = (CarpetContext)c;
String origName = lv.get(0).evalValue(c).getString();
String origName = lv.get(0).getString();
String name = InputValidator.validateSimpleString(origName, true);
MinecraftServer server = cc.s.getMinecraftServer();
for (String dpName : server.getDataPackManager().getNames())
{
if (dpName.equalsIgnoreCase("file/"+name+".zip") ||
dpName.equalsIgnoreCase("file/"+name))
return LazyValue.NULL;
return Value.NULL;
}
Value dpdata = lv.get(1).evalValue(c);
Value dpdata = lv.get(1);
if (!(dpdata instanceof MapValue))
throw new InternalExpressionException("datapack data needs to be a valid map type");
ResourcePackManager packManager = server.getDataPackManager();
Path dbFloder = server.getSavePath(WorldSavePath.DATAPACKS);
Path packFloder = dbFloder.resolve(name+".zip");
if (Files.exists(packFloder) || Files.exists(dbFloder.resolve(name))) return LazyValue.NULL;
if (Files.exists(packFloder) || Files.exists(dbFloder.resolve(name))) return Value.NULL;
Boolean [] successful = new Boolean[]{true};
server.submitAndJoin( () ->
{
@@ -1184,10 +1106,10 @@ public class Auxiliary {
}
});
return successful[0]?LazyValue.TRUE:LazyValue.FALSE;
return BooleanValue.of(successful[0]);
});
expression.addLazyFunction("enable_hidden_dimensions", 0, (c, t, lv) -> {
expression.addContextFunction("enable_hidden_dimensions", 0, (c, t, lv) -> {
CarpetContext cc = (CarpetContext)c;
// from minecraft.server.Main.main
MinecraftServer server = cc.s.getMinecraftServer();
@@ -1207,7 +1129,7 @@ public class Auxiliary {
RegistryOps<NbtElement> registryOps = RegistryOps.of(NbtOps.INSTANCE, serverRM.getResourceManager(), (DynamicRegistryManager.Impl) server.getRegistryManager());
SaveProperties saveProperties = session.readLevelProperties(registryOps, dataPackSettings2);
if (saveProperties == null) return LazyValue.NULL;
if (saveProperties == null) return Value.NULL;
//session.backupLevelDataFile(server.getRegistryManager(), saveProperties); // no need
// MinecraftServer.createWorlds
@@ -1232,8 +1154,7 @@ public class Auxiliary {
existing_worlds.put(registryKey2, serverWorld2);
}
}
Value ret = ListValue.wrap(addeds);
return (_c, _t) -> ret;
return ListValue.wrap(addeds);
});
}
@@ -1290,8 +1211,6 @@ public class Auxiliary {
}
}
private static <T> Stat<T> getStat(StatType<T> type, Identifier id)
{
T key = type.getRegistry().get(id);
@@ -3,6 +3,7 @@ package carpet.script.api;
import carpet.script.CarpetContext;
import carpet.script.Context;
import carpet.script.Expression;
import carpet.script.Fluff;
import carpet.script.LazyValue;
import carpet.script.argument.BlockArgument;
import carpet.script.argument.Vector3Argument;
@@ -30,11 +31,14 @@ import static java.lang.Math.min;
public class BlockIterators {
public static void apply(Expression expression)
{
expression.addLazyFunction("scan", -1, (c, t, lv) ->
// lazy cause of lazy expression
expression.addLazyFunction("scan", -1, (c, t, llv) ->
{
if (llv.size() < 3) throw new InternalExpressionException("'scan' needs many more arguments");
List<Value> lv = Fluff.AbstractFunction.unpackLazy(llv.subList(0, llv.size()-1), c, Context.NONE);
CarpetContext cc = (CarpetContext)c;
BlockArgument centerLocator = BlockArgument.findIn(cc, lv, 0);
Vector3Argument rangeLocator = Vector3Argument.findIn(cc, lv, centerLocator.offset);
Vector3Argument rangeLocator = Vector3Argument.findIn(lv, centerLocator.offset);
BlockPos center = centerLocator.block.getPos();
Vec3i range;
@@ -54,7 +58,7 @@ public class BlockIterators {
Vec3i upperRange = range;
if (lv.size() > rangeLocator.offset+1) // +1 cause we still need the expression
{
rangeLocator = Vector3Argument.findIn(cc, lv, rangeLocator.offset);
rangeLocator = Vector3Argument.findIn(lv, rangeLocator.offset);
if (rangeLocator.fromBlock)
{
upperRange = new Vec3i(
@@ -69,11 +73,11 @@ public class BlockIterators {
upperRange = new Vec3i(abs(rangeLocator.vec.x), abs(rangeLocator.vec.y), abs(rangeLocator.vec.z));
}
}
if (lv.size() != rangeLocator.offset+1)
if (llv.size() != rangeLocator.offset+1)
{
throw new InternalExpressionException("'scan' takes two, or three block positions, and an expression: "+lv.size()+" "+rangeLocator.offset);
}
LazyValue expr = lv.get(rangeLocator.offset);
LazyValue expr = llv.get(rangeLocator.offset);
int cx = center.getX();
int cy = center.getY();
@@ -135,9 +139,12 @@ public class BlockIterators {
return (c_, t_) -> new NumericValue(finalSCount);
});
expression.addLazyFunction("volume", -1, (c, t, lv) ->
// must be lazy
expression.addLazyFunction("volume", -1, (c, t, llv) ->
{
CarpetContext cc = (CarpetContext)c;
if (llv.size() < 3) throw new InternalExpressionException("'volume' needs many more arguments");
List<Value> lv = Fluff.AbstractFunction.unpackLazy(llv.subList(0, llv.size()-1), c, Context.NONE);
BlockArgument pos1Locator = BlockArgument.findIn(cc, lv, 0);
BlockArgument pos2Locator = BlockArgument.findIn(cc, lv, pos1Locator.offset);
@@ -156,7 +163,7 @@ public class BlockIterators {
int maxx = max(x1, x2);
int maxy = max(y1, y2);
int maxz = max(z1, z2);
LazyValue expr = lv.get(pos2Locator.offset);
LazyValue expr = llv.get(pos2Locator.offset);
//saving outer scope
LazyValue _x = c.getVariable("_x");
@@ -207,9 +214,8 @@ public class BlockIterators {
return (c_, t_) -> new NumericValue(finalSCount);
});
expression.addLazyFunction("neighbours", -1, (c, t, lv)->
expression.addContextFunction("neighbours", -1, (c, t, lv)->
{
BlockPos center = BlockArgument.findIn((CarpetContext) c, lv,0).block.getPos();
ServerWorld world = ((CarpetContext) c).s.getWorld();
@@ -220,11 +226,10 @@ public class BlockIterators {
neighbours.add(new BlockValue(null, world, center.south()));
neighbours.add(new BlockValue(null, world, center.east()));
neighbours.add(new BlockValue(null, world, center.west()));
Value retval = ListValue.wrap(neighbours);
return (c_, t_) -> retval;
return ListValue.wrap(neighbours);
});
expression.addLazyFunction("rect", -1, (c, t, lv)->
expression.addContextFunction("rect", -1, (c, t, lv)->
{
CarpetContext cc = (CarpetContext) c;
int cx, cy, cz;
@@ -237,7 +242,7 @@ public class BlockIterators {
cz = cpos.getZ();
if (lv.size() > cposLocator.offset)
{
Vector3Argument diffLocator = Vector3Argument.findIn(cc, lv, cposLocator.offset);
Vector3Argument diffLocator = Vector3Argument.findIn(lv, cposLocator.offset);
if (diffLocator.fromBlock)
{
sminx = MathHelper.floor(abs(diffLocator.vec.x - cx));
@@ -252,7 +257,7 @@ public class BlockIterators {
}
if (lv.size() > diffLocator.offset)
{
Vector3Argument posDiff = Vector3Argument.findIn(cc, lv, diffLocator.offset);
Vector3Argument posDiff = Vector3Argument.findIn(lv, diffLocator.offset);
if (posDiff.fromBlock)
{
smaxx = MathHelper.floor(abs(posDiff.vec.x - cx));
@@ -283,7 +288,7 @@ public class BlockIterators {
smaxz = 1;
}
return (c_, t_) -> new LazyListValue()
return new LazyListValue()
{
final int minx = cx-sminx;
final int miny = cy-sminy;
@@ -348,7 +353,7 @@ public class BlockIterators {
};
});
expression.addLazyFunction("diamond", -1, (c, t, lv)->
expression.addContextFunction("diamond", -1, (c, t, lv)->
{
CarpetContext cc = (CarpetContext)c;
@@ -377,17 +382,17 @@ public class BlockIterators {
BlockValue.fromCoords(cc, cx, cy, cz+1),
BlockValue.fromCoords(cc, cx, cy+1, cz)
);
return (_c, _t ) -> retval;
return retval;
}
else if (lv.size()==1+cposLocator.offset)
{
width = (int) ((NumericValue) lv.get(cposLocator.offset).evalValue(c)).getLong();
width = (int) ((NumericValue) lv.get(cposLocator.offset)).getLong();
height = 0;
}
else if(lv.size()==2+cposLocator.offset)
{
width = (int) ((NumericValue) lv.get(cposLocator.offset).evalValue(c)).getLong();
height = (int) ((NumericValue) lv.get(cposLocator.offset+1).evalValue(c)).getLong();
width = (int) ((NumericValue) lv.get(cposLocator.offset)).getLong();
height = (int) ((NumericValue) lv.get(cposLocator.offset+1)).getLong();
} else{
throw new InternalExpressionException("Incorrect number of arguments for 'diamond'");
}
@@ -398,7 +403,7 @@ public class BlockIterators {
}
if (height == 0)
{
return (c_, t_) -> new LazyListValue()
return new LazyListValue()
{
int curradius;
int curpos;
@@ -448,7 +453,7 @@ public class BlockIterators {
}
else
{
return (c_, t_) -> new LazyListValue()
return new LazyListValue()
{
int curradius;
int curpos;
+55 -86
View File
@@ -4,12 +4,10 @@ import carpet.script.CarpetContext;
import carpet.script.CarpetEventServer;
import carpet.script.CarpetScriptHost;
import carpet.script.Expression;
import carpet.script.LazyValue;
import carpet.script.argument.FunctionArgument;
import carpet.script.argument.Vector3Argument;
import carpet.script.exception.InternalExpressionException;
import carpet.script.value.EntityValue;
import carpet.script.value.FunctionValue;
import carpet.script.value.ListValue;
import carpet.script.value.NBTSerializableValue;
import carpet.script.value.NumericValue;
@@ -43,7 +41,7 @@ import java.util.stream.Collectors;
public class Entities {
public static void apply(Expression expression)
{
expression.addLazyFunction("player", -1, (c, t, lv) ->
expression.addContextFunction("player", -1, (c, t, lv) ->
{
if (lv.size() == 0)
{
@@ -51,26 +49,15 @@ public class Entities {
if (cc.host.user != null)
{
ServerPlayerEntity player = cc.s.getMinecraftServer().getPlayerManager().getPlayer(cc.host.user);
if (player == null) return LazyValue.NULL;
Value ret = new EntityValue(player);
return (_c, _t) -> ret;
return EntityValue.of(player);
}
Entity callingEntity = cc.s.getEntity();
if (callingEntity instanceof PlayerEntity)
{
Value retval = new EntityValue(callingEntity);
return (_c, _t) -> retval;
}
if (callingEntity instanceof PlayerEntity) return EntityValue.of(callingEntity);
Vec3d pos = ((CarpetContext)c).s.getPosition();
PlayerEntity closestPlayer = ((CarpetContext)c).s.getWorld().getClosestPlayer(pos.x, pos.y, pos.z, -1.0, EntityPredicates.VALID_ENTITY);
if (closestPlayer != null)
{
Value retval = new EntityValue(closestPlayer);
return (_c, _t) -> retval;
}
return (_c, _t) -> Value.NULL;
return EntityValue.of(closestPlayer);
}
String playerName = lv.get(0).evalValue(c).getString();
String playerName = lv.get(0).getString();
Value retval = Value.NULL;
if ("all".equalsIgnoreCase(playerName))
{
@@ -114,37 +101,36 @@ public class Entities {
if (player != null)
retval = new EntityValue(player);
}
Value finalVar = retval;
return (_c, _t) -> finalVar;
return retval;
});
expression.addLazyFunction("spawn", -1, (c, t, lv) ->
expression.addContextFunction("spawn", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext)c;
if (lv.size() < 2)
throw new InternalExpressionException("'spawn' function takes mob name, and position to spawn");
String entityString = lv.get(0).evalValue(c).getString();
String entityString = lv.get(0).getString();
Identifier entityId;
try
{
entityId = Identifier.fromCommandInput(new StringReader(entityString));
EntityType<? extends Entity> type = Registry.ENTITY_TYPE.getOrEmpty(entityId).orElse(null);
if (type == null || !type.isSummonable())
return LazyValue.NULL;
return Value.NULL;
}
catch (CommandSyntaxException exception)
{
return LazyValue.NULL;
return Value.NULL;
}
Vector3Argument position = Vector3Argument.findIn(cc, lv, 1);
Vector3Argument position = Vector3Argument.findIn(lv, 1);
if (position.fromBlock)
position.vec = position.vec.subtract(0, 0.5, 0);
NbtCompound tag = new NbtCompound();
boolean hasTag = false;
if (lv.size() > position.offset)
{
Value nbt = lv.get(position.offset).evalValue(c);
Value nbt = lv.get(position.offset);
NBTSerializableValue v = (nbt instanceof NBTSerializableValue) ? (NBTSerializableValue) nbt
: NBTSerializableValue.parseString(nbt.getString(), true);
hasTag = true;
@@ -160,51 +146,38 @@ public class Entities {
return !serverWorld.tryLoadEntity(entity_1x) ? null : entity_1x;
});
if (entity_1 == null) {
return LazyValue.NULL;
return Value.NULL;
} else {
if (!hasTag && entity_1 instanceof MobEntity) {
((MobEntity)entity_1).initialize(serverWorld, serverWorld.getLocalDifficulty(entity_1.getBlockPos()), SpawnReason.COMMAND, null, null);
}
Value res = new EntityValue(entity_1);
return (_c, _t) -> res;
return new EntityValue(entity_1);
}
});
expression.addLazyFunction("entity_id", 1, (c, t, lv) ->
expression.addContextFunction("entity_id", 1, (c, t, lv) ->
{
Value who = lv.get(0).evalValue(c);
Entity e;
Value who = lv.get(0);
if (who instanceof NumericValue)
{
e = ((CarpetContext)c).s.getWorld().getEntityById((int)((NumericValue) who).getLong());
}
else
{
e = ((CarpetContext)c).s.getWorld().getEntity(UUID.fromString(who.getString()));
}
if (e==null)
{
return LazyValue.NULL;
}
return (cc, tt) -> new EntityValue(e);
return EntityValue.of(((CarpetContext)c).s.getWorld().getEntityById((int)((NumericValue) who).getLong()));
return EntityValue.of(((CarpetContext)c).s.getWorld().getEntity(UUID.fromString(who.getString())));
});
expression.addLazyFunction("entity_list", 1, (c, t, lv) ->
expression.addContextFunction("entity_list", 1, (c, t, lv) ->
{
String who = lv.get(0).evalValue(c).getString();
String who = lv.get(0).getString();
ServerCommandSource source = ((CarpetContext)c).s;
EntityValue.EntityClassDescriptor eDesc = EntityValue.getEntityDescriptor(who, source.getMinecraftServer());
List<? extends Entity> entityList = source.getWorld().getEntitiesByType(eDesc.directType, eDesc.filteringPredicate);
Value retval = ListValue.wrap(entityList.stream().map(EntityValue::new).collect(Collectors.toList()));
return (_c, _t ) -> retval;
return ListValue.wrap(entityList.stream().map(EntityValue::new).collect(Collectors.toList()));
});
expression.addLazyFunction("entity_area", -1, (c, t, lv) ->
expression.addContextFunction("entity_area", -1, (c, t, lv) ->
{
if (lv.size()<3) throw new InternalExpressionException("'entity_area' requires entity type, center and range arguments");
String who = lv.get(0).evalValue(c).getString();
String who = lv.get(0).getString();
CarpetContext cc = (CarpetContext)c;
Vector3Argument centerLocator = Vector3Argument.findIn(cc, lv, 1, false, true);
Vector3Argument centerLocator = Vector3Argument.findIn(lv, 1, false, true);
Box centerBox;
if (centerLocator.entity != null)
@@ -217,90 +190,87 @@ public class Entities {
if (centerLocator.fromBlock) center.add(0.5, 0.5, 0.5);
centerBox = new Box(center, center);
}
Vector3Argument rangeLocator = Vector3Argument.findIn(cc, lv, centerLocator.offset);
Vector3Argument rangeLocator = Vector3Argument.findIn(lv, centerLocator.offset);
if (rangeLocator.fromBlock)
throw new InternalExpressionException("Range of 'entity_area' cannot come from a block argument");
Vec3d range = rangeLocator.vec;
Box area = centerBox.expand(range.x, range.y, range.z);
EntityValue.EntityClassDescriptor eDesc = EntityValue.getEntityDescriptor(who, cc.s.getMinecraftServer());
List<? extends Entity> entityList = cc.s.getWorld().getEntitiesByType(eDesc.directType, area,eDesc.filteringPredicate);
Value retval = ListValue.wrap(entityList.stream().map(EntityValue::new).collect(Collectors.toList()));
return (_c, _t ) -> retval;
return ListValue.wrap(entityList.stream().map(EntityValue::new).collect(Collectors.toList()));
});
expression.addLazyFunction("entity_selector", -1, (c, t, lv) ->
expression.addContextFunction("entity_selector", -1, (c, t, lv) ->
{
String selector = lv.get(0).evalValue(c).getString();
String selector = lv.get(0).getString();
List<Value> retlist = new ArrayList<>();
for (Entity e: EntityValue.getEntitiesFromSelector(((CarpetContext)c).s, selector))
{
retlist.add(new EntityValue(e));
}
return (c_, t_) -> ListValue.wrap(retlist);
return ListValue.wrap(retlist);
});
expression.addLazyFunction("query", -1, (c, t, lv) ->
expression.addContextFunction("query", -1, (c, t, lv) ->
{
if (lv.size()<2)
{
throw new InternalExpressionException("'query' takes entity as a first argument, and queried feature as a second");
}
Value v = lv.get(0).evalValue(c);
Value v = lv.get(0);
if (!(v instanceof EntityValue))
throw new InternalExpressionException("First argument to query should be an entity");
String what = lv.get(1).evalValue(c).getString().toLowerCase(Locale.ROOT);
String what = lv.get(1).getString().toLowerCase(Locale.ROOT);
if (what.equals("tags"))
c.host.issueDeprecation("'tags' for entity querying");
Value retval;
if (lv.size()==2)
retval = ((EntityValue) v).get(what, null);
else if (lv.size()==3)
retval = ((EntityValue) v).get(what, lv.get(2).evalValue(c));
retval = ((EntityValue) v).get(what, lv.get(2));
else
retval = ((EntityValue) v).get(what, ListValue.wrap(lv.subList(2, lv.size()).stream().map((vv) -> vv.evalValue(c)).collect(Collectors.toList())));
return (cc, tt) -> retval;
retval = ((EntityValue) v).get(what, ListValue.wrap(lv.subList(2, lv.size())));
return retval;
});
// or update
expression.addLazyFunction("modify", -1, (c, t, lv) ->
expression.addContextFunction("modify", -1, (c, t, lv) ->
{
if (lv.size()<2)
{
throw new InternalExpressionException("'modify' takes entity as a first argument, and queried feature as a second");
}
Value v = lv.get(0).evalValue(c);
Value v = lv.get(0);
if (!(v instanceof EntityValue))
throw new InternalExpressionException("First argument to modify should be an entity");
String what = lv.get(1).evalValue(c).getString();
String what = lv.get(1).getString();
if (lv.size()==2)
((EntityValue) v).set(what, null);
else if (lv.size()==3)
((EntityValue) v).set(what, lv.get(2).evalValue(c));
((EntityValue) v).set(what, lv.get(2));
else
((EntityValue) v).set(what, ListValue.wrap(lv.subList(2, lv.size()).stream().map((vv) -> vv.evalValue(c)).collect(Collectors.toList())));
return (cc, tt) -> v;
((EntityValue) v).set(what, ListValue.wrap(lv.subList(2, lv.size())));
return v;
});
expression.addLazyFunction("entity_types", -1, (c, t, lv) ->
expression.addContextFunction("entity_types", -1, (c, t, lv) ->
{
if (lv.size() > 1) throw new InternalExpressionException("'entity_types' requires one or no arguments");
String desc = (lv.size() == 1)?lv.get(0).evalValue(c).getString():"*";
Value ret = EntityValue.getEntityDescriptor(desc, ((CarpetContext) c).s.getMinecraftServer()).listValue;
return (_c, _t) -> ret;
String desc = (lv.size() == 1)?lv.get(0).getString():"*";
return EntityValue.getEntityDescriptor(desc, ((CarpetContext) c).s.getMinecraftServer()).listValue;
});
expression.addLazyFunction("entity_load_handler", -1, (c, t, lv) ->
expression.addContextFunction("entity_load_handler", -1, (c, t, lv) ->
{
if (c.host.isPerUser()) throw new InternalExpressionException("'entity_load_handler' can only be called in apps with global scope");
if (lv.size() < 2) throw new InternalExpressionException("'entity_load_handler' required the entity type, and a function to call");
Value entityValue = lv.get(0).evalValue(c);
Value entityValue = lv.get(0);
List<String> descriptors = (entityValue instanceof ListValue)
? ((ListValue) entityValue).getItems().stream().map(Value::getString).collect(Collectors.toList())
: Collections.singletonList(entityValue.getString());
Set<EntityType<? extends Entity>> types = new HashSet<>();
descriptors.forEach(s -> types.addAll(EntityValue.getEntityDescriptor(s, ((CarpetContext) c).s.getMinecraftServer()).typeList));
FunctionArgument<LazyValue> funArg = FunctionArgument.findIn(c, expression.module, lv, 1, true, false);
FunctionArgument funArg = FunctionArgument.findIn(c, expression.module, lv, 1, true, false);
CarpetEventServer events = ((CarpetScriptHost)c.host).getScriptServer().events;
if (funArg.function == null)
{
@@ -308,27 +278,26 @@ public class Entities {
}
else
{
types.forEach(et -> events.addBuiltInEvent(CarpetEventServer.Event.getEntityLoadEventName(et), c.host, funArg.function, FunctionValue.resolveArgs(funArg.args, c, t)));
types.forEach(et -> events.addBuiltInEvent(CarpetEventServer.Event.getEntityLoadEventName(et), c.host, funArg.function, funArg.args));
}
Value ret = new NumericValue(types.size());
return (cc, tt) -> ret;
return new NumericValue(types.size());
});
// or update
expression.addLazyFunction("entity_event", -1, (c, t, lv) ->
expression.addContextFunction("entity_event", -1, (c, t, lv) ->
{
if (lv.size()<3)
throw new InternalExpressionException("'entity_event' requires at least 3 arguments, entity, event to be handled, and function name, with optional arguments");
Value v = lv.get(0).evalValue(c);
Value v = lv.get(0);
if (!(v instanceof EntityValue))
throw new InternalExpressionException("First argument to entity_event should be an entity");
String what = lv.get(1).evalValue(c).getString();
String what = lv.get(1).getString();
FunctionArgument<LazyValue> funArg = FunctionArgument.findIn(c, expression.module, lv, 2, true, false);
FunctionArgument funArg = FunctionArgument.findIn(c, expression.module, lv, 2, true, false);
((EntityValue) v).setEvent((CarpetContext)c, what, funArg.function, FunctionValue.resolveArgs(funArg.args, c, t));
((EntityValue) v).setEvent((CarpetContext)c, what, funArg.function, funArg.args);
return LazyValue.NULL;
return Value.NULL;
});
}
}
+75 -129
View File
@@ -4,10 +4,10 @@ import carpet.fakes.IngredientInterface;
import carpet.fakes.RecipeManagerInterface;
import carpet.script.CarpetContext;
import carpet.script.Expression;
import carpet.script.LazyValue;
import carpet.script.exception.InternalExpressionException;
import carpet.script.exception.ThrowStatement;
import carpet.script.exception.Throwables;
import carpet.script.value.BooleanValue;
import carpet.script.value.ListValue;
import carpet.script.value.NBTSerializableValue;
import carpet.script.value.NullValue;
@@ -50,68 +50,52 @@ import java.util.stream.Collectors;
public class Inventories {
public static void apply(Expression expression)
{
expression.addLazyFunction("stack_limit", 1, (c, t, lv) ->
{
ItemStackArgument item = NBTSerializableValue.parseItem(lv.get(0).evalValue(c).getString());
Value res = new NumericValue(item.getItem().getMaxCount());
return (_c, _t) -> res;
});
expression.addUnaryFunction("stack_limit", v ->
new NumericValue(NBTSerializableValue.parseItem(v.getString()).getItem().getMaxCount()));
expression.addLazyFunction("item_category", 1, (c, t, lv) ->
expression.addUnaryFunction("item_category", v ->
{
ItemStackArgument item = NBTSerializableValue.parseItem(lv.get(0).evalValue(c).getString());
ItemStackArgument item = NBTSerializableValue.parseItem(v.getString());
ItemGroup ig = item.getItem().getGroup();
Value res = (ig==null)?Value.NULL:new StringValue(ig.getName());
return (_c, _t) -> res;
return (ig==null)?Value.NULL:new StringValue(ig.getName());
});
expression.addLazyFunction("item_list", -1, (c, t, lv) ->
expression.addContextFunction("item_list", -1, (c, t, lv) ->
{
if (lv.size() == 0)
{
Value res = ListValue.wrap(Registry.ITEM.getIds().stream().map(ValueConversions::of).collect(Collectors.toList()));
return (cc, tt) -> res;
}
return ListValue.wrap(Registry.ITEM.getIds().stream().map(ValueConversions::of).collect(Collectors.toList()));
CarpetContext cc = (CarpetContext)c;
TagManager tagManager = cc.s.getMinecraftServer().getTagManager();
String tag = lv.get(0).evalValue(c).getString();
String tag = lv.get(0).getString();
net.minecraft.tag.Tag<Item> itemTag = tagManager.getOrCreateTagGroup(Registry.ITEM_KEY).getTag(new Identifier(tag));
if (itemTag == null) return LazyValue.NULL;
Value ret = ListValue.wrap(itemTag.values().stream().map(b -> ValueConversions.of(Registry.ITEM.getId(b))).collect(Collectors.toList()));
return (_c, _t) -> ret;
if (itemTag == null) return Value.NULL;
return ListValue.wrap(itemTag.values().stream().map(b -> ValueConversions.of(Registry.ITEM.getId(b))).collect(Collectors.toList()));
});
expression.addLazyFunction("item_tags", -1, (c, t, lv) ->
expression.addContextFunction("item_tags", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext)c;
TagManager tagManager = cc.s.getMinecraftServer().getTagManager();
if (lv.size() == 0)
{
Value ret = ListValue.wrap(tagManager.getOrCreateTagGroup(Registry.ITEM_KEY).getTagIds().stream().map(ValueConversions::of).collect(Collectors.toList()));
return (_c, _t) -> ret;
}
Item item = NBTSerializableValue.parseItem(lv.get(0).evalValue(c).getString()).getItem();
return ListValue.wrap(tagManager.getOrCreateTagGroup(Registry.ITEM_KEY).getTagIds().stream().map(ValueConversions::of).collect(Collectors.toList()));
Item item = NBTSerializableValue.parseItem(lv.get(0).getString()).getItem();
if (lv.size() == 1)
{
Value ret = ListValue.wrap(tagManager.getOrCreateTagGroup(Registry.ITEM_KEY).getTags().entrySet().stream().filter(e -> e.getValue().contains(item)).map(e -> ValueConversions.of(e.getKey())).collect(Collectors.toList()));
return (_c, _t) -> ret;
}
String tag = lv.get(1).evalValue(c).getString();
Tag<Item> itemTag = tagManager.getOrCreateTagGroup(Registry.ITEM_KEY).getTag(new Identifier(tag));
if (itemTag == null) return LazyValue.NULL;
return itemTag.contains(item)?LazyValue.TRUE:LazyValue.FALSE;
return ListValue.wrap(tagManager.getOrCreateTagGroup(Registry.ITEM_KEY).getTags().entrySet().stream().filter(e -> e.getValue().contains(item)).map(e -> ValueConversions.of(e.getKey())).collect(Collectors.toList()));
String tag = lv.get(1).getString();
net.minecraft.tag.Tag<Item> itemTag = tagManager.getOrCreateTagGroup(Registry.ITEM_KEY).getTag(new Identifier(tag));
if (itemTag == null) return Value.NULL;
return BooleanValue.of(itemTag.contains(item));
});
expression.addLazyFunction("recipe_data", -1, (c, t, lv) ->
expression.addContextFunction("recipe_data", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext)c;
if (lv.size() < 1) throw new InternalExpressionException("'recipe_data' requires at least one argument");
String recipeName = lv.get(0).evalValue(c).getString();
String recipeName = lv.get(0).getString();
RecipeType type = RecipeType.CRAFTING;
if (lv.size() > 1)
{
String recipeType = lv.get(1).evalValue(c).getString();
String recipeType = lv.get(1).getString();
try
{
type = Registry.RECIPE_TYPE.get(new Identifier(recipeType));
@@ -124,7 +108,7 @@ public class Inventories {
List<Recipe<?>> recipes;
recipes = ((RecipeManagerInterface) cc.s.getMinecraftServer().getRecipeManager()).getAllMatching(type, new Identifier(recipeName));
if (recipes.isEmpty())
return LazyValue.NULL;
return Value.NULL;
List<Value> recipesOutput = new ArrayList<>();
for (Recipe<?> recipe: recipes)
{
@@ -144,7 +128,7 @@ public class Inventories {
else
{
List<Value> alternatives = new ArrayList<>();
stacks.forEach(col -> col.stream().map(ListValue::fromItemStack).forEach(alternatives::add));
stacks.forEach(col -> col.stream().map(ValueConversions::of).forEach(alternatives::add));
ingredientValue.add(ListValue.wrap(alternatives));
}
}
@@ -183,91 +167,75 @@ public class Inventories {
recipeSpec = ListValue.of(new StringValue("custom"));
}
recipesOutput.add(ListValue.of(ListValue.fromItemStack(result), ListValue.wrap(ingredientValue), recipeSpec));
recipesOutput.add(ListValue.of(ValueConversions.of(result), ListValue.wrap(ingredientValue), recipeSpec));
}
Value ret = ListValue.wrap(recipesOutput);
return (_c, _t) -> ret;
return ListValue.wrap(recipesOutput);
});
expression.addLazyFunction("crafting_remaining_item", 1, (c, t, lv) ->
expression.addUnaryFunction("crafting_remaining_item", v ->
{
String itemStr = lv.get(0).evalValue(c).getString();
String itemStr = v.getString();
Item item;
Identifier id = new Identifier(itemStr);
item = Registry.ITEM.getOrEmpty(id).orElseThrow(() -> new ThrowStatement(itemStr, Throwables.UNKNOWN_ITEM));
if (!item.hasRecipeRemainder()) return LazyValue.NULL;
Value ret = new StringValue(NBTSerializableValue.nameFromRegistryId(Registry.ITEM.getId(item.getRecipeRemainder())));
return (_c, _t ) -> ret;
if (!item.hasRecipeRemainder()) return Value.NULL;
return new StringValue(NBTSerializableValue.nameFromRegistryId(Registry.ITEM.getId(item.getRecipeRemainder())));
});
expression.addLazyFunction("inventory_size", -1, (c, t, lv) ->
expression.addContextFunction("inventory_size", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext) c;
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
if (inventoryLocator == null)
return (_c, _t) -> Value.NULL;
Value res = new NumericValue(inventoryLocator.inventory.size());
return (_c, _t) -> res;
if (inventoryLocator == null) return Value.NULL;
return new NumericValue(inventoryLocator.inventory.size());
});
expression.addLazyFunction("inventory_has_items", -1, (c, t, lv) ->
expression.addContextFunction("inventory_has_items", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext) c;
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
if (inventoryLocator == null)
return (_c, _t) -> Value.NULL;
Value res = new NumericValue(!inventoryLocator.inventory.isEmpty());
return (_c, _t) -> res;
if (inventoryLocator == null) return Value.NULL;
return new NumericValue(!inventoryLocator.inventory.isEmpty());
});
//inventory_get(<b, e>, <n>) -> item_triple
expression.addLazyFunction("inventory_get", -1, (c, t, lv) ->
expression.addContextFunction("inventory_get", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext) c;
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
if (inventoryLocator == null)
return (_c, _t) -> Value.NULL;
if (inventoryLocator == null) return Value.NULL;
if (lv.size() == inventoryLocator.offset)
{
List<Value> fullInventory = new ArrayList<>();
for (int i = 0, maxi = inventoryLocator.inventory.size(); i < maxi; i++)
{
fullInventory.add(ListValue.fromItemStack(inventoryLocator.inventory.getStack(i)));
}
Value res = ListValue.wrap(fullInventory);
return (_c, _t) -> res;
fullInventory.add(ValueConversions.of(inventoryLocator.inventory.getStack(i)));
return ListValue.wrap(fullInventory);
}
int slot = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset).evalValue(c)).getLong();
int slot = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset)).getLong();
slot = NBTSerializableValue.validateSlot(slot, inventoryLocator.inventory);
if (slot == inventoryLocator.inventory.size())
return (_c, _t) -> Value.NULL;
Value res = ListValue.fromItemStack(inventoryLocator.inventory.getStack(slot));
return (_c, _t) -> res;
if (slot == inventoryLocator.inventory.size()) return Value.NULL;
return ValueConversions.of(inventoryLocator.inventory.getStack(slot));
});
//inventory_set(<b,e>, <n>, <count>, <item>, <nbt>)
expression.addLazyFunction("inventory_set", -1, (c, t, lv) ->
expression.addContextFunction("inventory_set", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext) c;
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
if (inventoryLocator == null)
return (_c, _t) -> Value.NULL;
if (inventoryLocator == null) return Value.NULL;
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();
int slot = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset+0)).getLong();
slot = NBTSerializableValue.validateSlot(slot, inventoryLocator.inventory);
if (slot == inventoryLocator.inventory.size())
return (_c, _t) -> Value.NULL;
int count = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset+1).evalValue(c)).getLong();
if (slot == inventoryLocator.inventory.size()) return Value.NULL;
int count = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset+1)).getLong();
if (count == 0)
{
// clear slot
ItemStack removedStack = inventoryLocator.inventory.removeStack(slot);
syncPlayerInventory(inventoryLocator, slot);
//Value res = ListValue.fromItemStack(removedStack); // that tuple will be read only but cheaper if noone cares
return (_c, _t) -> ListValue.fromItemStack(removedStack);
return ValueConversions.of(removedStack);
}
if (lv.size() < inventoryLocator.offset+3)
{
@@ -276,12 +244,12 @@ public class Inventories {
newStack.setCount(count);
inventoryLocator.inventory.setStack(slot, newStack);
syncPlayerInventory(inventoryLocator, slot);
return (_c, _t) -> ListValue.fromItemStack(previousStack);
return ValueConversions.of(previousStack);
}
NbtCompound nbt = null; // skipping one argument
if (lv.size() > inventoryLocator.offset+3)
{
Value nbtValue = lv.get(inventoryLocator.offset+3).evalValue(c);
Value nbtValue = lv.get(inventoryLocator.offset+3);
if (nbtValue instanceof NBTSerializableValue)
nbt = ((NBTSerializableValue)nbtValue).getCompoundTag();
else if (nbtValue instanceof NullValue)
@@ -289,11 +257,7 @@ public class Inventories {
else
nbt = new NBTSerializableValue(nbtValue.getString()).getCompoundTag();
}
ItemStackArgument newitem = NBTSerializableValue.parseItem(
lv.get(inventoryLocator.offset+2).evalValue(c).getString(),
nbt
);
ItemStackArgument newitem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset+2).getString(), nbt);
ItemStack previousStack = inventoryLocator.inventory.getStack(slot);
try
{
@@ -304,62 +268,52 @@ public class Inventories {
{
throw new InternalExpressionException(e.getMessage());
}
return (_c, _t) -> ListValue.fromItemStack(previousStack);
return ValueConversions.of(previousStack);
});
//inventory_find(<b, e>, <item> or null (first empty slot), <start_from=0> ) -> <N> or null
expression.addLazyFunction("inventory_find", -1, (c, t, lv) ->
expression.addContextFunction("inventory_find", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext) c;
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
if (inventoryLocator == null)
return (_c, _t) -> Value.NULL;
if (inventoryLocator == null) return Value.NULL;
ItemStackArgument itemArg = null;
if (lv.size() > inventoryLocator.offset)
{
Value secondArg = lv.get(inventoryLocator.offset+0).evalValue(c);
Value secondArg = lv.get(inventoryLocator.offset+0);
if (!(secondArg instanceof NullValue))
itemArg = NBTSerializableValue.parseItem(secondArg.getString());
}
int startIndex = 0;
if (lv.size() > inventoryLocator.offset+1)
{
startIndex = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset+1).evalValue(c)).getLong();
startIndex = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset+1)).getLong();
}
startIndex = NBTSerializableValue.validateSlot(startIndex, inventoryLocator.inventory);
for (int i = startIndex, maxi = inventoryLocator.inventory.size(); i < maxi; i++)
{
ItemStack stack = inventoryLocator.inventory.getStack(i);
if ( (itemArg == null && stack.isEmpty()) || (itemArg != null && itemArg.getItem().equals(stack.getItem())) )
{
Value res = new NumericValue(i);
return (_c, _t) -> res;
}
return new NumericValue(i);
}
return (_c, _t) -> Value.NULL;
return Value.NULL;
});
//inventory_remove(<b, e>, <item>, <amount=1>) -> bool
expression.addLazyFunction("inventory_remove", -1, (c, t, lv) ->
expression.addContextFunction("inventory_remove", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext) c;
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
if (inventoryLocator == null)
return (_c, _t) -> Value.NULL;
if (inventoryLocator == null) return Value.NULL;
if (lv.size() <= inventoryLocator.offset)
throw new InternalExpressionException("'inventory_remove' requires at least an item to be removed");
ItemStackArgument searchItem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset).evalValue(c).getString());
ItemStackArgument searchItem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset).getString());
int amount = 1;
if (lv.size() > inventoryLocator.offset+1)
{
amount = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset+1).evalValue(c)).getLong();
}
amount = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset+1)).getLong();
// not enough
if (((amount == 1) && (!inventoryLocator.inventory.containsAny(Sets.newHashSet(searchItem.getItem()))))
|| (inventoryLocator.inventory.count(searchItem.getItem()) < amount))
{
return (_c, _t) -> Value.FALSE;
}
|| (inventoryLocator.inventory.count(searchItem.getItem()) < amount)) return Value.FALSE;
for (int i = 0, maxi = inventoryLocator.inventory.size(); i < maxi; i++)
{
ItemStack stack = inventoryLocator.inventory.getStack(i);
@@ -373,7 +327,7 @@ public class Inventories {
stack.setCount(left);
inventoryLocator.inventory.setStack(i, stack);
syncPlayerInventory(inventoryLocator, i);
return (_c, _t) -> Value.TRUE;
return Value.TRUE;
}
else
{
@@ -384,37 +338,30 @@ public class Inventories {
}
if (amount > 0)
throw new InternalExpressionException("Something bad happened - cannot pull all items from inventory");
return (_c, _t) -> Value.TRUE;
return Value.TRUE;
});
//inventory_drop(<b, e>, <n>, <amount=1, 0-whatever's there>) -> entity_item (and sets slot) or null if cannot
expression.addLazyFunction("drop_item", -1, (c, t, lv) ->
expression.addContextFunction("drop_item", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext) c;
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
if (inventoryLocator == null)
return (_c, _t) -> Value.NULL;
if (inventoryLocator == null) return Value.NULL;
if (lv.size() == inventoryLocator.offset)
throw new InternalExpressionException("Slot number is required for inventory_drop");
int slot = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset).evalValue(c)).getLong();
int slot = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset)).getLong();
slot = NBTSerializableValue.validateSlot(slot, inventoryLocator.inventory);
if (slot == inventoryLocator.inventory.size())
return (_c, _t) -> Value.NULL;
if (slot == inventoryLocator.inventory.size()) return Value.NULL;
int amount = 0;
if (lv.size() > inventoryLocator.offset+1)
amount = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset+1).evalValue(c)).getLong();
amount = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset+1)).getLong();
if (amount < 0)
throw new InternalExpressionException("Cannot throw negative number of items");
ItemStack stack = inventoryLocator.inventory.getStack(slot);
if (stack == null || stack.isEmpty())
return (_c, _t) -> Value.ZERO;
if (amount == 0)
amount = stack.getCount();
if (stack == null || stack.isEmpty()) return Value.ZERO;
if (amount == 0) amount = stack.getCount();
ItemStack droppedStack = inventoryLocator.inventory.removeStack(slot, amount);
if (droppedStack.isEmpty())
{
return (_c, _t) -> Value.ZERO;
}
if (droppedStack.isEmpty()) return Value.ZERO;
Object owner = inventoryLocator.owner;
ItemEntity item;
if (owner instanceof PlayerEntity)
@@ -439,8 +386,7 @@ public class Inventories {
item.setToDefaultPickupDelay();
cc.s.getWorld().spawnEntity(item);
}
Value res = new NumericValue(item.getStack().getCount());
return (_c, _t) -> res;
return new NumericValue(item.getStack().getCount());
});
}
+14 -20
View File
@@ -25,31 +25,29 @@ public class Monitoring {
public static void apply(Expression expression)
{
expression.addLazyFunction("system_info", -1, (c, t, lv) ->
expression.addContextFunction("system_info", -1, (c, t, lv) ->
{
if (lv.size() == 0)
{
Value ret = SystemInfo.getAll((CarpetContext) c);
return (cc, tt) -> ret;
return SystemInfo.getAll((CarpetContext) c);
}
if (lv.size() == 1) {
String what = lv.get(0).evalValue(c).getString();
String what = lv.get(0).getString();
Value res = SystemInfo.get(what, (CarpetContext) c);
if (res == null) throw new InternalExpressionException("Unknown option for 'system_info': " + what);
return (cc, tt) -> res;
return res;
}
throw new InternalExpressionException("'system_info' requires one or no parameters");
});
// game processed snooper functions
expression.addLazyFunction("get_mob_counts", -1, (c, t, lv) ->
expression.addContextFunction("get_mob_counts", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext)c;
ServerWorld world = cc.s.getWorld();
SpawnHelper.Info info = world.getChunkManager().getSpawnInfo();
if (info == null) return LazyValue.NULL;
if (info == null) return Value.NULL;
Object2IntMap<SpawnGroup> mobcounts = info.getGroupToCount();
int chunks = ((SpawnHelperInnerInterface)info).cmGetChunkCount();
Value retVal;
if (lv.size() == 0)
{
Map<Value, Value> retDict = new HashMap<>();
@@ -63,19 +61,15 @@ public class Monitoring {
new NumericValue(currentCap))
);
}
retVal = MapValue.wrap(retDict);
return MapValue.wrap(retDict);
}
else
{
String catString = lv.get(0).evalValue(c).getString();
SpawnGroup cat = SpawnGroup.byName(catString.toLowerCase(Locale.ROOT));
if (cat == null) throw new InternalExpressionException("Unreconized mob category: "+catString);
retVal = ListValue.of(
new NumericValue(mobcounts.getInt(cat)),
new NumericValue((int)(cat.getCapacity() * chunks / SpawnReporter.currentMagicNumber()))
);
}
return (_c, _t) -> retVal;
String catString = lv.get(0).getString();
SpawnGroup cat = SpawnGroup.byName(catString.toLowerCase(Locale.ROOT));
if (cat == null) throw new InternalExpressionException("Unreconized mob category: "+catString);
return ListValue.of(
new NumericValue(mobcounts.getInt(cat)),
new NumericValue((int)(cat.getCapacity() * chunks / SpawnReporter.currentMagicNumber()))
);
});
}
}
+149 -241
View File
@@ -64,77 +64,68 @@ public class Scoreboards {
{
// scoreboard(player,'objective')
// scoreboard(player, objective, newValue)
expression.addLazyFunction("scoreboard", -1, (c, t, lv) ->
expression.addContextFunction("scoreboard", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext)c;
Scoreboard scoreboard = cc.s.getMinecraftServer().getScoreboard();
if (lv.size()==0)
{
Value ret = ListValue.wrap(scoreboard.getObjectiveNames().stream().map(StringValue::new).collect(Collectors.toList()));
return (_c, _t) -> ret;
}
String objectiveName = lv.get(0).evalValue(c).getString();
return ListValue.wrap(scoreboard.getObjectiveNames().stream().map(StringValue::new).collect(Collectors.toList()));
String objectiveName = lv.get(0).getString();
ScoreboardObjective objective = scoreboard.getObjective(objectiveName);
if (objective == null) return LazyValue.NULL;
if (objective == null) return Value.NULL;
if (lv.size()==1)
return ListValue.wrap(scoreboard.getAllPlayerScores(objective).stream().map(s -> new StringValue(s.getPlayerName())).collect(Collectors.toList()));
String key = getScoreboardKeyFromValue(lv.get(1));
if(lv.size()==2)
{
Value ret = ListValue.wrap(scoreboard.getAllPlayerScores(objective).stream().map(s -> new StringValue(s.getPlayerName())).collect(Collectors.toList()));
return (_c, _t) -> ret;
if(!scoreboard.playerHasObjective(key, objective)) return Value.NULL;
return NumericValue.of(scoreboard.getPlayerScore(key,objective).getScore());
}
String key = getScoreboardKeyFromValue(lv.get(1).evalValue(c));
if(lv.size()==2) {
if(scoreboard.playerHasObjective(key, objective)) {
return (_c,_t) -> NumericValue.of(scoreboard.getPlayerScore(key,objective).getScore());
}
return LazyValue.NULL;
}
Value value = lv.get(2).evalValue(c);
Value value = lv.get(2);
if(value.isNull()) {
ScoreboardPlayerScore score = scoreboard.getPlayerScore(key, objective);
scoreboard.resetPlayerScore(key,objective);
return (_c,_t) -> NumericValue.of(score.getScore());
return NumericValue.of(score.getScore());
}
if (value instanceof NumericValue) {
ScoreboardPlayerScore score = scoreboard.getPlayerScore(key, objective);
score.setScore(NumericValue.asNumber(value).getInt());
return (_c,_t) -> NumericValue.of(score.getScore());
return NumericValue.of(score.getScore());
}
throw new InternalExpressionException("'scoreboard' requires a number or null as the third parameter");
});
expression.addLazyFunction("scoreboard_remove", -1, (c, t, lv)->
expression.addContextFunction("scoreboard_remove", -1, (c, t, lv)->
{
if (lv.size()==0) throw new InternalExpressionException("'scoreboard_remove' requires at least one parameter");
CarpetContext cc = (CarpetContext)c;
Scoreboard scoreboard = cc.s.getMinecraftServer().getScoreboard();
String objectiveName = lv.get(0).evalValue(c).getString();
String objectiveName = lv.get(0).getString();
ScoreboardObjective objective = scoreboard.getObjective(objectiveName);
if (objective == null)
return LazyValue.FALSE;
if (objective == null) return Value.FALSE;
if (lv.size() == 1)
{
scoreboard.removeObjective(objective);
return LazyValue.TRUE;
return Value.TRUE;
}
String key = getScoreboardKeyFromValue(lv.get(1).evalValue(c));
if (!scoreboard.playerHasObjective(key, objective)) return LazyValue.NULL;
String key = getScoreboardKeyFromValue(lv.get(1));
if (!scoreboard.playerHasObjective(key, objective)) return Value.NULL;
ScoreboardPlayerScore scoreboardPlayerScore = scoreboard.getPlayerScore(key, objective);
Value previous = new NumericValue(scoreboardPlayerScore.getScore());
scoreboard.resetPlayerScore(key, objective);
return (c_, t_) -> previous;
return previous;
});
// objective_add('lvl','level')
// objective_add('counter')
expression.addLazyFunction("scoreboard_add", -1, (c, t, lv)->
expression.addContextFunction("scoreboard_add", -1, (c, t, lv)->
{
CarpetContext cc = (CarpetContext)c;
Scoreboard scoreboard = cc.s.getMinecraftServer().getScoreboard();
if (lv.size() == 0 || lv.size()>2) throw new InternalExpressionException("'scoreboard_add' should have one or two parameters");
String objectiveName = lv.get(0).evalValue(c).getString();
String objectiveName = lv.get(0).getString();
ScoreboardCriterion criterion;
if (lv.size() == 1 )
{
@@ -142,7 +133,7 @@ public class Scoreboards {
}
else
{
String critetionName = lv.get(1).evalValue(c).getString();
String critetionName = lv.get(1).getString();
criterion = ScoreboardCriterion.getOrCreateStatCriterion(critetionName).orElse(null);
if (criterion==null)
{
@@ -153,62 +144,62 @@ public class Scoreboards {
ScoreboardObjective objective = scoreboard.getObjective(objectiveName);
if (objective != null) {
c.host.issueDeprecation("reading or modifying an objective's criterion with scoreboard_add");
if(lv.size() == 1) return (_c, _t) -> StringValue.of(objective.getCriterion().getName());
if(objective.getCriterion().equals(criterion) || lv.size() == 1) return LazyValue.NULL;
if(lv.size() == 1) return StringValue.of(objective.getCriterion().getName());
if(objective.getCriterion().equals(criterion) || lv.size() == 1) return Value.NULL;
((Scoreboard_scarpetMixin)scoreboard).getObjectivesByCriterion().get(objective.getCriterion()).remove(objective);
((ScoreboardObjective_scarpetMixin) objective).setCriterion(criterion);
(((Scoreboard_scarpetMixin)scoreboard).getObjectivesByCriterion().computeIfAbsent(criterion, (criterion1) -> Lists.newArrayList())).add(objective);
scoreboard.updateObjective(objective);
return LazyValue.FALSE;
return Value.FALSE;
}
scoreboard.addObjective(objectiveName, criterion, new LiteralText(objectiveName), criterion.getDefaultRenderType());
return LazyValue.TRUE;
return Value.TRUE;
});
expression.addLazyFunction("scoreboard_property", -1, (c, t, lv) ->
expression.addContextFunction("scoreboard_property", -1, (c, t, lv) ->
{
if(lv.size() < 2) throw new InternalExpressionException("'scoreboard_property' requires at least two parameters");
CarpetContext cc = (CarpetContext)c;
Scoreboard scoreboard = cc.s.getMinecraftServer().getScoreboard();
ScoreboardObjective objective = scoreboard.getObjective(lv.get(0).evalValue(c).getString());
if(objective == null) return LazyValue.NULL;
ScoreboardObjective objective = scoreboard.getObjective(lv.get(0).getString());
if(objective == null) return Value.NULL;
boolean modify = lv.size() > 2;
Value setValue = null;
if(modify) {
setValue = lv.get(2).evalValue(c);
setValue = lv.get(2);
}
String property = lv.get(1).evalValue(c).getString();
String property = lv.get(1).getString();
switch (property) {
case "criterion":
if(modify) {
ScoreboardCriterion criterion = ScoreboardCriterion.getOrCreateStatCriterion(setValue.getString()).orElse(null);
if (criterion==null) throw new InternalExpressionException("Unknown scoreboard criterion: "+ setValue.getString());
if(objective.getCriterion().equals(criterion) || lv.size() == 1) return LazyValue.FALSE;
if(objective.getCriterion().equals(criterion) || lv.size() == 1) return Value.FALSE;
((Scoreboard_scarpetMixin)scoreboard).getObjectivesByCriterion().get(objective.getCriterion()).remove(objective);
((ScoreboardObjective_scarpetMixin) objective).setCriterion(criterion);
(((Scoreboard_scarpetMixin)scoreboard).getObjectivesByCriterion().computeIfAbsent(criterion, (criterion1) -> Lists.newArrayList())).add(objective);
scoreboard.updateObjective(objective);
return LazyValue.TRUE;
return Value.TRUE;
}
return (_c, _t) -> StringValue.of(objective.getCriterion().getName());
return StringValue.of(objective.getCriterion().getName());
case "display_name":
if(modify) {
Text text = FormattedTextValue.getTextByValue(setValue);
objective.setDisplayName(text);
return LazyValue.TRUE;
return Value.TRUE;
}
return (_c, _t) -> new FormattedTextValue(objective.getDisplayName());
return new FormattedTextValue(objective.getDisplayName());
case "display_slot":
if(modify) {
int slotId = Scoreboard.getDisplaySlotId(setValue.getString());
if(slotId == -1) throw new InternalExpressionException("Unknown scoreboard display slot: " + setValue.getString());
if(objective.equals(scoreboard.getObjectiveForSlot(slotId))) {
return LazyValue.FALSE;
return Value.FALSE;
}
scoreboard.setObjectiveSlot(slotId,objective);
return LazyValue.TRUE;
return Value.TRUE;
}
List<Value> slots = new ArrayList<>();
@@ -218,325 +209,247 @@ public class Scoreboards {
slots.add(StringValue.of(slotName));
}
}
return (_c, _t) -> ListValue.wrap(slots);
return ListValue.wrap(slots);
case "render_type":
if(modify) {
ScoreboardCriterion.RenderType renderType = ScoreboardCriterion.RenderType.getType(setValue.getString().toLowerCase());
if(objective.getRenderType().equals(renderType)) return LazyValue.FALSE;
if(objective.getRenderType().equals(renderType)) return Value.FALSE;
objective.setRenderType(renderType);
return LazyValue.TRUE;
return Value.TRUE;
}
return (_c, _t) -> StringValue.of(objective.getRenderType().getName());
return StringValue.of(objective.getRenderType().getName());
default:
throw new InternalExpressionException("scoreboard property '" + property + "' is not a valid property");
}
});
expression.addLazyFunction("scoreboard_display", 2, (c, t, lv) ->
expression.addContextFunction("scoreboard_display", 2, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext)c;
Scoreboard scoreboard = cc.s.getMinecraftServer().getScoreboard();
String location = lv.get(0).evalValue(c).getString();
String location = lv.get(0).getString();
int slot = Scoreboard.getDisplaySlotId(location);
if (slot < 0) throw new InternalExpressionException("Invalid objective slot: "+location);
Value target = lv.get(1).evalValue(c);
Value target = lv.get(1);
if (target instanceof NullValue)
{
scoreboard.setObjectiveSlot(slot, null);
return (_c, _t) -> new NumericValue(slot);
return new NumericValue(slot);
}
String objectiveString = target.getString();
ScoreboardObjective objective = scoreboard.getObjective(objectiveString);
if (objective == null) return LazyValue.NULL;
if (objective == null) return Value.NULL;
scoreboard.setObjectiveSlot(slot, objective);
return (_c, _t) -> new NumericValue(slot);
return new NumericValue(slot);
});
expression.addLazyFunction("team_list", -1, (c, t, lv) ->
expression.addContextFunction("team_list", -1, (c, t, lv) ->
{
if(lv.size() > 1) throw new InternalExpressionException("'team_list' requires zero or one parameters");
CarpetContext cc = (CarpetContext)c;
ServerScoreboard scoreboard = cc.s.getMinecraftServer().getScoreboard();
if(lv.size() == 0) {
Value ret = ListValue.wrap(scoreboard.getTeamNames().stream().map(StringValue::of).collect(Collectors.toList()));
return (_c, _t) -> ret;
} else if(lv.size() == 1) {
Team team = scoreboard.getTeam(lv.get(0).evalValue(c).getString());
if(team == null) return LazyValue.NULL;
Value ret = ListValue.wrap(team.getPlayerList().stream().map(StringValue::of).collect(Collectors.toList()));
return (_c, _t) -> ret;
} else {
return LazyValue.NULL;
}
if(lv.size() == 0)
return ListValue.wrap(scoreboard.getTeamNames().stream().map(StringValue::of).collect(Collectors.toList()));
if (lv.size() != 1) return Value.NULL;
Team team = scoreboard.getTeam(lv.get(0).getString());
if(team == null) return Value.NULL;
return ListValue.wrap(team.getPlayerList().stream().map(StringValue::of).collect(Collectors.toList()));
});
expression.addLazyFunction("team_add", -1, (c, t, lv) ->
expression.addContextFunction("team_add", -1, (c, t, lv) ->
{
if(!(lv.size() < 3 && lv.size() > 0)) throw new InternalExpressionException("'team_add' requires one or two parameters");
CarpetContext cc = (CarpetContext)c;
ServerScoreboard scoreboard = cc.s.getMinecraftServer().getScoreboard();
String teamName = lv.get(0).evalValue(c).getString();
String teamName = lv.get(0).getString();
if(lv.size() == 1) {
if(scoreboard.getTeam(teamName) == null) {
scoreboard.addTeam(teamName);
Value ret = new StringValue(teamName);
return (_c, _t) -> ret;
} else {
return LazyValue.NULL;
}
} else if(lv.size() == 2) {
Value playerVal = lv.get(1).evalValue(c);
String player = EntityValue.getPlayerNameByValue(playerVal);
if(player == null) return LazyValue.NULL;
Team team = scoreboard.getTeam(teamName);
if(team == null) return LazyValue.NULL;
if(team.isEqual(scoreboard.getPlayerTeam(player))) {
return LazyValue.FALSE;
} else {
scoreboard.addPlayerToTeam(player,scoreboard.getTeam(teamName));
return LazyValue.TRUE;
}
} else {
return LazyValue.NULL;
if(lv.size() == 1)
{
if (scoreboard.getTeam(teamName) != null) return Value.NULL;
scoreboard.addTeam(teamName);
return new StringValue(teamName);
}
});
expression.addLazyFunction("team_remove", 1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext)c;
ServerScoreboard scoreboard = cc.s.getMinecraftServer().getScoreboard();
Value teamVal = lv.get(0).evalValue(c);
String team = teamVal.getString();
if(scoreboard.getTeam(team) != null) {
scoreboard.removeTeam(scoreboard.getTeam(team));
return LazyValue.TRUE;
} else {
return LazyValue.NULL;
}
});
expression.addLazyFunction("team_leave", 1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext)c;
ServerScoreboard scoreboard = cc.s.getMinecraftServer().getScoreboard();
Value playerVal = lv.get(0).evalValue(c);
if(lv.size() != 2) return Value.NULL;
Value playerVal = lv.get(1);
String player = EntityValue.getPlayerNameByValue(playerVal);
if(player == null) return LazyValue.NULL;
Value ret = new NumericValue(scoreboard.clearPlayerTeam(player));
return (_c, _t) -> ret;
if(player == null) return Value.NULL;
Team team = scoreboard.getTeam(teamName);
if(team == null) return Value.NULL;
if(team.isEqual(scoreboard.getPlayerTeam(player))) return Value.FALSE;
scoreboard.addPlayerToTeam(player,scoreboard.getTeam(teamName));
return Value.TRUE;
});
expression.addLazyFunction("team_property", -1, (c, t, lv) ->
expression.addContextFunction("team_remove", 1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext)c;
ServerScoreboard scoreboard = cc.s.getMinecraftServer().getScoreboard();
Value teamVal = lv.get(0);
String team = teamVal.getString();
if(scoreboard.getTeam(team) == null) return Value.NULL;
scoreboard.removeTeam(scoreboard.getTeam(team));
return Value.TRUE;
});
expression.addContextFunction("team_leave", 1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext)c;
ServerScoreboard scoreboard = cc.s.getMinecraftServer().getScoreboard();
Value playerVal = lv.get(0);
String player = EntityValue.getPlayerNameByValue(playerVal);
if(player == null) return Value.NULL;
return new NumericValue(scoreboard.clearPlayerTeam(player));
});
expression.addContextFunction("team_property", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext)c;
ServerScoreboard scoreboard = cc.s.getMinecraftServer().getScoreboard();
if(lv.size() < 2 || lv.size() > 3) throw new InternalExpressionException("'team_property' requires two or three arguments");
Value teamVal = lv.get(0).evalValue(c);
Value propertyVal = lv.get(1).evalValue(c);
Value teamVal = lv.get(0);
Value propertyVal = lv.get(1);
Value settingVal = null;
boolean modifying = false;
if(lv.size() == 3) {
if(lv.size() == 3)
{
modifying = true;
settingVal = lv.get(2).evalValue(c);
settingVal = lv.get(2);
}
Team team = scoreboard.getTeam(teamVal.getString());
if(team == null) return LazyValue.NULL;
if(team == null) return Value.NULL;
if(!(propertyVal instanceof StringValue)) throw new InternalExpressionException("'team_property' requires a string as the second argument");
switch (propertyVal.getString()) {
case "collisionRule":
if(!modifying) {
Value ret = new StringValue(team.getCollisionRule().name);
return (_c, _t) -> ret;
}
if(!modifying) return new StringValue(team.getCollisionRule().name);
if(!(settingVal instanceof StringValue)) throw new InternalExpressionException("'team_property' requires a string as the third argument for the property " + propertyVal.getString());
AbstractTeam.CollisionRule collisionRule = AbstractTeam.CollisionRule.getRule(settingVal.getString());
if(collisionRule == null) throw new InternalExpressionException("Unknown value for property " + propertyVal.getString() + ": " + settingVal.getString());
team.setCollisionRule(collisionRule);
break;
case "color":
if(!modifying) {
Value ret = new StringValue(team.getColor().getName());
return (_c, _t) -> ret;
}
if(!modifying) return new StringValue(team.getColor().getName());
if(!(settingVal instanceof StringValue)) throw new InternalExpressionException("'team_property' requires a string as the third argument for the property " + propertyVal.getString());
Formatting color = Formatting.byName(settingVal.getString().toUpperCase());
if(color == null || !color.isColor()) throw new InternalExpressionException("Unknown value for property " + propertyVal.getString() + ": " + settingVal.getString());
team.setColor(color);
break;
case "deathMessageVisibility":
if(!modifying) {
Value ret = new StringValue(team.getDeathMessageVisibilityRule().name);
return (_c, _t) -> ret;
}
if(!modifying) return new StringValue(team.getDeathMessageVisibilityRule().name);
if(!(settingVal instanceof StringValue)) throw new InternalExpressionException("'team_property' requires a string as the third argument for the property " + propertyVal.getString());
AbstractTeam.VisibilityRule deathMessageVisibility = AbstractTeam.VisibilityRule.getRule(settingVal.getString());
if(deathMessageVisibility == null) throw new InternalExpressionException("Unknown value for property " + propertyVal.getString() + ": " + settingVal.getString());
team.setDeathMessageVisibilityRule(deathMessageVisibility);
break;
case "displayName":
if(!modifying) {
Value ret = new FormattedTextValue(team.getDisplayName());
return (_c, _t) -> ret;
}
if(!modifying) return new FormattedTextValue(team.getDisplayName());
if(!(settingVal instanceof StringValue)) throw new InternalExpressionException("'team_property' requires a string or formatted text as the third argument for the property " + propertyVal.getString());
Text displayName;
displayName = FormattedTextValue.getTextByValue(settingVal);
team.setDisplayName(displayName);
break;
case "friendlyFire":
if(!modifying) {
Value ret = new NumericValue(team.isFriendlyFireAllowed());
return (_c, _t) -> ret;
}
if(!modifying) return new NumericValue(team.isFriendlyFireAllowed());
if(!(settingVal instanceof NumericValue)) throw new InternalExpressionException("'team_property' requires a boolean as the third argument for the property " + propertyVal.getString());
boolean friendlyFire = settingVal.getBoolean();
team.setFriendlyFireAllowed(friendlyFire);
break;
case "nametagVisibility":
if(!modifying) {
Value ret = new StringValue(team.getNameTagVisibilityRule().name);
return (_c, _t) -> ret;
}
if(!modifying) return new StringValue(team.getNameTagVisibilityRule().name);
if(!(settingVal instanceof StringValue)) throw new InternalExpressionException("'team_property' requires a string as the third argument for the property " + propertyVal.getString());
AbstractTeam.VisibilityRule nametagVisibility = AbstractTeam.VisibilityRule.getRule(settingVal.getString());
if(nametagVisibility == null) throw new InternalExpressionException("Unknown value for property " + propertyVal.getString() + ": " + settingVal.getString());
team.setNameTagVisibilityRule(nametagVisibility);
break;
case "prefix":
if(!modifying) {
Value ret = new FormattedTextValue(team.getPrefix());
return (_c, _t) -> ret;
}
if(!modifying) return new FormattedTextValue(team.getPrefix());
if(!(settingVal instanceof StringValue)) throw new InternalExpressionException("'team_property ' requires a string or formatted text as the third argument for the property " + propertyVal.getString());
Text prefix;
prefix = FormattedTextValue.getTextByValue(settingVal);
team.setPrefix(prefix);
break;
case "seeFriendlyInvisibles":
if(!modifying) {
Value ret = new NumericValue(team.shouldShowFriendlyInvisibles());
return (_c, _t) -> ret;
}
if(!modifying) return new NumericValue(team.shouldShowFriendlyInvisibles());
if(!(settingVal instanceof NumericValue)) throw new InternalExpressionException("'team_property' requires a boolean as the third argument for the property " + propertyVal.getString());
boolean seeFriendlyInvisibles = settingVal.getBoolean();
team.setShowFriendlyInvisibles(seeFriendlyInvisibles);
break;
case "suffix":
if(!modifying) {
Value ret = new FormattedTextValue(team.getSuffix());
return (_c, _t) -> ret;
}
if(!modifying) return new FormattedTextValue(team.getSuffix());
if(!(settingVal instanceof StringValue)) throw new InternalExpressionException("'team_property' requires a string or formatted text as the third argument for the property " + propertyVal.getString());
Text suffix;
suffix = FormattedTextValue.getTextByValue(settingVal);
team.setSuffix(suffix);
break;
default:
throw new InternalExpressionException("team property '" + propertyVal.getString() + "' is not a valid property");
}
return LazyValue.TRUE;
return Value.TRUE;
});
expression.addLazyFunction("bossbar", -1, (c, t, lv) ->
expression.addContextFunction("bossbar", -1, (c, t, lv) ->
{
BossBarManager bossBarManager = ((CarpetContext)c).s.getMinecraftServer().getBossBarManager();
if(lv.size() > 3) throw new InternalExpressionException("'bossbar' accepts max three arguments");
if(lv.size() == 0) {
Value ret = ListValue.wrap(bossBarManager.getAll().stream().map(CommandBossBar::getId).map(Identifier::toString).map(StringValue::of).collect(Collectors.toList()));
return (_c, _t) -> ret;
}
if(lv.size() == 0) return ListValue.wrap(bossBarManager.getAll().stream().map(CommandBossBar::getId).map(Identifier::toString).map(StringValue::of).collect(Collectors.toList()));
String id = lv.get(0).evalValue(c).getString();
String id = lv.get(0).getString();
Identifier identifier;
try {
try
{
identifier = new Identifier(id);
} catch (InvalidIdentifierException invalidIdentifierException) {
return LazyValue.NULL;
}
catch (InvalidIdentifierException invalidIdentifierException)
{
return Value.NULL;
}
if(lv.size() == 1) {
if(bossBarManager.get(identifier) != null) return LazyValue.FALSE;
Value ret = StringValue.of(bossBarManager.add(identifier,new LiteralText(id)).getId().toString());
return (_c, _t) -> ret;
if(lv.size() == 1)
{
if(bossBarManager.get(identifier) != null) return Value.FALSE;
return StringValue.of(bossBarManager.add(identifier,new LiteralText(id)).getId().toString());
}
String property = lv.get(1).evalValue(c).getString();
String property = lv.get(1).getString();
CommandBossBar bossBar = bossBarManager.get(identifier);
if(bossBar == null) return LazyValue.NULL;
if(bossBar == null) return Value.NULL;
Value propertyValue = (lv.size() == 3)?lv.get(2).evalValue(c):null;
Value propertyValue = (lv.size() == 3)?lv.get(2):null;
switch (property) {
case "color":
if(propertyValue == null) {
BossBar.Color color = (bossBar).getColor();
if(color == null) return LazyValue.NULL;
return (_c, _t) -> StringValue.of(color.getName());
if(color == null) return Value.NULL;
return StringValue.of(color.getName());
}
BossBar.Color color = BossBar.Color.byName(propertyValue.getString());
if(color == null) return LazyValue.NULL;
if(color == null) return Value.NULL;
bossBar.setColor(BossBar.Color.byName(propertyValue.getString()));
return LazyValue.TRUE;
return Value.TRUE;
case "max":
if(propertyValue == null) return (_c, _t) -> NumericValue.of(bossBar.getMaxValue());
if(propertyValue == null) return NumericValue.of(bossBar.getMaxValue());
if(!(propertyValue instanceof NumericValue)) throw new InternalExpressionException("'bossbar' requires a number as the value for the property " + property);
bossBar.setMaxValue(((NumericValue) propertyValue).getInt());
return LazyValue.TRUE;
return Value.TRUE;
case "name":
if(propertyValue == null) return (_c, _t) -> new FormattedTextValue(bossBar.getName());
if(propertyValue == null) return new FormattedTextValue(bossBar.getName());
bossBar.setName(FormattedTextValue.getTextByValue(propertyValue));
return LazyValue.TRUE;
return Value.TRUE;
case "add_player":
if(propertyValue == null) throw new InternalExpressionException("Bossbar property " + property + " can't be queried, add a third parameter");
@@ -545,27 +458,25 @@ public class Scoreboards {
ServerPlayerEntity player = EntityValue.getPlayerByValue(((CarpetContext)c).s.getMinecraftServer(),propertyValue);
if(player != null) bossBar.addPlayer(player);
});
return LazyValue.TRUE;
return Value.TRUE;
}
ServerPlayerEntity player = EntityValue.getPlayerByValue(((CarpetContext) c).s.getMinecraftServer(), propertyValue);
if(player != null) {
bossBar.addPlayer(player);
return LazyValue.TRUE;
return Value.TRUE;
}
return LazyValue.FALSE;
return Value.FALSE;
case "players":
if(propertyValue == null) {
return (_c, _t) -> ListValue.wrap(bossBar.getPlayers().stream().map(EntityValue::new).collect(Collectors.toList()));
}
if(propertyValue instanceof ListValue) {
if (propertyValue == null) return ListValue.wrap(bossBar.getPlayers().stream().map(EntityValue::new).collect(Collectors.toList()));
if(propertyValue instanceof ListValue)
{
bossBar.clearPlayers();
((ListValue) propertyValue).getItems().forEach((v) -> {
ServerPlayerEntity p = EntityValue.getPlayerByValue(((CarpetContext) c).s.getMinecraftServer(), v);
if (p != null) bossBar.addPlayer(p);
});
return LazyValue.TRUE;
return Value.TRUE;
}
@@ -573,32 +484,29 @@ public class Scoreboards {
bossBar.clearPlayers();
if (p != null) {
bossBar.addPlayer(p);
return LazyValue.TRUE;
return Value.TRUE;
}
return LazyValue.FALSE;
return Value.FALSE;
case "style":
if(propertyValue == null) {
return (_c, _t) -> StringValue.of(bossBar.getStyle().getName());
}
if(propertyValue == null) return StringValue.of(bossBar.getStyle().getName());
BossBar.Style style = BossBar.Style.byName(propertyValue.getString());
if(style == null) throw new InternalExpressionException("'" + propertyValue.getString() + "' is not a valid value for property " + property);
bossBar.setStyle(style);
return LazyValue.TRUE;
return Value.TRUE;
case "value":
if(propertyValue == null) return (_c, _t) -> NumericValue.of(bossBar.getValue());
if(propertyValue == null) return NumericValue.of(bossBar.getValue());
if(!(propertyValue instanceof NumericValue)) throw new InternalExpressionException("'bossbar' requires a number as the value for the property " + property);
bossBar.setValue(((NumericValue) propertyValue).getInt());
return LazyValue.TRUE;
return Value.TRUE;
case "visible":
if(propertyValue == null) return (_c, _t) -> new NumericValue(bossBar.isVisible());
if(propertyValue == null) return new NumericValue(bossBar.isVisible());
bossBar.setVisible(propertyValue.getBoolean());
return LazyValue.TRUE;
return Value.TRUE;
case "remove":
bossBarManager.remove(bossBar);
return LazyValue.TRUE;
return Value.TRUE;
default:
throw new InternalExpressionException("Unknown bossbar property " + property);
}
@@ -15,16 +15,16 @@ public class Threading
public static void apply(Expression expression)
{
//"overidden" native call to cancel if on main thread
expression.addLazyFunction("task_join", 1, (c, t, lv) -> {
expression.addContextFunction("task_join", 1, (c, t, lv) -> {
if (((CarpetContext)c).s.getMinecraftServer().isOnThread())
throw new InternalExpressionException("'task_join' cannot be called from main thread to avoid deadlocks");
Value v = lv.get(0).evalValue(c);
Value v = lv.get(0);
if (!(v instanceof ThreadValue))
throw new InternalExpressionException("'task_join' could only be used with a task value");
Value ret = ((ThreadValue) v).join();
return (_c, _t) -> ret;
return ((ThreadValue) v).join();
});
// has to be lazy due to deferred execution of the expression
expression.addLazyFunctionWithDelegation("task_dock", 1, (c, t, expr, tok, lv) -> {
CarpetContext cc = (CarpetContext)c;
MinecraftServer server = cc.s.getMinecraftServer();
File diff suppressed because it is too large. Load diff