Skip to content

Commit 27d2abc

Browse files
committed
Various additions to the Waypoint Module
1 parent 0a98268 commit 27d2abc

13 files changed

Lines changed: 562 additions & 15 deletions

File tree

api/src/main/java/com/lunarclient/apollo/module/waypoint/Waypoint.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.awt.Color;
2828
import lombok.Builder;
2929
import lombok.Getter;
30+
import org.jetbrains.annotations.Nullable;
3031

3132
/**
3233
* Represents a waypoint which can be shown on the client.
@@ -82,4 +83,45 @@ public final class Waypoint {
8283
*/
8384
boolean hidden;
8485

86+
/**
87+
* Whether the beacon beam for this waypoint is drawn.
88+
*
89+
* @since 1.2.7
90+
*/
91+
@Builder.Default
92+
boolean showBeam = true;
93+
94+
/**
95+
* Whether the in-world block outline highlight at the waypoint location is drawn.
96+
*
97+
* @since 1.2.7
98+
*/
99+
@Builder.Default
100+
boolean highlightBlock = true;
101+
102+
/**
103+
* Line width of the block highlight outline when {@link #highlightBlock} is enabled.
104+
*
105+
* <p>Accepts {@code 1.5F} to {@code 7.5F}. Leaving the
106+
* field at its default of {@code 0.0F} is treated as a
107+
* fallback to the player's own configured line width.</p>
108+
*
109+
* @since 1.2.7
110+
*/
111+
@Builder.Default
112+
float highlightBlockLineWidth = 0.0F;
113+
114+
/**
115+
* Label and HUD text overrides applied to this waypoint.
116+
*
117+
* <p>Set to a built {@link WaypointTextStyle} to drive the
118+
* client's text rendering from the server; leave {@code null} to
119+
* defer to the Lunar waypoint mod's own settings.</p>
120+
*
121+
* @return the text style, or {@code null} when no override is sent
122+
* @since 1.2.7
123+
*/
124+
@Builder.Default
125+
@Nullable WaypointTextStyle textStyle = null;
126+
85127
}

api/src/main/java/com/lunarclient/apollo/module/waypoint/WaypointModule.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,22 @@ public boolean isClientNotify() {
127127
*/
128128
public abstract void resetWaypoints(Recipients recipients);
129129

130+
/**
131+
* Shows a {@link Waypoint} for the {@link Recipients} that was previously hidden.
132+
*
133+
* @param recipients the recipients that are receiving the packet
134+
* @param waypointName the waypoint name
135+
* @since 1.2.7
136+
*/
137+
public abstract void showWaypoint(Recipients recipients, String waypointName);
138+
139+
/**
140+
* Hides a {@link Waypoint} for the {@link Recipients} without removing it.
141+
*
142+
* @param recipients the recipients that are receiving the packet
143+
* @param waypointName the waypoint name
144+
* @since 1.2.7
145+
*/
146+
public abstract void hideWaypoint(Recipients recipients, String waypointName);
147+
130148
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* This file is part of Apollo, licensed under the MIT License.
3+
*
4+
* Copyright (c) 2026 Moonsworth
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
package com.lunarclient.apollo.module.waypoint;
25+
26+
import lombok.Builder;
27+
import lombok.Getter;
28+
29+
/**
30+
* Overrides for a waypoint's on-screen label, icons and distance HUD on the Lunar client.
31+
*
32+
* @since 1.2.7
33+
*/
34+
@Getter
35+
@Builder
36+
public final class WaypointTextStyle {
37+
38+
/**
39+
* Whether the waypoint label (text and box) is drawn at all.
40+
*
41+
* @since 1.2.7
42+
*/
43+
@Builder.Default
44+
boolean showText = true;
45+
46+
/**
47+
* Restricts the waypoint label drawing to when the player is looking roughly toward the waypoint.
48+
*
49+
* @since 1.2.7
50+
*/
51+
@Builder.Default
52+
boolean onlyShowTextWhenLookingNear = false;
53+
54+
/**
55+
* Whether the waypoint icons are drawn.
56+
*
57+
* @since 1.2.7
58+
*/
59+
@Builder.Default
60+
boolean showIcons = false;
61+
62+
/**
63+
* The waypoint scale applied to the label icon.
64+
*
65+
* <p>Accepts {@code 0.1F} to {@code 3.0F}</p>
66+
*
67+
* @since 1.2.7
68+
*/
69+
@Builder.Default
70+
float textIconScale = 1.5F;
71+
72+
/**
73+
* The waypoint scale applied to the main label text.
74+
*
75+
* <p>Accepts {@code 0.1F} to {@code 2.0F}</p>
76+
*
77+
* @since 1.2.7
78+
*/
79+
@Builder.Default
80+
float labelScale = 1.0F;
81+
82+
/**
83+
* The waypoint padding of the label background box.
84+
*
85+
* <p>Accepts {@code 1.0F} to {@code 8.0F}</p>
86+
*
87+
* @since 1.2.7
88+
*/
89+
@Builder.Default
90+
float boxPadding = 4.0F;
91+
92+
/**
93+
* Whether a border is drawn around the label background box.
94+
*
95+
* @since 1.2.7
96+
*/
97+
@Builder.Default
98+
boolean boxBorders = true;
99+
100+
/**
101+
* Whether a shadow is drawn behind the label text.
102+
*
103+
* @since 1.2.7
104+
*/
105+
@Builder.Default
106+
boolean textShadow = false;
107+
108+
/**
109+
* Whether the distance from the player to the waypoint is shown next to the label.
110+
*
111+
* @since 1.2.7
112+
*/
113+
@Builder.Default
114+
boolean showDistance = true;
115+
116+
}

common/src/main/java/com/lunarclient/apollo/module/waypoint/WaypointModuleImpl.java

Lines changed: 133 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@
3131
import com.lunarclient.apollo.player.ApolloPlayer;
3232
import com.lunarclient.apollo.recipients.Recipients;
3333
import com.lunarclient.apollo.waypoint.v1.DisplayWaypointMessage;
34+
import com.lunarclient.apollo.waypoint.v1.HideWaypointMessage;
3435
import com.lunarclient.apollo.waypoint.v1.RemoveWaypointMessage;
3536
import com.lunarclient.apollo.waypoint.v1.ResetWaypointsMessage;
37+
import com.lunarclient.apollo.waypoint.v1.ShowWaypointMessage;
3638
import java.awt.Color;
3739
import java.lang.reflect.Type;
3840
import java.util.Arrays;
@@ -43,6 +45,8 @@
4345
import org.spongepowered.configurate.serialize.SerializationException;
4446
import org.spongepowered.configurate.serialize.TypeSerializer;
4547

48+
import static com.lunarclient.apollo.util.Ranges.checkRange;
49+
4650
/**
4751
* Provides the waypoints module.
4852
*
@@ -87,6 +91,24 @@ public void resetWaypoints(@NonNull Recipients recipients) {
8791
recipients.forEach(player -> ((AbstractApolloPlayer) player).sendPacket(message));
8892
}
8993

94+
@Override
95+
public void showWaypoint(@NonNull Recipients recipients, @NonNull String waypointName) {
96+
ShowWaypointMessage message = ShowWaypointMessage.newBuilder()
97+
.setName(waypointName)
98+
.build();
99+
100+
recipients.forEach(player -> ((AbstractApolloPlayer) player).sendPacket(message));
101+
}
102+
103+
@Override
104+
public void hideWaypoint(@NonNull Recipients recipients, @NonNull String waypointName) {
105+
HideWaypointMessage message = HideWaypointMessage.newBuilder()
106+
.setName(waypointName)
107+
.build();
108+
109+
recipients.forEach(player -> ((AbstractApolloPlayer) player).sendPacket(message));
110+
}
111+
90112
private void onPlayerRegister(ApolloRegisterPlayerEvent event) {
91113
ApolloPlayer player = event.getPlayer();
92114
List<Waypoint> waypoints = this.getOptions().get(player, WaypointModule.DEFAULT_WAYPOINTS);
@@ -99,31 +121,74 @@ private void onPlayerRegister(ApolloRegisterPlayerEvent event) {
99121
}
100122

101123
private DisplayWaypointMessage toProtobuf(Waypoint waypoint) {
102-
return DisplayWaypointMessage.newBuilder()
124+
DisplayWaypointMessage.Builder builder = DisplayWaypointMessage.newBuilder()
103125
.setName(waypoint.getName())
104126
.setLocation(NetworkTypes.toProtobuf(waypoint.getLocation()))
105127
.setColor(NetworkTypes.toProtobuf(waypoint.getColor()))
106128
.setPreventRemoval(waypoint.isPreventRemoval())
107129
.setHidden(waypoint.isHidden())
130+
.setShowBeam(waypoint.isShowBeam())
131+
.setHighlightBlock(waypoint.isHighlightBlock());
132+
133+
float highlightBlockLineWidth = waypoint.getHighlightBlockLineWidth();
134+
if (highlightBlockLineWidth != 0.0F) {
135+
builder.setHighlightBlockLineWidth(checkRange(highlightBlockLineWidth, 1.5F, 7.5F, "Waypoint#highlightBlockLineWidth"));
136+
}
137+
138+
WaypointTextStyle style = waypoint.getTextStyle();
139+
if (style != null) {
140+
builder.setStyle(this.toProtobuf(style));
141+
}
142+
143+
return builder.build();
144+
}
145+
146+
private com.lunarclient.apollo.waypoint.v1.WaypointTextStyle toProtobuf(WaypointTextStyle style) {
147+
return com.lunarclient.apollo.waypoint.v1.WaypointTextStyle.newBuilder()
148+
.setShowText(style.isShowText())
149+
.setOnlyShowTextWhenLookingNear(style.isOnlyShowTextWhenLookingNear())
150+
.setShowIcons(style.isShowIcons())
151+
.setTextIconScale(checkRange(style.getTextIconScale(), 0.1F, 3.0F, "WaypointTextStyle#textIconScale"))
152+
.setLabelScale(checkRange(style.getLabelScale(), 0.1F, 2.0F, "WaypointTextStyle#labelScale"))
153+
.setBoxPadding(checkRange(style.getBoxPadding(), 1.0F, 8.0F, "WaypointTextStyle#boxPadding"))
154+
.setBoxBorders(style.isBoxBorders())
155+
.setTextShadow(style.isTextShadow())
156+
.setShowDistance(style.isShowDistance())
108157
.build();
109158
}
110159

111160
private static final class WaypointSerializer implements TypeSerializer<Waypoint> {
112161
@Override
113162
public Waypoint deserialize(Type type, ConfigurationNode node) throws SerializationException {
114-
return Waypoint.builder()
163+
Waypoint.WaypointBuilder builder = Waypoint.builder()
115164
.name(this.virtualNode(node, "name").getString())
116165
.location(ApolloBlockLocation.builder()
117166
.world(this.virtualNode(node, "location", "world").getString())
118167
.x(this.virtualNode(node, "location", "x").getInt())
119168
.y(this.virtualNode(node, "location", "y").getInt())
120169
.z(this.virtualNode(node, "location", "z").getInt())
121-
.build()
122-
)
123-
.color(Color.decode(this.virtualNode(node, "color").getString("#FFFFFF")))
124-
.preventRemoval(this.virtualNode(node, "prevent-removal").getBoolean())
125-
.hidden(this.virtualNode(node, "hidden").getBoolean())
126-
.build();
170+
.build())
171+
.color(Color.decode(node.node("color").getString("#FFFFFF")))
172+
.preventRemoval(node.node("prevent-removal").getBoolean())
173+
.hidden(node.node("hidden").getBoolean());
174+
175+
if (node.hasChild("show-beam")) {
176+
builder.showBeam(node.node("show-beam").getBoolean(true));
177+
}
178+
179+
if (node.hasChild("highlight-block")) {
180+
builder.highlightBlock(node.node("highlight-block").getBoolean(true));
181+
}
182+
183+
if (node.hasChild("highlight-block-line-width")) {
184+
builder.highlightBlockLineWidth((float) node.node("highlight-block-line-width").getDouble(4.0D));
185+
}
186+
187+
if (node.hasChild("style")) {
188+
builder.textStyle(this.readStyle(node.node("style")));
189+
}
190+
191+
return builder.build();
127192
}
128193

129194
@Override
@@ -141,6 +206,66 @@ public void serialize(Type type, @Nullable Waypoint waypoint, ConfigurationNode
141206
node.node("color").set(String.format("#%06X", (0xFFFFFF & waypoint.getColor().getRGB())));
142207
node.node("prevent-removal").set(waypoint.isPreventRemoval());
143208
node.node("hidden").set(waypoint.isHidden());
209+
node.node("show-beam").set(waypoint.isShowBeam());
210+
node.node("highlight-block").set(waypoint.isHighlightBlock());
211+
node.node("highlight-block-line-width").set(waypoint.getHighlightBlockLineWidth());
212+
213+
if (waypoint.getTextStyle() != null) {
214+
this.writeStyle(node.node("style"), waypoint.getTextStyle());
215+
}
216+
}
217+
218+
private WaypointTextStyle readStyle(ConfigurationNode node) {
219+
WaypointTextStyle.WaypointTextStyleBuilder builder = WaypointTextStyle.builder();
220+
if (node.hasChild("show-text")) {
221+
builder.showText(node.node("show-text").getBoolean(true));
222+
}
223+
224+
if (node.hasChild("only-show-text-when-looking-near")) {
225+
builder.onlyShowTextWhenLookingNear(node.node("only-show-text-when-looking-near").getBoolean(false));
226+
}
227+
228+
if (node.hasChild("show-icons")) {
229+
builder.showIcons(node.node("show-icons").getBoolean(false));
230+
}
231+
232+
if (node.hasChild("text-icon-scale")) {
233+
builder.textIconScale(node.node("text-icon-scale").getFloat(1.5F));
234+
}
235+
236+
if (node.hasChild("label-scale")) {
237+
builder.labelScale(node.node("label-scale").getFloat(1.0F));
238+
}
239+
240+
if (node.hasChild("box-padding")) {
241+
builder.boxPadding(node.node("box-padding").getFloat(4.0F));
242+
}
243+
244+
if (node.hasChild("box-borders")) {
245+
builder.boxBorders(node.node("box-borders").getBoolean(true));
246+
}
247+
248+
if (node.hasChild("text-shadow")) {
249+
builder.textShadow(node.node("text-shadow").getBoolean(false));
250+
}
251+
252+
if (node.hasChild("show-distance")) {
253+
builder.showDistance(node.node("show-distance").getBoolean(true));
254+
}
255+
256+
return builder.build();
257+
}
258+
259+
private void writeStyle(ConfigurationNode node, WaypointTextStyle style) throws SerializationException {
260+
node.node("show-text").set(style.isShowText());
261+
node.node("only-show-text-when-looking-near").set(style.isOnlyShowTextWhenLookingNear());
262+
node.node("show-icons").set(style.isShowIcons());
263+
node.node("text-icon-scale").set(style.getTextIconScale());
264+
node.node("label-scale").set(style.getLabelScale());
265+
node.node("box-padding").set(style.getBoxPadding());
266+
node.node("box-borders").set(style.isBoxBorders());
267+
node.node("text-shadow").set(style.isTextShadow());
268+
node.node("show-distance").set(style.isShowDistance());
144269
}
145270

146271
private ConfigurationNode virtualNode(ConfigurationNode source, Object... path) throws SerializationException {

0 commit comments

Comments
 (0)