diff --git a/run/config/SignMeUp/Waypoints.json b/run/config/SignMeUp/Waypoints.json
index 06a1e15..58ca93b 100644
--- a/run/config/SignMeUp/Waypoints.json
+++ b/run/config/SignMeUp/Waypoints.json
@@ -5,28 +5,36 @@
"description": "没什么好描述的",
"x": -211,
"y": 95,
- "z": 66
+ "z": 66,
+ "rx": 0.0,
+ "ry": 0.0
},
{
"name": "主展馆",
"description": "",
"x": -127,
"y": 96,
- "z": 40
+ "z": 40,
+ "rx": 0.0,
+ "ry": 0.0
},
{
"name": "111",
"description": "222",
"x": -137,
"y": 97,
- "z": 24
+ "z": 24,
+ "rx": 0.0,
+ "ry": 0.0
},
{
"name": "新路径点",
"description": "描述文本",
"x": -127,
"y": 70,
- "z": 40
+ "z": 40,
+ "rx": 0.0,
+ "ry": 0.0
}
]
}
\ No newline at end of file
diff --git a/src/main/java/org/teacon/signmeup/api/MiniMap.java b/src/main/java/org/teacon/signmeup/api/MiniMap.java
new file mode 100644
index 0000000..db1ef84
--- /dev/null
+++ b/src/main/java/org/teacon/signmeup/api/MiniMap.java
@@ -0,0 +1,38 @@
+package org.teacon.signmeup.api;
+
+import net.neoforged.fml.loading.FMLLoader;
+import org.teacon.signmeup.hud.MiniMapAPI;
+
+public interface MiniMap {
+ static MiniMap getInstance() {
+ if (!FMLLoader.getDist().isClient()) {
+ throw new IllegalStateException("This API is only available on Client.");
+ }
+ return MiniMapAPI.INSTANCE;
+ }
+
+ /**
+ *
Set the visibility of MiniMap.
+ *
+ * Mods should make sure the minimap is hided in a minimize time
+ * After the expected time range, mods must invoke setMiniMapVisibility(modID, true)
+ * to show the minimap normally.
+ *
+ * For the first time a mod hide the minimap, a message will be shown
+ * to make players clear that the minimap is hided. And it will also be shown
+ * on the map screen.
+ *
+ * There's no need for different mods to check whether the minimap is visibility.
+ * Minimap won't be shown if any mod set it invisible.
+ *
+ * This method can be invoked from any threads.
+ *
+ * @param modID the caller's mod id.
+ * @param visibility whether the MiniMap should be visible.
+ * @throws IllegalArgumentException if target mod (specific by modID) is not loaded
+ * @throws IllegalStateException if the same mod wants to hide / show the minimap, but
+ * it's already hided / shown
+ * @throws NullPointerException if modID is null
+ */
+ void setMiniMapVisibility(String modID, boolean visibility);
+}
diff --git a/src/main/java/org/teacon/signmeup/command/OpCommands.java b/src/main/java/org/teacon/signmeup/command/OpCommands.java
index 35b4842..091bca4 100644
--- a/src/main/java/org/teacon/signmeup/command/OpCommands.java
+++ b/src/main/java/org/teacon/signmeup/command/OpCommands.java
@@ -9,8 +9,10 @@
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.SharedSuggestionProvider;
+import net.minecraft.commands.arguments.coordinates.RotationArgument;
import net.minecraft.commands.arguments.coordinates.Vec3Argument;
import net.minecraft.commands.arguments.coordinates.WorldCoordinates;
+import net.minecraft.core.Rotations;
import net.minecraft.network.chat.Component;
import org.teacon.signmeup.config.Waypoints;
import org.teacon.signmeup.network.RemoveWaypointPacket;
@@ -29,10 +31,12 @@ public static void waypoints(CommandDispatcher dispatcher) {
.requires(commandSourceStack -> commandSourceStack.hasPermission(2))
.then(Commands.literal("set")
.then(Commands.argument("pos", Vec3Argument.vec3(false))
- .then(Commands.argument("name", StringArgumentType.string())
- .executes(OpCommands::setWaypoint)
- .then(Commands.argument("description", StringArgumentType.string())
+ .then(Commands.argument("rotation", RotationArgument.rotation())
+ .then(Commands.argument("name", StringArgumentType.string())
.executes(OpCommands::setWaypoint)
+ .then(Commands.argument("description", StringArgumentType.string())
+ .executes(OpCommands::setWaypoint)
+ )
)
)
)
@@ -51,7 +55,8 @@ private static int setWaypoint(CommandContext context) {
var pos = context.getArgument("pos", WorldCoordinates.class).getBlockPos(context.getSource());
var name = context.getArgument("name", String.class);
var description = context.getArgument("description", String.class);
- var waypoint = new Waypoints.WayPoint(name, description, pos.getX(), pos.getY(), pos.getZ());
+ var rotation = context.getArgument("rotation", WorldCoordinates.class).getRotation(context.getSource());
+ var waypoint = new Waypoints.WayPoint(name, description, pos.getX(), pos.getY(), pos.getZ(), rotation.x, rotation.y);
ConfigHelper.getConfigWrite(Waypoints.class, waypoints -> {
waypoints.waypoints.stream().filter(w -> w.name.equals(waypoint.name)).findFirst().ifPresentOrElse(
@@ -59,7 +64,7 @@ private static int setWaypoint(CommandContext context) {
() -> {
context.getSource().sendSuccess(() -> Component.literal("Added " + waypoint), true);
waypoints.waypoints.add(waypoint);
- NetworkHelper.sendToAllPlayers(new SetWaypointPacket(name, description, pos));
+ NetworkHelper.sendToAllPlayers(new SetWaypointPacket(name, description, pos, new Rotations(rotation.x, 0, rotation.y)));
}
);
});
diff --git a/src/main/java/org/teacon/signmeup/config/Waypoints.java b/src/main/java/org/teacon/signmeup/config/Waypoints.java
index 93251a4..1b83551 100644
--- a/src/main/java/org/teacon/signmeup/config/Waypoints.java
+++ b/src/main/java/org/teacon/signmeup/config/Waypoints.java
@@ -19,29 +19,24 @@ public String getChildDirName() {
public static class WayPoint {
public String name, description;
public int x, y, z;
+ public float rx, ry;
- public WayPoint(String name, String description, int x, int y, int z) {
+ public WayPoint(String name, String description, int x, int y, int z, float rx, float ry) {
this.name = name;
this.description = description;
this.x = x;
this.y = y;
this.z = z;
- }
-
- public WayPoint(String name, String description, BlockPos pos) {
- this.name = name;
- this.description = description;
- this.x = pos.getX();
- this.y = pos.getY();
- this.z = pos.getZ();
+ this.rx = rx;
+ this.ry = ry;
}
public WayPoint() {
- this("", "", 0, 0, 0);
+ this("", "", 0, 0, 0, 0, 0);
}
public static WayPoint dumbWayPoint(String name) {
- return new WayPoint(name, "", 0, 0, 0);
+ return new WayPoint(name, "", 0, 0, 0, 0, 0);
}
@Override
@@ -59,7 +54,7 @@ public int hashCode() {
@Override
public String toString() {
- return "[WayPoint name=" + name + ", description=" + description + ", <" + x + ", " + y + ", " + z + ">]";
+ return "[WayPoint name=" + name + ", description=" + description + ", <" + x + ", " + y + ", " + z + ">, rotation=<" + rx + ", " + ry + ">]";
}
}
}
diff --git a/src/main/java/org/teacon/signmeup/gui/map/MapScreen.java b/src/main/java/org/teacon/signmeup/gui/map/MapScreen.java
index f797d3b..0e02262 100644
--- a/src/main/java/org/teacon/signmeup/gui/map/MapScreen.java
+++ b/src/main/java/org/teacon/signmeup/gui/map/MapScreen.java
@@ -3,6 +3,7 @@
import cn.ussshenzhou.t88.gui.advanced.THoverSensitiveImageButton;
import cn.ussshenzhou.t88.gui.screen.TScreen;
import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component;
import net.neoforged.neoforge.client.ClientHooks;
@@ -10,6 +11,9 @@
import org.teacon.signmeup.gui.map.bp.CommandsButtonPanel;
import org.teacon.signmeup.gui.map.bp.WayPointsButtonPanel;
import org.teacon.signmeup.gui.settings.SettingsScreen;
+import org.teacon.signmeup.hud.MiniMapAPI;
+
+import java.util.Set;
/**
* @author USS_Shenzhou
@@ -48,6 +52,15 @@ public void render(GuiGraphics graphics, int pMouseX, int pMouseY, float pPartia
super.render(graphics, pMouseX, pMouseY, pPartialTick);
wayPointsButtonPanel.highlight(mapPanel.getHighlightWaypoints(pMouseX, pMouseY));
+
+ String hider = MiniMapAPI.INSTANCE.getHiderString();
+ if (hider != null) {
+ Font font = Minecraft.getInstance().font;
+ graphics.drawCenteredString(
+ font, Component.translatable("hud.sign_up.minimap.hide", hider),
+ graphics.guiWidth() / 2, graphics.guiHeight() - font.lineHeight * 2, 0xFFE8DDCD
+ );
+ }
}
public String getHighlightWaypoints() {
diff --git a/src/main/java/org/teacon/signmeup/hud/MiniMapAPI.java b/src/main/java/org/teacon/signmeup/hud/MiniMapAPI.java
new file mode 100644
index 0000000..07ce548
--- /dev/null
+++ b/src/main/java/org/teacon/signmeup/hud/MiniMapAPI.java
@@ -0,0 +1,64 @@
+package org.teacon.signmeup.hud;
+
+import net.neoforged.fml.loading.FMLLoader;
+import net.neoforged.fml.loading.moddiscovery.ModInfo;
+import org.teacon.signmeup.api.MiniMap;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.stream.Collectors;
+
+public final class MiniMapAPI implements MiniMap {
+ public static final MiniMapAPI INSTANCE = new MiniMapAPI();
+
+ private final Map ID_NAME_MAP = FMLLoader.getLoadingModList().getMods().stream().collect(Collectors.toMap(
+ ModInfo::getModId, ModInfo::getDisplayName
+ ));
+
+ private final CopyOnWriteArrayList hider = new CopyOnWriteArrayList<>();
+
+ @Override
+ public void setMiniMapVisibility(String modID, boolean visibility) {
+ Objects.requireNonNull(modID, "Argument modID cannot be null");
+ if (!ID_NAME_MAP.containsKey(modID)) {
+ throw new IllegalArgumentException("No such mod: " + modID);
+ }
+
+ if (!(visibility ? hider.remove(modID) : hider.addIfAbsent(modID))) {
+ throw new IllegalStateException("The minimap has already been " + (!visibility ? "hided" : "visible") + " by " + modID);
+ }
+ }
+
+ public boolean visible() {
+ return hider.isEmpty();
+ }
+
+ public String getHiderString() {
+ if (hider.isEmpty()) {
+ return null;
+ }
+
+ Iterator iterator = hider.iterator();
+ if (!iterator.hasNext()) {
+ return null;
+ }
+ String m1 = iterator.next();
+ if (!iterator.hasNext()) {
+ return m1;
+ }
+ String m2 = iterator.next();
+ if (!iterator.hasNext()) {
+ return m1 + ", " + m2;
+ }
+ int size = hider.size() - 2;
+ if (size > 1) {
+ return m1 + ", " + m2 + ", ... (" + size + " more mods)";
+ } else if (size == 1) {
+ return m1 + ", " + m2 + ", ... (1 more mod)";
+ }else {
+ return m1 + ", " + m2;
+ }
+ }
+}
diff --git a/src/main/java/org/teacon/signmeup/hud/MiniMapPanel.java b/src/main/java/org/teacon/signmeup/hud/MiniMapPanel.java
index 6e5fa56..977aaf2 100644
--- a/src/main/java/org/teacon/signmeup/hud/MiniMapPanel.java
+++ b/src/main/java/org/teacon/signmeup/hud/MiniMapPanel.java
@@ -10,6 +10,8 @@
import org.teacon.signmeup.SignMeUp;
import org.teacon.signmeup.config.MiniMap;
+import java.util.Set;
+
import static net.minecraft.util.Mth.PI;
/**
@@ -45,8 +47,8 @@ public MiniMapPanel() {
@Override
public void tickT() {
super.tickT();
- var debugOn = Minecraft.getInstance().getDebugOverlay().showDebugScreen();
- children.forEach(childTComponent -> childTComponent.setVisibleT(!debugOn));
+ var visible = !Minecraft.getInstance().getDebugOverlay().showDebugScreen() && MiniMapAPI.INSTANCE.visible();
+ children.forEach(childTComponent -> childTComponent.setVisibleT(visible));
}
@Override
diff --git a/src/main/java/org/teacon/signmeup/network/SetWaypointPacket.java b/src/main/java/org/teacon/signmeup/network/SetWaypointPacket.java
index 9871947..0cde74d 100644
--- a/src/main/java/org/teacon/signmeup/network/SetWaypointPacket.java
+++ b/src/main/java/org/teacon/signmeup/network/SetWaypointPacket.java
@@ -6,6 +6,7 @@
import cn.ussshenzhou.t88.network.annotation.NetPacket;
import io.netty.buffer.ByteBuf;
import net.minecraft.core.BlockPos;
+import net.minecraft.core.Rotations;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.neoforged.neoforge.network.handling.IPayloadContext;
@@ -16,7 +17,7 @@
* @author USS_Shenzhou
*/
@NetPacket(modid = SignMeUp.MODID)
-public record SetWaypointPacket(String name, String description, BlockPos pos) {
+public record SetWaypointPacket(String name, String description, BlockPos pos, Rotations rotation) {
@Codec
public static final StreamCodec STREAM_CODEC = StreamCodec.composite(
@@ -26,12 +27,14 @@ public record SetWaypointPacket(String name, String description, BlockPos pos) {
SetWaypointPacket::description,
BlockPos.STREAM_CODEC,
SetWaypointPacket::pos,
+ Rotations.STREAM_CODEC,
+ SetWaypointPacket::rotation,
SetWaypointPacket::new
);
@ClientHandler
public void clientHandler(IPayloadContext context){
- var waypoint = new Waypoints.WayPoint(name, description, pos.getX(), pos.getY(), pos.getZ());
+ var waypoint = new Waypoints.WayPoint(name, description, pos.getX(), pos.getY(), pos.getZ(), rotation.getX(), rotation.getZ());
ConfigHelper.getConfigWrite(Waypoints.class, waypoints -> waypoints.waypoints.add(waypoint));
}
}
diff --git a/src/main/java/org/teacon/signmeup/network/TeleportToWayPointPacket.java b/src/main/java/org/teacon/signmeup/network/TeleportToWayPointPacket.java
index 9548389..67ccc53 100644
--- a/src/main/java/org/teacon/signmeup/network/TeleportToWayPointPacket.java
+++ b/src/main/java/org/teacon/signmeup/network/TeleportToWayPointPacket.java
@@ -5,13 +5,16 @@
import cn.ussshenzhou.t88.network.annotation.NetPacket;
import cn.ussshenzhou.t88.network.annotation.ServerHandler;
import io.netty.buffer.ByteBuf;
+import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
+import net.minecraft.server.level.ServerLevel;
import net.neoforged.neoforge.network.handling.IPayloadContext;
import org.teacon.signmeup.SignMeUp;
import org.teacon.signmeup.config.Waypoints;
import java.util.Map;
+import java.util.Set;
import java.util.stream.Collectors;
/**
@@ -32,9 +35,19 @@ public record TeleportToWayPointPacket(String name) {
@ServerHandler
public void serverHandler(IPayloadContext context) {
context.enqueueWork(() -> {
- var waypoints = WAYPOINTS.get(name);
var player = context.player();
- player.teleportTo(waypoints.x, waypoints.y, waypoints.z);
+ if (!(player.level() instanceof ServerLevel level)) {
+ return;
+ }
+
+ for (Waypoints.WayPoint waypoint : ConfigHelper.getConfigRead(Waypoints.class).waypoints) {
+ if (waypoint.name.equals(name)) {
+ player.teleportTo(level, waypoint.x, waypoint.y, waypoint.z, Set.of(), waypoint.rx, waypoint.ry);
+ return;
+ }
+ }
+
+ player.sendSystemMessage(Component.literal("Open a new SMU map! The waypoint data is out of date."));
});
}
}
diff --git a/src/main/resources/assets/sign_up/lang/en_us.json b/src/main/resources/assets/sign_up/lang/en_us.json
index 380d5c3..17b67de 100644
--- a/src/main/resources/assets/sign_up/lang/en_us.json
+++ b/src/main/resources/assets/sign_up/lang/en_us.json
@@ -3,11 +3,13 @@
"key.sign_up.open_map": "Show Map",
"key.sign_up.open_new_map": "New Map Instance",
- "gui.sign_up.minimap": " Minimap",
+ "gui.sign_up.minimap": "Minimap",
"gui.sign_up.minimap.minimap": "Minimap",
"gui.sign_up.minimap.minimap.on": "On",
"gui.sign_up.minimap.minimap.off": "Off",
"gui.sign_up.minimap.range": "Minimap Range",
"gui.sign_up.minimap.rotate": "Follow Player Rotating",
- "gui.sign_up.minimap.ssaa": "SSAA Ratio"
+ "gui.sign_up.minimap.ssaa": "SSAA Ratio",
+
+ "hud.sign_up.minimap.hide": "Minimap is hided by: %s"
}
\ No newline at end of file
diff --git a/src/main/resources/assets/sign_up/lang/zh_cn.json b/src/main/resources/assets/sign_up/lang/zh_cn.json
index 0e0dcd2..d6c8df4 100644
--- a/src/main/resources/assets/sign_up/lang/zh_cn.json
+++ b/src/main/resources/assets/sign_up/lang/zh_cn.json
@@ -1,3 +1,15 @@
{
+ "key.categories.sign_up": "Sign Me Up",
+ "key.sign_up.open_map": "打开地图",
+ "key.sign_up.open_new_map": "打开新地图",
+ "gui.sign_up.minimap": "小地图",
+ "gui.sign_up.minimap.minimap": "小地图",
+ "gui.sign_up.minimap.minimap.on": "开启",
+ "gui.sign_up.minimap.minimap.off": "关闭",
+ "gui.sign_up.minimap.range": "小地图渲染范围",
+ "gui.sign_up.minimap.rotate": "跟随玩家旋转",
+ "gui.sign_up.minimap.ssaa": "SSAA 角度",
+
+ "hud.sign_up.minimap.hide": "小地图被以下模组隐藏:%s"
}
\ No newline at end of file