entity actions
This commit is contained in:
1 parent
11818e3d57
commit
15ac7a4621
10 files changed
+136
-12
No files matched your search
@@ -50,7 +50,7 @@ public abstract class PlayerEntity_scarpetEventsMixin extends LivingEntity
|
||||
{
|
||||
if (PLAYER_COLLIDES_WITH_ENTITY.isNeeded() && !world.isClient)
|
||||
{
|
||||
PLAYER_COLLIDES_WITH_ENTITY.onEntityAction((ServerPlayerEntity)(Object)this, entity, null);
|
||||
PLAYER_COLLIDES_WITH_ENTITY.onEntityHandAction((ServerPlayerEntity)(Object)this, entity, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,7 +224,7 @@ public class ServerPlayNetworkHandler_scarpetEventsMixin
|
||||
))
|
||||
private void onEntityInteract(PlayerInteractEntityC2SPacket playerInteractEntityC2SPacket_1, CallbackInfo ci)
|
||||
{
|
||||
PLAYER_INTERACTS_WITH_ENTITY.onEntityAction(player, playerInteractEntityC2SPacket_1.getEntity(player.getServerWorld()), playerInteractEntityC2SPacket_1.getHand());
|
||||
PLAYER_INTERACTS_WITH_ENTITY.onEntityHandAction(player, playerInteractEntityC2SPacket_1.getEntity(player.getServerWorld()), playerInteractEntityC2SPacket_1.getHand());
|
||||
}
|
||||
|
||||
@Inject(method = "onPlayerInteractEntity", at = @At(
|
||||
@@ -234,7 +234,7 @@ public class ServerPlayNetworkHandler_scarpetEventsMixin
|
||||
private void onEntityAttack(PlayerInteractEntityC2SPacket playerInteractEntityC2SPacket_1, CallbackInfo ci)
|
||||
{
|
||||
//todo add hit and hand in the future
|
||||
PLAYER_ATTACKS_ENTITY.onEntityAction(player, playerInteractEntityC2SPacket_1.getEntity(player.getServerWorld()), null);
|
||||
PLAYER_ATTACKS_ENTITY.onEntityHandAction(player, playerInteractEntityC2SPacket_1.getEntity(player.getServerWorld()), null);
|
||||
}
|
||||
|
||||
@Inject(method = "onButtonClick", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayerEntity;updateLastActionTime()V"))
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.script.CarpetEventServer;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LightningEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@@ -12,6 +15,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import static carpet.script.CarpetEventServer.Event.ENTITY_LOAD;
|
||||
import static carpet.script.CarpetEventServer.Event.LIGHTNING;
|
||||
|
||||
@Mixin(ServerWorld.class)
|
||||
@@ -30,4 +34,24 @@ public class ServerWorld_scarpetEventMixin
|
||||
if (LIGHTNING.isNeeded()) LIGHTNING.onWorldEventFlag((ServerWorld) (Object)this, blockPos, bl2?1:0);
|
||||
}
|
||||
|
||||
@Inject(method = "loadEntityUnchecked", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/server/world/ServerChunkManager;loadEntity(Lnet/minecraft/entity/Entity;)V"
|
||||
))
|
||||
private void onEntityAddedToWorld(Entity entity, CallbackInfo ci)
|
||||
{
|
||||
CarpetEventServer.Event event = ENTITY_LOAD.get(entity.getType());
|
||||
if (event != null)
|
||||
{
|
||||
if (event.isNeeded())
|
||||
{
|
||||
event.onEntityAction(entity);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CarpetSettings.LOG.error("Failed to handle entity "+entity.getType().getTranslationKey());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import carpet.script.value.StringValue;
|
||||
import carpet.script.value.Value;
|
||||
import carpet.utils.Messenger;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
@@ -211,6 +212,11 @@ public class CarpetEventServer
|
||||
public static class Event
|
||||
{
|
||||
public static final Map<String, Event> byName = new HashMap<>();
|
||||
public static List<String> publicEvents()
|
||||
{
|
||||
return byName.entrySet().stream().filter(e -> e.getValue().isPublic).map(Map.Entry::getKey).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static final Event TICK = new Event("tick", 0, true)
|
||||
{
|
||||
@Override
|
||||
@@ -407,7 +413,7 @@ public class CarpetEventServer
|
||||
public static final Event PLAYER_INTERACTS_WITH_ENTITY = new Event("player_interacts_with_entity", 3, false)
|
||||
{
|
||||
@Override
|
||||
public void onEntityAction(ServerPlayerEntity player, Entity entity, Hand enumhand)
|
||||
public void onEntityHandAction(ServerPlayerEntity player, Entity entity, Hand enumhand)
|
||||
{
|
||||
handler.call( () -> Arrays.asList(
|
||||
((c, t) -> new EntityValue(player)),
|
||||
@@ -434,7 +440,7 @@ public class CarpetEventServer
|
||||
public static final Event PLAYER_ATTACKS_ENTITY = new Event("player_attacks_entity", 2, false)
|
||||
{
|
||||
@Override
|
||||
public void onEntityAction(ServerPlayerEntity player, Entity entity, Hand enumhand)
|
||||
public void onEntityHandAction(ServerPlayerEntity player, Entity entity, Hand enumhand)
|
||||
{
|
||||
handler.call( () -> Arrays.asList(
|
||||
((c, t) -> new EntityValue(player)),
|
||||
@@ -596,7 +602,7 @@ public class CarpetEventServer
|
||||
public static final Event PLAYER_COLLIDES_WITH_ENTITY = new Event("player_collides_with_entity", 2, false)
|
||||
{
|
||||
@Override
|
||||
public void onEntityAction(ServerPlayerEntity player, Entity entity, Hand enumhand) {
|
||||
public void onEntityHandAction(ServerPlayerEntity player, Entity entity, Hand enumhand) {
|
||||
handler.call( () -> Arrays.asList(
|
||||
((c, t) -> new EntityValue(player)),
|
||||
((c, t) -> new EntityValue(entity))
|
||||
@@ -695,17 +701,38 @@ public class CarpetEventServer
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public static final Map<EntityType<?>, Event> ENTITY_LOAD= new HashMap<EntityType<?>, Event>() {{
|
||||
EntityType.get("zombie");
|
||||
Registry.ENTITY_TYPE.forEach(et -> {
|
||||
put(et, new Event("entity_loaded_" + Registry.ENTITY_TYPE.getId(et), 1, true, false)
|
||||
{
|
||||
@Override
|
||||
public void onEntityAction(Entity entity)
|
||||
{
|
||||
super.onEntityAction(entity);
|
||||
}
|
||||
});
|
||||
});
|
||||
}};
|
||||
|
||||
// on projectile thrown (arrow from bows, crossbows, tridents, snoballs, e-pearls
|
||||
|
||||
public final String name;
|
||||
|
||||
public final CallbackList handler;
|
||||
public final boolean globalOnly;
|
||||
public final boolean isPublic; // public events can be targetted with __on_<event> defs
|
||||
public Event(String name, int reqArgs, boolean isGlobalOnly)
|
||||
{
|
||||
this(name, reqArgs, isGlobalOnly, true);
|
||||
}
|
||||
public Event(String name, int reqArgs, boolean isGlobalOnly, boolean isPublic)
|
||||
{
|
||||
this.name = name;
|
||||
this.handler = new CallbackList(reqArgs);
|
||||
this.globalOnly = isGlobalOnly;
|
||||
this.isPublic = isPublic;
|
||||
byName.put(name, this);
|
||||
}
|
||||
public boolean isNeeded()
|
||||
@@ -724,7 +751,8 @@ public class CarpetEventServer
|
||||
public void onBlockHit(ServerPlayerEntity player, Hand enumhand, BlockHitResult hitRes) { }
|
||||
public void onBlockBroken(ServerPlayerEntity player, BlockPos pos, BlockState previousBS) { }
|
||||
public void onBlockPlaced(ServerPlayerEntity player, BlockPos pos, Hand enumhand, ItemStack itemstack) { }
|
||||
public void onEntityAction(ServerPlayerEntity player, Entity entity, Hand enumhand) { }
|
||||
public void onEntityHandAction(ServerPlayerEntity player, Entity entity, Hand enumhand) { }
|
||||
public void onEntityAction(Entity entity) { }
|
||||
public void onDimensionChange(ServerPlayerEntity player, Vec3d from, Vec3d to, RegistryKey<World> fromDim, RegistryKey<World> dimTo) {}
|
||||
public void onDamage(Entity target, float amount, DamageSource source) { }
|
||||
public void onRecipeSelected(ServerPlayerEntity player, Identifier recipe, boolean fullStack) {}
|
||||
|
||||
@@ -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);
|
||||
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, true, false);
|
||||
|
||||
CarpetServer.scriptServer.events.scheduleCall(
|
||||
(CarpetContext) c,
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package carpet.script.api;
|
||||
|
||||
import carpet.script.CarpetContext;
|
||||
import carpet.script.CarpetScriptHost;
|
||||
import carpet.script.Expression;
|
||||
import carpet.script.LazyValue;
|
||||
import carpet.script.argument.FunctionArgument;
|
||||
import carpet.script.argument.Vector3Argument;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import carpet.script.value.EntityValue;
|
||||
@@ -266,6 +268,16 @@ public class Entities {
|
||||
return (cc, tt) -> v;
|
||||
});
|
||||
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
// or update
|
||||
expression.addLazyFunction("entity_event", -1, (c, t, lv) ->
|
||||
{
|
||||
@@ -275,6 +287,7 @@ public class Entities {
|
||||
if (!(v instanceof EntityValue))
|
||||
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;
|
||||
|
||||
@@ -21,7 +21,7 @@ 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)
|
||||
public static FunctionArgument findIn(Context c, Module module, List<LazyValue> params, int offset, boolean prematureEvaluation, boolean allowNone)
|
||||
{
|
||||
Value functionValue = params.get(offset).evalValue(c);
|
||||
if (!(functionValue instanceof FunctionValue))
|
||||
|
||||
@@ -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);
|
||||
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 0, false, false);
|
||||
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?)
|
||||
|
||||
@@ -17,7 +17,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);
|
||||
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 0, true, false);
|
||||
ThreadValue thread = new ThreadValue(Value.NULL, functionArgument.function, expr, tok, c, functionArgument.args);
|
||||
Thread.yield();
|
||||
return (cc, tt) -> thread;
|
||||
@@ -28,7 +28,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);
|
||||
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, true, false);
|
||||
ThreadValue thread = new ThreadValue(queue, functionArgument.function, expr, tok, c, functionArgument.args);
|
||||
Thread.yield();
|
||||
return (cc, tt) -> thread;
|
||||
|
||||
@@ -15,6 +15,7 @@ import carpet.script.EntityEventsGroup;
|
||||
import carpet.script.argument.Vector3Argument;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import net.minecraft.entity.SpawnGroup;
|
||||
@@ -70,15 +71,18 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static carpet.script.value.NBTSerializableValue.nameFromRegistryId;
|
||||
import static carpet.utils.MobAI.genericJump;
|
||||
@@ -210,6 +214,61 @@ public class EntityValue extends Value
|
||||
"illager", EntityGroup.ILLAGER
|
||||
);
|
||||
|
||||
public static class EntityClassDescriptor
|
||||
{
|
||||
public EntityType<?> directType;
|
||||
public Predicate<? super Entity> filteringPredicate;
|
||||
public List<EntityType<?>> typeList;
|
||||
EntityClassDescriptor(EntityType<?> type, Predicate<? super Entity> predicate, Stream<EntityType<?>> types)
|
||||
{
|
||||
directType = type;
|
||||
filteringPredicate = predicate;
|
||||
typeList = types.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public Map<String, EntityClassDescriptor> byName = new HashMap<String, EntityClassDescriptor>() {{
|
||||
Stream<EntityType<?>> allTypes = Registry.ENTITY_TYPE.stream();
|
||||
Set<EntityType<?>> projectiles = Sets.newHashSet(
|
||||
EntityType.ARROW, EntityType.DRAGON_FIREBALL
|
||||
);
|
||||
Set<EntityType<?>> deads = Sets.newHashSet(
|
||||
EntityType.AREA_EFFECT_CLOUD, EntityType.BOAT,
|
||||
)
|
||||
|
||||
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("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()));
|
||||
}
|
||||
}}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static final Map<String, Pair<EntityType<?>, Predicate<? super Entity>>> entityPredicates =
|
||||
new HashMap<String, Pair<EntityType<?>, Predicate<? super Entity>>>()
|
||||
{{
|
||||
|
||||
Reference in new issue
Block a user