refactor entity events. Allow multiple hosts have events on things
This commit is contained in:
1 parent
1c35f5b6a9
commit
afd7952a62
11 files changed
+190
-186
No files matched your search
@@ -15,7 +15,6 @@ import com.mojang.brigadier.CommandDispatcher;
|
|||||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
import com.mojang.brigadier.context.CommandContext;
|
import com.mojang.brigadier.context.CommandContext;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|
||||||
import com.mojang.brigadier.suggestion.Suggestions;
|
import com.mojang.brigadier.suggestion.Suggestions;
|
||||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
@@ -26,7 +25,6 @@ import net.minecraft.command.arguments.BlockStateArgument;
|
|||||||
import net.minecraft.command.arguments.BlockStateArgumentType;
|
import net.minecraft.command.arguments.BlockStateArgumentType;
|
||||||
import net.minecraft.server.command.ServerCommandSource;
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
|
||||||
import net.minecraft.util.Clearable;
|
import net.minecraft.util.Clearable;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
@@ -305,7 +303,7 @@ public class ScriptCommand
|
|||||||
Messenger.m(source, "w Handlers for "+event.name+": ");
|
Messenger.m(source, "w Handlers for "+event.name+": ");
|
||||||
shownEvent = true;
|
shownEvent = true;
|
||||||
}
|
}
|
||||||
Messenger.m(source, "w - "+c.udf+(c.host==null?"":" (from "+c.host+")"));
|
Messenger.m(source, "w - "+c.function +(c.host==null?"":" (from "+c.host+")"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -1,22 +1,10 @@
|
|||||||
package carpet.fakes;
|
package carpet.fakes;
|
||||||
|
|
||||||
import carpet.script.CarpetContext;
|
import carpet.script.EntityEventsGroup;
|
||||||
import carpet.script.CarpetEventServer;
|
|
||||||
import carpet.script.value.FunctionValue;
|
|
||||||
import carpet.script.value.Value;
|
|
||||||
import net.minecraft.entity.damage.DamageSource;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface EntityInterface
|
public interface EntityInterface
|
||||||
{
|
{
|
||||||
float getMainYaw(float partialTicks);
|
float getMainYaw(float partialTicks);
|
||||||
//scarpet part
|
|
||||||
void onDeathCallback(String reason);
|
EntityEventsGroup getEventContainer();
|
||||||
void setDeathCallback(CarpetContext cc, FunctionValue function, List<Value> extraArgs);
|
|
||||||
void onDamageCallback(float amount, DamageSource source);
|
|
||||||
void setDamageCallback(CarpetContext cc, FunctionValue function, List<Value> extraArgs);
|
|
||||||
void setRemovedCallback(CarpetContext cc, FunctionValue function, List<Value> extraArgs);
|
|
||||||
void setTickCallback(CarpetContext cc, FunctionValue function, List<Value> extraArgs);
|
|
||||||
CarpetEventServer.ScheduledCall getTickCallback();
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package carpet.mixins;
|
package carpet.mixins;
|
||||||
|
|
||||||
import carpet.fakes.EntityInterface;
|
import carpet.fakes.EntityInterface;
|
||||||
|
import carpet.script.EntityEventsGroup;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.damage.DamageSource;
|
import net.minecraft.entity.damage.DamageSource;
|
||||||
import net.minecraft.entity.damage.DamageTracker;
|
import net.minecraft.entity.damage.DamageTracker;
|
||||||
@@ -19,6 +20,6 @@ public class DamageTracker_scarpetEventMixin
|
|||||||
@Inject(method = "onDamage", at = @At("HEAD"))
|
@Inject(method = "onDamage", at = @At("HEAD"))
|
||||||
private void onDamageTaken(DamageSource damageSource_1, float float_1, float float_2, CallbackInfo ci)
|
private void onDamageTaken(DamageSource damageSource_1, float float_1, float float_2, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
((EntityInterface)entity).onDamageCallback(float_2, damageSource_1);
|
((EntityInterface)entity).getEventContainer().onEvent(EntityEventsGroup.EntityEventType.ON_DAMAGE, entity, float_2, damageSource_1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,96 +1,37 @@
|
|||||||
package carpet.mixins;
|
package carpet.mixins;
|
||||||
|
|
||||||
import carpet.CarpetServer;
|
|
||||||
import carpet.fakes.EntityInterface;
|
import carpet.fakes.EntityInterface;
|
||||||
import carpet.script.CarpetContext;
|
import carpet.script.EntityEventsGroup;
|
||||||
import carpet.script.CarpetEventServer;
|
|
||||||
import carpet.script.value.FunctionValue;
|
|
||||||
import carpet.script.value.Value;
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.damage.DamageSource;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Mixin(Entity.class)
|
@Mixin(Entity.class)
|
||||||
public abstract class Entity_scarpetEventsMixin implements EntityInterface
|
public abstract class Entity_scarpetEventsMixin implements EntityInterface
|
||||||
{
|
{
|
||||||
@Shadow public boolean removed;
|
@Shadow public boolean removed;
|
||||||
private CarpetEventServer.ScheduledCall deathCall;
|
|
||||||
private CarpetEventServer.ScheduledCall removeCall;
|
private EntityEventsGroup events = new EntityEventsGroup();
|
||||||
private CarpetEventServer.ScheduledCall tickCall;
|
|
||||||
private CarpetEventServer.ScheduledCall damageCall;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDeathCallback(CarpetContext cc, FunctionValue function, List<Value> extraArgs)
|
public EntityEventsGroup getEventContainer()
|
||||||
{
|
{
|
||||||
deathCall = CarpetServer.scriptServer.events.makeDeathCall(cc, function, extraArgs);
|
return events;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRemovedCallback(CarpetContext cc, FunctionValue function, List<Value> extraArgs)
|
|
||||||
{
|
|
||||||
removeCall = CarpetServer.scriptServer.events.makeRemovedCall(cc, function, extraArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setTickCallback(CarpetContext cc, FunctionValue function, List<Value> extraArgs)
|
|
||||||
{
|
|
||||||
tickCall = CarpetServer.scriptServer.events.makeTickCall(cc, function, extraArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CarpetEventServer.ScheduledCall getTickCallback()
|
|
||||||
{
|
|
||||||
return tickCall;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDamageCallback(CarpetContext cc, FunctionValue function, List<Value> extraArgs)
|
|
||||||
{
|
|
||||||
damageCall = CarpetServer.scriptServer.events.makeDamageCall(cc, function, extraArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDeathCallback(String reason)
|
|
||||||
{
|
|
||||||
if (deathCall != null)
|
|
||||||
{
|
|
||||||
CarpetServer.scriptServer.events.onEntityDeath(deathCall, (Entity)(Object)this, reason);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDamageCallback(float amount, DamageSource source)
|
|
||||||
{
|
|
||||||
if (damageCall != null)
|
|
||||||
{
|
|
||||||
CarpetServer.scriptServer.events.onEntityDamage(damageCall, (Entity)(Object)this, amount, source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Inject(method = "tick", at = @At("HEAD"))
|
@Inject(method = "tick", at = @At("HEAD"))
|
||||||
private void onTickCall(CallbackInfo ci)
|
private void onTickCall(CallbackInfo ci)
|
||||||
{
|
{
|
||||||
if (tickCall != null)
|
events.onEvent(EntityEventsGroup.EntityEventType.ON_TICK, (Entity) (Object) this);
|
||||||
{
|
|
||||||
CarpetServer.scriptServer.events.onEntityTick(tickCall, (Entity) (Object) this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Inject(method = "remove", at = @At("HEAD"))
|
@Inject(method = "remove", at = @At("HEAD"))
|
||||||
private void onRemove(CallbackInfo ci)
|
private void onRemove(CallbackInfo ci)
|
||||||
{
|
{
|
||||||
if (!removed && removeCall != null)
|
if (!removed) events.onEvent(EntityEventsGroup.EntityEventType.ON_REMOVED, (Entity) (Object) this);
|
||||||
{
|
|
||||||
CarpetServer.scriptServer.events.onEntityRemoved(removeCall, (Entity)(Object)this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,23 +1,28 @@
|
|||||||
package carpet.mixins;
|
package carpet.mixins;
|
||||||
|
|
||||||
import carpet.CarpetServer;
|
|
||||||
import carpet.fakes.EntityInterface;
|
import carpet.fakes.EntityInterface;
|
||||||
|
import carpet.script.EntityEventsGroup;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraft.entity.FallingBlockEntity;
|
import net.minecraft.entity.FallingBlockEntity;
|
||||||
|
import net.minecraft.world.World;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
@Mixin(FallingBlockEntity.class)
|
@Mixin(FallingBlockEntity.class)
|
||||||
public class FallingBlockEntity_scarpetEventsMixin
|
public abstract class FallingBlockEntity_scarpetEventsMixin extends Entity
|
||||||
{
|
{
|
||||||
|
public FallingBlockEntity_scarpetEventsMixin(EntityType<?> type, World world)
|
||||||
|
{
|
||||||
|
super(type, world);
|
||||||
|
}
|
||||||
|
|
||||||
@Inject(method = "tick", at = @At("HEAD"))
|
@Inject(method = "tick", at = @At("HEAD"))
|
||||||
private void onTickCall(CallbackInfo ci)
|
private void onTickCall(CallbackInfo ci)
|
||||||
{
|
{
|
||||||
if (((EntityInterface)this).getTickCallback() != null)
|
// calling extra on_tick because falling blocks do not fall back to super tick call
|
||||||
{
|
((EntityInterface)this).getEventContainer().onEvent(EntityEventsGroup.EntityEventType.ON_TICK, this);
|
||||||
CarpetServer.scriptServer.events.onEntityTick(((EntityInterface)this).getTickCallback(), (Entity) (Object) this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package carpet.mixins;
|
package carpet.mixins;
|
||||||
|
|
||||||
import carpet.fakes.EntityInterface;
|
import carpet.fakes.EntityInterface;
|
||||||
|
import carpet.script.EntityEventsGroup;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
@@ -12,12 +13,17 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
@Mixin(LivingEntity.class)
|
@Mixin(LivingEntity.class)
|
||||||
public abstract class LivingEntity_scarpetEventsMixin
|
public abstract class LivingEntity_scarpetEventsMixin extends Entity
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public LivingEntity_scarpetEventsMixin(EntityType<?> type, World world)
|
||||||
|
{
|
||||||
|
super(type, world);
|
||||||
|
}
|
||||||
|
|
||||||
@Inject(method = "onDeath", at = @At("HEAD"))
|
@Inject(method = "onDeath", at = @At("HEAD"))
|
||||||
private void onDeathCall(DamageSource damageSource_1, CallbackInfo ci)
|
private void onDeathCall(DamageSource damageSource_1, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
((EntityInterface)this).onDeathCallback(damageSource_1.name);
|
((EntityInterface)this).getEventContainer().onEvent(EntityEventsGroup.EntityEventType.ON_DEATH, this, damageSource_1.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,7 +9,6 @@ import carpet.script.value.NumericValue;
|
|||||||
import carpet.script.value.StringValue;
|
import carpet.script.value.StringValue;
|
||||||
import carpet.script.value.Value;
|
import carpet.script.value.Value;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.entity.damage.DamageSource;
|
|
||||||
import net.minecraft.server.command.ServerCommandSource;
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
@@ -33,6 +32,7 @@ import java.util.Map;
|
|||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class CarpetEventServer
|
public class CarpetEventServer
|
||||||
{
|
{
|
||||||
@@ -41,54 +41,56 @@ public class CarpetEventServer
|
|||||||
public static class Callback
|
public static class Callback
|
||||||
{
|
{
|
||||||
public String host;
|
public String host;
|
||||||
public FunctionValue udf;
|
public FunctionValue function;
|
||||||
|
|
||||||
public Callback(String host, FunctionValue udf)
|
public Callback(String host, FunctionValue function)
|
||||||
{
|
{
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.udf = udf;
|
this.function = function;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return udf.getString()+((host==null)?"":"(from "+host+")");
|
return function.getString()+((host==null)?"":"(from "+host+")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ScheduledCall extends Callback
|
public static class ScheduledCall extends Callback
|
||||||
{
|
{
|
||||||
public List<LazyValue> args;
|
public List<Value> args;
|
||||||
public ServerCommandSource context_source;
|
private CarpetContext ctx;
|
||||||
public BlockPos context_origin;
|
|
||||||
public long dueTime;
|
public long dueTime;
|
||||||
|
|
||||||
public ScheduledCall(CarpetContext context, FunctionValue udf, List<LazyValue> args, long dueTime)
|
public ScheduledCall(CarpetContext context, FunctionValue function, List<Value> args, long dueTime)
|
||||||
{
|
{
|
||||||
super(context.host.getName(), udf);
|
super(context.host.getName(), function);
|
||||||
this.args = args;
|
this.args = args;
|
||||||
this.context_source = context.s;
|
this.ctx = context;
|
||||||
this.context_origin = context.origin;
|
|
||||||
this.dueTime = dueTime;
|
this.dueTime = dueTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void execute()
|
public void execute()
|
||||||
{
|
{
|
||||||
CarpetServer.scriptServer.runas(context_origin, context_source, host, udf, args);
|
CarpetServer.scriptServer.runas(ctx.origin, ctx.s, host, function, lazify(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void execute(List<LazyValue> args)
|
public void execute(List<Value> args)
|
||||||
{
|
{
|
||||||
if (this.args == null)
|
if (this.args == null || this.args.isEmpty())
|
||||||
CarpetServer.scriptServer.runas(context_origin, context_source, host, udf, args);
|
CarpetServer.scriptServer.runas(ctx.origin, ctx.s, host, function, lazify(args));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
List<LazyValue> combinedArgs = new ArrayList<>();
|
List<Value> combinedArgs = new ArrayList<>();
|
||||||
combinedArgs.addAll(args);
|
combinedArgs.addAll(args);
|
||||||
combinedArgs.addAll(this.args);
|
combinedArgs.addAll(this.args);
|
||||||
CarpetServer.scriptServer.runas(context_origin, context_source, host, udf, combinedArgs);
|
CarpetServer.scriptServer.runas(ctx.origin, ctx.s, 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
|
public static class CallbackList
|
||||||
@@ -110,7 +112,7 @@ public class CarpetEventServer
|
|||||||
List<LazyValue> argv = argumentSupplier.get(); // empty for onTickDone
|
List<LazyValue> argv = argumentSupplier.get(); // empty for onTickDone
|
||||||
ServerCommandSource source = cmdSourceSupplier.get();
|
ServerCommandSource source = cmdSourceSupplier.get();
|
||||||
assert argv.size() == reqArgs;
|
assert argv.size() == reqArgs;
|
||||||
callList.removeIf(call -> !CarpetServer.scriptServer.runas(source, call.host, call.udf, argv)); // this actually does the calls
|
callList.removeIf(call -> !CarpetServer.scriptServer.runas(source, call.host, call.function, argv)); // this actually does the calls
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public boolean addEventCall(String hostName, String funName)
|
public boolean addEventCall(String hostName, String funName)
|
||||||
@@ -148,7 +150,7 @@ public class CarpetEventServer
|
|||||||
|
|
||||||
public void removeEventCall(String hostName, String funName)
|
public void removeEventCall(String hostName, String funName)
|
||||||
{
|
{
|
||||||
callList.removeIf((c)-> c.udf.getString().equals(funName) && ( hostName == null || c.host.equalsIgnoreCase(hostName) ) );
|
callList.removeIf((c)-> c.function.getString().equals(funName) && ( hostName == null || c.host.equalsIgnoreCase(hostName) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeAllCalls(String hostName)
|
public void removeAllCalls(String hostName)
|
||||||
@@ -460,7 +462,7 @@ public class CarpetEventServer
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
public void scheduleCall(CarpetContext context, FunctionValue function, List<LazyValue> args, long due)
|
public void scheduleCall(CarpetContext context, FunctionValue function, List<Value> args, long due)
|
||||||
{
|
{
|
||||||
scheduledCalls.add(new ScheduledCall(context, function, args, due));
|
scheduledCalls.add(new ScheduledCall(context, function, args, due));
|
||||||
}
|
}
|
||||||
@@ -510,60 +512,4 @@ public class CarpetEventServer
|
|||||||
}
|
}
|
||||||
return Pair.of(null, funName);
|
return Pair.of(null, funName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScheduledCall makeEventCall(CarpetContext cc, FunctionValue function, List<Value> extraArgs, int argCount)
|
|
||||||
{
|
|
||||||
if (function == null || (function.getArguments().size()-(extraArgs == null ? 0 : extraArgs.size())) != argCount)
|
|
||||||
{
|
|
||||||
// call won't match arguments
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
List<LazyValue> 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 ScheduledCall makeDeathCall(CarpetContext cc, FunctionValue function, List<Value> extraArgs)
|
|
||||||
{
|
|
||||||
return makeEventCall(cc, function, extraArgs, 2);
|
|
||||||
}
|
|
||||||
public ScheduledCall makeRemovedCall(CarpetContext cc, FunctionValue function, List<Value> extraArgs)
|
|
||||||
{
|
|
||||||
return makeEventCall(cc, function, extraArgs, 1);
|
|
||||||
}
|
|
||||||
public ScheduledCall makeTickCall(CarpetContext cc, FunctionValue function, List<Value> extraArgs)
|
|
||||||
{
|
|
||||||
return makeEventCall(cc, function, extraArgs, 1);
|
|
||||||
}
|
|
||||||
public ScheduledCall makeDamageCall(CarpetContext cc, FunctionValue function, List<Value> extraArgs)
|
|
||||||
{
|
|
||||||
return makeEventCall(cc, function, extraArgs, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
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)));
|
|
||||||
}
|
|
||||||
public void onEntityTick(ScheduledCall tickCall, Entity entity)
|
|
||||||
{
|
|
||||||
tickCall.execute(Collections.singletonList((c, t) -> new EntityValue(entity)));
|
|
||||||
}
|
|
||||||
public void onEntityDamage(ScheduledCall call, Entity e, float amount, DamageSource source)
|
|
||||||
{
|
|
||||||
call.execute(Arrays.asList(
|
|
||||||
(c, t) -> new EntityValue(e),
|
|
||||||
(c, t) -> new NumericValue(amount),
|
|
||||||
(c, t) -> new StringValue(source.getName()),
|
|
||||||
(c, t) -> source.getAttacker()==null?Value.NULL:new EntityValue(source.getAttacker())
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -3074,11 +3074,11 @@ public class CarpetExpression
|
|||||||
FunctionValue function = (FunctionValue)functionValue;
|
FunctionValue function = (FunctionValue)functionValue;
|
||||||
|
|
||||||
CarpetContext cc = (CarpetContext)c;
|
CarpetContext cc = (CarpetContext)c;
|
||||||
List<LazyValue> args = new ArrayList<>();
|
List<Value> args = new ArrayList<>();
|
||||||
for (int i=2; i < lv.size(); i++)
|
for (int i=2; i < lv.size(); i++)
|
||||||
{
|
{
|
||||||
Value arg = lv.get(i).evalValue(cc);
|
Value arg = lv.get(i).evalValue(cc);
|
||||||
args.add( (_c, _t) -> arg);
|
args.add(arg);
|
||||||
}
|
}
|
||||||
if (function.getArguments().size() != args.size())
|
if (function.getArguments().size() != args.size())
|
||||||
throw new InternalExpressionException("Function "+function.getString()+" takes "+
|
throw new InternalExpressionException("Function "+function.getString()+" takes "+
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package carpet.script;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class Context
|
public class Context
|
||||||
{
|
{
|
||||||
@@ -20,7 +19,7 @@ public class Context
|
|||||||
|
|
||||||
public Map<String, LazyValue> variables = new HashMap<>();
|
public Map<String, LazyValue> variables = new HashMap<>();
|
||||||
|
|
||||||
protected ScriptHost host;
|
public ScriptHost host;
|
||||||
|
|
||||||
Context(ScriptHost host)
|
Context(ScriptHost host)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
package carpet.script;
|
||||||
|
|
||||||
|
import carpet.CarpetServer;
|
||||||
|
import carpet.script.exception.InternalExpressionException;
|
||||||
|
import carpet.script.value.EntityValue;
|
||||||
|
import carpet.script.value.FunctionValue;
|
||||||
|
import carpet.script.value.NumericValue;
|
||||||
|
import carpet.script.value.StringValue;
|
||||||
|
import carpet.script.value.Value;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.damage.DamageSource;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class EntityEventsGroup
|
||||||
|
{
|
||||||
|
private Map<EntityEventType, Map<String, CarpetEventServer.ScheduledCall>> actions;
|
||||||
|
public EntityEventsGroup()
|
||||||
|
{
|
||||||
|
actions = new EnumMap<>(EntityEventType.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onEvent(EntityEventType type, Entity entity, Object ... args)
|
||||||
|
{
|
||||||
|
if (actions.isEmpty()) return; // most of the cases, trying to be nice
|
||||||
|
Map<String, CarpetEventServer.ScheduledCall> actionSet = actions.get(type);
|
||||||
|
if (actionSet == null) return;
|
||||||
|
|
||||||
|
for (Iterator<Map.Entry<String, CarpetEventServer.ScheduledCall>> iterator = actionSet.entrySet().iterator(); iterator.hasNext(); )
|
||||||
|
{
|
||||||
|
Map.Entry<String, CarpetEventServer.ScheduledCall> 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 (actionSet.isEmpty()) actions.remove(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addEvent(EntityEventType type, CarpetContext cc, FunctionValue fun, List<Value> extraargs)
|
||||||
|
{
|
||||||
|
if (fun != null)
|
||||||
|
{
|
||||||
|
CarpetEventServer.ScheduledCall call = type.create(cc, 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);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
actions.computeIfAbsent(type, k -> new HashMap<>()).remove(cc.host.getName());
|
||||||
|
if (actions.get(type).isEmpty())
|
||||||
|
actions.remove(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public enum EntityEventType
|
||||||
|
{
|
||||||
|
ON_DEATH("on_death", 1)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public List<Value> makeArgs(Entity entity, Object... providedArgs)
|
||||||
|
{
|
||||||
|
return Arrays.asList(
|
||||||
|
new EntityValue(entity),
|
||||||
|
new StringValue((String)providedArgs[0])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ON_REMOVED("on_removed", 0),
|
||||||
|
ON_TICK("on_tick", 0),
|
||||||
|
ON_DAMAGE("on_damaged", 2)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public List<Value> makeArgs(Entity entity, Object... providedArgs)
|
||||||
|
{
|
||||||
|
float amount = (Float)providedArgs[0];
|
||||||
|
DamageSource source = (DamageSource)providedArgs[1];
|
||||||
|
return Arrays.asList(
|
||||||
|
new EntityValue(entity),
|
||||||
|
new NumericValue(amount),
|
||||||
|
new StringValue(source.getName()),
|
||||||
|
source.getAttacker()==null?Value.NULL:new EntityValue(source.getAttacker())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static Map<String, EntityEventType> byName = Arrays.stream(EntityEventType.values()).collect(Collectors.toMap(ev -> ev.id, ev -> ev));
|
||||||
|
|
||||||
|
public int argcount;
|
||||||
|
public String id;
|
||||||
|
EntityEventType(String identifier, int args)
|
||||||
|
{
|
||||||
|
id = identifier;
|
||||||
|
argcount = args+1; // entity is not extra
|
||||||
|
}
|
||||||
|
public CarpetEventServer.ScheduledCall create(CarpetContext cc, 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);
|
||||||
|
}
|
||||||
|
public void call(CarpetEventServer.ScheduledCall tickCall, Entity entity, Object ... args)
|
||||||
|
{
|
||||||
|
assert args.length == argcount-1;
|
||||||
|
tickCall.execute(makeArgs(entity, args));
|
||||||
|
}
|
||||||
|
protected List<Value> makeArgs(Entity entity, Object ... args)
|
||||||
|
{
|
||||||
|
return Collections.singletonList(new EntityValue(entity));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ import carpet.fakes.ItemEntityInterface;
|
|||||||
import carpet.fakes.MobEntityInterface;
|
import carpet.fakes.MobEntityInterface;
|
||||||
import carpet.helpers.Tracer;
|
import carpet.helpers.Tracer;
|
||||||
import carpet.script.CarpetContext;
|
import carpet.script.CarpetContext;
|
||||||
import carpet.script.Fluff;
|
import carpet.script.EntityEventsGroup;
|
||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
import com.mojang.brigadier.StringReader;
|
import com.mojang.brigadier.StringReader;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
@@ -775,17 +775,11 @@ public class EntityValue extends Value
|
|||||||
// "nbt" <-big one, for now use run('data merge entity ...
|
// "nbt" <-big one, for now use run('data merge entity ...
|
||||||
}};
|
}};
|
||||||
|
|
||||||
public void setEvent(CarpetContext cc, String event, FunctionValue fun, List<Value> args)
|
public void setEvent(CarpetContext cc, String eventName, FunctionValue fun, List<Value> args)
|
||||||
{
|
{
|
||||||
if (!(events.containsKey(event)))
|
EntityEventsGroup.EntityEventType event = EntityEventsGroup.EntityEventType.byName.get(eventName);
|
||||||
throw new InternalExpressionException("Unknown entity event: " + event);
|
if (event == null)
|
||||||
events.get(event).accept(cc, entity, fun, args);
|
throw new InternalExpressionException("Unknown entity event: " + eventName);
|
||||||
|
((EntityInterface)entity).getEventContainer().addEvent(event, cc, fun, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, Fluff.QuadConsumer<CarpetContext, Entity, FunctionValue, List<Value>>> events = new HashMap<String, Fluff.QuadConsumer<CarpetContext, Entity, FunctionValue, List<Value>>>() {{
|
|
||||||
put("on_death", (c, e, f, l) -> ((EntityInterface)e).setDeathCallback(c, f, l));
|
|
||||||
put("on_removed", (c, e, f, l) -> ((EntityInterface)e).setRemovedCallback(c, f, l));
|
|
||||||
put("on_tick", (c, e, f, l) -> ((EntityInterface)e).setTickCallback(c, f, l));
|
|
||||||
put("on_damaged", (c, e, f, l) -> ((EntityInterface)e).setDamageCallback(c, f, l));
|
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user