From e31a348fe0224b8894890ab3e266b351daf90ea4 Mon Sep 17 00:00:00 2001 From: Yanbing Zhao Date: Tue, 27 Jul 2021 02:36:04 +0800 Subject: [PATCH] Use command pos instead of player pos --- docs/design.md | 2 +- .../signin/client/ClientGuideMapManager.java | 20 ++++++++++++----- .../java/org/teacon/signin/client/Hotkey.java | 6 ++--- .../teacon/signin/command/CommandImpl.java | 22 ++++++++++++------- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/docs/design.md b/docs/design.md index a1cc4e8..bdd0659 100644 --- a/docs/design.md +++ b/docs/design.md @@ -154,7 +154,7 @@ SignMeUp 的相关定义位于 `data//signup_guides/.json` 里, * 位于所处的世界(`world` 决定) * 没有离开地图的范围(`range` 和 `center` 决定) -均满足的第一个导引图(`ResourceLocation` 是有序的)。 +均满足的距离最近的第一个导引图(`ResourceLocation` 是有序的)。 导引图的左上角是标题,下方是 128x128 大小的地图(由资源包渲染),右上角是子标题,下面是介绍,右下角是所有触发器按钮的列表,竖直排列。 diff --git a/src/main/java/org/teacon/signin/client/ClientGuideMapManager.java b/src/main/java/org/teacon/signin/client/ClientGuideMapManager.java index a7a72bc..87fd864 100644 --- a/src/main/java/org/teacon/signin/client/ClientGuideMapManager.java +++ b/src/main/java/org/teacon/signin/client/ClientGuideMapManager.java @@ -3,6 +3,7 @@ import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.util.math.vector.Vector3i; import org.teacon.signin.data.GuideMap; import org.teacon.signin.data.Trigger; import org.teacon.signin.data.Waypoint; @@ -19,17 +20,24 @@ public synchronized void acceptUpdateFromServer(SortedMap nearestTo(ClientPlayerEntity player) { + public Map.Entry nearestTo(Vector3d pos) { + double minDistanceSq = Double.MAX_VALUE; + Map.Entry result = null; for (Map.Entry entry : this.availableMaps.entrySet()) { // Skip the dimension check because the client manager only knows // guide maps that are for the current dimension. - final GuideMap map = entry.getValue(); - final Vector3d destination = Vector3d.copyCenteredWithVerticalOffset(map.center, player.getPosY()); - if (player.getPosition().withinDistance(destination, map.radius)) { - return entry; + final GuideMap guideMap = entry.getValue(); + final double dx = pos.getX() - guideMap.center.getX(); + final double dz = pos.getZ() - guideMap.center.getZ(); + if (Math.min(Math.abs(dx), Math.abs(dz)) <= guideMap.radius) { + final double distanceSq = dx * dx + dz * dz; + if (distanceSq < minDistanceSq) { + minDistanceSq = distanceSq; + result = entry; + } } } - return null; + return result; } public Trigger findTrigger(ResourceLocation triggerId) { diff --git a/src/main/java/org/teacon/signin/client/Hotkey.java b/src/main/java/org/teacon/signin/client/Hotkey.java index 5cf7b28..442e781 100644 --- a/src/main/java/org/teacon/signin/client/Hotkey.java +++ b/src/main/java/org/teacon/signin/client/Hotkey.java @@ -20,11 +20,11 @@ public static void keyTyped(InputEvent.KeyInputEvent event) { if (SignMeUpClient.keyOpenMap != null && SignMeUpClient.keyOpenMap.isPressed()) { Minecraft mc = Minecraft.getInstance(); if (mc.player != null) { - final Map.Entry entry = SignMeUpClient.MANAGER.nearestTo(mc.player); + final Vector3d position = mc.player.getPositionVec(); + final Map.Entry entry = SignMeUpClient.MANAGER.nearestTo(position); if (entry != null) { - final Vector3d position = mc.player.getPositionVec(); mc.displayGuiScreen(new GuideMapScreen(entry.getKey(), entry.getValue(), position)); - } else if (mc.player != null) { + } else { mc.player.sendStatusMessage(new TranslationTextComponent("sign_up.status.no_map_available"), true); } } diff --git a/src/main/java/org/teacon/signin/command/CommandImpl.java b/src/main/java/org/teacon/signin/command/CommandImpl.java index 1ddc0e2..b5a0790 100644 --- a/src/main/java/org/teacon/signin/command/CommandImpl.java +++ b/src/main/java/org/teacon/signin/command/CommandImpl.java @@ -56,7 +56,7 @@ public static int closeSpecificMap(CommandContext context) throws if (map != null) { // Here we have to send a packet to client side // for rendering the map GUI - MapScreenPacket packet = new MapScreenPacket(MapScreenPacket.Action.CLOSE_SPECIFIC, player.getPositionVec(), id); + MapScreenPacket packet = new MapScreenPacket(MapScreenPacket.Action.CLOSE_SPECIFIC, src.getPos(), id); SignMeUp.channel.sendTo(packet, player.connection.netManager, NetworkDirection.PLAY_TO_CLIENT); return Command.SINGLE_SUCCESS; } else { @@ -85,7 +85,7 @@ public static int openSpecificMap(CommandContext context) throws if (map != null) { // Here we have to send a packet to client side // for rendering the map GUI - final MapScreenPacket packet = new MapScreenPacket(MapScreenPacket.Action.OPEN_SPECIFIC, player.getPositionVec(), id); + final MapScreenPacket packet = new MapScreenPacket(MapScreenPacket.Action.OPEN_SPECIFIC, src.getPos(), id); SignMeUp.channel.sendTo(packet, player.connection.netManager, NetworkDirection.PLAY_TO_CLIENT); return Command.SINGLE_SUCCESS; } else { @@ -103,23 +103,29 @@ public static int openNearestMap(CommandContext context) throws C CommandSource src = context.getSource(); ServerPlayerEntity player = src.asPlayer(); RegistryKey worldKey = src.getWorld().getDimensionKey(); + GuideMap map = null; + double minDistanceSq = Double.MAX_VALUE; // We first check the dimension if (src.asPlayer().world.getDimensionKey() == worldKey) { // Then we look for the nearest in-range map for (GuideMap guideMap : SignMeUp.MANAGER.getAllMaps()) { - final Vector3d destination = Vector3d.copyCenteredWithVerticalOffset(guideMap.center, player.getPosY()); - if (player.getPosition().withinDistance(destination, guideMap.radius)) { - map = guideMap; - break; // Escape from the loop if we find one... + final double dx = src.getPos().getX() - guideMap.center.getX(); + final double dz = src.getPos().getZ() - guideMap.center.getZ(); + if (Math.min(Math.abs(dx), Math.abs(dz)) <= guideMap.radius) { + final double distanceSq = dx * dx + dz * dz; + if (distanceSq < minDistanceSq) { + minDistanceSq = distanceSq; + map = guideMap; + } } } } if (map != null) { // Same packet as above - final MapScreenPacket packet = new MapScreenPacket(MapScreenPacket.Action.OPEN_SPECIFIC, player.getPositionVec(), SignMeUp.MANAGER.findMapId(map)); + final MapScreenPacket packet = new MapScreenPacket(MapScreenPacket.Action.OPEN_SPECIFIC, src.getPos(), SignMeUp.MANAGER.findMapId(map)); SignMeUp.channel.sendTo(packet, player.connection.netManager, NetworkDirection.PLAY_TO_CLIENT); return Command.SINGLE_SUCCESS; } else { @@ -144,7 +150,7 @@ public static int listWaypoints(CommandContext context) throws Co src.sendFeedback(new StringTextComponent(" - ") .appendSibling(waypoint.getTitle()).appendString("\n ") .appendSibling(new TranslationTextComponent("sign_up.text.distance")) - .appendString(": " + df.format(waypoint.getActualLocation().distanceSq(player.getPosition())) + " ") + .appendString(": " + df.format(Vector3d.copy(waypoint.getActualLocation()).distanceTo(src.getPos())) + " ") .appendSibling(new TranslationTextComponent("sign_up.text.blocks_away")) , false );