entity load handler and rework of handling of events.

This commit is contained in:
gnembon committed 2020-10-30 22:59:27 -03:00
1 parent 51f34643db
commit 7ccd46433a
15 files changed
+413 -299

No files matched your search

@@ -74,7 +74,7 @@ public class ScriptCommand
scarpetMatches.addAll(APIFunctions.stream().
filter(s -> s.startsWith(prefix) && s.length() <= maxLen).map(s -> s+"(").collect(Collectors.toList()));
// not that useful in commandline, more so in external scripts, so skipping here
if (eventPrefix != null) scarpetMatches.addAll(CarpetEventServer.Event.byName.keySet().stream().
if (eventPrefix != null) scarpetMatches.addAll(CarpetEventServer.Event.publicEvents().stream().
filter(s -> s.startsWith(eventPrefix)).map(s -> "__on_"+s+"(").collect(Collectors.toList()));
scarpetMatches.addAll(host.globaFunctionNames(host.main, s -> s.startsWith(prefix)).map(s -> s+"(").collect(Collectors.toList()));
scarpetMatches.addAll(host.globaVariableNames(host.main, s -> s.startsWith(prefix)).collect(Collectors.toList()));
@@ -269,7 +269,7 @@ public class ScriptCommand
executes( (cc) -> listEvents(cc.getSource())).
then(literal("add_to").
then(argument("event", StringArgumentType.word()).
suggests( (cc, bb) -> suggestMatching(CarpetEventServer.Event.byName.keySet() ,bb)).
suggests( (cc, bb) -> suggestMatching(CarpetEventServer.Event.publicEvents() ,bb)).
then(argument("call", StringArgumentType.word()).
suggests( (cc, bb) -> suggestMatching(suggestFunctionCalls(cc), bb)).
executes( (cc) -> CarpetServer.scriptServer.events.addEvent(
@@ -291,7 +291,7 @@ public class ScriptCommand
)?1:0)))))).
then(literal("remove_from").
then(argument("event", StringArgumentType.word()).
suggests( (cc, bb) -> suggestMatching(CarpetEventServer.Event.byName.keySet() ,bb)).
suggests( (cc, bb) -> suggestMatching(CarpetEventServer.Event.publicEvents() ,bb)).
then(argument("call", StringArgumentType.greedyString()).
suggests( (cc, bb) -> suggestMatching(CarpetEventServer.Event.byName.get(StringArgumentType.getString(cc, "event")).handler.callList.stream().map(CarpetEventServer.Callback::toString), bb)).
executes( (cc) -> CarpetServer.scriptServer.events.removeEvent(
+144 -128
View File
@@ -34,7 +34,6 @@ import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.dimension.DimensionType;
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList;
@@ -62,11 +61,36 @@ public class CarpetEventServer
{
public final String host;
public final FunctionValue function;
public final List<Value> parametrizedArgs;
public Callback(String host, FunctionValue function)
public Callback(String host, FunctionValue function, List<Value> parametrizedArgs)
{
this.host = host;
this.function = function;
this.parametrizedArgs = parametrizedArgs;
}
/**
* Used in entity events
* @param asSource - entity command source
* @param runtimeArgs = options
*/
public boolean execute(ServerCommandSource asSource, List<Value> runtimeArgs)
{
//!CarpetServer.scriptServer.runas(source, call.host, call.function, argv)
//CarpetServer.scriptServer.runas(source, call.host, call.function, argv)
if (this.parametrizedArgs == null || this.parametrizedArgs.isEmpty())
return CarpetServer.scriptServer.runas(
asSource.withLevel(CarpetSettings.runPermissionLevel),
host, function, runtimeArgs);
else
{
List<Value> combinedArgs = new ArrayList<>(runtimeArgs);
combinedArgs.addAll(this.parametrizedArgs);
return CarpetServer.scriptServer.runas(
asSource.withLevel(CarpetSettings.runPermissionLevel),
host, function, combinedArgs);
}
}
@Override
@@ -78,14 +102,13 @@ public class CarpetEventServer
public static class ScheduledCall extends Callback
{
public final List<Value> args;
private final CarpetContext ctx;
public long dueTime;
public ScheduledCall(CarpetContext context, FunctionValue function, List<Value> args, long dueTime)
{
super(context.host.getName(), function);
this.args = args;
super(context.host.getName(), function, args);
this.ctx = context;
this.dueTime = dueTime;
}
@@ -95,34 +118,10 @@ public class CarpetEventServer
*/
public void execute()
{
CarpetServer.scriptServer.runas(ctx.origin, ctx.s, host, function, lazify(args));
CarpetServer.scriptServer.runas(ctx.origin, ctx.s, host, function, parametrizedArgs);
}
/**
* Used in entity events
* @param asSource - entity command source
* @param args = options
*/
public void execute(ServerCommandSource asSource, List<Value> args)
{
if (this.args == null || this.args.isEmpty())
CarpetServer.scriptServer.runas(
ctx.origin, asSource.withLevel(CarpetSettings.runPermissionLevel),
host, function, lazify(args));
else
{
List<Value> combinedArgs = new ArrayList<>();
combinedArgs.addAll(args);
combinedArgs.addAll(this.args);
CarpetServer.scriptServer.runas(
ctx.origin, asSource.withLevel(CarpetSettings.runPermissionLevel),
host, function, lazify(combinedArgs));
}
}
private List<LazyValue> lazify(List<Value> args)
{
return args.stream().map(v -> (LazyValue) (c, t) -> v ).collect(Collectors.toList());
}
}
public static class CallbackList
@@ -137,18 +136,17 @@ public class CarpetEventServer
this.reqArgs = reqArgs;
}
public void call(Supplier<List<LazyValue>> argumentSupplier, Supplier<ServerCommandSource> cmdSourceSupplier)
public void call(Supplier<List<Value>> argumentSupplier, Supplier<ServerCommandSource> cmdSourceSupplier)
{
if (callList.size() > 0)
{
List<LazyValue> argv = argumentSupplier.get(); // empty for onTickDone
List<Value> argv = argumentSupplier.get(); // empty for onTickDone
ServerCommandSource source = cmdSourceSupplier.get();
assert argv.size() == reqArgs;
List<Callback> fails = new ArrayList<>();
for (Callback call: callList)
{
if (!CarpetServer.scriptServer.runas(source, call.host, call.function, argv))
fails.add(call);
if (!call.execute(source, argv)) fails.add(call);
}
for (Callback call : fails) callList.remove(call);
}
@@ -178,19 +176,19 @@ public class CarpetEventServer
//remove duplicates
removeEventCall(hostName, udf.getString());
callList.add(new Callback(hostName, udf));
callList.add(new Callback(hostName, udf, null));
return true;
}
public boolean addEventCallDirect(ScriptHost host, FunctionValue function)
public boolean addEventCallInternal(ScriptHost host, FunctionValue function, List<Value> args)
{
if (function == null || function.getArguments().size() != reqArgs)
if (function == null || (function.getArguments().size() - (args==null?0:args.size())) != reqArgs)
{
return false;
}
//all clear
//remove duplicates
removeEventCall(host.getName(), function.getString());
callList.add(new Callback(host.getName(), function));
callList.add(new Callback(host.getName(), function, args));
return true;
}
@@ -259,8 +257,8 @@ public class CarpetEventServer
{
ChunkPos pos = chunk.getPos();
return Arrays.asList(
((c, t) -> new NumericValue(pos.x << 4)),
((c, t) -> new NumericValue(pos.z << 4))
(new NumericValue(pos.x << 4)),
(new NumericValue(pos.z << 4))
);
}, () -> CarpetServer.minecraft_server.getCommandSource().withWorld(world)
);
@@ -272,7 +270,7 @@ public class CarpetEventServer
@Override
public void onPlayerEvent(ServerPlayerEntity player)
{
handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource);
handler.call( () -> Collections.singletonList((new EntityValue(player))), player::getCommandSource);
}
};
public static final Event PLAYER_DEPLOYS_ELYTRA = new Event("player_deploys_elytra", 1, false)
@@ -280,7 +278,7 @@ public class CarpetEventServer
@Override
public void onPlayerEvent(ServerPlayerEntity player)
{
handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource);
handler.call( () -> Collections.singletonList((new EntityValue(player))), player::getCommandSource);
}
};
public static final Event PLAYER_WAKES_UP = new Event("player_wakes_up", 1, false)
@@ -288,7 +286,7 @@ public class CarpetEventServer
@Override
public void onPlayerEvent(ServerPlayerEntity player)
{
handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource);
handler.call( () -> Collections.singletonList((new EntityValue(player))), player::getCommandSource);
}
};
public static final Event PLAYER_RIDES = new Event("player_rides", 5, false)
@@ -297,11 +295,11 @@ public class CarpetEventServer
public void onMountControls(ServerPlayerEntity player, float strafeSpeed, float forwardSpeed, boolean jumping, boolean sneaking)
{
handler.call( () -> Arrays.asList(
((c, t) -> new EntityValue(player)),
((c, t) -> new NumericValue(forwardSpeed)),
((c, t) -> new NumericValue(strafeSpeed)),
((c, t) -> new NumericValue(jumping)),
((c, t) -> new NumericValue(sneaking))
(new EntityValue(player)),
(new NumericValue(forwardSpeed)),
(new NumericValue(strafeSpeed)),
(new NumericValue(jumping)),
(new NumericValue(sneaking))
), player::getCommandSource);
}
};
@@ -314,9 +312,9 @@ public class CarpetEventServer
{
//ItemStack itemstack = player.getStackInHand(enumhand);
return Arrays.asList(
((c, t) -> new EntityValue(player)),
((c, t) -> ListValue.fromItemStack(itemstack)),
((c, t) -> new StringValue(enumhand == Hand.MAIN_HAND ? "mainhand" : "offhand"))
(new EntityValue(player)),
(ListValue.fromItemStack(itemstack)),
(new StringValue(enumhand == Hand.MAIN_HAND ? "mainhand" : "offhand"))
);
}, player::getCommandSource);
}
@@ -329,9 +327,9 @@ public class CarpetEventServer
handler.call( () ->
{
return Arrays.asList(
((c, t) -> new EntityValue(player)),
((c, t) -> new BlockValue(null, player.getServerWorld(), blockpos)),
((c, t) -> new StringValue(facing.getName()))
(new EntityValue(player)),
(new BlockValue(null, player.getServerWorld(), blockpos)),
(new StringValue(facing.getName()))
);
}, player::getCommandSource);
}
@@ -348,12 +346,12 @@ public class CarpetEventServer
Direction enumfacing = hitRes.getSide();
Vec3d vec3d = hitRes.getPos().subtract(blockpos.getX(), blockpos.getY(), blockpos.getZ());
return Arrays.asList(
((c, t) -> new EntityValue(player)),
((c, t) -> ListValue.fromItemStack(itemstack)),
((c, t) -> new StringValue(enumhand == Hand.MAIN_HAND ? "mainhand" : "offhand")),
((c, t) -> new BlockValue(null, player.getServerWorld(), blockpos)),
((c, t) -> new StringValue(enumfacing.getName())),
((c, t) -> ListValue.of(
(new EntityValue(player)),
(ListValue.fromItemStack(itemstack)),
(new StringValue(enumhand == Hand.MAIN_HAND ? "mainhand" : "offhand")),
(new BlockValue(null, player.getServerWorld(), blockpos)),
(new StringValue(enumfacing.getName())),
(ListValue.of(
new NumericValue(vec3d.x),
new NumericValue(vec3d.y),
new NumericValue(vec3d.z)
@@ -373,11 +371,11 @@ public class CarpetEventServer
Direction enumfacing = hitRes.getSide();
Vec3d vec3d = hitRes.getPos().subtract(blockpos.getX(), blockpos.getY(), blockpos.getZ());
return Arrays.asList(
((c, t) -> new EntityValue(player)),
((c, t) -> new StringValue(enumhand == Hand.MAIN_HAND ? "mainhand" : "offhand")),
((c, t) -> new BlockValue(null, player.getServerWorld(), blockpos)),
((c, t) -> new StringValue(enumfacing.getName())),
((c, t) -> ListValue.of(
(new EntityValue(player)),
(new StringValue(enumhand == Hand.MAIN_HAND ? "mainhand" : "offhand")),
(new BlockValue(null, player.getServerWorld(), blockpos)),
(new StringValue(enumfacing.getName())),
(ListValue.of(
new NumericValue(vec3d.x),
new NumericValue(vec3d.y),
new NumericValue(vec3d.z)
@@ -392,10 +390,10 @@ public class CarpetEventServer
public void onBlockPlaced(ServerPlayerEntity player, BlockPos pos, Hand enumhand, ItemStack itemstack)
{
handler.call( () -> Arrays.asList(
((c, t) -> new EntityValue(player)),
((c, t) -> ListValue.fromItemStack(itemstack)),
((c, t) -> new StringValue(enumhand == Hand.MAIN_HAND ? "mainhand" : "offhand")),
((c, t) -> new BlockValue(null, player.getServerWorld(), pos))
(new EntityValue(player)),
(ListValue.fromItemStack(itemstack)),
(new StringValue(enumhand == Hand.MAIN_HAND ? "mainhand" : "offhand")),
(new BlockValue(null, player.getServerWorld(), pos))
), player::getCommandSource);
}
};
@@ -405,8 +403,8 @@ public class CarpetEventServer
public void onBlockBroken(ServerPlayerEntity player, BlockPos pos, BlockState previousBS)
{
handler.call( () -> Arrays.asList(
((c, t) -> new EntityValue(player)),
((c, t) -> new BlockValue(previousBS, player.getServerWorld(), pos))
(new EntityValue(player)),
(new BlockValue(previousBS, player.getServerWorld(), pos))
), player::getCommandSource);
}
};
@@ -416,9 +414,9 @@ public class CarpetEventServer
public void onEntityHandAction(ServerPlayerEntity player, Entity entity, Hand enumhand)
{
handler.call( () -> Arrays.asList(
((c, t) -> new EntityValue(player)),
((c, t) -> new EntityValue(entity)),
((c, t) -> new StringValue(enumhand==Hand.MAIN_HAND?"mainhand":"offhand"))
(new EntityValue(player)),
(new EntityValue(entity)),
(new StringValue(enumhand==Hand.MAIN_HAND?"mainhand":"offhand"))
), player::getCommandSource);
}
};
@@ -430,8 +428,8 @@ public class CarpetEventServer
{
//ItemStack itemstack = player.getStackInHand(enumhand);
return Arrays.asList(
((c, t) -> new EntityValue(player)),
((c, t) -> ListValue.fromItemStack(itemstack))
(new EntityValue(player)),
(ListValue.fromItemStack(itemstack))
);
}, player::getCommandSource);
}
@@ -443,8 +441,8 @@ public class CarpetEventServer
public void onEntityHandAction(ServerPlayerEntity player, Entity entity, Hand enumhand)
{
handler.call( () -> Arrays.asList(
((c, t) -> new EntityValue(player)),
((c, t) -> new EntityValue(entity))
(new EntityValue(player)),
(new EntityValue(entity))
), player::getCommandSource);
}
};
@@ -453,7 +451,7 @@ public class CarpetEventServer
@Override
public void onPlayerEvent(ServerPlayerEntity player)
{
handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource);
handler.call( () -> Collections.singletonList((new EntityValue(player))), player::getCommandSource);
}
};
public static final Event PLAYER_STOPS_SNEAKING = new Event("player_stops_sneaking", 1, false)
@@ -461,7 +459,7 @@ public class CarpetEventServer
@Override
public void onPlayerEvent(ServerPlayerEntity player)
{
handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource);
handler.call( () -> Collections.singletonList((new EntityValue(player))), player::getCommandSource);
}
};
public static final Event PLAYER_STARTS_SPRINTING = new Event("player_starts_sprinting", 1, false)
@@ -469,7 +467,7 @@ public class CarpetEventServer
@Override
public void onPlayerEvent(ServerPlayerEntity player)
{
handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource);
handler.call( () -> Collections.singletonList((new EntityValue(player))), player::getCommandSource);
}
};
public static final Event PLAYER_STOPS_SPRINTING = new Event("player_stops_sprinting", 1, false)
@@ -477,7 +475,7 @@ public class CarpetEventServer
@Override
public void onPlayerEvent(ServerPlayerEntity player)
{
handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource);
handler.call( () -> Collections.singletonList((new EntityValue(player))), player::getCommandSource);
}
};
@@ -490,9 +488,9 @@ public class CarpetEventServer
handler.call( () ->
{
return Arrays.asList(
((c, t) -> new EntityValue(player)),
((c, t) -> ListValue.fromItemStack(itemstack)),
((c, t) -> new StringValue(enumhand == Hand.MAIN_HAND ? "mainhand" : "offhand"))
(new EntityValue(player)),
(ListValue.fromItemStack(itemstack)),
(new StringValue(enumhand == Hand.MAIN_HAND ? "mainhand" : "offhand"))
);
}, player::getCommandSource);
}
@@ -506,9 +504,9 @@ public class CarpetEventServer
handler.call( () ->
{
return Arrays.asList(
((c, t) -> new EntityValue(player)),
((c, t) -> ListValue.fromItemStack(itemstack)),
((c, t) -> new StringValue(enumhand == Hand.MAIN_HAND ? "mainhand" : "offhand"))
(new EntityValue(player)),
(ListValue.fromItemStack(itemstack)),
(new StringValue(enumhand == Hand.MAIN_HAND ? "mainhand" : "offhand"))
);
}, player::getCommandSource);
}
@@ -518,7 +516,7 @@ public class CarpetEventServer
@Override
public void onPlayerEvent(ServerPlayerEntity player)
{
handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource);
handler.call( () -> Collections.singletonList((new EntityValue(player))), player::getCommandSource);
}
};
public static final Event PLAYER_DROPS_STACK = new Event("player_drops_stack", 1, false)
@@ -526,7 +524,7 @@ public class CarpetEventServer
@Override
public void onPlayerEvent(ServerPlayerEntity player)
{
handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource);
handler.call( () -> Collections.singletonList((new EntityValue(player))), player::getCommandSource);
}
};
public static final Event PLAYER_CHOOSES_RECIPE = new Event("player_chooses_recipe", 3, false)
@@ -537,9 +535,9 @@ public class CarpetEventServer
handler.call( () ->
{
return Arrays.asList(
((c, t) -> new EntityValue(player)),
((c, t) -> new StringValue(NBTSerializableValue.nameFromRegistryId(recipe))),
((c, t) -> new NumericValue(fullStack))
(new EntityValue(player)),
(new StringValue(NBTSerializableValue.nameFromRegistryId(recipe))),
(new NumericValue(fullStack))
);
}, player::getCommandSource);
}
@@ -553,9 +551,9 @@ public class CarpetEventServer
handler.call( () ->
{
return Arrays.asList(
((c, t) -> new EntityValue(player)),
((c, t) -> new NumericValue(from)),
((c, t) -> new NumericValue(to))
(new EntityValue(player)),
(new NumericValue(from)),
(new NumericValue(to))
);
}, player::getCommandSource);
}
@@ -565,7 +563,7 @@ public class CarpetEventServer
@Override
public void onPlayerEvent(ServerPlayerEntity player)
{
handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource);
handler.call( () -> Collections.singletonList((new EntityValue(player))), player::getCommandSource);
}
};
public static final Event PLAYER_TAKES_DAMAGE = new Event("player_takes_damage", 4, false)
@@ -576,10 +574,10 @@ public class CarpetEventServer
handler.call( () ->
{
return Arrays.asList(
((c, t) -> new EntityValue(target)),
((c, t) -> new NumericValue(amount)),
((c, t) ->new StringValue(source.getName())),
((c, t) -> source.getAttacker()==null?Value.NULL:new EntityValue(source.getAttacker()))
( new EntityValue(target)),
( new NumericValue(amount)),
(new StringValue(source.getName())),
( source.getAttacker()==null?Value.NULL:new EntityValue(source.getAttacker()))
);
}, target::getCommandSource);
}
@@ -592,9 +590,9 @@ public class CarpetEventServer
handler.call( () ->
{
return Arrays.asList(
((c, t) -> new EntityValue(source.getAttacker())),
((c, t) -> new NumericValue(amount)),
((c, t) -> new EntityValue(target))
(new EntityValue(source.getAttacker())),
(new NumericValue(amount)),
(new EntityValue(target))
);
}, () -> source.getAttacker().getCommandSource());
}
@@ -604,8 +602,8 @@ public class CarpetEventServer
@Override
public void onEntityHandAction(ServerPlayerEntity player, Entity entity, Hand enumhand) {
handler.call( () -> Arrays.asList(
((c, t) -> new EntityValue(player)),
((c, t) -> new EntityValue(entity))
(new EntityValue(player)),
(new EntityValue(entity))
), player::getCommandSource);
}
};
@@ -615,7 +613,7 @@ public class CarpetEventServer
@Override
public void onPlayerEvent(ServerPlayerEntity player)
{
handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource);
handler.call( () -> Collections.singletonList((new EntityValue(player))), player::getCommandSource);
}
};
public static final Event PLAYER_RESPAWNS = new Event("player_respawns", 1, false)
@@ -623,7 +621,7 @@ public class CarpetEventServer
@Override
public void onPlayerEvent(ServerPlayerEntity player)
{
handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource);
handler.call( () -> Collections.singletonList((new EntityValue(player))), player::getCommandSource);
}
};
public static final Event PLAYER_CHANGES_DIMENSION = new Event("player_changes_dimension", 5, false)
@@ -638,11 +636,11 @@ public class CarpetEventServer
Value toDimStr = new StringValue(NBTSerializableValue.nameFromRegistryId(dimTo.getValue()));
handler.call( () -> Arrays.asList(
((c, t) -> new EntityValue(player)),
((c, t) -> fromValue),
((c, t) -> fromDimStr),
((c, t) -> toValue),
((c, t) -> toDimStr)
(new EntityValue(player)),
(fromValue),
(fromDimStr),
(toValue),
(toDimStr)
), player::getCommandSource);
}
};
@@ -650,7 +648,7 @@ public class CarpetEventServer
@Override
public void onPlayerEvent(ServerPlayerEntity player)
{
handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource);
handler.call( () -> Collections.singletonList((new EntityValue(player))), player::getCommandSource);
}
};
public static final Event PLAYER_DISCONNECTS = new Event("player_disconnects", 2, false) {
@@ -658,8 +656,8 @@ public class CarpetEventServer
public void onPlayerMessage(ServerPlayerEntity player, String message)
{
handler.call( () -> Arrays.asList(
((c, t) -> new EntityValue(player)),
((c, t) -> new StringValue(message))
(new EntityValue(player)),
(new StringValue(message))
), player::getCommandSource);
}
};
@@ -680,10 +678,10 @@ public class CarpetEventServer
Identifier id = getStatId(stat);
if (skippedStats.contains(id)) return;
handler.call( () -> Arrays.asList(
((c, t) -> new EntityValue(player)),
((c, t) -> new StringValue(NBTSerializableValue.nameFromRegistryId(Registry.STAT_TYPE.getId(stat.getType())))),
((c, t) -> new StringValue(NBTSerializableValue.nameFromRegistryId(id))),
((c, t) -> new NumericValue(amount))
(new EntityValue(player)),
(new StringValue(NBTSerializableValue.nameFromRegistryId(Registry.STAT_TYPE.getId(stat.getType())))),
(new StringValue(NBTSerializableValue.nameFromRegistryId(id))),
(new NumericValue(amount))
), player::getCommandSource);
}
};
@@ -694,23 +692,30 @@ public class CarpetEventServer
{
handler.call(
() -> Arrays.asList(
((c, t) -> new BlockValue(null, world, pos)),
((c, t) -> flag>0?Value.TRUE:Value.FALSE)
(new BlockValue(null, world, pos)),
(flag>0?Value.TRUE:Value.FALSE)
), () -> CarpetServer.minecraft_server.getCommandSource().withWorld(world)
);
}
};
public static String getLoadEvent(EntityType<? extends Entity> et)
{
return "entity_loaded_" + Registry.ENTITY_TYPE.getId(et);
}
public static final Map<EntityType<?>, Event> ENTITY_LOAD= new HashMap<EntityType<?>, Event>() {{
public static final Map<EntityType<? extends Entity>, Event> ENTITY_LOAD= new HashMap<EntityType<? extends Entity>, Event>() {{
EntityType.get("zombie");
Registry.ENTITY_TYPE.forEach(et -> {
put(et, new Event("entity_loaded_" + Registry.ENTITY_TYPE.getId(et), 1, true, false)
put(et, new Event(getLoadEvent(et), 1, true, false)
{
@Override
public void onEntityAction(Entity entity)
{
super.onEntityAction(entity);
handler.call(
() -> Collections.singletonList((new EntityValue(entity))),
() -> CarpetServer.minecraft_server.getCommandSource().withWorld((ServerWorld) entity.world).withLevel(CarpetSettings.runPermissionLevel)
);
}
});
});
@@ -808,12 +813,13 @@ public class CarpetEventServer
return added;
}
public boolean addEventDirectly(String event, ScriptHost host, FunctionValue function)
public void addEventDirectly(String event, ScriptHost host, FunctionValue function, List<Value> args)
{
Event ev = Event.byName.get(event);
if (!canAddEvent(ev, host))
throw new InternalExpressionException("Global event "+event+" can only be added to apps with global scope");
return ev.handler.addEventCallDirect(host, function);
boolean success = ev.handler.addEventCallInternal(host, function, args);
if (!success) throw new InternalExpressionException("Global event "+event+" requires "+ev.handler.reqArgs+", not "+(function.getNumParams()-((args==null)?0:args.size())));
}
private boolean canAddEvent(Event event, ScriptHost host)
@@ -836,6 +842,16 @@ public class CarpetEventServer
Messenger.m(source, "gi Removed event: " + funName + " from "+event);
return true;
}
public boolean removeEventDirectly(String event, ScriptHost host)
{
if (!Event.byName.containsKey(event))
{
return false;
}
Event.byName.get(event).handler.removeAllCalls(host.getName());
return true;
}
public void removeEventDirectly(String event, ScriptHost host, String funName)
{
@@ -109,7 +109,7 @@ public class CarpetScriptHost extends ScriptHost
// this is nasty, we have the host and function, yet we add it via names, but hey - works for now
String event = funName.replaceFirst("__on_", "");
if (CarpetEventServer.Event.byName.containsKey(event))
scriptServer.events.addEventDirectly(event, this, function);
scriptServer.events.addEventDirectly(event, this, function, null);
}
else if (funName.equals("__config"))
{
@@ -305,12 +305,12 @@ public class CarpetScriptHost extends ScriptHost
}
}
public Value callUDF(BlockPos pos, ServerCommandSource source, FunctionValue fun, List<LazyValue> argv) throws InvalidCallbackException
public Value callUDF(BlockPos pos, ServerCommandSource source, FunctionValue fun, List<Value> argv) throws InvalidCallbackException
{
if (CarpetServer.scriptServer.stopAll)
return Value.NULL;
try { // cause we can't throw checked exceptions in lambda. Left if be until need to handle these more gracefully
fun.assertArgsOk(argv.size(), (b) -> {
fun.assertArgsOk(argv, (b) -> {
throw new InternalExpressionException("");
});
}
@@ -323,7 +323,7 @@ public class CarpetScriptHost extends ScriptHost
// TODO: this is just for now - invoke would be able to invoke other hosts scripts
Context context = new CarpetContext(this, source, pos);
return fun.getExpression().evalValue(
() -> fun.lazyEval(context, Context.VOID, fun.getExpression(), fun.getToken(), argv),
() -> fun.lazyEval(context, Context.VOID, fun.getExpression(), fun.getToken(), FunctionValue.lazify(argv)),
context,
Context.VOID);
}
@@ -334,6 +334,7 @@ public class CarpetScriptHost extends ScriptHost
return Value.NULL;
}
@Override
public void onClose()
{
@@ -268,12 +268,12 @@ public class CarpetScriptServer
return true;
}
public boolean runas(ServerCommandSource source, String hostname, FunctionValue udf, List<LazyValue> argv)
public boolean runas(ServerCommandSource source, String hostname, FunctionValue udf, List<Value> argv)
{
return runas(BlockPos.ORIGIN, source, hostname, udf, argv);
}
public boolean runas(BlockPos origin, ServerCommandSource source, String hostname, FunctionValue udf, List<LazyValue> argv)
public boolean runas(BlockPos origin, ServerCommandSource source, String hostname, FunctionValue udf, List<Value> argv)
{
CarpetScriptHost host = globalHost;
try
@@ -19,7 +19,7 @@ import java.util.Map;
public class EntityEventsGroup
{
private final Map<Event, Map<String, CarpetEventServer.ScheduledCall>> actions;
private final Map<Event, Map<String, CarpetEventServer.Callback>> actions;
private final Entity entity;
public EntityEventsGroup(Entity e)
{
@@ -30,35 +30,37 @@ public class EntityEventsGroup
public void onEvent(Event type, Object... args)
{
if (actions.isEmpty()) return; // most of the cases, trying to be nice
Map<String, CarpetEventServer.ScheduledCall> actionSet = actions.get(type);
Map<String, CarpetEventServer.Callback> actionSet = actions.get(type);
if (actionSet == null) return;
for (Iterator<Map.Entry<String, CarpetEventServer.ScheduledCall>> iterator = actionSet.entrySet().iterator(); iterator.hasNext(); )
for (Iterator<Map.Entry<String, CarpetEventServer.Callback>> iterator = actionSet.entrySet().iterator(); iterator.hasNext(); )
{
Map.Entry<String, CarpetEventServer.ScheduledCall> action = iterator.next();
Map.Entry<String, CarpetEventServer.Callback> action = iterator.next();
ScriptHost host = CarpetServer.scriptServer.getHostByName(action.getKey());
if (host == null)
{
iterator.remove();
continue;
}
type.call(action.getValue(), entity, args); // optionally remove when call failing
if (!type.call(action.getValue(), entity, args))
iterator.remove();
}
if (actionSet.isEmpty()) actions.remove(type);
}
public void addEvent(Event type, CarpetContext cc, FunctionValue fun, List<Value> extraargs)
public void addEvent(Event type, String hostName, FunctionValue fun, List<Value> extraargs)
{
if (fun != null)
{
CarpetEventServer.ScheduledCall call = type.create(cc, fun, extraargs);
CarpetEventServer.Callback call = type.create(hostName, fun, extraargs);
if (call == null)
throw new InternalExpressionException("wrong number of arguments for callback, required "+type.argcount);
actions.computeIfAbsent(type, k -> new HashMap<>()).put(cc.host.getName(), call);
actions.computeIfAbsent(type, k -> new HashMap<>()).put(hostName, call);
}
else
{
actions.computeIfAbsent(type, k -> new HashMap<>()).remove(cc.host.getName());
actions.computeIfAbsent(type, k -> new HashMap<>()).remove(hostName);
if (actions.get(type).isEmpty())
actions.remove(type);
}
@@ -105,18 +107,18 @@ public class EntityEventsGroup
argcount = args+1; // entity is not extra
byName.put(identifier, this);
}
public CarpetEventServer.ScheduledCall create(CarpetContext cc, FunctionValue function, List<Value> extraArgs)
public CarpetEventServer.Callback create(String hostName, FunctionValue function, List<Value> extraArgs)
{
if ((function.getArguments().size()-(extraArgs == null ? 0 : extraArgs.size())) != argcount)
{
return null;
}
return new CarpetEventServer.ScheduledCall(cc, function, extraArgs, 0);
return new CarpetEventServer.Callback(hostName, function, extraArgs);
}
public void call(CarpetEventServer.ScheduledCall tickCall, Entity entity, Object ... args)
public boolean call(CarpetEventServer.Callback tickCall, Entity entity, Object ... args)
{
assert args.length == argcount-1;
tickCall.execute(entity.getCommandSource(), makeArgs(entity, args));
return tickCall.execute(entity.getCommandSource(), makeArgs(entity, args));
}
protected List<Value> makeArgs(Entity entity, Object ... args)
{
@@ -640,7 +640,7 @@ public class Auxiliary {
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 functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, true, false);
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, true, false, true);
CarpetServer.scriptServer.events.scheduleCall(
(CarpetContext) c,
+37 -40
View File
@@ -1,6 +1,7 @@
package carpet.script.api;
import carpet.script.CarpetContext;
import carpet.script.CarpetEventServer;
import carpet.script.CarpetScriptHost;
import carpet.script.Expression;
import carpet.script.LazyValue;
@@ -11,7 +12,6 @@ import carpet.script.value.EntityValue;
import carpet.script.value.FunctionValue;
import carpet.script.value.ListValue;
import carpet.script.value.NBTSerializableValue;
import carpet.script.value.NullValue;
import carpet.script.value.NumericValue;
import carpet.script.value.Value;
import com.mojang.brigadier.StringReader;
@@ -29,13 +29,13 @@ import net.minecraft.util.Identifier;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.registry.Registry;
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class Entities {
@@ -119,7 +119,7 @@ public class Entities {
try
{
entityId = Identifier.fromCommandInput(new StringReader(entityString));
EntityType type = Registry.ENTITY_TYPE.getOrEmpty(entityId).orElse(null);
EntityType<? extends Entity> type = Registry.ENTITY_TYPE.getOrEmpty(entityId).orElse(null);
if (type == null || !type.isSummonable())
return LazyValue.NULL;
}
@@ -183,12 +183,8 @@ public class Entities {
expression.addLazyFunction("entity_list", 1, (c, t, lv) ->
{
String who = lv.get(0).evalValue(c).getString();
Pair<EntityType<?>, Predicate<? super Entity>> pair = EntityValue.getPredicate(who);
if (pair == null)
{
throw new InternalExpressionException("Unknown entity selection criterion: "+who);
}
List<Entity> entityList = ((CarpetContext)c).s.getWorld().getEntitiesByType(pair.getKey(), pair.getValue());
EntityValue.EntityClassDescriptor eDesc = EntityValue.getEntityDescriptor(who);
List<Entity> entityList = ((CarpetContext)c).s.getWorld().getEntitiesByType(eDesc.directType, eDesc.filteringPredicate);
Value retval = ListValue.wrap(entityList.stream().map(EntityValue::new).collect(Collectors.toList()));
return (_c, _t ) -> retval;
});
@@ -206,13 +202,8 @@ public class Entities {
throw new InternalExpressionException("Range of 'entity_area' cannot come from a block argument");
Vec3d range = rangeLocator.vec;
Box area = new Box(center, center).expand(range.x, range.y, range.z);
Pair<EntityType<?>, Predicate<? super Entity>> pair = EntityValue.getPredicate(who);
if (pair == null)
{
throw new InternalExpressionException("Unknown entity selection criterion: "+who);
}
List<Entity> entityList = ((CarpetContext)c).s.getWorld().getEntitiesByType((EntityType<Entity>) pair.getKey(), area, pair.getValue());
EntityValue.EntityClassDescriptor eDesc = EntityValue.getEntityDescriptor(who);
List<? extends Entity> entityList = ((CarpetContext)c).s.getWorld().getEntitiesByType(eDesc.directType, area,eDesc.filteringPredicate);
Value retval = ListValue.wrap(entityList.stream().map(EntityValue::new).collect(Collectors.toList()));
return (_c, _t ) -> retval;
});
@@ -268,15 +259,36 @@ public class Entities {
return (cc, tt) -> v;
});
expression.addFunction("entity_types", (lv) ->
{
if (lv.size() > 1) throw new InternalExpressionException("'entity_types' requires one or no arguments");
String desc = (lv.size() == 1)?lv.get(0).getString():"*";
return EntityValue.getEntityDescriptor(desc).listValue;
});
expression.addLazyFunction("entity_load_handler", -1, (c, t, lv) ->
{
if (lv.size() < 3) throw new InternalExpressionException("'entity_load_handler' required the entity type, and a function to call");
String entityString = lv.get(0).evalValue(c).getString();
FunctionArgument funArg = FunctionArgument.findIn(c, expression.module, lv, 2, true, true);
((CarpetScriptHost)c.host).getScriptServer().events.addEventDirectly(entityString, c.host, funArg.function);
};
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);
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).typeList));
FunctionArgument funArg = FunctionArgument.findIn(c, expression.module, lv, 1, false, true, false);
CarpetEventServer events = ((CarpetScriptHost)c.host).getScriptServer().events;
if (funArg.function == null)
{
types.forEach(et -> events.removeEventDirectly(CarpetEventServer.Event.getLoadEvent(et), c.host));
}
else
{
types.forEach(et -> events.addEventDirectly(CarpetEventServer.Event.getLoadEvent(et), c.host, funArg.function, FunctionValue.resolveArgs(funArg.args, c, t)));
}
Value ret = new NumericValue(types.size());
return (cc, tt) -> ret;
});
// or update
expression.addLazyFunction("entity_event", -1, (c, t, lv) ->
@@ -288,24 +300,9 @@ public class Entities {
throw new InternalExpressionException("First argument to entity_event should be an entity");
String what = lv.get(1).evalValue(c).getString();
Value functionValue = lv.get(2).evalValue(c);
if (functionValue instanceof NullValue)
functionValue = null;
else if (!(functionValue instanceof FunctionValue))
{
String name = functionValue.getString();
functionValue = c.host.getAssertFunction(expression.module, name);
}
FunctionValue function = (FunctionValue)functionValue;
List<Value> args = null;
if (lv.size()==4)
args = Collections.singletonList(lv.get(3).evalValue(c));
else if (lv.size()>4)
{
args = lv.subList(3, lv.size()).stream().map((vv) -> vv.evalValue(c)).collect(Collectors.toList());
}
FunctionArgument funArg = FunctionArgument.findIn(c, expression.module, lv, 2, false, true, false);
((EntityValue) v).setEvent((CarpetContext)c, what, function, args);
((EntityValue) v).setEvent((CarpetContext)c, what, funArg.function, FunctionValue.resolveArgs(funArg.args, c, t));
return LazyValue.NULL;
});
@@ -21,9 +21,34 @@ public class FunctionArgument extends Argument
this.function = function;
this.args = args;
}
public static FunctionArgument findIn(Context c, Module module, List<LazyValue> params, int offset, boolean prematureEvaluation, boolean allowNone)
/**
* @param c context
* @param module module
* @param params list of lazy params
* @param offset offset where to start looking for functional argument
* @param prematureEvaluation evaluates eagerly arguments in current context before returning
* @param allowNone none indicates no function present, otherwise it will croak
* @param checkArgs whether the caller expects trailing parameters to fully resolve function argument list
* if not - argument count check will not be performed and its up to the caller to verify
* if the number of supplied arguments is right
* @return argument data
*/
public static FunctionArgument findIn(
Context c,
Module module,
List<LazyValue> params,
int offset,
boolean prematureEvaluation,
boolean allowNone,
boolean checkArgs)
{
Value functionValue = params.get(offset).evalValue(c);
if (functionValue.isNull())
{
if (allowNone) return new FunctionArgument(null, offset+1, null);
throw new InternalExpressionException("function argument cannot be null");
}
if (!(functionValue instanceof FunctionValue))
{
String name = functionValue.getString();
@@ -31,11 +56,14 @@ public class FunctionArgument extends Argument
}
FunctionValue fun = (FunctionValue)functionValue;
int argsize = fun.getArguments().size();
int extraargs = params.size() - argsize - offset - 1;
if (extraargs < 0)
throw new InternalExpressionException("Function "+fun.getPrettyString()+" requires at least "+fun.getArguments().size()+" arguments");
if (extraargs > 0 && fun.getVarArgs()==null)
throw new InternalExpressionException("Function "+fun.getPrettyString()+" requires "+fun.getArguments().size()+" arguments");
if (checkArgs)
{
int extraargs = params.size() - argsize - offset - 1;
if (extraargs < 0)
throw new InternalExpressionException("Function " + fun.getPrettyString() + " requires at least " + fun.getArguments().size() + " arguments");
if (extraargs > 0 && fun.getVarArgs() == null)
throw new InternalExpressionException("Function " + fun.getPrettyString() + " requires " + fun.getArguments().size() + " arguments");
}
List<LazyValue> lvargs = new ArrayList<>();
if (prematureEvaluation)
{
@@ -43,7 +43,7 @@ public class Functions {
//lv.remove(lv.size()-1); // aint gonna cut it // maybe it will because of the eager eval changes
if (t != Context.SIGNATURE) // just call the function
{
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 0, false, false);
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 0, false, false, true);
FunctionValue fun = functionArgument.function;
Value retval = fun.callInContext(expr, c, t, fun.getExpression(), fun.getToken(), functionArgument.args).evalValue(c);
return (cc, tt) -> retval; ///!!!! dono might need to store expr and token in statics? (e? t?)
@@ -4,7 +4,6 @@ import carpet.script.Expression;
import carpet.script.argument.FunctionArgument;
import carpet.script.exception.ExitStatement;
import carpet.script.exception.InternalExpressionException;
import carpet.script.value.FunctionValue;
import carpet.script.value.NumericValue;
import carpet.script.value.ThreadValue;
import carpet.script.value.Value;
@@ -17,7 +16,7 @@ public class Threading
{
if (lv.size() == 0)
throw new InternalExpressionException("'task' requires at least function to call as a parameter");
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 0, true, false);
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 0, true, false, true);
ThreadValue thread = new ThreadValue(Value.NULL, functionArgument.function, expr, tok, c, functionArgument.args);
Thread.yield();
return (cc, tt) -> thread;
@@ -28,7 +27,7 @@ public class Threading
if (lv.size() < 2)
throw new InternalExpressionException("'task' requires at least function to call as a parameter");
Value queue = lv.get(0).evalValue(c);
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, true, false);
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, true, false, true);
ThreadValue thread = new ThreadValue(queue, functionArgument.function, expr, tok, c, functionArgument.args);
Thread.yield();
return (cc, tt) -> thread;
@@ -25,6 +25,7 @@ import net.minecraft.entity.EntityGroup;
import net.minecraft.entity.ai.brain.MemoryModuleType;
import net.minecraft.entity.ai.pathing.Path;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.packet.s2c.play.EntityPassengersSetS2CPacket;
@@ -191,117 +192,139 @@ public class EntityValue extends Value
return "entity";
}
@Override
public int hashCode()
{
return entity.hashCode();
}
public static Pair<EntityType<?>, Predicate<? super Entity>> getPredicate(String who)
public static EntityClassDescriptor getEntityDescriptor(String who)
{
Pair<EntityType<?>, Predicate<? super Entity>> res = entityPredicates.get(who);
if (res != null) return res;
return res; //TODO add more here like search by tags, or type
EntityClassDescriptor eDesc = EntityClassDescriptor.byName.get(who);
if (eDesc == null) throw new InternalExpressionException(who+" is not a valid entity descriptor");
return eDesc;
//TODO add more here like search by tags, or type
//if (who.startsWith('tag:'))
}
private static Map<String, EntityGroup> entityGroupMap = ImmutableMap.of(
"undead", EntityGroup.UNDEAD,
"arthropod", EntityGroup.ARTHROPOD,
"aquatic", EntityGroup.AQUATIC,
"regular", EntityGroup.DEFAULT,
"illager", EntityGroup.ILLAGER
);
public static class EntityClassDescriptor
{
public EntityType<?> directType;
public EntityType<? extends Entity> directType;
public Predicate<? super Entity> filteringPredicate;
public List<EntityType<?>> typeList;
EntityClassDescriptor(EntityType<?> type, Predicate<? super Entity> predicate, Stream<EntityType<?>> types)
public List<EntityType<? extends Entity>> typeList;
public Value listValue;
EntityClassDescriptor(EntityType<?> type, Predicate<? super Entity> predicate, List<EntityType<?>> types)
{
directType = type;
filteringPredicate = predicate;
typeList = types.collect(Collectors.toList());
typeList = types;
listValue = (types==null)?Value.NULL:ListValue.wrap(types.stream().map(et -> StringValue.of(nameFromRegistryId(Registry.ENTITY_TYPE.getId(et)))).collect(Collectors.toList()));
}
EntityClassDescriptor(EntityType<?> type, Predicate<? super Entity> predicate, Stream<EntityType<?>> types)
{
this(type, predicate, types.collect(Collectors.toList()));
}
public Map<String, EntityClassDescriptor> byName = new HashMap<String, EntityClassDescriptor>() {{
Stream<EntityType<?>> allTypes = Registry.ENTITY_TYPE.stream();
public final static Map<String, EntityClassDescriptor> byName = new HashMap<String, EntityClassDescriptor>() {{
List<EntityType<?>> allTypes = Registry.ENTITY_TYPE.stream().collect(Collectors.toList());
// nonliving types
Set<EntityType<?>> projectiles = Sets.newHashSet(
EntityType.ARROW, EntityType.DRAGON_FIREBALL
EntityType.ARROW, EntityType.DRAGON_FIREBALL, EntityType.FIREWORK_ROCKET,
EntityType.FIREBALL, EntityType.LLAMA_SPIT, EntityType.SMALL_FIREBALL,
EntityType.SNOWBALL, EntityType.SPECTRAL_ARROW, EntityType.EGG,
EntityType.ENDER_PEARL, EntityType.EXPERIENCE_BOTTLE, EntityType.POTION,
EntityType.TRIDENT, EntityType.WITHER_SKULL, EntityType.FISHING_BOBBER
);
Set<EntityType<?>> deads = Sets.newHashSet(
EntityType.AREA_EFFECT_CLOUD, EntityType.BOAT,
)
EntityType.AREA_EFFECT_CLOUD, EntityType.BOAT, EntityType.END_CRYSTAL,
EntityType.EVOKER_FANGS, EntityType.EXPERIENCE_ORB, EntityType.EYE_OF_ENDER,
EntityType.FALLING_BLOCK, EntityType.ITEM, EntityType.ITEM_FRAME,
EntityType.LEASH_KNOT, EntityType.LIGHTNING_BOLT, EntityType.PAINTING,
EntityType.TNT
);
Set<EntityType<?>> minecarts = Sets.newHashSet(
EntityType.MINECART, EntityType.CHEST_MINECART, EntityType.COMMAND_BLOCK_MINECART,
EntityType.FURNACE_MINECART, EntityType.HOPPER_MINECART,
EntityType.SPAWNER_MINECART, EntityType.TNT_MINECART
);
// living mob groups - non-defeault
Set<EntityType<?>> undeads = Sets.newHashSet(
EntityType.STRAY, EntityType.SKELETON, EntityType.WITHER_SKELETON,
EntityType.ZOMBIE, EntityType.DROWNED, EntityType.ZOMBIE_VILLAGER,
EntityType.ZOMBIE_HORSE, EntityType.SKELETON_HORSE, EntityType.PHANTOM,
EntityType.WITHER, EntityType.ZOGLIN, EntityType.HUSK, EntityType.ZOMBIFIED_PIGLIN
);
Set<EntityType<?>> arthropods = Sets.newHashSet(
EntityType.BEE, EntityType.ENDERMITE, EntityType.SILVERFISH, EntityType.SPIDER,
EntityType.CAVE_SPIDER
);
Set<EntityType<?>> aquatique = Sets.newHashSet(
EntityType.GUARDIAN, EntityType.TURTLE, EntityType.COD, EntityType.DOLPHIN, EntityType.PUFFERFISH,
EntityType.SALMON, EntityType.SQUID, EntityType.TROPICAL_FISH
);
Set<EntityType<?>> illagers = Sets.newHashSet(
EntityType.PILLAGER, EntityType.ILLUSIONER, EntityType.VINDICATOR, EntityType.EVOKER,
EntityType.RAVAGER, EntityType.WITCH
);
Set<EntityType<?>> living = allTypes.stream().filter(et ->
!deads.contains(et) && !projectiles.contains(et) && !minecarts.contains(et)
).collect(Collectors.toSet());
Set<EntityType<?>> regular = allTypes.stream().filter(et ->
living.contains(et) && !undeads.contains(et) && !arthropods.contains(et) && !aquatique.contains(et) && !illagers.contains(et)
).collect(Collectors.toSet());
put("*", new EntityClassDescriptor(null, e -> true, allTypes) );
put("valid", new EntityClassDescriptor(null, EntityPredicates.VALID_ENTITY, allTypes));
put("!valid", new EntityClassDescriptor(null, e -> !e.isAlive(), allTypes));
put("living", Pair.of(null, (e) -> e instanceof LivingEntity && e.isAlive(), allTypes.filter(et -> et.)));
put("!living", Pair.of(null, (e) -> !(e instanceof LivingEntity) && e.isAlive()));
put("living", new EntityClassDescriptor(null, (e) -> (e instanceof LivingEntity && e.isAlive()), allTypes.stream().filter(living::contains)));
put("!living", new EntityClassDescriptor(null, (e) -> (!(e instanceof LivingEntity) && e.isAlive()), allTypes.stream().filter(et -> !living.contains(et))));
put("projectile", Pair.of(null, (e) -> e instanceof ProjectileEntity && e.isAlive()));
put("!projectile", Pair.of(null, (e) -> !(e instanceof ProjectileEntity) && e.isAlive()));
put("projectile", new EntityClassDescriptor(null, (e) -> (e instanceof ProjectileEntity && e.isAlive()), allTypes.stream().filter(projectiles::contains)));
put("!projectile", new EntityClassDescriptor(null, (e) -> (!(e instanceof ProjectileEntity) && e.isAlive()), allTypes.stream().filter(et -> !projectiles.contains(et) && !living.contains(et))));
put("minecarts", new EntityClassDescriptor(null, (e) -> (e instanceof AbstractMinecartEntity && e.isAlive()), allTypes.stream().filter(minecarts::contains)));
put("!minecarts", new EntityClassDescriptor(null, (e) -> (!(e instanceof AbstractMinecartEntity) && e.isAlive()), allTypes.stream().filter(et -> !minecarts.contains(et) && !living.contains(et))));
// combat groups
put("arthropod", new EntityClassDescriptor(null, e -> ((e instanceof LivingEntity) && ((LivingEntity) e).getGroup() == EntityGroup.ARTHROPOD && e.isAlive()), allTypes.stream().filter(arthropods::contains)));
put("!arthropod", new EntityClassDescriptor(null, e -> ((e instanceof LivingEntity) && ((LivingEntity) e).getGroup() != EntityGroup.ARTHROPOD && e.isAlive()), allTypes.stream().filter(et -> !arthropods.contains(et) && living.contains(et))));
put("undead", new EntityClassDescriptor(null, e -> ((e instanceof LivingEntity) && ((LivingEntity) e).getGroup() == EntityGroup.UNDEAD && e.isAlive()), allTypes.stream().filter(undeads::contains)));
put("!undead", new EntityClassDescriptor(null, e -> ((e instanceof LivingEntity) && ((LivingEntity) e).getGroup() != EntityGroup.UNDEAD && e.isAlive()), allTypes.stream().filter(et -> !undeads.contains(et) && living.contains(et))));
put("aquatic", new EntityClassDescriptor(null, e -> ((e instanceof LivingEntity) && ((LivingEntity) e).getGroup() == EntityGroup.AQUATIC && e.isAlive()), allTypes.stream().filter(aquatique::contains)));
put("!aquatic", new EntityClassDescriptor(null, e -> ((e instanceof LivingEntity) && ((LivingEntity) e).getGroup() != EntityGroup.AQUATIC && e.isAlive()), allTypes.stream().filter(et -> !aquatique.contains(et) && living.contains(et))));
put("illager", new EntityClassDescriptor(null, e -> ((e instanceof LivingEntity) && ((LivingEntity) e).getGroup() == EntityGroup.ILLAGER && e.isAlive()), allTypes.stream().filter(illagers::contains)));
put("!illager", new EntityClassDescriptor(null, e -> ((e instanceof LivingEntity) && ((LivingEntity) e).getGroup() != EntityGroup.ILLAGER && e.isAlive()), allTypes.stream().filter(et -> !illagers.contains(et) && living.contains(et))));
put("regular", new EntityClassDescriptor(null, e -> ((e instanceof LivingEntity) && ((LivingEntity) e).getGroup() == EntityGroup.DEFAULT && e.isAlive()), allTypes.stream().filter(regular::contains)));
put("!regular", new EntityClassDescriptor(null, e -> ((e instanceof LivingEntity) && ((LivingEntity) e).getGroup() != EntityGroup.DEFAULT && e.isAlive()), allTypes.stream().filter(et -> !regular.contains(et) && living.contains(et))));
for (String groupStr : entityGroupMap.keySet())
{
EntityGroup group = entityGroupMap.get(groupStr);
put( groupStr, Pair.of(null, e -> ((e instanceof LivingEntity) && ((LivingEntity) e).getGroup() == group && e.isAlive())));
put("!"+groupStr, Pair.of(null, e -> ((e instanceof LivingEntity) && ((LivingEntity) e).getGroup() != group && e.isAlive())));
}
for (Identifier typeId : Registry.ENTITY_TYPE.getIds())
{
EntityType type = Registry.ENTITY_TYPE.get(typeId);
EntityType<?> type = Registry.ENTITY_TYPE.get(typeId);
String mobType = ValueConversions.simplify(typeId);
put( mobType, Pair.of(type, EntityPredicates.VALID_ENTITY));
put("!"+mobType, Pair.of(null, (e) -> e.getType() != type && e.isAlive()));
put( mobType, new EntityClassDescriptor(type, EntityPredicates.VALID_ENTITY, Stream.of(type)));
put("!"+mobType, new EntityClassDescriptor(null, (e) -> e.getType() != type && e.isAlive(), allTypes.stream().filter(et -> et != type)));
}
for (SpawnGroup catId : SpawnGroup.values())
{
String catStr = catId.getName();
put( catStr, Pair.of(null, e -> (e.getType().getSpawnGroup() == catId) && e.isAlive()));
put("!"+catStr, Pair.of(null, e -> (e.getType().getSpawnGroup() != catId) && e.isAlive()));
put( catStr, new EntityClassDescriptor(null, e -> ((e.getType().getSpawnGroup() == catId) && e.isAlive()), allTypes.stream().filter(et -> et.getSpawnGroup() == catId)));
put("!"+catStr, new EntityClassDescriptor(null, e -> ((e.getType().getSpawnGroup() != catId) && e.isAlive()), allTypes.stream().filter(et -> et.getSpawnGroup() != catId)));
}
}}
}};
}
private static final Map<String, Pair<EntityType<?>, Predicate<? super Entity>>> entityPredicates =
new HashMap<String, Pair<EntityType<?>, Predicate<? super Entity>>>()
{{
put("*", Pair.of(null, e -> true));
put("valid", Pair.of(null, EntityPredicates.VALID_ENTITY));
put("!valid", Pair.of(null, e -> !e.isAlive()));
put("living", Pair.of(null, (e) -> e instanceof LivingEntity && e.isAlive()));
put("!living", Pair.of(null, (e) -> !(e instanceof LivingEntity) && e.isAlive()));
put("projectile", Pair.of(null, (e) -> e instanceof ProjectileEntity && e.isAlive()));
put("!projectile", Pair.of(null, (e) -> !(e instanceof ProjectileEntity) && e.isAlive()));
for (String groupStr : entityGroupMap.keySet())
{
EntityGroup group = entityGroupMap.get(groupStr);
put( groupStr, Pair.of(null, e -> ((e instanceof LivingEntity) && ((LivingEntity) e).getGroup() == group && e.isAlive())));
put("!"+groupStr, Pair.of(null, e -> ((e instanceof LivingEntity) && ((LivingEntity) e).getGroup() != group && e.isAlive())));
}
for (Identifier typeId : Registry.ENTITY_TYPE.getIds())
{
EntityType type = Registry.ENTITY_TYPE.get(typeId);
String mobType = ValueConversions.simplify(typeId);
put( mobType, Pair.of(type, EntityPredicates.VALID_ENTITY));
put("!"+mobType, Pair.of(null, (e) -> e.getType() != type && e.isAlive()));
}
for (SpawnGroup catId : SpawnGroup.values())
{
String catStr = catId.getName();
put( catStr, Pair.of(null, e -> (e.getType().getSpawnGroup() == catId) && e.isAlive()));
put("!"+catStr, Pair.of(null, e -> (e.getType().getSpawnGroup() != catId) && e.isAlive()));
}
}};
public Value get(String what, Value arg)
{
if (!(featureAccessors.containsKey(what)))
@@ -1323,7 +1346,7 @@ public class EntityValue extends Value
EntityEventsGroup.Event event = EntityEventsGroup.Event.byName.get(eventName);
if (event == null)
throw new InternalExpressionException("Unknown entity event: " + eventName);
((EntityInterface)entity).getEventContainer().addEvent(event, cc, fun, args);
((EntityInterface)entity).getEventContainer().addEvent(event, cc.host.getName(), fun, args);
}
@Override
@@ -24,13 +24,13 @@ import java.util.stream.Collectors;
public class FunctionValue extends Value implements Fluff.ILazyFunction
{
private Expression expression;
private Tokenizer.Token token;
private String name;
private LazyValue body;
private final Expression expression;
private final Tokenizer.Token token;
private final String name;
private final LazyValue body;
private Map<String, LazyValue> outerState;
private List<String> args;
private String varArgs;
private final List<String> args;
private final String varArgs;
private static long variantCounter = 1;
private long variant;
@@ -99,8 +99,6 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
return name.hashCode()+(int)variant;
}
@Override
public boolean equals(Object o)
{
@@ -178,7 +176,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
@Override
public LazyValue lazyEval(Context c, Integer type, Expression e, Tokenizer.Token t, List<LazyValue> lazyParams)
{
assertArgsOk(lazyParams.size(), (fixedArgs) ->{
assertArgsOk(lazyParams, (fixedArgs) ->{
if (fixedArgs) // wrong number of args for fixed args
{
throw new ExpressionException(c, e, t,
@@ -264,8 +262,9 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
return StringTag.of(getString());
}
public void assertArgsOk(int size, Consumer<Boolean> feedback)
public void assertArgsOk(List<?> list, Consumer<Boolean> feedback)
{
int size = list==null?0:list.size();
if (varArgs == null && args.size() != size) // wrong number of args for fixed args
{
feedback.accept(true);
@@ -276,4 +275,17 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
feedback.accept(false);
}
}
public static List<Value> resolveArgs(List<LazyValue> lzargs, Context c, Integer t)
{
List<Value> args = new ArrayList<>(lzargs.size());
lzargs.forEach( v -> args.add( v.evalValue(c, t)));
return args;
}
public static List<LazyValue> lazify(List<Value> args)
{
List<LazyValue> lzargs = new ArrayList<>(args.size());
args.forEach( v -> lzargs.add( (c, t) -> v));
return lzargs;
}
}