Skip to content

Commit

Permalink
Feature: API for mods to disable minimap. Waypoints now contains rota…
Browse files Browse the repository at this point in the history
…tion angle.
  • Loading branch information
burningtnt committed Dec 11, 2024
1 parent ebb31bb commit e0001a7
Show file tree
Hide file tree
Showing 11 changed files with 184 additions and 29 deletions.
16 changes: 12 additions & 4 deletions run/config/SignMeUp/Waypoints.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
]
}
38 changes: 38 additions & 0 deletions src/main/java/org/teacon/signmeup/api/MiniMap.java
Original file line number Diff line number Diff line change
@@ -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;
}

/**
* <p>Set the visibility of MiniMap.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>This method can be invoked from any threads.</p>
*
* @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);
}
15 changes: 10 additions & 5 deletions src/main/java/org/teacon/signmeup/command/OpCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -29,10 +31,12 @@ public static void waypoints(CommandDispatcher<CommandSourceStack> 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)
)
)
)
)
Expand All @@ -51,15 +55,16 @@ private static int setWaypoint(CommandContext<CommandSourceStack> 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(
point -> context.getSource().sendSuccess(() -> Component.literal("[" + point + "] already exists. Remove it first if you want to replace it."), true),
() -> {
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)));
}
);
});
Expand Down
19 changes: 7 additions & 12 deletions src/main/java/org/teacon/signmeup/config/Waypoints.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 + ">]";
}
}
}
13 changes: 13 additions & 0 deletions src/main/java/org/teacon/signmeup/gui/map/MapScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
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;
import org.teacon.signmeup.SignMeUp;
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
Expand Down Expand Up @@ -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() {
Expand Down
64 changes: 64 additions & 0 deletions src/main/java/org/teacon/signmeup/hud/MiniMapAPI.java
Original file line number Diff line number Diff line change
@@ -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<String, String> ID_NAME_MAP = FMLLoader.getLoadingModList().getMods().stream().collect(Collectors.toMap(
ModInfo::getModId, ModInfo::getDisplayName
));

private final CopyOnWriteArrayList<String> 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<String> 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;
}
}
}
6 changes: 4 additions & 2 deletions src/main/java/org/teacon/signmeup/hud/MiniMapPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<ByteBuf, SetWaypointPacket> STREAM_CODEC = StreamCodec.composite(
Expand All @@ -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));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -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."));
});
}
}
6 changes: 4 additions & 2 deletions src/main/resources/assets/sign_up/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
12 changes: 12 additions & 0 deletions src/main/resources/assets/sign_up/lang/zh_cn.json
Original file line number Diff line number Diff line change
@@ -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"
}

0 comments on commit e0001a7

Please sign in to comment.