Instantly share code, notes, and snippets.
Created
March 7, 2026 10:24
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save Ensamisten/53456d35b1d3144e7379bc680370aa3c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package io.github.ensamisten.client.command.brigadier; | |
| import com.mojang.brigadier.CommandDispatcher; | |
| import com.mojang.brigadier.arguments.IntegerArgumentType; | |
| import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; | |
| import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; | |
| import net.minecraft.client.MinecraftClient; | |
| import net.minecraft.particle.DustParticleEffect; | |
| import net.minecraft.sound.SoundEvents; | |
| import net.minecraft.text.Text; | |
| import net.minecraft.util.math.BlockPos; | |
| import net.minecraft.util.math.Vec3d; | |
| import org.joml.Vector3f; | |
| import java.util.ArrayList; | |
| import java.util.Iterator; | |
| import java.util.List; | |
| public class NavigationCommand { | |
| private static final int GOLD_COLOR = 0xFFD700; // RGB hex for gold | |
| public static BlockPos targetCoords; | |
| public static boolean isNavigating = false; | |
| private static long navigationStartTime; | |
| private static int linePoints = 100; | |
| public static void register(CommandDispatcher<FabricClientCommandSource> dispatcher) { | |
| dispatcher.register(ClientCommandManager.literal("navigationstart") | |
| .then(ClientCommandManager.argument("x", IntegerArgumentType.integer()) | |
| .then(ClientCommandManager.argument("y", IntegerArgumentType.integer()) | |
| .then(ClientCommandManager.argument("z", IntegerArgumentType.integer()) | |
| .executes((context) -> { | |
| int x = IntegerArgumentType.getInteger(context, "x"); | |
| int y = IntegerArgumentType.getInteger(context, "y"); | |
| int z = IntegerArgumentType.getInteger(context, "z"); | |
| NavigationCommand.startNavigation(new BlockPos(x, y, z)); | |
| return 1; | |
| }))))); | |
| dispatcher.register(ClientCommandManager.literal("navigationstop").executes((context) -> { | |
| NavigationCommand.stopNavigation(); | |
| return 1; | |
| })); | |
| dispatcher.register(ClientCommandManager.literal("navigationsetpathpoints").then(ClientCommandManager.argument("points", IntegerArgumentType.integer(10, 10000)).executes((context) -> { | |
| int points = IntegerArgumentType.getInteger(context, "points"); | |
| NavigationCommand.setLinePoints(points); | |
| return 1; | |
| }))); | |
| } | |
| private static void setLinePoints(int points) { | |
| if (points == linePoints) { | |
| MinecraftClient.getInstance().player.sendMessage(Text.literal("§7[§3Navigation Assistant ➣§7]§f: §c❌ §f| §6Path line point count is already set to §e" + points + "§6."), false); | |
| MinecraftClient.getInstance().player.playSound(SoundEvents.ENTITY_VILLAGER_NO, 2.0F, 1.0F); | |
| } else { | |
| linePoints = points; | |
| MinecraftClient.getInstance().player.sendMessage(Text.literal("§7[§3Navigation Assistant ➣§7]§f: §a✔ §f| §6Number of path line points set to §e" + points + "§6."), false); | |
| MinecraftClient.getInstance().player.playSound(SoundEvents.ITEM_BOOK_PAGE_TURN, 2.0F, 1.0F); | |
| } | |
| } | |
| private static void startNavigation(BlockPos coords) { | |
| if (isNavigating && coords.equals(targetCoords)) { | |
| MinecraftClient.getInstance().player.sendMessage(Text.literal("§7[§3Navigation Assistant ➣§7]§f: §c❌ §f| §4Already navigating to these coordinates."), false); | |
| MinecraftClient.getInstance().player.playSound(SoundEvents.ENTITY_VILLAGER_NO, 2.0F, 1.0F); | |
| } else { | |
| if (isNavigating) { | |
| MinecraftClient.getInstance().player.sendMessage(Text.literal("§7[§3Navigation Assistant ➣§7]§f: §9→ §f| §6Switching route to §e" + coords.toShortString() + "§6."), false); | |
| MinecraftClient.getInstance().player.playSound(SoundEvents.ENTITY_WITCH_THROW, 2.0F, 2.0F); | |
| } else { | |
| MinecraftClient.getInstance().player.sendMessage(Text.literal("§7[§3Navigation Assistant ➣§7]§f: §a✔ §f| §6Navigation started to §e" + coords.toShortString() + "§6."), false); | |
| MinecraftClient.getInstance().player.playSound(SoundEvents.ENTITY_VILLAGER_YES, 2.0F, 1.0F); | |
| } | |
| targetCoords = coords; | |
| isNavigating = true; | |
| navigationStartTime = System.currentTimeMillis(); | |
| } | |
| } | |
| public static void stopNavigation() { | |
| if (isNavigating) { | |
| isNavigating = false; | |
| targetCoords = null; | |
| MinecraftClient.getInstance().player.sendMessage(Text.literal("§7[§3Navigation Assistant ➣§7]§f: §c❌ §f| §4Navigation stopped."), false); | |
| MinecraftClient.getInstance().player.playSound(SoundEvents.BLOCK_ANVIL_BREAK, 2.0F, 1.0F); | |
| } else { | |
| MinecraftClient.getInstance().player.sendMessage(Text.literal("§7[§3Navigation Assistant ➣§7]§f: §c❌ §f| §4You can't stop navigation when you're not navigating."), false); | |
| MinecraftClient.getInstance().player.playSound(SoundEvents.ENTITY_VILLAGER_NO, 2.0F, 1.0F); | |
| } | |
| } | |
| // 1. Change onClientTick to be static (it only uses static fields/methods) | |
| public static void onClientTick(MinecraftClient client) { // was: private void | |
| if (isNavigating && client.player != null && targetCoords != null) { | |
| Vec3d playerPos = client.player.getEntityPos(); // also: getEntityPos() doesn't exist — use getPos() | |
| double distance = playerPos.distanceTo(Vec3d.ofCenter(targetCoords)); | |
| if (distance <= 5.0) { | |
| showNavigationStats(client, playerPos); // was: this.showNavigationStats(...) | |
| stopNavigation(); // was: this.stopNavigation() | |
| } else { | |
| List<Vec3d> path = calculatePath(playerPos, Vec3d.ofCenter(targetCoords)); | |
| renderParticlePath(client, path); | |
| updateActionBar(client, playerPos); | |
| } | |
| } | |
| } | |
| public static List<Vec3d> calculatePath(Vec3d start, Vec3d end) { | |
| List<Vec3d> path = new ArrayList(); | |
| Vec3d direction = end.subtract(start).normalize(); | |
| Vec3d current = start; | |
| double totalDistance = start.distanceTo(end); | |
| double stepSize = Math.max(0.5, totalDistance / (double)linePoints); | |
| while(current.distanceTo(end) > stepSize) { | |
| path.add(current); | |
| Vec3d nextStep = current.add(direction.multiply(stepSize)); | |
| if (NavigationCommand.isBlockedAhead(nextStep)) { | |
| nextStep = nextStep.add(0.0, 1.0, 0.0); | |
| } | |
| current = nextStep; | |
| if (path.size() >= linePoints) { | |
| break; | |
| } | |
| } | |
| path.add(end); | |
| return path; | |
| } | |
| private static boolean isBlockedAhead(Vec3d pos) { | |
| MinecraftClient client = MinecraftClient.getInstance(); | |
| BlockPos blockPos = new BlockPos((int)pos.x, (int)pos.y, (int)pos.z); | |
| return !client.world.getBlockState(blockPos).isAir(); | |
| } | |
| public static void renderParticlePath(MinecraftClient client, List<Vec3d> path) { | |
| Iterator var3 = path.iterator(); | |
| while(var3.hasNext()) { | |
| Vec3d pos = (Vec3d) var3.next(); | |
| client.world.addParticleClient(new DustParticleEffect(GOLD_COLOR, 1.0F), pos.x, pos.y, pos.z, 0.0, 0.0, 0.0); | |
| } | |
| } | |
| public static void updateActionBar(MinecraftClient client, Vec3d playerPos) { | |
| double distance = playerPos.distanceTo(Vec3d.of(targetCoords)); | |
| String message = String.format("Distance to target: §2%.2f §7blocks §f| ", distance); | |
| client.player.sendMessage(Text.literal("§7" + message + "§b" + targetCoords.getX() + ", " + targetCoords.getY() + ", " + targetCoords.getZ()), true); | |
| } | |
| public static void showNavigationStats(MinecraftClient client, Vec3d finalPos) { | |
| Vec3d startPos = client.player.getEntityPos(); | |
| String stats = String.format("§7[§3Navigation Assistant ➣§7]§f: §a✔ §f| §aNavigation complete!\n"); | |
| client.player.playSound(SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP, 2.0F, 1.0F); | |
| client.player.sendMessage(Text.literal(stats), false); | |
| } | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment