add VisualRange enter/exit notifications to Notifications

uses the radar hud's Range setting so notifications match exactly
what the radar shows
This commit is contained in:
froslanz
2026-10-22 09:51:12 -04:00
parent 4ff4902981
commit 7c44258b9b
@@ -1,11 +1,19 @@
package cc.fros.features.modules.client;
import cc.fros.Fros;
import cc.fros.event.impl.ClientEvent;
import cc.fros.event.system.Subscribe;
import cc.fros.features.modules.Module;
import cc.fros.features.modules.hud.RadarHudModule;
import cc.fros.features.settings.Setting;
import cc.fros.util.TextUtil;
import cc.fros.util.chat.ChatUtil;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.world.entity.player.Player;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import static cc.fros.util.chat.SimpleSignature.from;
@@ -13,6 +21,12 @@ public class NotificationsModule extends Module {
private static final String MODULE_FORMAT = "{gray} %s %s%s";
public final Setting<Boolean> moduleToggle = bool("ModuleToggle", true);
public final Setting<Boolean> visualRange = bool("VisualRange", true);
private final Map<UUID, String> inRange = new HashMap<>();
private ClientLevel lastLevel;
private RadarHudModule radar;
private boolean tracked;
public NotificationsModule() {
super("Notifications", "Displays notifications for various client events", Category.CLIENT);
@@ -36,4 +50,57 @@ public class NotificationsModule extends Module {
moduleState ? "{green}" : "{red}",
moduleState ? "on" : "off"), from(event.getFeature().getName()));
}
@Override
public void onTick() {
if (!visualRange.getValue() || mc.player == null || mc.level == null) {
inRange.clear();
tracked = false;
return;
}
if (mc.level != lastLevel) {
// world change: re-baseline silently instead of notifying everyone present
lastLevel = mc.level;
tracked = false;
inRange.clear();
}
double range = getRadarRange();
Map<UUID, String> now = new HashMap<>();
for (Player player : mc.level.players()) {
if (player == mc.player) continue;
if (mc.player.distanceTo(player) <= range) {
now.put(player.getUUID(), player.getScoreboardName());
}
}
if (tracked) {
for (Map.Entry<UUID, String> entry : now.entrySet()) {
if (inRange.containsKey(entry.getKey())) continue;
notify(entry.getValue(), "{green}", "entered your visual range");
}
for (Map.Entry<UUID, String> entry : inRange.entrySet()) {
if (now.containsKey(entry.getKey())) continue;
notify(entry.getValue(), "{red}", "left your visual range");
}
}
inRange.clear();
inRange.putAll(now);
tracked = true;
}
private void notify(String name, String color, String message) {
ChatUtil.sendMessage(TextUtil.text(MODULE_FORMAT,
name,
color,
message), from(getName() + ":" + name));
}
private double getRadarRange() {
// stay in sync with what the radar hud actually shows
if (radar == null) radar = Fros.moduleManager.getModuleByClass(RadarHudModule.class);
return radar != null ? radar.range.getValue() : 64.0;
}
}