Merge branch 'master' into 1.16

This commit is contained in:
gnembon committed 2020-07-19 01:37:30 -03:00
commit 33651de9cd
3 files changed
+191 -1

No files matched your search

+17
View File
@@ -240,6 +240,11 @@ Returns mob's attack target or null if none or not applicable.
Returns creature's home position or null if none or not applicable. Returns creature's home position or null if none or not applicable.
### `query(e, 'path')`
Returns path of the entity if present, `null` otherwise. The path comprises of list of nodes, each is a list
of block value, node type, penalty, and a boolean indicated if the node has been visited.
### `query(e, 'pose')` ### `query(e, 'pose')`
Returns a pose of an entity, one of the following options Returns a pose of an entity, one of the following options
@@ -359,6 +364,18 @@ entities and blocks, blocks will take over the priority even if transparent or n
Regardless of the options selected, the result could be `null` if nothing is in reach, entity, if look targets an Regardless of the options selected, the result could be `null` if nothing is in reach, entity, if look targets an
entity, and block value if block is in reach. entity, and block value if block is in reach.
### `query(e, 'brain', memory)`
Retrieves brain memory for entity. Possible memory units highly depend on the game version. Brain is availalble
for villagers (1.15+) and Piglins (1.16+). If memory is not present or not available for the entity, `null` is returned.
Available retrievable memories for 1.15:
* `home`, `job_site`, `meeting_point`, `secondary_job_site`, `mobs`, `visible_mobs`, `visible_villager_babies`,
`nearest_players`, `nearest_visible_player`, `walk_target`, `look_target`, `interaction_target`,
`breed_target`, `path`, `interactable_doors`, `opened_doors`, `nearest_bed`, `hurt_by`, `hurt_by_entity`,
`nearest_hostile`, `hiding_place`, `heard_bell_time`, `cant_reach_walk_target_since`,
`golem_last_seen_time`, `last_slept`, `last_woken`, `last_worked_at_poi`
### `query(e, 'nbt', path?)` ### `query(e, 'nbt', path?)`
Returns full NBT of the entity. If path is specified, it fetches only the portion of the NBT that corresponds to the Returns full NBT of the entity. If path is specified, it fetches only the portion of the NBT that corresponds to the
@@ -13,6 +13,8 @@ import carpet.script.argument.Vector3Argument;
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;
import net.minecraft.entity.ai.brain.MemoryModuleType;
import net.minecraft.entity.ai.pathing.Path;
import net.minecraft.nbt.StringTag; import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.network.packet.s2c.play.EntityPassengersSetS2CPacket; import net.minecraft.network.packet.s2c.play.EntityPassengersSetS2CPacket;
@@ -60,6 +62,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
@@ -200,7 +203,14 @@ public class EntityValue extends Value
{ {
if (!(featureAccessors.containsKey(what))) if (!(featureAccessors.containsKey(what)))
throw new InternalExpressionException("Unknown entity feature: "+what); throw new InternalExpressionException("Unknown entity feature: "+what);
return featureAccessors.get(what).apply(entity, arg); try
{
return featureAccessors.get(what).apply(entity, arg);
}
catch (NullPointerException npe)
{
throw new InternalExpressionException("Cannot fetch '"+what+"' with these arguments");
}
} }
private static final Map<String, EquipmentSlot> inventorySlots = new HashMap<String, EquipmentSlot>(){{ private static final Map<String, EquipmentSlot> inventorySlots = new HashMap<String, EquipmentSlot>(){{
put("mainhand", EquipmentSlot.MAINHAND); put("mainhand", EquipmentSlot.MAINHAND);
@@ -210,6 +220,7 @@ public class EntityValue extends Value
put("legs", EquipmentSlot.LEGS); put("legs", EquipmentSlot.LEGS);
put("feet", EquipmentSlot.FEET); put("feet", EquipmentSlot.FEET);
}}; }};
private static final Map<String, BiFunction<Entity, Value, Value>> featureAccessors = new HashMap<String, BiFunction<Entity, Value, Value>>() {{ private static final Map<String, BiFunction<Entity, Value, Value>> featureAccessors = new HashMap<String, BiFunction<Entity, Value, Value>>() {{
//put("test", (e, a) -> a == null ? Value.NULL : new StringValue(a.getString())); //put("test", (e, a) -> a == null ? Value.NULL : new StringValue(a.getString()));
put("removed", (entity, arg) -> new NumericValue(entity.removed)); put("removed", (entity, arg) -> new NumericValue(entity.removed));
@@ -321,6 +332,30 @@ public class EntityValue extends Value
} }
return Value.NULL; return Value.NULL;
}); });
put("path", (e, a) -> {
if (e instanceof MobEntity)
{
Path path = ((MobEntity)e).getNavigation().getCurrentPath();
if (path == null) return Value.NULL;
return ValueConversions.fromPath((ServerWorld)e.getEntityWorld(), path);
}
return Value.NULL;
});
put("brain", (e, a) -> {
String module = a.getString();
MemoryModuleType<?> moduleType = Registry.MEMORY_MODULE_TYPE.get(new Identifier(module));
if (moduleType == MemoryModuleType.DUMMY) return Value.NULL;
if (e instanceof LivingEntity)
{
LivingEntity livingEntity = (LivingEntity)e;
Optional<?> memory = livingEntity.getBrain().getOptionalMemory(moduleType);
if (memory==null || !memory.isPresent()) return Value.NULL;
return ValueConversions.fromEntityMemory(e, memory.get());
}
return Value.NULL;
});
put("gamemode_id", (e, a) -> { put("gamemode_id", (e, a) -> {
if (e instanceof ServerPlayerEntity) if (e instanceof ServerPlayerEntity)
{ {
@@ -0,0 +1,138 @@
package carpet.script.value;
import net.minecraft.entity.Entity;
import net.minecraft.entity.ai.brain.LookTarget;
import net.minecraft.entity.ai.brain.WalkTarget;
import net.minecraft.entity.ai.pathing.Path;
import net.minecraft.entity.ai.pathing.PathNode;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.GlobalPos;
import net.minecraft.util.Identifier;
import net.minecraft.util.Timestamp;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.dimension.DimensionType;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Collectors;
public class ValueConversions
{
public static Value fromPos(BlockPos pos)
{
return ListValue.of(new NumericValue(pos.getX()), new NumericValue(pos.getY()), new NumericValue(pos.getZ()));
}
public static Value dimName(ServerWorld world)
{
return ofId(Registry.DIMENSION_TYPE.getId(world.getDimension().getType()));
}
public static Value dimName(DimensionType dim)
{
return ofId(Registry.DIMENSION_TYPE.getId(dim));
}
public static Value ofId(Identifier id)
{
if (id == null) // should be Value.NULL
return Value.NULL;
if (id.getNamespace().equals("minecraft"))
return new StringValue(id.getPath());
return new StringValue(id.toString());
}
public static Value ofGlobalPos(GlobalPos pos)
{
return ListValue.of(
ValueConversions.dimName(pos.getDimension()),
ValueConversions.fromPos(pos.getPos())
);
}
public static Value fromPath(ServerWorld world, Path path)
{
List<Value> nodes = new ArrayList<>();
for (PathNode node: path.getNodes())
{
nodes.add( ListValue.of(
new BlockValue(null, world, node.getPos()),
new StringValue(node.type.name().toLowerCase(Locale.ROOT)),
new NumericValue(node.penalty),
new NumericValue(node.visited)
));
}
return ListValue.wrap(nodes);
}
public static Value fromEntityMemory(Entity e, Object v)
{
if (v instanceof GlobalPos)
{
GlobalPos pos = (GlobalPos)v;
return ofGlobalPos(pos);
};
if (v instanceof Entity)
{
return new EntityValue((Entity)v);
};
if (v instanceof BlockPos)
{
return new BlockValue(null, (ServerWorld) e.getEntityWorld(), (BlockPos) v);
};
if (v instanceof Timestamp)
{
return new NumericValue(((Timestamp) v).getTime());
}
if (v instanceof Long)
{
return new NumericValue((Long)v);
}
if (v instanceof DamageSource)
{
DamageSource source = (DamageSource) v;
return ListValue.of(
new StringValue(source.getName()),
source.getAttacker()==null?Value.NULL:new EntityValue(source.getAttacker())
);
}
if (v instanceof Path)
{
return fromPath((ServerWorld)e.getEntityWorld(), (Path)v);
}
if (v instanceof LookTarget)
{
return new BlockValue(null, (ServerWorld) e.getEntityWorld(), ((LookTarget)v).getBlockPos());
}
if (v instanceof WalkTarget)
{
return ListValue.of(
new BlockValue(null, (ServerWorld) e.getEntityWorld(), ((LookTarget)v).getBlockPos()),
new NumericValue(((WalkTarget) v).getSpeed()),
new NumericValue(((WalkTarget) v).getCompletionRange())
);
}
if (v instanceof Set)
{
v = new ArrayList(((Set) v));
}
if (v instanceof List)
{
List l = (List)v;
if (l.isEmpty()) return ListValue.of();
Object el = l.get(0);
if (el instanceof Entity)
{
return ListValue.wrap((List<Value>) l.stream().map(o -> new EntityValue((Entity)o)).collect(Collectors.toList()));
}
if (el instanceof GlobalPos)
{
return ListValue.wrap((List<Value>) l.stream().map(o -> ofGlobalPos((GlobalPos) o)).collect(Collectors.toList()));
}
}
return Value.NULL;
}
}