Merge pull request #56 from gnembon/tracing_functions
Tracing functions
This commit is contained in:
23 files changed
+710
-214
No files matched your search
@@ -11,6 +11,7 @@ import carpet.commands.DistanceCommand;
|
|||||||
import carpet.commands.DrawCommand;
|
import carpet.commands.DrawCommand;
|
||||||
import carpet.commands.InfoCommand;
|
import carpet.commands.InfoCommand;
|
||||||
import carpet.commands.LogCommand;
|
import carpet.commands.LogCommand;
|
||||||
|
import carpet.commands.MobAICommand;
|
||||||
import carpet.commands.PerimeterInfoCommand;
|
import carpet.commands.PerimeterInfoCommand;
|
||||||
import carpet.commands.PlayerCommand;
|
import carpet.commands.PlayerCommand;
|
||||||
import carpet.commands.ScriptCommand;
|
import carpet.commands.ScriptCommand;
|
||||||
@@ -22,6 +23,7 @@ import carpet.script.CarpetScriptServer;
|
|||||||
import carpet.settings.CarpetSettings;
|
import carpet.settings.CarpetSettings;
|
||||||
import carpet.settings.SettingsManager;
|
import carpet.settings.SettingsManager;
|
||||||
import carpet.utils.HUDController;
|
import carpet.utils.HUDController;
|
||||||
|
import carpet.utils.MobAI;
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import net.minecraft.server.command.ServerCommandSource;
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
import net.minecraft.server.MinecraftServer;
|
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);
|
e.onServerLoaded(server);
|
||||||
});
|
});
|
||||||
scriptServer = new CarpetScriptServer();
|
scriptServer = new CarpetScriptServer();
|
||||||
|
MobAI.resetTrackers();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void tick(MinecraftServer server)
|
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);
|
PerimeterInfoCommand.register(dispatcher);
|
||||||
DrawCommand.register(dispatcher);
|
DrawCommand.register(dispatcher);
|
||||||
ScriptCommand.register(dispatcher);
|
ScriptCommand.register(dispatcher);
|
||||||
|
MobAICommand.register(dispatcher);
|
||||||
extensions.forEach(e -> e.registerCommands(dispatcher));
|
extensions.forEach(e -> e.registerCommands(dispatcher));
|
||||||
//TestCommand.register(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ 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;
|
||||||
@@ -24,6 +25,7 @@ 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;
|
||||||
@@ -206,9 +208,17 @@ public class ScriptCommand
|
|||||||
suggests( (cc, bb) -> suggestMatching(CarpetServer.scriptServer.listAvailableModules(),bb)).
|
suggests( (cc, bb) -> suggestMatching(CarpetServer.scriptServer.listAvailableModules(),bb)).
|
||||||
executes((cc) ->
|
executes((cc) ->
|
||||||
{
|
{
|
||||||
boolean success = CarpetServer.scriptServer.addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "package"), false);
|
boolean success = CarpetServer.scriptServer.addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "package"), true);
|
||||||
return success?1:0;
|
return success?1:0;
|
||||||
})
|
}).
|
||||||
|
then(literal("shared").
|
||||||
|
executes((cc) ->
|
||||||
|
{
|
||||||
|
boolean success = CarpetServer.scriptServer.addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "package"), false);
|
||||||
|
return success?1:0;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
LiteralArgumentBuilder<ServerCommandSource> f = literal("unload").requires( (player) -> player.hasPermissionLevel(2) ).
|
LiteralArgumentBuilder<ServerCommandSource> f = literal("unload").requires( (player) -> player.hasPermissionLevel(2) ).
|
||||||
then(argument("package", StringArgumentType.word()).
|
then(argument("package", StringArgumentType.word()).
|
||||||
@@ -267,8 +277,8 @@ public class ScriptCommand
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
String name = StringArgumentType.getString(context, "package").toLowerCase(Locale.ROOT);
|
String name = StringArgumentType.getString(context, "package").toLowerCase(Locale.ROOT);
|
||||||
return CarpetServer.scriptServer.modules.getOrDefault(name, CarpetServer.scriptServer.globalHost);
|
ScriptHost parentHost = CarpetServer.scriptServer.modules.getOrDefault(name, CarpetServer.scriptServer.globalHost);
|
||||||
|
return parentHost.retrieveForExecution(context.getSource());
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException ignored)
|
catch (IllegalArgumentException ignored)
|
||||||
{
|
{
|
||||||
@@ -277,7 +287,6 @@ public class ScriptCommand
|
|||||||
}
|
}
|
||||||
private static Collection<String> suggestFunctionCalls(CommandContext<ServerCommandSource> c)
|
private static Collection<String> suggestFunctionCalls(CommandContext<ServerCommandSource> c)
|
||||||
{
|
{
|
||||||
ServerCommandSource s = c.getSource();
|
|
||||||
ScriptHost host = getHost(c);
|
ScriptHost host = getHost(c);
|
||||||
return host.getPublicFunctions();
|
return host.getPublicFunctions();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -122,6 +122,11 @@ public class CarpetEventServer
|
|||||||
{
|
{
|
||||||
callList.removeIf((c)-> c.udf.equalsIgnoreCase(callName) && ( hostName == null || c.host.equalsIgnoreCase(hostName) ) );
|
callList.removeIf((c)-> c.udf.equalsIgnoreCase(callName) && ( hostName == null || c.host.equalsIgnoreCase(hostName) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeAllCalls(String hostName)
|
||||||
|
{
|
||||||
|
callList.removeIf((c)-> c.host.equals(hostName));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, CallbackList> eventHandlers = new HashMap<>();
|
public Map<String, CallbackList> eventHandlers = new HashMap<>();
|
||||||
@@ -194,6 +199,11 @@ public class CarpetEventServer
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeAllHostEvents(String hostName)
|
||||||
|
{
|
||||||
|
eventHandlers.forEach((e, a) -> a.removeAllCalls(hostName));
|
||||||
|
}
|
||||||
|
|
||||||
private Callback decodeCallback(String funName)
|
private Callback decodeCallback(String funName)
|
||||||
{
|
{
|
||||||
Pattern find = Pattern.compile("(\\w+)\\(from (\\w+)\\)");
|
Pattern find = Pattern.compile("(\\w+)\\(from (\\w+)\\)");
|
||||||
|
|||||||
@@ -35,13 +35,17 @@ import net.minecraft.entity.Entity;
|
|||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraft.entity.EquipmentSlot;
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
import net.minecraft.entity.ItemEntity;
|
import net.minecraft.entity.ItemEntity;
|
||||||
|
import net.minecraft.entity.LightningEntity;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.SpawnType;
|
||||||
import net.minecraft.entity.decoration.ArmorStandEntity;
|
import net.minecraft.entity.decoration.ArmorStandEntity;
|
||||||
|
import net.minecraft.entity.mob.MobEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.BlockItem;
|
import net.minecraft.item.BlockItem;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.Items;
|
import net.minecraft.item.Items;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.nbt.Tag;
|
||||||
import net.minecraft.particle.ParticleEffect;
|
import net.minecraft.particle.ParticleEffect;
|
||||||
import net.minecraft.predicate.entity.EntityPredicates;
|
import net.minecraft.predicate.entity.EntityPredicates;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
@@ -53,6 +57,8 @@ import net.minecraft.sound.SoundCategory;
|
|||||||
import net.minecraft.state.StateFactory;
|
import net.minecraft.state.StateFactory;
|
||||||
import net.minecraft.state.property.Property;
|
import net.minecraft.state.property.Property;
|
||||||
import net.minecraft.text.LiteralText;
|
import net.minecraft.text.LiteralText;
|
||||||
|
import net.minecraft.text.TranslatableText;
|
||||||
|
import net.minecraft.util.Clearable;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.hit.BlockHitResult;
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
import net.minecraft.util.hit.EntityHitResult;
|
import net.minecraft.util.hit.EntityHitResult;
|
||||||
@@ -73,6 +79,7 @@ import org.apache.commons.lang3.tuple.Pair;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@@ -599,7 +606,7 @@ public class CarpetExpression
|
|||||||
throw new InternalExpressionException("Block requires at least one parameter");
|
throw new InternalExpressionException("Block requires at least one parameter");
|
||||||
}
|
}
|
||||||
CompoundTag tag = BlockValue.fromParams(cc, lv, 0, true).block.getData();
|
CompoundTag tag = BlockValue.fromParams(cc, lv, 0, true).block.getData();
|
||||||
if (tag.isEmpty())
|
if (tag == null)
|
||||||
return (c_, t_) -> Value.NULL;
|
return (c_, t_) -> Value.NULL;
|
||||||
Value retval = new NBTSerializableValue(tag);
|
Value retval = new NBTSerializableValue(tag);
|
||||||
return (c_, t_) -> retval;
|
return (c_, t_) -> retval;
|
||||||
@@ -672,7 +679,6 @@ public class CarpetExpression
|
|||||||
this.expr.addLazyFunction("blast_resistance", -1, (c, t, lv) ->
|
this.expr.addLazyFunction("blast_resistance", -1, (c, t, lv) ->
|
||||||
genericStateTest(c, "blast_resistance", lv, (s, p, w) -> new NumericValue(s.getBlock().getBlastResistance())));
|
genericStateTest(c, "blast_resistance", lv, (s, p, w) -> new NumericValue(s.getBlock().getBlastResistance())));
|
||||||
|
|
||||||
// Deprecated
|
|
||||||
this.expr.addLazyFunction("top", -1, (c, t, lv) ->
|
this.expr.addLazyFunction("top", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
String type = lv.get(0).evalValue(c).getString().toLowerCase(Locale.ROOT);
|
String type = lv.get(0).evalValue(c).getString().toLowerCase(Locale.ROOT);
|
||||||
@@ -686,20 +692,10 @@ public class CarpetExpression
|
|||||||
case "surface": htype = Heightmap.Type.WORLD_SURFACE; break;
|
case "surface": htype = Heightmap.Type.WORLD_SURFACE; break;
|
||||||
default: throw new InternalExpressionException("Unknown heightmap type: "+type);
|
default: throw new InternalExpressionException("Unknown heightmap type: "+type);
|
||||||
}
|
}
|
||||||
int x;
|
BlockValue.LocatorResult locator = BlockValue.fromParams((CarpetContext)c, lv, 1);
|
||||||
int z;
|
BlockPos pos = locator.block.getPos();
|
||||||
Value v1 = lv.get(1).evalValue(c);
|
int x = pos.getX();
|
||||||
if (v1 instanceof BlockValue)
|
int z = pos.getZ();
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
Value retval = new NumericValue(((CarpetContext)c).s.getWorld().getChunk(x >> 4, z >> 4).sampleHeightmap(htype, x & 15, z & 15) + 1);
|
Value retval = new NumericValue(((CarpetContext)c).s.getWorld().getChunk(x >> 4, z >> 4).sampleHeightmap(htype, x & 15, z & 15) + 1);
|
||||||
return (c_, t_) -> retval;
|
return (c_, t_) -> retval;
|
||||||
//BlockPos pos = new BlockPos(x,y,z);
|
//BlockPos pos = new BlockPos(x,y,z);
|
||||||
@@ -783,7 +779,8 @@ public class CarpetExpression
|
|||||||
return (c_, t_) -> Value.FALSE;
|
return (c_, t_) -> Value.FALSE;
|
||||||
CarpetSettings.impendingFillSkipUpdates = !CarpetSettings.fillUpdates;
|
CarpetSettings.impendingFillSkipUpdates = !CarpetSettings.fillUpdates;
|
||||||
BlockPos targetPos = targetLocator.block.getPos();
|
BlockPos targetPos = targetLocator.block.getPos();
|
||||||
cc.s.getWorld().setBlockState(targetPos, sourceBlockState, 2);
|
Clearable.clear(world.getBlockEntity(targetPos));
|
||||||
|
world.setBlockState(targetPos, sourceBlockState, 2);
|
||||||
|
|
||||||
if ( data != null)
|
if ( data != null)
|
||||||
{
|
{
|
||||||
@@ -935,32 +932,27 @@ public class CarpetExpression
|
|||||||
{
|
{
|
||||||
BlockValue.LocatorResult locator = BlockValue.fromParams((CarpetContext) c, lv, 0);
|
BlockValue.LocatorResult locator = BlockValue.fromParams((CarpetContext) c, lv, 0);
|
||||||
BlockState state = locator.block.getBlockState();
|
BlockState state = locator.block.getBlockState();
|
||||||
|
if (lv.size() <= locator.offset)
|
||||||
|
throw new InternalExpressionException("property requires to specify a property to query");
|
||||||
String tag = lv.get(locator.offset).evalValue(c).getString();
|
String tag = lv.get(locator.offset).evalValue(c).getString();
|
||||||
StateFactory<Block, BlockState> states = state.getBlock().getStateFactory();
|
StateFactory<Block, BlockState> states = state.getBlock().getStateFactory();
|
||||||
Property<?> property = states.getProperty(tag);
|
Property<?> property = states.getProperty(tag);
|
||||||
if (property == null)
|
if (property == null)
|
||||||
return LazyValue.NULL;
|
return LazyValue.NULL;
|
||||||
Value retval = new StringValue(state.get(property).toString());
|
Value retval = new StringValue(state.get(property).toString().toLowerCase(Locale.ROOT));
|
||||||
return (_c, _t) -> retval;
|
return (_c, _t) -> retval;
|
||||||
});
|
});
|
||||||
|
|
||||||
/*this.expr.addLazyFunction("trace_block", -1, (c, t, lv) -> {
|
this.expr.addLazyFunction("block_properties", -1, (c, t, lv) ->
|
||||||
Value entityValue = lv.get(0).evalValue(c);
|
{
|
||||||
if (!(entityValue instanceof EntityValue))
|
BlockValue.LocatorResult locator = BlockValue.fromParams((CarpetContext) c, lv, 0);
|
||||||
throw new InternalExpressionException("First argument of trace_block should be an entity");
|
BlockState state = locator.block.getBlockState();
|
||||||
Entity e = ((EntityValue) entityValue).getEntity();
|
StateFactory<Block, BlockState> states = state.getBlock().getStateFactory();
|
||||||
HitResult hitres = Tracer.traceEntityLook(e, 20);
|
Value res = ListValue.wrap(states.getProperties().stream().map(
|
||||||
switch (hitres.getType())
|
p -> new StringValue(p.getName())).collect(Collectors.toList())
|
||||||
{
|
);
|
||||||
case MISS:
|
return (_c, _t) -> res;
|
||||||
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) -> {
|
this.expr.addLazyFunction("set_biome", -1, (c, t, lv) -> {
|
||||||
CarpetContext cc = (CarpetContext)c;
|
CarpetContext cc = (CarpetContext)c;
|
||||||
@@ -1141,9 +1133,9 @@ public class CarpetExpression
|
|||||||
{
|
{
|
||||||
Value nbtValue = lv.get(inventoryLocator.offset+3).evalValue(c);
|
Value nbtValue = lv.get(inventoryLocator.offset+3).evalValue(c);
|
||||||
if (nbtValue instanceof NBTSerializableValue)
|
if (nbtValue instanceof NBTSerializableValue)
|
||||||
nbt = ((NBTSerializableValue)nbtValue).getTag();
|
nbt = ((NBTSerializableValue)nbtValue).getCompoundTag();
|
||||||
else
|
else
|
||||||
nbt = new NBTSerializableValue(nbtValue.getString()).getTag();
|
nbt = new NBTSerializableValue(nbtValue.getString()).getCompoundTag();
|
||||||
}
|
}
|
||||||
ItemStackArgument newitem = NBTSerializableValue.parseItem(
|
ItemStackArgument newitem = NBTSerializableValue.parseItem(
|
||||||
lv.get(inventoryLocator.offset+2).evalValue(c).getString(),
|
lv.get(inventoryLocator.offset+2).evalValue(c).getString(),
|
||||||
@@ -1597,6 +1589,60 @@ public class CarpetExpression
|
|||||||
return (cc, tt) -> finalVar;
|
return (cc, tt) -> finalVar;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.expr.addLazyFunction("spawn", -1, (c, t, lv) -> {
|
||||||
|
CarpetContext cc = (CarpetContext)c;
|
||||||
|
if (lv.size() < 2)
|
||||||
|
throw new InternalExpressionException("spawn function takes mob name, and position to spawn");
|
||||||
|
String entityString = lv.get(0).evalValue(c).getString();
|
||||||
|
Identifier entityId;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
entityId = Identifier.fromCommandInput(new StringReader(entityString));
|
||||||
|
EntityType type = Registry.ENTITY_TYPE.getOrEmpty(entityId).orElse(null);
|
||||||
|
if (type == null || !type.isSummonable())
|
||||||
|
return LazyValue.NULL;
|
||||||
|
}
|
||||||
|
catch (CommandSyntaxException exception)
|
||||||
|
{
|
||||||
|
return LazyValue.NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockValue.VectorLocator position = BlockValue.locateVec(cc, lv, 1);
|
||||||
|
if (position.fromBlock)
|
||||||
|
position.vec = position.vec.subtract(0, 0.5, 0);
|
||||||
|
CompoundTag tag = new CompoundTag();
|
||||||
|
boolean hasTag = false;
|
||||||
|
if (lv.size() > position.offset)
|
||||||
|
{
|
||||||
|
hasTag = true;
|
||||||
|
tag = new NBTSerializableValue(lv.get(position.offset).evalValue(c).getString()).getCompoundTag();
|
||||||
|
}
|
||||||
|
tag.putString("id", entityId.toString());
|
||||||
|
Vec3d vec3d = position.vec;
|
||||||
|
|
||||||
|
if (EntityType.getId(EntityType.LIGHTNING_BOLT).equals(entityId)) {
|
||||||
|
LightningEntity lightningEntity_1 = new LightningEntity(cc.s.getWorld(), vec3d.x, vec3d.y, vec3d.z, false);
|
||||||
|
cc.s.getWorld().addLightning(lightningEntity_1);
|
||||||
|
cc.s.sendFeedback(new TranslatableText("commands.summon.success", lightningEntity_1.getDisplayName()), true);
|
||||||
|
return LazyValue.NULL;
|
||||||
|
} else {
|
||||||
|
ServerWorld serverWorld = cc.s.getWorld();
|
||||||
|
Entity entity_1 = EntityType.loadEntityWithPassengers(tag, serverWorld, (entity_1x) -> {
|
||||||
|
entity_1x.setPositionAndAngles(vec3d.x, vec3d.y, vec3d.z, entity_1x.yaw, entity_1x.pitch);
|
||||||
|
return !serverWorld.method_18768(entity_1x) ? null : entity_1x;
|
||||||
|
});
|
||||||
|
if (entity_1 == null) {
|
||||||
|
return LazyValue.NULL;
|
||||||
|
} else {
|
||||||
|
if (!hasTag && entity_1 instanceof MobEntity) {
|
||||||
|
((MobEntity)entity_1).initialize(serverWorld, serverWorld.getLocalDifficulty(new BlockPos(entity_1)), SpawnType.COMMAND, null, null);
|
||||||
|
}
|
||||||
|
Value res = new EntityValue(entity_1);
|
||||||
|
return (_c, _t) -> res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.expr.addLazyFunction("entity_id", 1, (c, t, lv) ->
|
this.expr.addLazyFunction("entity_id", 1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
Value who = lv.get(0).evalValue(c);
|
Value who = lv.get(0).evalValue(c);
|
||||||
@@ -1661,7 +1707,6 @@ public class CarpetExpression
|
|||||||
return (c_, t_) -> ListValue.wrap(retlist);
|
return (c_, t_) -> ListValue.wrap(retlist);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
this.expr.addLazyFunction("query", -1, (c, t, lv) -> {
|
this.expr.addLazyFunction("query", -1, (c, t, lv) -> {
|
||||||
if (lv.size()<2)
|
if (lv.size()<2)
|
||||||
{
|
{
|
||||||
@@ -2441,15 +2486,16 @@ public class CarpetExpression
|
|||||||
this.expr.addLazyFunction("print", 1, (c, t, lv) ->
|
this.expr.addLazyFunction("print", 1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
ServerCommandSource s = ((CarpetContext)c).s;
|
ServerCommandSource s = ((CarpetContext)c).s;
|
||||||
|
Value res = lv.get(0).evalValue(c);
|
||||||
if (s.getEntity() instanceof PlayerEntity)
|
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
|
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
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class CarpetScriptServer
|
|||||||
|
|
||||||
public CarpetScriptServer()
|
public CarpetScriptServer()
|
||||||
{
|
{
|
||||||
globalHost = createMinecraftScriptHost(null, null);
|
globalHost = createMinecraftScriptHost(null, null, false, null);
|
||||||
events = new CarpetEventServer();
|
events = new CarpetEventServer();
|
||||||
modules = new HashMap<>();
|
modules = new HashMap<>();
|
||||||
tickStart = 0L;
|
tickStart = 0L;
|
||||||
@@ -56,6 +56,17 @@ public class CarpetScriptServer
|
|||||||
|
|
||||||
ModuleInterface getModule(String name)
|
ModuleInterface getModule(String name)
|
||||||
{
|
{
|
||||||
|
File folder = CarpetServer.minecraft_server.getLevelStorage().resolveFile(
|
||||||
|
CarpetServer.minecraft_server.getLevelName(), "scripts");
|
||||||
|
File[] listOfFiles = folder.listFiles();
|
||||||
|
if (listOfFiles != null)
|
||||||
|
for (File script : listOfFiles)
|
||||||
|
{
|
||||||
|
if (script.getName().equalsIgnoreCase(name+".sc"))
|
||||||
|
{
|
||||||
|
return new FileModule(script);
|
||||||
|
}
|
||||||
|
}
|
||||||
for (ModuleInterface moduleData : bundledModuleData)
|
for (ModuleInterface moduleData : bundledModuleData)
|
||||||
{
|
{
|
||||||
if (moduleData.getName().equalsIgnoreCase(name))
|
if (moduleData.getName().equalsIgnoreCase(name))
|
||||||
@@ -63,19 +74,6 @@ public class CarpetScriptServer
|
|||||||
return moduleData;
|
return moduleData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
File folder = CarpetServer.minecraft_server.getLevelStorage().resolveFile(
|
|
||||||
CarpetServer.minecraft_server.getLevelName(), "scripts");
|
|
||||||
File[] listOfFiles = folder.listFiles();
|
|
||||||
if (listOfFiles == null)
|
|
||||||
return null;
|
|
||||||
for (File script : listOfFiles)
|
|
||||||
{
|
|
||||||
if (script.getName().equalsIgnoreCase(name+".sc"))
|
|
||||||
{
|
|
||||||
return new FileModule(script);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,8 +82,7 @@ public class CarpetScriptServer
|
|||||||
List<String> moduleNames = new ArrayList<>();
|
List<String> moduleNames = new ArrayList<>();
|
||||||
for (ModuleInterface mi: bundledModuleData)
|
for (ModuleInterface mi: bundledModuleData)
|
||||||
{
|
{
|
||||||
if (!modules.containsKey(mi.getName()))
|
moduleNames.add(mi.getName());
|
||||||
moduleNames.add(mi.getName());
|
|
||||||
}
|
}
|
||||||
File folder = CarpetServer.minecraft_server.getLevelStorage().resolveFile(
|
File folder = CarpetServer.minecraft_server.getLevelStorage().resolveFile(
|
||||||
CarpetServer.minecraft_server.getLevelName(), "scripts");
|
CarpetServer.minecraft_server.getLevelName(), "scripts");
|
||||||
@@ -97,8 +94,7 @@ public class CarpetScriptServer
|
|||||||
if (script.getName().endsWith(".sc"))
|
if (script.getName().endsWith(".sc"))
|
||||||
{
|
{
|
||||||
String name = script.getName().replaceFirst("\\.sc","").toLowerCase(Locale.ROOT);
|
String name = script.getName().replaceFirst("\\.sc","").toLowerCase(Locale.ROOT);
|
||||||
if (!modules.containsKey(name))
|
moduleNames.add(name);
|
||||||
moduleNames.add(name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return moduleNames;
|
return moduleNames;
|
||||||
@@ -112,12 +108,35 @@ public class CarpetScriptServer
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static ScriptHost createMinecraftScriptHost(String name, ModuleInterface code)
|
private ScriptHost createMinecraftScriptHost(String name, ModuleInterface module, boolean perPlayer, ServerCommandSource source)
|
||||||
{
|
{
|
||||||
ScriptHost host = new ScriptHost(name);
|
ScriptHost host = new ScriptHost(name, module, perPlayer );
|
||||||
host.globalVariables.put("_x", (c, t) -> Value.ZERO);
|
host.globalVariables.put("_x", (c, t) -> Value.ZERO);
|
||||||
host.globalVariables.put("_y", (c, t) -> Value.ZERO);
|
host.globalVariables.put("_y", (c, t) -> Value.ZERO);
|
||||||
host.globalVariables.put("_z", (c, t) -> Value.ZERO);
|
host.globalVariables.put("_z", (c, t) -> Value.ZERO);
|
||||||
|
// parse code and convert to expression
|
||||||
|
if (module != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String code = module.getCode();
|
||||||
|
if (code == null)
|
||||||
|
{
|
||||||
|
Messenger.m(source, "r Unable to load the package - not found");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
setChatErrorSnooper(source);
|
||||||
|
CarpetExpression ex = new CarpetExpression(code, source, new BlockPos(0, 0, 0));
|
||||||
|
ex.getExpr().asAModule();
|
||||||
|
ex.scriptRunCommand(host, new BlockPos(source.getPosition()));
|
||||||
|
}
|
||||||
|
catch (CarpetExpressionException e)
|
||||||
|
{
|
||||||
|
Messenger.m(source, "r Exception white evaluating expression at " + new BlockPos(source.getPosition()) + ": " + e.getMessage());
|
||||||
|
resetErrorSnooper();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
return host;
|
return host;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +145,12 @@ public class CarpetScriptServer
|
|||||||
//TODO add per player modules to support player actions better on a server
|
//TODO add per player modules to support player actions better on a server
|
||||||
name = name.toLowerCase(Locale.ROOT);
|
name = name.toLowerCase(Locale.ROOT);
|
||||||
ModuleInterface module = getModule(name);
|
ModuleInterface module = getModule(name);
|
||||||
ScriptHost newHost = createMinecraftScriptHost(name, module);
|
ScriptHost newHost = createMinecraftScriptHost(name, module, perPlayer, source);
|
||||||
|
if (newHost == null)
|
||||||
|
{
|
||||||
|
Messenger.m(source, "r Failed to add a module");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (module == null)
|
if (module == null)
|
||||||
{
|
{
|
||||||
Messenger.m(source, "r Unable to locate the package, but created empty host "+name+" instead");
|
Messenger.m(source, "r Unable to locate the package, but created empty host "+name+" instead");
|
||||||
@@ -134,27 +158,12 @@ public class CarpetScriptServer
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
String code = module.getCode();
|
String code = module.getCode();
|
||||||
if (code == null)
|
if (module.getCode() == null)
|
||||||
{
|
{
|
||||||
Messenger.m(source, "r Unable to load the package - not found");
|
Messenger.m(source, "r Unable to load the package - not found");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// parse code and convert to expression
|
|
||||||
// fill functions etc.
|
|
||||||
// possibly add a command
|
|
||||||
try
|
|
||||||
{
|
|
||||||
setChatErrorSnooper(source);
|
|
||||||
CarpetExpression ex = new CarpetExpression(module.getCode(), source, new BlockPos(0, 0, 0));
|
|
||||||
ex.getExpr().asAModule();
|
|
||||||
ex.scriptRunCommand(newHost, new BlockPos(source.getPosition()));
|
|
||||||
}
|
|
||||||
catch (CarpetExpressionException e)
|
|
||||||
{
|
|
||||||
Messenger.m(source, "r Exception white evaluating expression at "+new BlockPos(source.getPosition())+": "+e.getMessage());
|
|
||||||
resetErrorSnooper();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
modules.put(name, newHost);
|
modules.put(name, newHost);
|
||||||
|
|
||||||
addEvents(source, name);
|
addEvents(source, name);
|
||||||
@@ -206,7 +215,7 @@ public class CarpetScriptServer
|
|||||||
requires((player) -> modules.containsKey(hostName)).
|
requires((player) -> modules.containsKey(hostName)).
|
||||||
executes( (c) ->
|
executes( (c) ->
|
||||||
{
|
{
|
||||||
Messenger.m(c.getSource(), "gi "+modules.get(hostName).call(c.getSource(),"__command", null, ""));
|
Messenger.m(c.getSource(), "gi "+modules.get(hostName).retrieveForExecution(c.getSource()).call(c.getSource(),"__command", null, ""));
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -218,7 +227,7 @@ public class CarpetScriptServer
|
|||||||
executes( (c) -> {
|
executes( (c) -> {
|
||||||
Messenger.m(
|
Messenger.m(
|
||||||
c.getSource(),
|
c.getSource(),
|
||||||
"gi "+modules.get(hostName).call(
|
"gi "+modules.get(hostName).retrieveForExecution(c.getSource()).call(
|
||||||
c.getSource(),
|
c.getSource(),
|
||||||
function,
|
function,
|
||||||
null,
|
null,
|
||||||
@@ -231,7 +240,7 @@ public class CarpetScriptServer
|
|||||||
executes( (c) -> {
|
executes( (c) -> {
|
||||||
Messenger.m(
|
Messenger.m(
|
||||||
c.getSource(),
|
c.getSource(),
|
||||||
"gi "+modules.get(hostName).call(
|
"gi "+modules.get(hostName).retrieveForExecution(c.getSource()).call(
|
||||||
c.getSource(),
|
c.getSource(),
|
||||||
function,
|
function,
|
||||||
null,
|
null,
|
||||||
@@ -304,6 +313,7 @@ public class CarpetScriptServer
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// stop all events associated with name
|
// stop all events associated with name
|
||||||
|
events.removeAllHostEvents(name);
|
||||||
modules.remove(name);
|
modules.remove(name);
|
||||||
CarpetServer.settingsManager.notifyPlayersCommandsChanged();
|
CarpetServer.settingsManager.notifyPlayersCommandsChanged();
|
||||||
Messenger.m(source, "w Removed host "+name);
|
Messenger.m(source, "w Removed host "+name);
|
||||||
@@ -319,7 +329,7 @@ public class CarpetScriptServer
|
|||||||
{
|
{
|
||||||
ScriptHost host = globalHost;
|
ScriptHost host = globalHost;
|
||||||
if (hostname != null)
|
if (hostname != null)
|
||||||
host = modules.get(hostname);
|
host = modules.get(hostname).retrieveForExecution(source);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
host.callUDF(origin, source, host.globalFunctions.get(udf_name), argv);
|
host.callUDF(origin, source, host.globalFunctions.get(udf_name), argv);
|
||||||
|
|||||||
@@ -498,21 +498,9 @@ public class Expression implements Cloneable
|
|||||||
Value.assertNotNull(v);
|
Value.assertNotNull(v);
|
||||||
return lazyfun.apply(c, t, v);
|
return lazyfun.apply(c, t, v);
|
||||||
}
|
}
|
||||||
catch (InternalExpressionException exc)
|
catch (RuntimeException exc)
|
||||||
{
|
{
|
||||||
throw new ExpressionException(e, token, exc.getMessage());
|
throw handleCodeException(exc, e, token);
|
||||||
}
|
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -532,21 +520,9 @@ public class Expression implements Cloneable
|
|||||||
Value.assertNotNull(v1, v2);
|
Value.assertNotNull(v1, v2);
|
||||||
return lazyfun.apply(c, type, e, t, 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());
|
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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -565,26 +541,27 @@ public class Expression implements Cloneable
|
|||||||
Value.assertNotNull(v1, v2);
|
Value.assertNotNull(v1, v2);
|
||||||
return lazyfun.apply(c, t, v1, v2);
|
return lazyfun.apply(c, t, v1, v2);
|
||||||
}
|
}
|
||||||
catch (InternalExpressionException exc)
|
catch (RuntimeException exc)
|
||||||
{
|
{
|
||||||
throw new ExpressionException(e, token, exc.getMessage());
|
throw handleCodeException(exc, e, token);
|
||||||
}
|
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
private void addUnaryOperator(String surface, boolean leftAssoc, Function<Value, Value> fun)
|
||||||
{
|
{
|
||||||
operators.put(surface+"u", new AbstractUnaryOperator(precedence.get("unary+-!"), leftAssoc)
|
operators.put(surface+"u", new AbstractUnaryOperator(precedence.get("unary+-!"), leftAssoc)
|
||||||
@@ -679,21 +656,9 @@ public class Expression implements Cloneable
|
|||||||
{
|
{
|
||||||
return fun.apply(c, i, lazyParams);
|
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());
|
throw new ExpressionException(function_context, t, "Your math is wrong, "+exc.getMessage());
|
||||||
}
|
}
|
||||||
catch (ExitStatement exit)
|
catch (ExitStatement | ExpressionException exit)
|
||||||
{
|
{
|
||||||
throw exit;
|
throw exit;
|
||||||
}
|
}
|
||||||
@@ -1060,7 +1025,7 @@ public class Expression implements Cloneable
|
|||||||
Value ret = lv.get(lv.size() - 1).evalValue(c);
|
Value ret = lv.get(lv.size() - 1).evalValue(c);
|
||||||
return (cc, tt) -> ret;
|
return (cc, tt) -> ret;
|
||||||
}
|
}
|
||||||
return (cc, tt) -> Value.ZERO;
|
return (cc, tt) -> Value.NULL;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1892,18 +1857,7 @@ public class Expression implements Cloneable
|
|||||||
return LazyListValue.range(from, to, step);
|
return LazyListValue.range(from, to, step);
|
||||||
});
|
});
|
||||||
|
|
||||||
addBinaryFunction("get", (v1, v2) ->
|
addBinaryFunction("get", (v1, v2) -> v1.getElementAt(v2));
|
||||||
{
|
|
||||||
if (v1 instanceof LazyListValue || !(v1 instanceof ListValue))
|
|
||||||
throw new InternalExpressionException("First argument of get should be a list");
|
|
||||||
List<Value> items = ((ListValue)v1).getItems();
|
|
||||||
long index = NumericValue.asNumber(v2).getLong();
|
|
||||||
int numitems = items.size();
|
|
||||||
long range = abs(index)/numitems;
|
|
||||||
index += (range+2)*numitems;
|
|
||||||
index = index % numitems;
|
|
||||||
return items.get((int)index);
|
|
||||||
});
|
|
||||||
|
|
||||||
//Deprecated, use "get" instead
|
//Deprecated, use "get" instead
|
||||||
addBinaryFunction("element", (v1, v2) ->
|
addBinaryFunction("element", (v1, v2) ->
|
||||||
@@ -2521,6 +2475,8 @@ public class Expression implements Cloneable
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addUnaryFunction("type", v -> new StringValue(v.getTypeString()));
|
||||||
|
|
||||||
addUnaryFunction("length", v -> new NumericValue(v.length()));
|
addUnaryFunction("length", v -> new NumericValue(v.length()));
|
||||||
addLazyFunction("rand", 1, (c, t, lv) -> {
|
addLazyFunction("rand", 1, (c, t, lv) -> {
|
||||||
Value argument = lv.get(0).evalValue(c);
|
Value argument = lv.get(0).evalValue(c);
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ import carpet.script.exception.InvalidCallbackException;
|
|||||||
import carpet.script.value.NumericValue;
|
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 com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import net.minecraft.server.command.ServerCommandSource;
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
@@ -23,22 +25,21 @@ import static java.lang.Math.max;
|
|||||||
|
|
||||||
public class ScriptHost
|
public class ScriptHost
|
||||||
{
|
{
|
||||||
|
public final Map<String, ScriptHost> userHosts = new HashMap<>();
|
||||||
public final Map<String, UserDefinedFunction> globalFunctions = new HashMap<>();
|
public Map<String, UserDefinedFunction> globalFunctions = new HashMap<>();
|
||||||
|
public Map<String, LazyValue> globalVariables = new HashMap<>();
|
||||||
public final Map<String, LazyValue> globalVariables = new HashMap<>();
|
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
public String getName() {return name;}
|
public String getName() {return name;}
|
||||||
|
|
||||||
private ModuleInterface myCode;
|
private final ModuleInterface myCode;
|
||||||
|
public final boolean perUser;
|
||||||
|
|
||||||
ScriptHost(String name) { this(name, null);}
|
ScriptHost(String name, ModuleInterface code, boolean perUser)
|
||||||
|
|
||||||
ScriptHost(String name, ModuleInterface code)
|
|
||||||
{
|
{
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.myCode = code;
|
this.myCode = code;
|
||||||
|
this.perUser = perUser;
|
||||||
globalVariables.put("euler", (c, t) -> Expression.euler);
|
globalVariables.put("euler", (c, t) -> Expression.euler);
|
||||||
globalVariables.put("pi", (c, t) -> Expression.PI);
|
globalVariables.put("pi", (c, t) -> Expression.PI);
|
||||||
globalVariables.put("null", (c, t) -> Value.NULL);
|
globalVariables.put("null", (c, t) -> Value.NULL);
|
||||||
@@ -51,6 +52,35 @@ public class ScriptHost
|
|||||||
globalVariables.put("_a", (c, t) -> Value.ZERO);
|
globalVariables.put("_a", (c, t) -> Value.ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ScriptHost retrieveForExecution(String /*Nullable*/ user)
|
||||||
|
{
|
||||||
|
if (!perUser)
|
||||||
|
return this;
|
||||||
|
ScriptHost userHost = userHosts.get(user);
|
||||||
|
if (userHost != null)
|
||||||
|
return userHost;
|
||||||
|
userHost = new ScriptHost(this.name, myCode, false);
|
||||||
|
userHost.globalVariables.putAll(this.globalVariables);
|
||||||
|
userHost.globalFunctions.putAll(this.globalFunctions);
|
||||||
|
userHosts.put(user, userHost);
|
||||||
|
return userHost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScriptHost retrieveForExecution(ServerCommandSource source)
|
||||||
|
{
|
||||||
|
if (!perUser)
|
||||||
|
return this;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ServerPlayerEntity player = source.getPlayer();
|
||||||
|
return retrieveForExecution(player.getName().getString());
|
||||||
|
}
|
||||||
|
catch (CommandSyntaxException e)
|
||||||
|
{
|
||||||
|
return retrieveForExecution((String)null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Expression getExpressionForFunction(String name)
|
public Expression getExpressionForFunction(String name)
|
||||||
{
|
{
|
||||||
return globalFunctions.get(name).getExpression();
|
return globalFunctions.get(name).getExpression();
|
||||||
@@ -190,4 +220,6 @@ public class ScriptHost
|
|||||||
CarpetSettings.LOG.error("Callback failed: "+e.getMessage());
|
CarpetSettings.LOG.error("Callback failed: "+e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -78,7 +78,7 @@ public class BlockValue extends Value
|
|||||||
Value v1 = params.get(0 + offset).evalValue(c);
|
Value v1 = params.get(0 + offset).evalValue(c);
|
||||||
if (v1 instanceof BlockValue)
|
if (v1 instanceof BlockValue)
|
||||||
{
|
{
|
||||||
return new VectorLocator(new Vec3d(((BlockValue) v1).getPos()).add(0.5,0.5,0.5), 1+offset);
|
return (new VectorLocator(new Vec3d(((BlockValue) v1).getPos()).add(0.5,0.5,0.5), 1+offset)).fromBlock();
|
||||||
}
|
}
|
||||||
if (v1 instanceof ListValue)
|
if (v1 instanceof ListValue)
|
||||||
{
|
{
|
||||||
@@ -241,6 +241,12 @@ public class BlockValue extends Value
|
|||||||
return this != NULL && !getBlockState().isAir();
|
return this != NULL && !getBlockState().isAir();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTypeString()
|
||||||
|
{
|
||||||
|
return "block";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value clone()
|
public Value clone()
|
||||||
{
|
{
|
||||||
@@ -270,6 +276,7 @@ public class BlockValue extends Value
|
|||||||
public int offset;
|
public int offset;
|
||||||
public double yaw;
|
public double yaw;
|
||||||
public double pitch;
|
public double pitch;
|
||||||
|
public boolean fromBlock;
|
||||||
VectorLocator(Vec3d v, int o)
|
VectorLocator(Vec3d v, int o)
|
||||||
{
|
{
|
||||||
vec = v;
|
vec = v;
|
||||||
@@ -284,6 +291,12 @@ public class BlockValue extends Value
|
|||||||
yaw = y;
|
yaw = y;
|
||||||
pitch = p;
|
pitch = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public VectorLocator fromBlock()
|
||||||
|
{
|
||||||
|
fromBlock = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SpecificDirection {
|
public enum SpecificDirection {
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package carpet.script.value;
|
package carpet.script.value;
|
||||||
|
|
||||||
import carpet.fakes.MobEntityInterface;
|
import carpet.fakes.MobEntityInterface;
|
||||||
|
import carpet.helpers.Tracer;
|
||||||
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.client.network.packet.EntityPositionS2CPacket;
|
||||||
import net.minecraft.client.network.packet.EntityVelocityUpdateS2CPacket;
|
import net.minecraft.client.network.packet.EntityVelocityUpdateS2CPacket;
|
||||||
import net.minecraft.command.EntitySelector;
|
import net.minecraft.command.EntitySelector;
|
||||||
import net.minecraft.command.EntitySelectorReader;
|
import net.minecraft.command.EntitySelectorReader;
|
||||||
@@ -26,8 +28,12 @@ import net.minecraft.nbt.Tag;
|
|||||||
import net.minecraft.predicate.entity.EntityPredicates;
|
import net.minecraft.predicate.entity.EntityPredicates;
|
||||||
import net.minecraft.server.command.ServerCommandSource;
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.text.LiteralText;
|
import net.minecraft.text.LiteralText;
|
||||||
import net.minecraft.util.Identifier;
|
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.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
@@ -122,6 +128,12 @@ public class EntityValue extends Value
|
|||||||
return this.get(what, null);
|
return this.get(what, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTypeString()
|
||||||
|
{
|
||||||
|
return "entity";
|
||||||
|
}
|
||||||
|
|
||||||
public static Pair<EntityType<?>, Predicate<? super Entity>> getPredicate(String who)
|
public static Pair<EntityType<?>, Predicate<? super Entity>> getPredicate(String who)
|
||||||
{
|
{
|
||||||
Pair<EntityType<?>, Predicate<? super Entity>> res = entityPredicates.get(who);
|
Pair<EntityType<?>, Predicate<? super Entity>> res = entityPredicates.get(who);
|
||||||
@@ -308,31 +320,76 @@ public class EntityValue extends Value
|
|||||||
return new StringValue(Direction.getEntityFacingOrder(e)[index].asString());
|
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) -> {
|
put("nbt",(e, a) -> {
|
||||||
CompoundTag nbttagcompound = e.toTag((new CompoundTag()));
|
CompoundTag nbttagcompound = e.toTag((new CompoundTag()));
|
||||||
if (a==null)
|
if (a==null)
|
||||||
return new StringValue(nbttagcompound.toString());
|
return new NBTSerializableValue(nbttagcompound);//StringValue(nbttagcompound.toString());
|
||||||
NbtPathArgumentType.NbtPath path;
|
NbtPathArgumentType.NbtPath path = NBTSerializableValue.cachePath(a.getString());
|
||||||
try
|
|
||||||
{
|
|
||||||
path = NbtPathArgumentType.nbtPath().method_9362(new StringReader(a.getString()));
|
|
||||||
}
|
|
||||||
catch (CommandSyntaxException exc)
|
|
||||||
{
|
|
||||||
throw new InternalExpressionException("Incorrect path: "+a.getString());
|
|
||||||
}
|
|
||||||
String res = null;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
List<Tag> tags = path.get(nbttagcompound);
|
List<Tag> tags = path.get(nbttagcompound);
|
||||||
if (tags.size()==0)
|
if (tags.size()==0)
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
if (tags.size()==1)
|
if (tags.size()==1)
|
||||||
return new StringValue(tags.get(0).toText().getString());
|
return NBTSerializableValue.decodeTag(tags.get(0));
|
||||||
return ListValue.wrap(tags.stream().map((t) -> new StringValue(t.toText().getString())).collect(Collectors.toList()));
|
return ListValue.wrap(tags.stream().map(NBTSerializableValue::decodeTag).collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
catch (CommandSyntaxException ignored) { }
|
catch (CommandSyntaxException ignored) { }
|
||||||
return new StringValue(res);
|
return Value.NULL;
|
||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
private static <Req extends Entity> Req assertEntityArgType(Class<Req> klass, Value arg)
|
private static <Req extends Entity> Req assertEntityArgType(Class<Req> klass, Value arg)
|
||||||
@@ -356,6 +413,21 @@ public class EntityValue extends Value
|
|||||||
featureModifiers.get(what).accept(entity, toWhat);
|
featureModifiers.get(what).accept(entity, toWhat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void updatePosition(Entity e)
|
||||||
|
{
|
||||||
|
if (e instanceof ServerPlayerEntity)
|
||||||
|
((ServerPlayerEntity)e).networkHandler.requestTeleport(e.x, e.y, e.z, e.yaw, e.pitch);
|
||||||
|
else
|
||||||
|
((ServerWorld)e.getEntityWorld()).method_14178().sendToNearbyPlayers(e,new EntityPositionS2CPacket(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateVelocity(Entity e)
|
||||||
|
{
|
||||||
|
((ServerWorld)e.getEntityWorld()).method_14178().sendToNearbyPlayers(e, new EntityVelocityUpdateS2CPacket(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static Map<String, BiConsumer<Entity, Value>> featureModifiers = new HashMap<String, BiConsumer<Entity, Value>>() {{
|
private static Map<String, BiConsumer<Entity, Value>> featureModifiers = new HashMap<String, BiConsumer<Entity, Value>>() {{
|
||||||
put("remove", (entity, value) -> entity.remove());
|
put("remove", (entity, value) -> entity.remove());
|
||||||
put("health", (e, v) -> { if (e instanceof LivingEntity) ((LivingEntity) e).setHealth((float) NumericValue.asNumber(v).getDouble()); });
|
put("health", (e, v) -> { if (e instanceof LivingEntity) ((LivingEntity) e).setHealth((float) NumericValue.asNumber(v).getDouble()); });
|
||||||
@@ -375,8 +447,7 @@ public class EntityValue extends Value
|
|||||||
e.yaw = (float) NumericValue.asNumber(coords.get(3)).getDouble();
|
e.yaw = (float) NumericValue.asNumber(coords.get(3)).getDouble();
|
||||||
e.prevYaw = e.yaw;
|
e.prevYaw = e.yaw;
|
||||||
e.setPosition(e.x, e.y, e.z);
|
e.setPosition(e.x, e.y, e.z);
|
||||||
if (e instanceof ServerPlayerEntity)
|
updatePosition(e);
|
||||||
((ServerPlayerEntity)e).networkHandler.requestTeleport(e.x, e.y, e.z, e.yaw, e.pitch);
|
|
||||||
});
|
});
|
||||||
put("pos", (e, v) ->
|
put("pos", (e, v) ->
|
||||||
{
|
{
|
||||||
@@ -389,43 +460,37 @@ public class EntityValue extends Value
|
|||||||
e.y = NumericValue.asNumber(coords.get(1)).getDouble();
|
e.y = NumericValue.asNumber(coords.get(1)).getDouble();
|
||||||
e.z = NumericValue.asNumber(coords.get(2)).getDouble();
|
e.z = NumericValue.asNumber(coords.get(2)).getDouble();
|
||||||
e.setPosition(e.x, e.y, e.z);
|
e.setPosition(e.x, e.y, e.z);
|
||||||
if (e instanceof ServerPlayerEntity)
|
updatePosition(e);
|
||||||
((ServerPlayerEntity)e).networkHandler.requestTeleport(e.x, e.y, e.z, e.yaw, e.pitch);
|
|
||||||
});
|
});
|
||||||
put("x", (e, v) ->
|
put("x", (e, v) ->
|
||||||
{
|
{
|
||||||
e.x = NumericValue.asNumber(v).getDouble();
|
e.x = NumericValue.asNumber(v).getDouble();
|
||||||
e.setPosition(e.x, e.y, e.z);
|
e.setPosition(e.x, e.y, e.z);
|
||||||
if (e instanceof ServerPlayerEntity)
|
updatePosition(e);
|
||||||
((ServerPlayerEntity)e).networkHandler.requestTeleport(e.x, e.y, e.z, e.yaw, e.pitch);
|
|
||||||
});
|
});
|
||||||
put("y", (e, v) ->
|
put("y", (e, v) ->
|
||||||
{
|
{
|
||||||
e.y = NumericValue.asNumber(v).getDouble();
|
e.y = NumericValue.asNumber(v).getDouble();
|
||||||
e.setPosition(e.x, e.y, e.z);
|
e.setPosition(e.x, e.y, e.z);
|
||||||
if (e instanceof ServerPlayerEntity)
|
updatePosition(e);
|
||||||
((ServerPlayerEntity)e).networkHandler.requestTeleport(e.x, e.y, e.z, e.yaw, e.pitch);
|
|
||||||
});
|
});
|
||||||
put("z", (e, v) ->
|
put("z", (e, v) ->
|
||||||
{
|
{
|
||||||
e.z = NumericValue.asNumber(v).getDouble();
|
e.z = NumericValue.asNumber(v).getDouble();
|
||||||
e.setPosition(e.x, e.y, e.z);
|
e.setPosition(e.x, e.y, e.z);
|
||||||
if (e instanceof ServerPlayerEntity)
|
updatePosition(e);
|
||||||
((ServerPlayerEntity)e).networkHandler.requestTeleport(e.x, e.y, e.z, e.yaw, e.pitch);
|
|
||||||
});
|
});
|
||||||
put("pitch", (e, v) ->
|
put("pitch", (e, v) ->
|
||||||
{
|
{
|
||||||
e.pitch = (float) NumericValue.asNumber(v).getDouble();
|
e.pitch = (float) NumericValue.asNumber(v).getDouble();
|
||||||
e.prevPitch = e.pitch;
|
e.prevPitch = e.pitch;
|
||||||
if (e instanceof ServerPlayerEntity)
|
updatePosition(e);
|
||||||
((ServerPlayerEntity)e).networkHandler.requestTeleport(e.x, e.y, e.z, e.yaw, e.pitch);
|
|
||||||
});
|
});
|
||||||
put("yaw", (e, v) ->
|
put("yaw", (e, v) ->
|
||||||
{
|
{
|
||||||
e.yaw = (float) NumericValue.asNumber(v).getDouble();
|
e.yaw = (float) NumericValue.asNumber(v).getDouble();
|
||||||
e.prevYaw = e.yaw;
|
e.prevYaw = e.yaw;
|
||||||
if (e instanceof ServerPlayerEntity)
|
updatePosition(e);
|
||||||
((ServerPlayerEntity)e).networkHandler.requestTeleport(e.x, e.y, e.z, e.yaw, e.pitch);
|
|
||||||
});
|
});
|
||||||
//"look"
|
//"look"
|
||||||
//"turn"
|
//"turn"
|
||||||
@@ -442,8 +507,7 @@ public class EntityValue extends Value
|
|||||||
e.y += NumericValue.asNumber(coords.get(1)).getDouble();
|
e.y += NumericValue.asNumber(coords.get(1)).getDouble();
|
||||||
e.z += NumericValue.asNumber(coords.get(2)).getDouble();
|
e.z += NumericValue.asNumber(coords.get(2)).getDouble();
|
||||||
e.setPosition(e.x, e.y, e.z);
|
e.setPosition(e.x, e.y, e.z);
|
||||||
if (e instanceof ServerPlayerEntity)
|
updatePosition(e);
|
||||||
((ServerPlayerEntity)e).networkHandler.requestTeleport(e.y, e.y, e.z, e.yaw, e.pitch);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
put("motion", (e, v) ->
|
put("motion", (e, v) ->
|
||||||
@@ -458,29 +522,25 @@ public class EntityValue extends Value
|
|||||||
NumericValue.asNumber(coords.get(1)).getDouble(),
|
NumericValue.asNumber(coords.get(1)).getDouble(),
|
||||||
NumericValue.asNumber(coords.get(2)).getDouble()
|
NumericValue.asNumber(coords.get(2)).getDouble()
|
||||||
);
|
);
|
||||||
if (e instanceof ServerPlayerEntity)
|
updateVelocity(e);
|
||||||
((ServerPlayerEntity)e).networkHandler.sendPacket(new EntityVelocityUpdateS2CPacket(e));
|
|
||||||
});
|
});
|
||||||
put("motion_x", (e, v) ->
|
put("motion_x", (e, v) ->
|
||||||
{
|
{
|
||||||
Vec3d velocity = e.getVelocity();
|
Vec3d velocity = e.getVelocity();
|
||||||
e.setVelocity(NumericValue.asNumber(v).getDouble(), velocity.y, velocity.z);
|
e.setVelocity(NumericValue.asNumber(v).getDouble(), velocity.y, velocity.z);
|
||||||
if (e instanceof ServerPlayerEntity)
|
updateVelocity(e);
|
||||||
((ServerPlayerEntity)e).networkHandler.sendPacket(new EntityVelocityUpdateS2CPacket(e));
|
|
||||||
});
|
});
|
||||||
put("motion_y", (e, v) ->
|
put("motion_y", (e, v) ->
|
||||||
{
|
{
|
||||||
Vec3d velocity = e.getVelocity();
|
Vec3d velocity = e.getVelocity();
|
||||||
e.setVelocity(velocity.x, NumericValue.asNumber(v).getDouble(), velocity.z);
|
e.setVelocity(velocity.x, NumericValue.asNumber(v).getDouble(), velocity.z);
|
||||||
if (e instanceof ServerPlayerEntity)
|
updateVelocity(e);
|
||||||
((ServerPlayerEntity)e).networkHandler.sendPacket(new EntityVelocityUpdateS2CPacket(e));
|
|
||||||
});
|
});
|
||||||
put("motion_z", (e, v) ->
|
put("motion_z", (e, v) ->
|
||||||
{
|
{
|
||||||
Vec3d velocity = e.getVelocity();
|
Vec3d velocity = e.getVelocity();
|
||||||
e.setVelocity(velocity.x, velocity.y, NumericValue.asNumber(v).getDouble());
|
e.setVelocity(velocity.x, velocity.y, NumericValue.asNumber(v).getDouble());
|
||||||
if (e instanceof ServerPlayerEntity)
|
updateVelocity(e);
|
||||||
((ServerPlayerEntity)e).networkHandler.sendPacket(new EntityVelocityUpdateS2CPacket(e));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
put("accelerate", (e, v) ->
|
put("accelerate", (e, v) ->
|
||||||
@@ -495,14 +555,17 @@ public class EntityValue extends Value
|
|||||||
NumericValue.asNumber(coords.get(1)).getDouble(),
|
NumericValue.asNumber(coords.get(1)).getDouble(),
|
||||||
NumericValue.asNumber(coords.get(2)).getDouble()
|
NumericValue.asNumber(coords.get(2)).getDouble()
|
||||||
);
|
);
|
||||||
if (e instanceof ServerPlayerEntity)
|
updateVelocity(e);
|
||||||
((ServerPlayerEntity)e).networkHandler.sendPacket(new EntityVelocityUpdateS2CPacket(e));
|
|
||||||
|
|
||||||
});
|
});
|
||||||
put("custom_name", (e, v) -> {
|
put("custom_name", (e, v) -> {
|
||||||
String name = v.getString();
|
if (v instanceof NullValue)
|
||||||
if (name.isEmpty())
|
{
|
||||||
|
e.setCustomNameVisible(false);
|
||||||
e.setCustomName(null);
|
e.setCustomName(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
e.setCustomNameVisible(true);
|
||||||
e.setCustomName(new LiteralText(v.getString()));
|
e.setCustomName(new LiteralText(v.getString()));
|
||||||
});
|
});
|
||||||
put("dismount", (e, v) -> e.stopRiding() );
|
put("dismount", (e, v) -> e.stopRiding() );
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package carpet.script.value;
|
package carpet.script.value;
|
||||||
|
|
||||||
import carpet.script.exception.ExpressionException;
|
import carpet.script.exception.ExpressionException;
|
||||||
import carpet.script.value.Value;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -23,6 +23,12 @@ public class FunctionSignatureValue extends Value
|
|||||||
throw new ExpressionException("Function "+identifier+" is not defined yet");
|
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
|
@Override
|
||||||
public Value clone()
|
public Value clone()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package carpet.script.value;
|
package carpet.script.value;
|
||||||
|
|
||||||
import carpet.script.value.Value;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
|
|
||||||
public class GlobalValue extends Value
|
public class GlobalValue extends Value
|
||||||
{
|
{
|
||||||
@@ -21,4 +21,10 @@ public class GlobalValue extends Value
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTypeString()
|
||||||
|
{
|
||||||
|
throw new InternalExpressionException("How did you get here? Cannot get type of an internal struct.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -106,4 +106,15 @@ public abstract class LazyListValue extends ListValue implements Iterator<Value>
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Value getElementAt(Value v2)
|
||||||
|
{
|
||||||
|
throw new InternalExpressionException("get element can only be obtained for regular lists");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String getTypeString()
|
||||||
|
{
|
||||||
|
return "iterator";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -316,6 +316,22 @@ public class ListValue extends Value
|
|||||||
return (double)items.size();
|
return (double)items.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Value getElementAt(Value value)
|
||||||
|
{
|
||||||
|
long index = NumericValue.asNumber(value).getLong();
|
||||||
|
int numitems = items.size();
|
||||||
|
long range = abs(index)/numitems;
|
||||||
|
index += (range+2)*numitems;
|
||||||
|
index = index % numitems;
|
||||||
|
return items.get((int)index);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String getTypeString()
|
||||||
|
{
|
||||||
|
return "list";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -8,24 +8,28 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|||||||
import net.minecraft.block.entity.HopperBlockEntity;
|
import net.minecraft.block.entity.HopperBlockEntity;
|
||||||
import net.minecraft.command.arguments.ItemStackArgument;
|
import net.minecraft.command.arguments.ItemStackArgument;
|
||||||
import net.minecraft.command.arguments.ItemStringReader;
|
import net.minecraft.command.arguments.ItemStringReader;
|
||||||
|
import net.minecraft.command.arguments.NbtPathArgumentType;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.passive.VillagerEntity;
|
import net.minecraft.entity.passive.VillagerEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.inventory.Inventory;
|
import net.minecraft.inventory.Inventory;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.AbstractNumberTag;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.nbt.StringNbtReader;
|
import net.minecraft.nbt.StringNbtReader;
|
||||||
|
import net.minecraft.nbt.Tag;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class NBTSerializableValue extends Value
|
public class NBTSerializableValue extends Value
|
||||||
{
|
{
|
||||||
private String nbtString = null;
|
private String nbtString = null;
|
||||||
private CompoundTag nbtTag = null;
|
private Tag nbtTag = null;
|
||||||
private Supplier<CompoundTag> nbtSupplier = null;
|
private Supplier<CompoundTag> nbtSupplier = null;
|
||||||
|
|
||||||
public NBTSerializableValue(ItemStack stack)
|
public NBTSerializableValue(ItemStack stack)
|
||||||
@@ -48,7 +52,7 @@ public class NBTSerializableValue extends Value
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBTSerializableValue(CompoundTag tag)
|
public NBTSerializableValue(Tag tag)
|
||||||
{
|
{
|
||||||
nbtTag = tag;
|
nbtTag = tag;
|
||||||
}
|
}
|
||||||
@@ -152,7 +156,17 @@ public class NBTSerializableValue extends Value
|
|||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompoundTag getTag()
|
public static Value decodeTag(Tag t)
|
||||||
|
{
|
||||||
|
if (t instanceof CompoundTag)
|
||||||
|
return new NBTSerializableValue(t);
|
||||||
|
if (t instanceof AbstractNumberTag)
|
||||||
|
return new NumericValue(((AbstractNumberTag) t).getDouble());
|
||||||
|
// more can be done here
|
||||||
|
return new StringValue(t.asString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tag getTag()
|
||||||
{
|
{
|
||||||
if (nbtTag == null)
|
if (nbtTag == null)
|
||||||
nbtTag = nbtSupplier.get();
|
nbtTag = nbtSupplier.get();
|
||||||
@@ -181,6 +195,18 @@ public class NBTSerializableValue extends Value
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CompoundTag getCompoundTag()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return (CompoundTag) getTag();
|
||||||
|
}
|
||||||
|
catch (ClassCastException e)
|
||||||
|
{
|
||||||
|
throw new InternalExpressionException(getString()+" is not a valid compound tag");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class InventoryLocator
|
public static class InventoryLocator
|
||||||
{
|
{
|
||||||
public Object owner;
|
public Object owner;
|
||||||
@@ -195,4 +221,47 @@ public class NBTSerializableValue extends Value
|
|||||||
offset = o;
|
offset = o;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Map<String, NbtPathArgumentType.NbtPath> pathCache = new HashMap<>();
|
||||||
|
public static NbtPathArgumentType.NbtPath cachePath(String arg)
|
||||||
|
{
|
||||||
|
NbtPathArgumentType.NbtPath res = pathCache.get(arg);
|
||||||
|
if (res != null)
|
||||||
|
return res;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
res = NbtPathArgumentType.nbtPath().method_9362(new StringReader(arg));
|
||||||
|
}
|
||||||
|
catch (CommandSyntaxException exc)
|
||||||
|
{
|
||||||
|
throw new InternalExpressionException("Incorrect nbt path: "+arg);
|
||||||
|
}
|
||||||
|
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 NBTSerializableValue.decodeTag(tags.get(0));
|
||||||
|
return ListValue.wrap(tags.stream().map(NBTSerializableValue::decodeTag).collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
catch (CommandSyntaxException ignored) { }
|
||||||
|
return Value.NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
return o instanceof NullValue ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTypeString()
|
||||||
|
{
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -167,4 +167,10 @@ public class NumericValue extends Value
|
|||||||
return getLong();
|
return getLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTypeString()
|
||||||
|
{
|
||||||
|
return "number";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -24,4 +24,10 @@ public class StringValue extends Value
|
|||||||
{
|
{
|
||||||
this.str = str;
|
this.str = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTypeString()
|
||||||
|
{
|
||||||
|
return "number";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -172,4 +172,11 @@ public abstract class Value implements Comparable<Value>, Cloneable
|
|||||||
{
|
{
|
||||||
return (long)readNumber();
|
return (long)readNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Value getElementAt(Value v2)
|
||||||
|
{
|
||||||
|
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)
|
@Rule(desc = "Enables /player command to control/spawn players", category = COMMAND)
|
||||||
public static boolean commandPlayer = true;
|
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)
|
@Rule(desc = "Placing carpets may issue carpet commands for non-op players", category = SURVIVAL)
|
||||||
public static boolean carpets = false;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -27,6 +27,8 @@
|
|||||||
"ServerWorld_unloadedEntityMixin",
|
"ServerWorld_unloadedEntityMixin",
|
||||||
"MobEntity_leashMixin",
|
"MobEntity_leashMixin",
|
||||||
|
|
||||||
|
"VillagerEntity_aiMixin",
|
||||||
|
|
||||||
"ServerWorld_fakePlayersMixin",
|
"ServerWorld_fakePlayersMixin",
|
||||||
|
|
||||||
"ServerPlayNetworkHandler_coreMixin",
|
"ServerPlayNetworkHandler_coreMixin",
|
||||||
|
|||||||
Reference in new issue
Block a user