diff --git a/src/main/java/carpet/helpers/Tracer.java b/src/main/java/carpet/helpers/Tracer.java new file mode 100644 index 00000000..c49cfc19 --- /dev/null +++ b/src/main/java/carpet/helpers/Tracer.java @@ -0,0 +1,16 @@ +package carpet.helpers; + +import net.minecraft.entity.Entity; +import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.RayTraceContext; + +public class Tracer +{ + public static HitResult traceEntityLook(Entity entity, double reach) { + Vec3d vec3d_1 = entity.getCameraPosVec(1.0F); + Vec3d vec3d_2 = entity.getRotationVec(1.0F); + Vec3d vec3d_3 = vec3d_1.add(vec3d_2.x * reach, vec3d_2.y * reach, vec3d_2.z * reach); + return entity.world.rayTrace(new RayTraceContext(vec3d_1, vec3d_3, RayTraceContext.ShapeType.OUTLINE, RayTraceContext.FluidHandling.ANY, entity)); + } +} diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index 29b5ad6f..19389f1c 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -3,6 +3,7 @@ package carpet.script; import carpet.CarpetServer; import carpet.fakes.MinecraftServerInterface; import carpet.helpers.FeatureGenerator; +import carpet.helpers.Tracer; import carpet.script.Fluff.TriFunction; import carpet.script.exception.CarpetExpressionException; import carpet.script.exception.ExpressionException; @@ -53,6 +54,9 @@ import net.minecraft.state.StateFactory; import net.minecraft.state.property.Property; 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.Box; import net.minecraft.util.math.EulerAngle; @@ -1241,6 +1245,24 @@ public class CarpetExpression Value res = new NumericValue(item.getStack().getCount()); 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; + }); }