diff --git a/src/main/java/carpet/logging/LoggerRegistry.java b/src/main/java/carpet/logging/LoggerRegistry.java index bf4b332b..c1fc69c6 100644 --- a/src/main/java/carpet/logging/LoggerRegistry.java +++ b/src/main/java/carpet/logging/LoggerRegistry.java @@ -27,6 +27,7 @@ public class LoggerRegistry public static boolean __damage; public static boolean __packets; public static boolean __weather; + public static boolean __pathfinding; public static void initLoggers() { @@ -36,6 +37,7 @@ public class LoggerRegistry registerLogger("kills", new Logger("kills", null, null)); registerLogger("damage", new Logger("damage", "all", new String[]{"all","players","me"})); registerLogger("weather", new Logger("weather", null, null)); + registerLogger( "pathfinding", new Logger("pathfinding", "20", new String[]{"2", "5", "10"})); registerLogger("tps", new HUDLogger("tps", null, null)); registerLogger("packets", new HUDLogger("packets", null, null)); diff --git a/src/main/java/carpet/logging/logHelpers/PathfindingVisualizer.java b/src/main/java/carpet/logging/logHelpers/PathfindingVisualizer.java new file mode 100644 index 00000000..dcbfdf1b --- /dev/null +++ b/src/main/java/carpet/logging/logHelpers/PathfindingVisualizer.java @@ -0,0 +1,91 @@ +package carpet.logging.logHelpers; + +import carpet.logging.LoggerRegistry; +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.command.arguments.ParticleArgumentType; +import net.minecraft.entity.Entity; +import net.minecraft.particle.ParticleEffect; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.Vec3d; + +public class PathfindingVisualizer +{ + private static ParticleEffect failedPath; + private static ParticleEffect successfulPath; + private static ParticleEffect lvl1; + private static ParticleEffect lvl2; + private static ParticleEffect lvl3; + + static + { + failedPath = parseParticle("angry_villager"); + successfulPath = parseParticle("happy_villager"); + lvl1 = parseParticle("dust 1 1 0 1"); + lvl2 = parseParticle("dust 1 0.5 0 1"); + lvl3 = parseParticle("dust 1 0 0 1"); + } + + private static void drawParticleLine(ServerPlayerEntity player, Vec3d from, Vec3d to, float ratio, boolean successful) + { + ParticleEffect accent = successful ? successfulPath : failedPath; + ParticleEffect color = (ratio < 2)? lvl1 : ((ratio < 4)?lvl2:lvl3); + + ((ServerWorld)player.world).spawnParticles( + player, + accent, + true, + from.x, from.y, from.z, 5, + 0.5, 0.5, 0.5, 0.0); + + double lineLengthSq = from.squaredDistanceTo(to); + if (lineLengthSq == 0) return; + + Vec3d incvec = to.subtract(from).normalize();// multiply(50/sqrt(lineLengthSq)); + int pcount = 0; + for (Vec3d delta = new Vec3d(0.0,0.0,0.0); + delta.lengthSquared() + { + if (!(player instanceof ServerPlayerEntity)) + return null; + int minDuration = Integer.parseInt(option); + if (miliseconds < minDuration) + return null; + if (player.squaredDistanceTo(entity) > 1000 && player.squaredDistanceTo(target) > 1000) + return null; + if (minDuration < 1) + minDuration = 1; + drawParticleLine((ServerPlayerEntity) player, entity.getPos(), target, miliseconds/minDuration, successful ); + return null; + }); + } +} diff --git a/src/main/java/carpet/mixins/EntityNavigation_pathfindingMixin.java b/src/main/java/carpet/mixins/EntityNavigation_pathfindingMixin.java new file mode 100644 index 00000000..4794eddf --- /dev/null +++ b/src/main/java/carpet/mixins/EntityNavigation_pathfindingMixin.java @@ -0,0 +1,54 @@ +package carpet.mixins; + +import carpet.logging.LoggerRegistry; +import carpet.logging.logHelpers.PathfindingVisualizer; +import net.minecraft.entity.ai.pathing.EntityNavigation; +import net.minecraft.entity.ai.pathing.Path; +import net.minecraft.entity.mob.MobEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +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.Redirect; + +@Mixin(EntityNavigation.class) +public abstract class EntityNavigation_pathfindingMixin +{ + @Shadow /*@Nullable*/ protected abstract Path findPathTo(BlockPos blockPos_1, double double_1, double double_2, double double_3, int int_1, boolean boolean_1); + + @Shadow @Final protected MobEntity entity; + + @Redirect(method = "findPathTo(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/entity/ai/pathing/Path;", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/entity/ai/pathing/EntityNavigation;findPathTo(Lnet/minecraft/util/math/BlockPos;DDDIZ)Lnet/minecraft/entity/ai/pathing/Path;" + )) + private Path pathToBlock(EntityNavigation entityNavigation, BlockPos blockPos_1, double double_1, double double_2, double double_3, int int_1, boolean boolean_1) + { + if (!LoggerRegistry.__pathfinding) + return findPathTo(blockPos_1, double_1, double_2, double_3, int_1, boolean_1); + long start = System.nanoTime(); + Path path = findPathTo(blockPos_1, double_1, double_2, double_3, int_1, boolean_1); + long finish = System.nanoTime(); + float duration = (1.0F*((finish - start)/1000))/1000; + PathfindingVisualizer.slowPath(entity, new Vec3d(double_1, double_2, double_3), duration, path != null); + return path; + } + + @Redirect(method = "findPathTo(Lnet/minecraft/entity/Entity;)Lnet/minecraft/entity/ai/pathing/Path;", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/entity/ai/pathing/EntityNavigation;findPathTo(Lnet/minecraft/util/math/BlockPos;DDDIZ)Lnet/minecraft/entity/ai/pathing/Path;" + )) + private Path pathToEntity(EntityNavigation entityNavigation, BlockPos blockPos_1, double double_1, double double_2, double double_3, int int_1, boolean boolean_1) + { + if (!LoggerRegistry.__pathfinding) + return findPathTo(blockPos_1, double_1, double_2, double_3, int_1, boolean_1); + long start = System.nanoTime(); + Path path = findPathTo(blockPos_1, double_1, double_2, double_3, int_1, boolean_1); + long finish = System.nanoTime(); + float duration = (1.0F*((finish - start)/1000))/1000; + PathfindingVisualizer.slowPath(entity, new Vec3d(double_1, double_2, double_3), duration, path != null); + return path; + } +} diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index 675b4e56..65b70e42 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -78,6 +78,7 @@ "ProjectileEntityMixin", "FallingBlockEntityMixin", "ThrownEntityMixin", + "EntityNavigation_pathfindingMixin", "FloatingIslandsChunkGeneratorMixin", "EndCityFeatureMixin",