From 6505afdfdbaf88692cbea63903d54186898ca988 Mon Sep 17 00:00:00 2001 From: gnembon Date: Thu, 25 Jul 2019 14:10:01 -0300 Subject: [PATCH] better entity events, untested --- .../java/carpet/fakes/EntityInterface.java | 9 +++- .../mixins/Entity_scarpetEventsMixin.java | 32 +++++++++++- .../java/carpet/script/CarpetEventServer.java | 50 +++++++++++++++---- .../java/carpet/script/CarpetExpression.java | 22 +++++--- src/main/java/carpet/script/Fluff.java | 3 ++ .../java/carpet/script/value/EntityValue.java | 9 ++-- 6 files changed, 100 insertions(+), 25 deletions(-) diff --git a/src/main/java/carpet/fakes/EntityInterface.java b/src/main/java/carpet/fakes/EntityInterface.java index 6b4a4d0f..723e5425 100644 --- a/src/main/java/carpet/fakes/EntityInterface.java +++ b/src/main/java/carpet/fakes/EntityInterface.java @@ -3,13 +3,18 @@ package carpet.fakes; import carpet.script.CarpetContext; import carpet.script.CarpetEventServer; import carpet.script.ScriptHost; +import carpet.script.value.Value; + +import java.util.List; public interface EntityInterface { float getMainYaw(float partialTicks); //scarpet part void onDeathCallback(String reason); - void setDeathCallback(CarpetContext cc, String function); + void setDeathCallback(CarpetContext cc, String function, List extraArgs); void onDamageCallback(); - void setDamageCallback(CarpetEventServer.ScheduledCall call); + void setDamageCallback(CarpetContext cc, String function, List extraArgs); + void onRemovedCallback(); + void setRemovedCallback(CarpetContext cc, String function, List extraArgs); } diff --git a/src/main/java/carpet/mixins/Entity_scarpetEventsMixin.java b/src/main/java/carpet/mixins/Entity_scarpetEventsMixin.java index 0ee90509..bb798e6c 100644 --- a/src/main/java/carpet/mixins/Entity_scarpetEventsMixin.java +++ b/src/main/java/carpet/mixins/Entity_scarpetEventsMixin.java @@ -5,14 +5,26 @@ import carpet.fakes.EntityInterface; import carpet.script.CarpetContext; import carpet.script.CarpetEventServer; import carpet.script.ScriptHost; +import carpet.script.value.Value; import carpet.settings.CarpetSettings; import net.minecraft.entity.Entity; +import org.lwjgl.system.CallbackI; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; @Mixin(Entity.class) public abstract class Entity_scarpetEventsMixin implements EntityInterface { + @Shadow public boolean removed; private CarpetEventServer.ScheduledCall deathCall; + private CarpetEventServer.ScheduledCall removeCall; + + @Override public void onDeathCallback(String reason) { @@ -23,8 +35,24 @@ public abstract class Entity_scarpetEventsMixin implements EntityInterface } @Override - public void setDeathCallback(CarpetContext cc, String function) + public void setDeathCallback(CarpetContext cc, String function, List extraArgs) { - deathCall = CarpetServer.scriptServer.events.makeDeathCall(cc, function); + deathCall = CarpetServer.scriptServer.events.makeDeathCall(cc, function, extraArgs); + } + + @Override + public void setRemovedCallback(CarpetContext cc, String function, List extraArgs) + { + removeCall = CarpetServer.scriptServer.events.makeRemovedCall(cc, function, extraArgs); + } + + + @Inject(method = "remove", at = @At("HEAD")) + private void onRemove(CallbackInfo ci) + { + if (!removed && removeCall != null) + { + CarpetServer.scriptServer.events.onEntityRemoved(removeCall, (Entity)(Object)this); + } } } diff --git a/src/main/java/carpet/script/CarpetEventServer.java b/src/main/java/carpet/script/CarpetEventServer.java index e4b0fd0e..b0839442 100644 --- a/src/main/java/carpet/script/CarpetEventServer.java +++ b/src/main/java/carpet/script/CarpetEventServer.java @@ -6,6 +6,7 @@ import carpet.script.value.EntityValue; import carpet.script.value.ListValue; import carpet.script.value.NumericValue; import carpet.script.value.StringValue; +import carpet.script.value.Value; import carpet.settings.CarpetSettings; import net.minecraft.block.BlockState; import net.minecraft.nbt.CompoundTag; @@ -34,6 +35,7 @@ import java.util.Map; import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; public class CarpetEventServer { @@ -78,7 +80,15 @@ public class CarpetEventServer public void execute(List args) { - CarpetServer.scriptServer.runas(context_origin, context_source, host, udf, args); + if (this.args == null) + CarpetServer.scriptServer.runas(context_origin, context_source, host, udf, args); + else + { + List combinedArgs = new ArrayList<>(); + combinedArgs.addAll(args); + combinedArgs.addAll(this.args); + CarpetServer.scriptServer.runas(context_origin, context_source, host, udf, combinedArgs); + } } } @@ -221,6 +231,24 @@ public class CarpetEventServer return new Callback(null, funName); } + private ScheduledCall makeEventCall(CarpetContext cc, String function, List extraArgs, int argCount) + { + UserDefinedFunction udf = cc.host.globalFunctions.get(function); + if (udf == null || udf.getArguments().size() != argCount) + { + // call won't match arguments + return null; + } + List lazyArgs = null; + if (extraArgs != null) + { + lazyArgs = new ArrayList<>(); + for (Value v : extraArgs) + lazyArgs.add( (c, t) -> v); + } + return new ScheduledCall(cc, function, lazyArgs, 0); + } + public void onTick() { eventHandlers.get("tick").call(Collections::emptyList, CarpetServer.minecraft_server::getCommandSource); @@ -354,19 +382,23 @@ public class CarpetEventServer eventHandlers.get("player_stops_sprinting").call( () -> Arrays.asList(((c, t) -> new EntityValue(player))), player::getCommandSource); } - public ScheduledCall makeDeathCall(CarpetContext cc, String function) + public ScheduledCall makeDeathCall(CarpetContext cc, String function, List extraArgs) { - UserDefinedFunction udf = cc.host.globalFunctions.get(function); - if (udf == null || udf.getArguments().size() != 2) - { - // call won't match arguments - return null; - } - return new ScheduledCall(cc, function, null, 0); + return makeEventCall(cc, function, extraArgs, 2); } + public ScheduledCall makeRemovedCall(CarpetContext cc, String function, List extraArgs) + { + return makeEventCall(cc, function, extraArgs, 1); + } + public void onEntityDeath(ScheduledCall call, Entity e, String reason) { call.execute( Arrays.asList( (c, t)-> new EntityValue(e), (c, t)-> new StringValue(reason))); } + public void onEntityRemoved(ScheduledCall removeCall, Entity entity) + { + removeCall.execute(Collections.singletonList((c, t) -> new EntityValue(entity))); + } + } diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index 8bb4fb06..d6e9c534 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -3,7 +3,6 @@ package carpet.script; import carpet.CarpetServer; import carpet.fakes.MinecraftServerInterface; import carpet.helpers.FeatureGenerator; -import carpet.helpers.Tracer; import carpet.script.Fluff.TriFunction; import carpet.script.exception.CarpetExpressionException; import carpet.script.exception.ExpressionException; @@ -50,7 +49,6 @@ import net.minecraft.item.BlockItem; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.Tag; import net.minecraft.particle.ParticleEffect; import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.server.MinecraftServer; @@ -65,9 +63,6 @@ import net.minecraft.text.LiteralText; import net.minecraft.text.TranslatableText; import net.minecraft.util.Clearable; import net.minecraft.util.Identifier; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; import net.minecraft.util.math.EulerAngle; @@ -84,7 +79,7 @@ import org.apache.commons.lang3.tuple.Pair; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -1806,8 +1801,10 @@ public class CarpetExpression }); // or update - this.expr.addLazyFunction("entity_event", 3, (c, t, lv) -> + this.expr.addLazyFunction("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); if (!(v instanceof EntityValue)) throw new InternalExpressionException("First argument to get should be an entity"); @@ -1816,7 +1813,16 @@ public class CarpetExpression String function = null; if (!(functionValue instanceof NullValue)) function = functionValue.getString(); - ((EntityValue) v).setEvent((CarpetContext)c, what, function); + List args = null; + if (lv.size()==4) + args = Collections.singletonList(lv.get(3).evalValue(c)); + else if (lv.size()>4) + { + args = new ArrayList<>(lv.subList(3, lv.size()).stream().map((vv) -> vv.evalValue(c)).collect(Collectors.toList())); + } + + ((EntityValue) v).setEvent((CarpetContext)c, what, function, args); + return LazyValue.NULL; }); } diff --git a/src/main/java/carpet/script/Fluff.java b/src/main/java/carpet/script/Fluff.java index 93b0ca60..77dc72b1 100644 --- a/src/main/java/carpet/script/Fluff.java +++ b/src/main/java/carpet/script/Fluff.java @@ -15,6 +15,9 @@ public abstract class Fluff @FunctionalInterface public interface TriConsumer { void accept(A a, B b, C c); } + @FunctionalInterface + public interface QuadConsumer { void accept(A a, B b, C c, D d); } + @FunctionalInterface public interface QuadFunction { R apply(A a, B b, C c, D d);} diff --git a/src/main/java/carpet/script/value/EntityValue.java b/src/main/java/carpet/script/value/EntityValue.java index 4c27b140..7d5952ea 100644 --- a/src/main/java/carpet/script/value/EntityValue.java +++ b/src/main/java/carpet/script/value/EntityValue.java @@ -704,14 +704,15 @@ public class EntityValue extends Value // "nbt" <-big one, for now use run('data merge entity ... }}; - public void setEvent(CarpetContext cc, String event, String fun) + public void setEvent(CarpetContext cc, String event, String fun, List args) { if (!(events.containsKey(event))) throw new InternalExpressionException("unknown entity event: " + event); - events.get(event).accept(cc, entity, fun); + events.get(event).accept(cc, entity, fun, args); } - private static Map> events = new HashMap>() {{ - put("on_death", (c, e, f) -> { ((EntityInterface)e).setDeathCallback(c, f); }); + private static Map>> events = new HashMap>>() {{ + put("on_death", (c, e, f, l) -> ((EntityInterface)e).setDeathCallback(c, f, l)); + put("on_removed", (c, e, f, l) -> ((EntityInterface)e).setRemovedCallback(c, f, l)); }}; }