Skip to content

Commit

Permalink
In-game Waypoint Beacons
Browse files Browse the repository at this point in the history
  • Loading branch information
rfresh2 committed Jul 4, 2023
1 parent 49c2567 commit 122b31f
Show file tree
Hide file tree
Showing 9 changed files with 184 additions and 6 deletions.
6 changes: 5 additions & 1 deletion src/main/java/xaeroplus/XaeroPlus.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import net.minecraftforge.fml.common.eventhandler.EventBus;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import xaeroplus.event.ForgeEventHandler;
import xaeroplus.module.ModuleManager;
import xaeroplus.util.Shared;

Expand All @@ -24,6 +25,7 @@ public class XaeroPlus {
public static EventBus EVENT_BUS = MinecraftForge.EVENT_BUS;
public static Logger LOGGER = LogManager.getLogger("XaeroPlus");
private static boolean a = Shared.settingsLoadedInit; // needed to load static shared classes on init
private static final ForgeEventHandler forgeEventHandler = new ForgeEventHandler();

@Mod.Instance
public static XaeroPlus INSTANCE;
Expand All @@ -34,7 +36,9 @@ public void preInit(FMLPreInitializationEvent event) {
}

@Mod.EventHandler
public void init(FMLInitializationEvent event) { }
public void init(FMLInitializationEvent event) {
EVENT_BUS.register(forgeEventHandler);
}

@Mod.EventHandler
public void postInit(FMLPostInitializationEvent event) {
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/xaeroplus/event/ForgeEventHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package xaeroplus.event;

import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import xaero.common.XaeroMinimapSession;
import xaero.common.minimap.waypoints.render.WaypointsIngameRenderer;
import xaeroplus.util.CustomWaypointsIngameRenderer;

public class ForgeEventHandler {
@SubscribeEvent
public void onRenderWorldLastEvent(final RenderWorldLastEvent event) {
XaeroMinimapSession minimapSession = XaeroMinimapSession.getCurrentSession();
if (minimapSession == null) return;
WaypointsIngameRenderer waypointsIngameRenderer = minimapSession.getModMain().getInterfaces().getMinimapInterface().getWaypointsIngameRenderer();
((CustomWaypointsIngameRenderer) waypointsIngameRenderer).renderWaypointBeacons(event.getContext(), event.getPartialTicks());
}
}
33 changes: 33 additions & 0 deletions src/main/java/xaeroplus/mixin/client/MixinGuiWaypointSettings.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package xaeroplus.mixin.client;

import net.minecraft.client.gui.GuiScreen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import xaero.common.IXaeroMinimap;
import xaero.common.gui.ConfigSettingEntry;
import xaero.common.gui.GuiMinimapSettings;
import xaero.common.gui.GuiWaypointSettings;
import xaero.common.gui.ISettingEntry;
import xaeroplus.settings.XaeroPlusSettingsReflectionHax;

@Mixin(value = GuiWaypointSettings.class, remap = false)
public abstract class MixinGuiWaypointSettings extends GuiMinimapSettings {
public MixinGuiWaypointSettings(final IXaeroMinimap modMain, final String screenTitle, final GuiScreen par1Screen, final GuiScreen escScreen) {
super(modMain, screenTitle, par1Screen, escScreen);
}

@Inject(method = "<init>", at = @At("RETURN"))
public void init(final IXaeroMinimap modMain, final GuiScreen backScreen, final GuiScreen escScreen, final CallbackInfo ci) {
final ConfigSettingEntry[] configSettingEntries = XaeroPlusSettingsReflectionHax.getWaypointSettingEntries()
.toArray(new ConfigSettingEntry[0]);
final int oldLen = this.entries.length;
final int newLen = configSettingEntries.length;
final int totalNewLen = oldLen + configSettingEntries.length;
final ISettingEntry[] newEntries = new ISettingEntry[totalNewLen];
System.arraycopy(this.entries, 0, newEntries, newLen, oldLen);
System.arraycopy(configSettingEntries, 0, newEntries, 0, newLen);
this.entries = newEntries;
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,80 @@
package xaeroplus.mixin.client;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.tileentity.TileEntityBeaconRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3d;
import org.lwjgl.opengl.GL11;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import xaero.common.minimap.waypoints.Waypoint;
import xaero.common.minimap.waypoints.WaypointsManager;
import xaero.common.minimap.waypoints.render.WaypointFilterParams;
import xaero.common.minimap.waypoints.render.WaypointsIngameRenderer;
import xaero.common.settings.ModSettings;
import xaeroplus.settings.XaeroPlusSettingRegistry;
import xaeroplus.util.ColorHelper;
import xaeroplus.util.CustomWaypointsIngameRenderer;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import static xaeroplus.util.Shared.customDimensionId;

@Mixin(value = WaypointsIngameRenderer.class, remap = false)
public class MixinWaypointsIngameRenderer {
public class MixinWaypointsIngameRenderer implements CustomWaypointsIngameRenderer {
@Shadow private List<Waypoint> sortingList;
@Shadow private WaypointFilterParams filterParams;
List<Waypoint> beaconWaypoints = new ArrayList<>();
private static final ResourceLocation BEACON_BEAM_TEXTURE = new ResourceLocation("textures/entity/beacon_beam.png");
final Predicate<Waypoint> beaconViewFilter = new Predicate<Waypoint>() {
@Override
public boolean test(final Waypoint w) {
boolean deathpoints = filterParams.deathpoints;
if (!w.isDisabled()
&& w.getVisibilityType() != 2
&& w.getVisibilityType() != 3
&& (w.getWaypointType() != 1 && w.getWaypointType() != 2 || deathpoints)) {
double wpRenderX = (double)w.getX(filterParams.dimDiv) + 0.5 - filterParams.actualEntityX;
double wpRenderZ = (double)w.getZ(filterParams.dimDiv) + 0.5 - filterParams.actualEntityZ;
double offX = wpRenderX - filterParams.cameraX;
double offZ = wpRenderZ - filterParams.cameraZ;
double distance2D = Math.sqrt(offX * offX + offZ * offZ);
double waypointsDistance = filterParams.waypointsDistance;
double waypointsDistanceMin = filterParams.waypointsDistanceMin;
return w.isOneoffDestination()
|| (
w.getWaypointType() == 1
|| w.isGlobal()
|| w.isTemporary() && filterParams.temporaryWaypointsGlobal
|| waypointsDistance == 0.0
|| !(distance2D > waypointsDistance))
&& (waypointsDistanceMin == 0.0 || !(distance2D < waypointsDistanceMin));
} else {
return false;
}
}
};

@Inject(method = "renderWaypointsIterator", at = @At("HEAD"))
public void injectRenderWaypoints(final float[] worldModelView, final Iterator<Waypoint> iter, final double d3, final double d4, final double d5, final Entity entity, final BufferBuilder bufferbuilder, final Tessellator tessellator, final double dimDiv, final double actualEntityX, final double actualEntityY, final double actualEntityZ, final double smoothEntityY, final double fov, final int screenHeight, final float cameraAngleYaw, final float cameraAnglePitch, final Vec3d lookVector, final double clampDepth, final FontRenderer fontrenderer, final float[] waypointsProjection, final int screenWidth, final boolean detailedDisplayAllowed, final double uiScale, final double minDistance, final String subworldName, final CallbackInfo ci) {
beaconWaypoints = sortingList.stream().filter(beaconViewFilter).sorted().collect(Collectors.toList());
}

@Redirect(method = "render", at = @At(value = "INVOKE", target = "Lxaero/common/minimap/waypoints/WaypointsManager;getDimensionDivision(Ljava/lang/String;)D"))
public double redirectDimensionDivision(final WaypointsManager waypointsManager, final String worldContainerID) {
Expand All @@ -32,4 +94,32 @@ public double redirectDimensionDivision(final WaypointsManager waypointsManager,
}
return waypointsManager.getDimensionDivision(worldContainerID);
}

@Override
public void renderWaypointBeacons(final RenderGlobal renderGlobal, final float partialTicks) {
if (!XaeroPlusSettingRegistry.waypointBeacons.getValue()) return;
beaconWaypoints.forEach(w -> renderWaypointBeacon(w, partialTicks));
}

public void renderWaypointBeacon(final Waypoint waypoint, float partialTicks) {
final Minecraft mc = Minecraft.getMinecraft();
final RenderManager renderManager = mc.getRenderManager();
final Vec3d playerVec = renderManager.renderViewEntity.getPositionVector();
Vec3d waypointVec = new Vec3d(waypoint.getX(), waypoint.getY() + 0.118, waypoint.getZ());
double actualDistance = playerVec.distanceTo(waypointVec);
double maxRenderDistance = mc.gameSettings.renderDistanceChunks * 16;
if (actualDistance > maxRenderDistance) {
final Vec3d delta = waypointVec.subtract(playerVec).normalize();
waypointVec = playerVec.add(new Vec3d(delta.x * maxRenderDistance, delta.y * maxRenderDistance, delta.z * maxRenderDistance));
}
final double x = waypointVec.x - renderManager.viewerPosX;
final double z = waypointVec.z - renderManager.viewerPosZ;
final double y = -renderManager.viewerPosY;
final int color = ModSettings.COLORS[waypoint.getColor()];
GlStateManager.alphaFunc(GL11.GL_GREATER, 0.1f);
mc.renderEngine.bindTexture(BEACON_BEAM_TEXTURE);
final float time = mc.world.getTotalWorldTime();
final float[] colorRGBA = ColorHelper.getColorRGBA(color);
TileEntityBeaconRenderer.renderBeamSegment(x, y, z, partialTicks, 1.0f, time, 0, 256, colorRGBA);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -180,4 +180,7 @@ public enum DataFolderResolutionMode {
1000000f, 10000000f, 100000f,
"Experimental. The max number of queued lighting updates. Might prevent crashes on low memory systems when loading many chunks at fast rates",
1000000f, SettingLocation.WORLD_MAP_MAIN);
public static final XaeroPlusBooleanSetting waypointBeacons = XaeroPlusBooleanSetting.create("Waypoint Beacons",
"Render waypoint beacons in game.",
true, SettingLocation.WAYPOINTS);
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ public class XaeroPlusSettingsReflectionHax {
public static final List<XaeroPlusSetting> XAERO_PLUS_MINIMAP_OVERLAY_SETTINGS = new ArrayList<>();
public static final List<XaeroPlusSetting> XAERO_PLUS_MINIMAP_ENTITY_RADAR_SETTINGS = new ArrayList<>();
public static final List<XaeroPlusSetting> XAERO_PLUS_MINIMAP_SETTINGS = new ArrayList<>();
public static final List<XaeroPlusSetting> XAERO_PLUS_WAYPOINTS_SETTINGS = new ArrayList<>();
public static final Supplier<List<XaeroPlusSetting>> ALL_MINIMAP_SETTINGS = () ->
Stream.of(XAERO_PLUS_MINIMAP_OVERLAY_SETTINGS.stream(),
XAERO_PLUS_MINIMAP_SETTINGS.stream(),
XAERO_PLUS_MINIMAP_ENTITY_RADAR_SETTINGS.stream())
XAERO_PLUS_MINIMAP_ENTITY_RADAR_SETTINGS.stream(),
XAERO_PLUS_WAYPOINTS_SETTINGS.stream())
.flatMap(x -> x)
.collect(Collectors.toList());
public static final List<XaeroPlusSetting> XAERO_PLUS_KEYBIND_SETTINGS = new ArrayList<>();
Expand All @@ -41,7 +43,8 @@ public class XaeroPlusSettingsReflectionHax {
XAERO_PLUS_MINIMAP_OVERLAY_SETTINGS.stream(),
XAERO_PLUS_MINIMAP_ENTITY_RADAR_SETTINGS.stream(),
XAERO_PLUS_MINIMAP_SETTINGS.stream(),
XAERO_PLUS_KEYBIND_SETTINGS.stream())
XAERO_PLUS_KEYBIND_SETTINGS.stream(),
XAERO_PLUS_WAYPOINTS_SETTINGS.stream())
.flatMap(x -> x)
.collect(Collectors.toList());

Expand All @@ -50,7 +53,8 @@ public enum SettingLocation {
MINIMAP_OVERLAYS(XAERO_PLUS_MINIMAP_OVERLAY_SETTINGS),
MINIMAP(XAERO_PLUS_MINIMAP_SETTINGS),
KEYBINDS(XAERO_PLUS_KEYBIND_SETTINGS),
MINIMAP_ENTITY_RADAR(XAERO_PLUS_MINIMAP_ENTITY_RADAR_SETTINGS);
MINIMAP_ENTITY_RADAR(XAERO_PLUS_MINIMAP_ENTITY_RADAR_SETTINGS),
WAYPOINTS(XAERO_PLUS_WAYPOINTS_SETTINGS);

private final List<XaeroPlusSetting> settingsList;

Expand All @@ -68,7 +72,8 @@ public List<XaeroPlusSetting> getSettingsList() {
XAERO_PLUS_MINIMAP_OVERLAY_SETTINGS.stream(),
XAERO_PLUS_MINIMAP_ENTITY_RADAR_SETTINGS.stream(),
XAERO_PLUS_MINIMAP_SETTINGS.stream(),
XAERO_PLUS_KEYBIND_SETTINGS.stream())
XAERO_PLUS_KEYBIND_SETTINGS.stream(),
XAERO_PLUS_WAYPOINTS_SETTINGS.stream())
.flatMap(x -> x)
.filter(setting -> setting instanceof XaeroPlusBooleanSetting)
.map(XaeroPlusSetting::getKeyBinding)
Expand All @@ -79,6 +84,7 @@ public List<XaeroPlusSetting> getSettingsList() {
private static List<xaero.common.settings.ModOptions> MINIMAP_OVERLAY_MOD_OPTIONS_LIST = null;
private static List<xaero.common.settings.ModOptions> MINIMAP_MOD_OPTIONS_LIST = null;
private static List<xaero.common.settings.ModOptions> MINIMAP_ENTITY_RADAR_MOD_OPTIONS_LIST = null;
private static List<xaero.common.settings.ModOptions> WAYPOINTS_MOD_OPTIONS_LIST = null;

private static int enumOrdinal = 69; // needs to not overlap with existing enum indeces

Expand Down Expand Up @@ -131,6 +137,15 @@ public static List<xaero.common.gui.ConfigSettingEntry> getMiniMapConfigSettingE
.collect(Collectors.toList());
}

public static List<xaero.common.gui.ConfigSettingEntry> getWaypointSettingEntries() {
if (WAYPOINTS_MOD_OPTIONS_LIST == null) {
WAYPOINTS_MOD_OPTIONS_LIST = constructXaeroPlusSettings(xaero.common.settings.ModOptions.class, ModType.MINIMAP, XAERO_PLUS_WAYPOINTS_SETTINGS);
}
return WAYPOINTS_MOD_OPTIONS_LIST.stream()
.map(xaero.common.gui.ConfigSettingEntry::new)
.collect(Collectors.toList());
}

private static <T extends Enum<T>> ConstructorAccessor getModOptionsConstructorAccessor(Class<T> clazz, ModType type) throws Exception {
final int numArgs;
if (type == ModType.WORLDMAP) {
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/xaeroplus/util/ColorHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ public static int getColorWithAlpha(final int colorInt, final int a) {
return ((a & 255) << 24) | (colorInt & 0x00FFFFFF);
}

public static float[] getColorRGBA(final int colorInt) {
return new float[] {
((colorInt >> 16) & 255) / 255.0f,
((colorInt >> 8) & 255) / 255.0f,
(colorInt & 255) / 255.0f,
((colorInt >> 24) & 255) / 255.0f };
}

public static int getColorAlpha(final int colorInt) {
return (colorInt >> 24) & 255;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package xaeroplus.util;

import net.minecraft.client.renderer.RenderGlobal;

public interface CustomWaypointsIngameRenderer {
void renderWaypointBeacons(final RenderGlobal renderGlobal, final float partialTicks);
}
1 change: 1 addition & 0 deletions src/main/resources/mixins.xaeroplus.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"MixinGuiSettingsWorldMap",
"MixinGuiUpdateAll",
"MixinGuiWaypoints",
"MixinGuiWaypointSettings",
"MixinGuiWaypointsList",
"MixinGuiWorldMapSettings",
"MixinLeveledRegion",
Expand Down

0 comments on commit 122b31f

Please sign in to comment.