tracking and tracing
This commit is contained in:
1 parent
eee23e4ba6
commit
3c96345a60
20 files changed
+404
-128
No files matched your search
@@ -11,6 +11,7 @@ import carpet.commands.DistanceCommand;
|
||||
import carpet.commands.DrawCommand;
|
||||
import carpet.commands.InfoCommand;
|
||||
import carpet.commands.LogCommand;
|
||||
import carpet.commands.MobAICommand;
|
||||
import carpet.commands.PerimeterInfoCommand;
|
||||
import carpet.commands.PlayerCommand;
|
||||
import carpet.commands.ScriptCommand;
|
||||
@@ -22,6 +23,7 @@ import carpet.script.CarpetScriptServer;
|
||||
import carpet.settings.CarpetSettings;
|
||||
import carpet.settings.SettingsManager;
|
||||
import carpet.utils.HUDController;
|
||||
import carpet.utils.MobAI;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
@@ -59,6 +61,7 @@ public class CarpetServer // static for now - easier to handle all around the co
|
||||
e.onServerLoaded(server);
|
||||
});
|
||||
scriptServer = new CarpetScriptServer();
|
||||
MobAI.resetTrackers();
|
||||
}
|
||||
|
||||
public static void tick(MinecraftServer server)
|
||||
@@ -88,6 +91,7 @@ public class CarpetServer // static for now - easier to handle all around the co
|
||||
PerimeterInfoCommand.register(dispatcher);
|
||||
DrawCommand.register(dispatcher);
|
||||
ScriptCommand.register(dispatcher);
|
||||
MobAICommand.register(dispatcher);
|
||||
extensions.forEach(e -> e.registerCommands(dispatcher));
|
||||
//TestCommand.register(dispatcher);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package carpet.commands;
|
||||
|
||||
import carpet.settings.CarpetSettings;
|
||||
import carpet.utils.MobAI;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import net.minecraft.command.arguments.EntitySummonArgumentType;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import static net.minecraft.server.command.CommandManager.argument;
|
||||
import static net.minecraft.server.command.CommandManager.literal;
|
||||
import static net.minecraft.server.command.CommandSource.suggestMatching;
|
||||
|
||||
public class MobAICommand
|
||||
{
|
||||
public static void register(CommandDispatcher<ServerCommandSource> dispatcher)
|
||||
{
|
||||
LiteralArgumentBuilder<ServerCommandSource> command = literal("track").
|
||||
requires((player) -> CarpetSettings.commandTrackAI).
|
||||
then(argument("entity type", EntitySummonArgumentType.entitySummon()).
|
||||
|
||||
suggests( (c, b) -> suggestMatching(MobAI.availbleTypes(), b)).
|
||||
then(literal("clear").executes( (c) ->
|
||||
{
|
||||
MobAI.clearTracking(Registry.ENTITY_TYPE.get(EntitySummonArgumentType.getEntitySummon(c, "entity type")));
|
||||
return 1;
|
||||
}
|
||||
)).
|
||||
then(argument("aspect", StringArgumentType.word()).
|
||||
suggests( (c, b) -> suggestMatching(MobAI.availableFor(Registry.ENTITY_TYPE.get(EntitySummonArgumentType.getEntitySummon(c, "entity type"))),b)).
|
||||
executes( (c) -> {
|
||||
MobAI.startTracking(
|
||||
Registry.ENTITY_TYPE.get(EntitySummonArgumentType.getEntitySummon(c, "entity type")),
|
||||
MobAI.TrackingType.byName(StringArgumentType.getString(c, "aspect"))
|
||||
);
|
||||
return 1;
|
||||
})));
|
||||
dispatcher.register(command);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.utils.Messenger;
|
||||
import carpet.utils.MobAI;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.ai.brain.Activity;
|
||||
import net.minecraft.entity.ai.brain.MemoryModuleType;
|
||||
import net.minecraft.entity.passive.AbstractTraderEntity;
|
||||
import net.minecraft.entity.passive.VillagerEntity;
|
||||
import net.minecraft.particle.ParticleTypes;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.Timestamp;
|
||||
import net.minecraft.world.World;
|
||||
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.Optional;
|
||||
|
||||
@Mixin(VillagerEntity.class)
|
||||
public abstract class VillagerEntity_aiMixin extends AbstractTraderEntity
|
||||
{
|
||||
@Shadow protected abstract boolean hasSeenGolemRecently(long long_1);
|
||||
|
||||
@Inject(method = "tick", at = @At("HEAD"))
|
||||
private void ontick(CallbackInfo ci)
|
||||
{
|
||||
if (MobAI.isTracking(this, MobAI.TrackingType.IRON_GOLEM_SPAWNING) && !getEntityWorld().isClient())
|
||||
{
|
||||
long time;
|
||||
Optional<Long> optional_1 = this.brain.getOptionalMemory(MemoryModuleType.GOLEM_LAST_SEEN_TIME);
|
||||
if (!optional_1.isPresent()) {
|
||||
time = 0;
|
||||
} else {
|
||||
Long long_2 = optional_1.get();
|
||||
time = long_2+600 - getEntityWorld().getTime();
|
||||
}
|
||||
boolean recentlySeen = hasSeenGolemRecently(getEntityWorld().getTime());
|
||||
Optional<Timestamp> optional_11 = this.brain.getOptionalMemory(MemoryModuleType.LAST_SLEPT);
|
||||
Optional<Timestamp> optional_22 = this.brain.getOptionalMemory(MemoryModuleType.LAST_WORKED_AT_POI);
|
||||
boolean work = false;
|
||||
boolean sleep = false;
|
||||
boolean panic = this.brain.hasActivity(Activity.PANIC);
|
||||
long currentTime = this.world.getTime();
|
||||
if (optional_11.isPresent()) {
|
||||
sleep = (currentTime - optional_11.get().getTime()) < 24000L;
|
||||
}
|
||||
if (optional_22.isPresent()) {
|
||||
work = (currentTime - optional_22.get().getTime()) < 36000L;
|
||||
}
|
||||
|
||||
this.setCustomName(Messenger.c(
|
||||
(sleep?"eb ":"fb ")+"\u263d ",
|
||||
(work?"eb ":"fb ")+"\u2692 ",//"\u26CF ",
|
||||
(panic?"lb ":"fb ")+"\u2623 ",//"\u2622 \u2620 \u26A1 ",
|
||||
(recentlySeen?"rb ":"lb ")+time ));
|
||||
this.setCustomNameVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "summonGolem", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/util/math/Box;expand(DDD)Lnet/minecraft/util/math/Box;",
|
||||
shift = At.Shift.AFTER
|
||||
))
|
||||
private void particleIt(long long_1, int int_1, CallbackInfo ci)
|
||||
{
|
||||
if (MobAI.isTracking(this, MobAI.TrackingType.IRON_GOLEM_SPAWNING) && !getEntityWorld().isClient())
|
||||
{
|
||||
((ServerWorld) getEntityWorld()).spawnParticles(ParticleTypes.BARRIER, x, y+3, z, 1, 0.1, 0.1, 0.1, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
public VillagerEntity_aiMixin(EntityType<? extends AbstractTraderEntity> entityType_1, World world_1)
|
||||
{
|
||||
super(entityType_1, world_1);
|
||||
}
|
||||
}
|
||||
@@ -679,7 +679,6 @@ public class CarpetExpression
|
||||
this.expr.addLazyFunction("blast_resistance", -1, (c, t, lv) ->
|
||||
genericStateTest(c, "blast_resistance", lv, (s, p, w) -> new NumericValue(s.getBlock().getBlastResistance())));
|
||||
|
||||
// Deprecated
|
||||
this.expr.addLazyFunction("top", -1, (c, t, lv) ->
|
||||
{
|
||||
String type = lv.get(0).evalValue(c).getString().toLowerCase(Locale.ROOT);
|
||||
@@ -693,20 +692,10 @@ public class CarpetExpression
|
||||
case "surface": htype = Heightmap.Type.WORLD_SURFACE; break;
|
||||
default: throw new InternalExpressionException("Unknown heightmap type: "+type);
|
||||
}
|
||||
int x;
|
||||
int z;
|
||||
Value v1 = lv.get(1).evalValue(c);
|
||||
if (v1 instanceof BlockValue)
|
||||
{
|
||||
BlockPos inpos = ((BlockValue)v1).getPos();
|
||||
x = inpos.getX();
|
||||
z = inpos.getZ();
|
||||
}
|
||||
else
|
||||
{
|
||||
x = (int) NumericValue.asNumber(lv.get(1).evalValue(c)).getLong();
|
||||
z = (int) NumericValue.asNumber(lv.get(2).evalValue(c)).getLong();
|
||||
}
|
||||
BlockValue.LocatorResult locator = BlockValue.fromParams((CarpetContext)c, lv, 1);
|
||||
BlockPos pos = locator.block.getPos();
|
||||
int x = pos.getX();
|
||||
int z = pos.getZ();
|
||||
Value retval = new NumericValue(((CarpetContext)c).s.getWorld().getChunk(x >> 4, z >> 4).sampleHeightmap(htype, x & 15, z & 15) + 1);
|
||||
return (c_, t_) -> retval;
|
||||
//BlockPos pos = new BlockPos(x,y,z);
|
||||
@@ -965,24 +954,6 @@ public class CarpetExpression
|
||||
return (_c, _t) -> res;
|
||||
});
|
||||
|
||||
/*this.expr.addLazyFunction("trace_block", -1, (c, t, lv) -> {
|
||||
Value entityValue = lv.get(0).evalValue(c);
|
||||
if (!(entityValue instanceof EntityValue))
|
||||
throw new InternalExpressionException("First argument of trace_block should be an entity");
|
||||
Entity e = ((EntityValue) entityValue).getEntity();
|
||||
HitResult hitres = Tracer.traceEntityLook(e, 20);
|
||||
switch (hitres.getType())
|
||||
{
|
||||
case MISS:
|
||||
return (_c, _t) -> Value.NULL;
|
||||
case BLOCK:
|
||||
return (_c, _t) -> new BlockValue(null, e.getEntityWorld(), ((BlockHitResult)hitres).getBlockPos() );
|
||||
case ENTITY:
|
||||
return (_c, _t) -> new EntityValue(((EntityHitResult)hitres).getEntity());
|
||||
}
|
||||
return LazyValue.NULL;
|
||||
});*/
|
||||
|
||||
this.expr.addLazyFunction("set_biome", -1, (c, t, lv) -> {
|
||||
CarpetContext cc = (CarpetContext)c;
|
||||
BlockValue.LocatorResult locator = BlockValue.fromParams(cc, lv, 0);
|
||||
@@ -1736,7 +1707,6 @@ public class CarpetExpression
|
||||
return (c_, t_) -> ListValue.wrap(retlist);
|
||||
});
|
||||
|
||||
|
||||
this.expr.addLazyFunction("query", -1, (c, t, lv) -> {
|
||||
if (lv.size()<2)
|
||||
{
|
||||
@@ -2516,15 +2486,16 @@ public class CarpetExpression
|
||||
this.expr.addLazyFunction("print", 1, (c, t, lv) ->
|
||||
{
|
||||
ServerCommandSource s = ((CarpetContext)c).s;
|
||||
Value res = lv.get(0).evalValue(c);
|
||||
if (s.getEntity() instanceof PlayerEntity)
|
||||
{
|
||||
Messenger.m((PlayerEntity) s.getEntity(), "w "+ lv.get(0).evalValue(c).getString());
|
||||
Messenger.m((PlayerEntity) s.getEntity(), "w "+ res.getString());
|
||||
}
|
||||
else
|
||||
{
|
||||
Messenger.m(s, "w "+ lv.get(0).evalValue(c).getString());
|
||||
Messenger.m(s, "w "+ res.getString());
|
||||
}
|
||||
return lv.get(0); // pass through for variables
|
||||
return (_c, _t) -> res; // pass through for variables
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -498,21 +498,9 @@ public class Expression implements Cloneable
|
||||
Value.assertNotNull(v);
|
||||
return lazyfun.apply(c, t, v);
|
||||
}
|
||||
catch (InternalExpressionException exc)
|
||||
catch (RuntimeException exc)
|
||||
{
|
||||
throw new ExpressionException(e, token, exc.getMessage());
|
||||
}
|
||||
catch (ArithmeticException exc)
|
||||
{
|
||||
throw new ExpressionException(e, token, "Your math is wrong, "+exc.getMessage());
|
||||
}
|
||||
catch (ExitStatement exit)
|
||||
{
|
||||
throw exit;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
throw new ExpressionException(e, token, "Error while evaluating expression: "+exc.getMessage());
|
||||
throw handleCodeException(exc, e, token);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -532,21 +520,9 @@ public class Expression implements Cloneable
|
||||
Value.assertNotNull(v1, v2);
|
||||
return lazyfun.apply(c, type, e, t, v1, v2);
|
||||
}
|
||||
catch (InternalExpressionException exc) // might not actually throw it
|
||||
catch (RuntimeException exc)
|
||||
{
|
||||
throw new ExpressionException(e, t, exc.getMessage());
|
||||
}
|
||||
catch (ArithmeticException exc)
|
||||
{
|
||||
throw new ExpressionException(e, t, "Your math is wrong, "+exc.getMessage());
|
||||
}
|
||||
catch (ExitStatement exit)
|
||||
{
|
||||
throw exit;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
throw new ExpressionException(e, t, "Error while evaluating expression: "+exc.getMessage());
|
||||
throw handleCodeException(exc, e, t);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -565,26 +541,27 @@ public class Expression implements Cloneable
|
||||
Value.assertNotNull(v1, v2);
|
||||
return lazyfun.apply(c, t, v1, v2);
|
||||
}
|
||||
catch (InternalExpressionException exc)
|
||||
catch (RuntimeException exc)
|
||||
{
|
||||
throw new ExpressionException(e, token, exc.getMessage());
|
||||
}
|
||||
catch (ArithmeticException exc)
|
||||
{
|
||||
throw new ExpressionException(e, token, "Your math is wrong, "+exc.getMessage());
|
||||
}
|
||||
catch (ExitStatement exit)
|
||||
{
|
||||
throw exit;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
throw new ExpressionException(e, token, "Error while evaluating expression: "+exc.getMessage());
|
||||
throw handleCodeException(exc, e, token);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private RuntimeException handleCodeException(RuntimeException exc, Expression e, Tokenizer.Token token)
|
||||
{
|
||||
if (exc instanceof ExitStatement)
|
||||
return exc;
|
||||
if (exc instanceof InternalExpressionException)
|
||||
return new ExpressionException(e, token, exc.getMessage());
|
||||
if (exc instanceof ArithmeticException)
|
||||
return new ExpressionException(e, token, "Your math is wrong, "+exc.getMessage());
|
||||
if (exc instanceof ExpressionException)
|
||||
return exc;
|
||||
return new ExpressionException(e, token, "Error while evaluating expression: "+exc.getMessage());
|
||||
}
|
||||
|
||||
private void addUnaryOperator(String surface, boolean leftAssoc, Function<Value, Value> fun)
|
||||
{
|
||||
operators.put(surface+"u", new AbstractUnaryOperator(precedence.get("unary+-!"), leftAssoc)
|
||||
@@ -679,22 +656,10 @@ public class Expression implements Cloneable
|
||||
{
|
||||
return fun.apply(c, i, lazyParams);
|
||||
}
|
||||
catch (InternalExpressionException exc)
|
||||
catch (RuntimeException exc)
|
||||
{
|
||||
throw new ExpressionException(e, t, exc.getMessage());
|
||||
throw handleCodeException(exc, e, t);
|
||||
}
|
||||
catch (ArithmeticException exc)
|
||||
{
|
||||
throw new ExpressionException(e, t, "Your math is wrong, "+exc.getMessage());
|
||||
}
|
||||
catch (ExitStatement exit)
|
||||
{
|
||||
throw exit;
|
||||
}
|
||||
//catch (Exception exc)
|
||||
//{
|
||||
// throw new ExpressionException(e, t, "Error while evaluating expression: "+exc.getMessage());
|
||||
//}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -770,7 +735,7 @@ public class Expression implements Cloneable
|
||||
{
|
||||
throw new ExpressionException(function_context, t, "Your math is wrong, "+exc.getMessage());
|
||||
}
|
||||
catch (ExitStatement exit)
|
||||
catch (ExitStatement | ExpressionException exit)
|
||||
{
|
||||
throw exit;
|
||||
}
|
||||
@@ -1060,7 +1025,7 @@ public class Expression implements Cloneable
|
||||
Value ret = lv.get(lv.size() - 1).evalValue(c);
|
||||
return (cc, tt) -> ret;
|
||||
}
|
||||
return (cc, tt) -> Value.ZERO;
|
||||
return (cc, tt) -> Value.NULL;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1892,8 +1857,6 @@ public class Expression implements Cloneable
|
||||
return LazyListValue.range(from, to, step);
|
||||
});
|
||||
|
||||
addUnaryFunction("is_list", value -> (value instanceof ListValue)? Value.TRUE : Value.FALSE);
|
||||
|
||||
addBinaryFunction("get", (v1, v2) -> v1.getElementAt(v2));
|
||||
|
||||
//Deprecated, use "get" instead
|
||||
@@ -2512,6 +2475,8 @@ public class Expression implements Cloneable
|
||||
}
|
||||
});
|
||||
|
||||
addUnaryFunction("type", v -> new StringValue(v.getTypeString()));
|
||||
|
||||
addUnaryFunction("length", v -> new NumericValue(v.length()));
|
||||
addLazyFunction("rand", 1, (c, t, lv) -> {
|
||||
Value argument = lv.get(0).evalValue(c);
|
||||
|
||||
@@ -73,12 +73,10 @@ public class ScriptHost
|
||||
try
|
||||
{
|
||||
ServerPlayerEntity player = source.getPlayer();
|
||||
CarpetSettings.LOG.error("Retrieving "+player.getName().getString()+" host for "+getName());
|
||||
return retrieveForExecution(player.getName().getString());
|
||||
}
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
CarpetSettings.LOG.error("Retrieving global host for "+getName());
|
||||
return retrieveForExecution((String)null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,6 +241,12 @@ public class BlockValue extends Value
|
||||
return this != NULL && !getBlockState().isAir();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeString()
|
||||
{
|
||||
return "block";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value clone()
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package carpet.script.value;
|
||||
|
||||
import carpet.fakes.MobEntityInterface;
|
||||
import carpet.helpers.Tracer;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
@@ -30,6 +31,9 @@ import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.text.LiteralText;
|
||||
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.Direction;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
@@ -124,6 +128,12 @@ public class EntityValue extends Value
|
||||
return this.get(what, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeString()
|
||||
{
|
||||
return "entity";
|
||||
}
|
||||
|
||||
public static Pair<EntityType<?>, Predicate<? super Entity>> getPredicate(String who)
|
||||
{
|
||||
Pair<EntityType<?>, Predicate<? super Entity>> res = entityPredicates.get(who);
|
||||
@@ -310,20 +320,65 @@ public class EntityValue extends Value
|
||||
return new StringValue(Direction.getEntityFacingOrder(e)[index].asString());
|
||||
});
|
||||
|
||||
put("trace", (e, a) ->
|
||||
{
|
||||
float reach = 4.5f;
|
||||
boolean entities = true;
|
||||
boolean liquids = false;
|
||||
|
||||
if (a!=null)
|
||||
{
|
||||
if (!(a instanceof ListValue))
|
||||
{
|
||||
reach = (float) NumericValue.asNumber(a).getDouble();
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Value> args = ((ListValue) a).getItems();
|
||||
if (args.size()==0)
|
||||
throw new InternalExpressionException("trace needs more arguments");
|
||||
reach = (float) NumericValue.asNumber(args.get(0)).getDouble();
|
||||
if (args.size() > 1)
|
||||
{
|
||||
entities = false;
|
||||
for (int i = 1; i < args.size(); i++)
|
||||
{
|
||||
String what = args.get(i).getString();
|
||||
if (what.equalsIgnoreCase("entities"))
|
||||
entities = true;
|
||||
else if (what.equalsIgnoreCase("blocks")) {}
|
||||
else if (what.equalsIgnoreCase("liquids"))
|
||||
liquids = true;
|
||||
else throw new InternalExpressionException("Incorrect tracing: "+what);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (e instanceof ServerPlayerEntity && ((ServerPlayerEntity) e).interactionManager.isCreative())
|
||||
{
|
||||
reach = 5.0f;
|
||||
}
|
||||
|
||||
HitResult hitres;
|
||||
if (entities)
|
||||
hitres = Tracer.rayTrace(e, 1, reach, liquids);
|
||||
else
|
||||
hitres = Tracer.rayTraceBlocks(e, 1, reach, liquids);
|
||||
|
||||
switch (hitres.getType())
|
||||
{
|
||||
case MISS: return Value.NULL;
|
||||
case BLOCK: return new BlockValue(null, e.getEntityWorld(), ((BlockHitResult)hitres).getBlockPos() );
|
||||
case ENTITY: return new EntityValue(((EntityHitResult)hitres).getEntity());
|
||||
}
|
||||
return Value.NULL;
|
||||
});
|
||||
|
||||
put("nbt",(e, a) -> {
|
||||
CompoundTag nbttagcompound = e.toTag((new CompoundTag()));
|
||||
if (a==null)
|
||||
return new NBTSerializableValue(nbttagcompound);//StringValue(nbttagcompound.toString());
|
||||
NbtPathArgumentType.NbtPath path;
|
||||
try
|
||||
{
|
||||
path = NbtPathArgumentType.nbtPath().method_9362(new StringReader(a.getString()));
|
||||
}
|
||||
catch (CommandSyntaxException exc)
|
||||
{
|
||||
throw new InternalExpressionException("Incorrect path: "+a.getString());
|
||||
}
|
||||
String res = null;
|
||||
NbtPathArgumentType.NbtPath path = NBTSerializableValue.cachePath(a.getString());
|
||||
try
|
||||
{
|
||||
List<Tag> tags = path.get(nbttagcompound);
|
||||
@@ -331,7 +386,7 @@ public class EntityValue extends Value
|
||||
return Value.NULL;
|
||||
if (tags.size()==1)
|
||||
return NBTSerializableValue.decodeTag(tags.get(0));
|
||||
return ListValue.wrap(tags.stream().map(t -> NBTSerializableValue.decodeTag(t)).collect(Collectors.toList()));
|
||||
return ListValue.wrap(tags.stream().map(NBTSerializableValue::decodeTag).collect(Collectors.toList()));
|
||||
}
|
||||
catch (CommandSyntaxException ignored) { }
|
||||
return Value.NULL;
|
||||
@@ -504,9 +559,13 @@ public class EntityValue extends Value
|
||||
|
||||
});
|
||||
put("custom_name", (e, v) -> {
|
||||
String name = v.getString();
|
||||
if (name.isEmpty())
|
||||
if (v instanceof NullValue)
|
||||
{
|
||||
e.setCustomNameVisible(false);
|
||||
e.setCustomName(null);
|
||||
return;
|
||||
}
|
||||
e.setCustomNameVisible(true);
|
||||
e.setCustomName(new LiteralText(v.getString()));
|
||||
});
|
||||
put("dismount", (e, v) -> e.stopRiding() );
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package carpet.script.value;
|
||||
|
||||
import carpet.script.exception.ExpressionException;
|
||||
import carpet.script.value.Value;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -23,6 +23,12 @@ public class FunctionSignatureValue extends Value
|
||||
throw new ExpressionException("Function "+identifier+" is not defined yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeString()
|
||||
{
|
||||
throw new InternalExpressionException("How did you get here? Cannot get type of an internal struct.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value clone()
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package carpet.script.value;
|
||||
|
||||
import carpet.script.value.Value;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
|
||||
public class GlobalValue extends Value
|
||||
{
|
||||
@@ -21,4 +21,10 @@ public class GlobalValue extends Value
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeString()
|
||||
{
|
||||
throw new InternalExpressionException("How did you get here? Cannot get type of an internal struct.");
|
||||
}
|
||||
}
|
||||
@@ -111,5 +111,10 @@ public abstract class LazyListValue extends ListValue implements Iterator<Value>
|
||||
{
|
||||
throw new InternalExpressionException("get element can only be obtained for regular lists");
|
||||
}
|
||||
@Override
|
||||
public String getTypeString()
|
||||
{
|
||||
return "iterator";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -326,6 +326,11 @@ public class ListValue extends Value
|
||||
index = index % numitems;
|
||||
return items.get((int)index);
|
||||
}
|
||||
@Override
|
||||
public String getTypeString()
|
||||
{
|
||||
return "list";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -26,8 +26,6 @@ import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.lang.Math.abs;
|
||||
|
||||
public class NBTSerializableValue extends Value
|
||||
{
|
||||
private String nbtString = null;
|
||||
@@ -224,31 +222,38 @@ public class NBTSerializableValue extends Value
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value getElementAt(Value value)
|
||||
private static Map<String, NbtPathArgumentType.NbtPath> pathCache = new HashMap<>();
|
||||
public static NbtPathArgumentType.NbtPath cachePath(String arg)
|
||||
{
|
||||
String pathString = value.getString();
|
||||
|
||||
//return Value.NULL;
|
||||
|
||||
NbtPathArgumentType.NbtPath path;
|
||||
NbtPathArgumentType.NbtPath res = pathCache.get(arg);
|
||||
if (res != null)
|
||||
return res;
|
||||
try
|
||||
{
|
||||
path = NbtPathArgumentType.nbtPath().method_9362(new StringReader(pathString));
|
||||
res = NbtPathArgumentType.nbtPath().method_9362(new StringReader(arg));
|
||||
}
|
||||
catch (CommandSyntaxException exc)
|
||||
{
|
||||
throw new InternalExpressionException("Incorrect nbt path: "+pathString);
|
||||
throw new InternalExpressionException("Incorrect nbt path: "+arg);
|
||||
}
|
||||
String res = null;
|
||||
if (pathCache.size() > 1024)
|
||||
pathCache.clear();
|
||||
pathCache.put(arg, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value getElementAt(Value value)
|
||||
{
|
||||
NbtPathArgumentType.NbtPath path = cachePath(value.getString());
|
||||
try
|
||||
{
|
||||
List<Tag> tags = path.get(getTag());
|
||||
if (tags.size()==0)
|
||||
return Value.NULL;
|
||||
if (tags.size()==1)
|
||||
return new NBTSerializableValue(tags.get(0));
|
||||
return ListValue.wrap(tags.stream().map(NBTSerializableValue::new).collect(Collectors.toList()));
|
||||
return NBTSerializableValue.decodeTag(tags.get(0));
|
||||
return ListValue.wrap(tags.stream().map(NBTSerializableValue::decodeTag).collect(Collectors.toList()));
|
||||
}
|
||||
catch (CommandSyntaxException ignored) { }
|
||||
return Value.NULL;
|
||||
@@ -259,4 +264,10 @@ public class NBTSerializableValue extends Value
|
||||
index = index % numitems;
|
||||
return items.get((int)index); */
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeString()
|
||||
{
|
||||
return "nbt";
|
||||
}
|
||||
}
|
||||
@@ -38,4 +38,10 @@ public class NullValue extends NumericValue // TODO check nonsingleton code
|
||||
{
|
||||
return o instanceof NullValue ? 0 : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeString()
|
||||
{
|
||||
return "null";
|
||||
}
|
||||
}
|
||||
@@ -167,4 +167,10 @@ public class NumericValue extends Value
|
||||
return getLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeString()
|
||||
{
|
||||
return "number";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,4 +24,10 @@ public class StringValue extends Value
|
||||
{
|
||||
this.str = str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeString()
|
||||
{
|
||||
return "number";
|
||||
}
|
||||
}
|
||||
@@ -177,4 +177,6 @@ public abstract class Value implements Comparable<Value>, Cloneable
|
||||
{
|
||||
throw new InternalExpressionException("get element can only be obtained for lists and nbt values");
|
||||
}
|
||||
|
||||
public abstract String getTypeString();
|
||||
}
|
||||
@@ -211,6 +211,9 @@ public class CarpetSettings
|
||||
@Rule(desc = "Enables /player command to control/spawn players", category = COMMAND)
|
||||
public static boolean commandPlayer = true;
|
||||
|
||||
@Rule(desc = "Allows to track mobs AI via /track command", category = COMMAND)
|
||||
public static boolean commandTrackAI = true;
|
||||
|
||||
@Rule(desc = "Placing carpets may issue carpet commands for non-op players", category = SURVIVAL)
|
||||
public static boolean carpets = false;
|
||||
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
package carpet.utils;
|
||||
|
||||
import carpet.CarpetServer;
|
||||
import com.google.common.collect.Sets;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MobAI
|
||||
{
|
||||
private static Map<EntityType,Set<TrackingType>> aiTrackers = new HashMap<>();
|
||||
|
||||
public static void resetTrackers()
|
||||
{
|
||||
aiTrackers.clear();
|
||||
}
|
||||
|
||||
public static boolean isTracking(Entity e, TrackingType type)
|
||||
{
|
||||
Set<TrackingType> currentTrackers = aiTrackers.get(e.getType());
|
||||
if (currentTrackers == null)
|
||||
return false;
|
||||
return currentTrackers.contains(type);
|
||||
}
|
||||
|
||||
public static void clearTracking(EntityType etype)
|
||||
{
|
||||
aiTrackers.remove(etype);
|
||||
for(ServerWorld world : CarpetServer.minecraft_server.getWorlds() )
|
||||
{
|
||||
for (Entity e: world.getEntities(etype, Entity::hasCustomName))
|
||||
{
|
||||
e.setCustomNameVisible(false);
|
||||
e.setCustomName(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void startTracking(EntityType e, TrackingType type)
|
||||
{
|
||||
aiTrackers.putIfAbsent(e,Sets.newHashSet());
|
||||
aiTrackers.get(e).add(type);
|
||||
}
|
||||
|
||||
public static List<String> availbleTypes()
|
||||
{
|
||||
Set<EntityType> types = new HashSet<>();
|
||||
for (TrackingType type: TrackingType.values())
|
||||
{
|
||||
types.addAll(type.types);
|
||||
}
|
||||
return types.stream().map(t -> Registry.ENTITY_TYPE.getId(t).getPath()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<String> availableFor(EntityType<?> entityType)
|
||||
{
|
||||
Set<TrackingType> availableOptions = new HashSet<>();
|
||||
for (TrackingType type: TrackingType.values())
|
||||
for (EntityType etype: type.types)
|
||||
if (etype == entityType)
|
||||
availableOptions.add(type);
|
||||
return availableOptions.stream().map(t -> t.name).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public enum TrackingType
|
||||
{
|
||||
IRON_GOLEM_SPAWNING("iron_golem_spawning", Sets.newHashSet(EntityType.VILLAGER));
|
||||
public Set<EntityType> types;
|
||||
public String name;
|
||||
TrackingType(String name, Set<EntityType> applicableTypes)
|
||||
{
|
||||
this.name = name;
|
||||
types = applicableTypes;
|
||||
}
|
||||
|
||||
public static TrackingType byName(String aspect)
|
||||
{
|
||||
for (TrackingType type: values())
|
||||
if (type.name.equalsIgnoreCase(aspect))
|
||||
return type;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user