entity actions

This commit is contained in:
gnembon committed 2020-10-29 11:26:59 -03:00
1 parent 11818e3d57
commit 15ac7a4621
10 files changed
+136 -12

No files matched your search

@@ -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>>>()
{{