diff --git a/src/main/java/carpet/mixins/CommandManagerMixin.java b/src/main/java/carpet/mixins/CommandManagerMixin.java index 94b05a56..98cb741d 100644 --- a/src/main/java/carpet/mixins/CommandManagerMixin.java +++ b/src/main/java/carpet/mixins/CommandManagerMixin.java @@ -5,11 +5,13 @@ import carpet.settings.CarpetSettings; import com.mojang.brigadier.CommandDispatcher; import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; +import org.apache.logging.log4j.Logger; import org.spongepowered.asm.mixin.Final; 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.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @@ -39,4 +41,15 @@ public abstract class CommandManagerMixin { CarpetSettings.impendingFillSkipUpdates = false; } + + @Redirect(method = "execute", at = @At( + value = "INVOKE", + target = "Lorg/apache/logging/log4j/Logger;isDebugEnabled()Z" + )) + private boolean doesOutputCommandStackTrace(Logger logger) + { + if (CarpetSettings.superSecretSetting) + return true; + return logger.isDebugEnabled(); + } } \ No newline at end of file diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index a8d797cf..088fed23 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -1,6 +1,7 @@ package carpet.script; import carpet.CarpetServer; +import carpet.script.value.NullValue; import carpet.settings.CarpetSettings; import carpet.helpers.FeatureGenerator; import carpet.fakes.MinecraftServerInterface; @@ -24,6 +25,8 @@ import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; import net.minecraft.enchantment.Enchantments; import net.minecraft.entity.EntityType; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.decoration.ArmorStandEntity; import net.minecraft.item.Items; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.command.arguments.ParticleArgumentType; @@ -38,10 +41,12 @@ import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.state.property.Property; import net.minecraft.state.StateFactory; import net.minecraft.predicate.entity.EntityPredicates; +import net.minecraft.text.LiteralText; import net.minecraft.util.Identifier; import net.minecraft.sound.SoundCategory; import net.minecraft.util.math.Box; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.EulerRotation; import net.minecraft.util.math.Vec3d; import net.minecraft.util.registry.Registry; import net.minecraft.world.LightType; @@ -1874,6 +1879,62 @@ public class CarpetExpression return (c_, t_) -> new NumericValue(particleCount); }); + this.expr.addLazyFunction("create_marker", -1, (c, t, lv) ->{ + CarpetContext cc = (CarpetContext)c; + BlockState targetBlock = null; + BlockValue.VectorLocator pointLocator; + String name; + try + { + Value nameValue = lv.get(0).evalValue(c); + name = nameValue instanceof NullValue ? "" : nameValue.getString(); + pointLocator = BlockValue.locateVec(cc, lv, 1, true); + if (lv.size()>pointLocator.offset) + targetBlock = BlockValue.fromParams(cc, lv, pointLocator.offset, true).block.getBlockState(); + + } + catch (IndexOutOfBoundsException e) + { + throw new InternalExpressionException("create_marker requires a name and three coordinates, with optional direction, and optional block on its head"); + } + + ArmorStandEntity armorstand = new ArmorStandEntity(EntityType.ARMOR_STAND, cc.s.getWorld()); + armorstand.setPositionAndAngles( + pointLocator.vec.x, + pointLocator.vec.y - ((targetBlock==null)?(armorstand.getHeight()+0.41):(armorstand.getHeight()-0.3)), + pointLocator.vec.z, + (float)pointLocator.yaw, + (float) pointLocator.pitch + ); + armorstand.addScoreboardTag("__scarpet_marker"); + if (targetBlock != null) + armorstand.setEquippedStack(EquipmentSlot.HEAD, new ItemStack(targetBlock.getBlock().asItem())); + if (!name.isEmpty()) + { + armorstand.setCustomName(new LiteralText(name)); + armorstand.setCustomNameVisible(true); + } + armorstand.setHeadRotation(new EulerRotation((int)pointLocator.pitch,0,0)); + armorstand.setNoGravity(true); + armorstand.setInvisible(true); + armorstand.setInvulnerable(true); + cc.s.getWorld().spawnEntity(armorstand); + EntityValue result = new EntityValue(armorstand); + return (_c, _t) -> result; + }); + + this.expr.addLazyFunction("remove_all_markers", 0, (c, t, lv) -> { + CarpetContext cc = (CarpetContext)c; + int total = 0; + for (Entity e : cc.s.getWorld().getEntities(EntityType.ARMOR_STAND, (as) -> as.getScoreboardTags().contains("__scarpet_marker"))) + { + total ++; + e.remove(); + } + int finalTotal = total; + return (_cc, _tt) -> new NumericValue(finalTotal); + }); + //"overridden" native call that prints to stderr this.expr.addLazyFunction("print", 1, (c, t, lv) -> { diff --git a/src/main/java/carpet/script/Expression.java b/src/main/java/carpet/script/Expression.java index 18c13889..9515d8bb 100644 --- a/src/main/java/carpet/script/Expression.java +++ b/src/main/java/carpet/script/Expression.java @@ -2375,9 +2375,15 @@ public class Expression implements Cloneable String format = lv.get(0).getString(); if (lv.size() == 1) return new StringValue(format); + int argIndex = 1; + if (lv.get(1) instanceof ListValue) + { + lv = ((ListValue) lv.get(1)).getItems(); + argIndex = 0; + } List args = new ArrayList<>(); Matcher m = formatPattern.matcher(format); - int argIndex = 1; + for (int i = 0, len = format.length(); i < len; ) { if (m.find(i)) { // Anything between the start of the string and the beginning diff --git a/src/main/java/carpet/script/value/BlockValue.java b/src/main/java/carpet/script/value/BlockValue.java index 85c0dda4..f113788c 100644 --- a/src/main/java/carpet/script/value/BlockValue.java +++ b/src/main/java/carpet/script/value/BlockValue.java @@ -5,11 +5,9 @@ import carpet.script.LazyValue; import carpet.script.exception.InternalExpressionException; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; -import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.command.arguments.BlockArgumentParser; import net.minecraft.block.Blocks; -import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.util.registry.Registry; @@ -57,6 +55,10 @@ public class BlockValue extends Value } public static VectorLocator locateVec(CarpetContext c, List params, int offset) + { + return locateVec(c,params, offset, false); + } + public static VectorLocator locateVec(CarpetContext c, List params, int offset, boolean optionalDirection) { try { @@ -68,19 +70,34 @@ public class BlockValue extends Value if (v1 instanceof ListValue) { List args = ((ListValue) v1).getItems(); - return new VectorLocator( new Vec3d( + Vec3d pos = new Vec3d( NumericValue.asNumber(args.get(0)).getDouble(), NumericValue.asNumber(args.get(1)).getDouble(), - NumericValue.asNumber(args.get(2)).getDouble()), - offset+1 - ); + NumericValue.asNumber(args.get(2)).getDouble()); + double yaw = 0.0D; + double pitch = 0.0D; + if (args.size()>3 && optionalDirection) + { + yaw = NumericValue.asNumber(args.get(3)).getDouble(); + pitch = NumericValue.asNumber(args.get(4)).getDouble(); + } + return new VectorLocator(pos,offset+1, yaw, pitch); } - return new VectorLocator( new Vec3d( + Vec3d pos = new Vec3d( NumericValue.asNumber(v1).getDouble(), NumericValue.asNumber(params.get(1 + offset).evalValue(c)).getDouble(), - NumericValue.asNumber(params.get(2 + offset).evalValue(c)).getDouble()), - offset+3 - ); + NumericValue.asNumber(params.get(2 + offset).evalValue(c)).getDouble()); + double yaw = 0.0D; + double pitch = 0.0D; + int eatenLength = 3; + if (params.size()>3+offset && optionalDirection) + { + yaw = NumericValue.asNumber(params.get(3 + offset).evalValue(c)).getDouble(); + pitch = NumericValue.asNumber(params.get(4 + offset).evalValue(c)).getDouble(); + eatenLength = 5; + } + + return new VectorLocator(pos,offset+eatenLength, yaw, pitch); } catch (IndexOutOfBoundsException e) { @@ -205,10 +222,21 @@ public class BlockValue extends Value { public Vec3d vec; public int offset; + public double yaw; + public double pitch; VectorLocator(Vec3d v, int o) { vec = v; offset = o; + yaw = 0.0D; + pitch = 0.0D; + } + VectorLocator(Vec3d v, int o, double y, double p) + { + vec = v; + offset = o; + yaw = y; + pitch = p; } } }