Skip to content

Commit a51943a

Browse files
committed
Added Waypoints, LogoutSpots, Breadcrumbs
1 parent 10cb7db commit a51943a

19 files changed

+1826
-17
lines changed

README.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,63 @@ All credit for the original client goes to Wurst‑Imperium and its contributors
8484
### Notes
8585
- Scanning only includes chunks the server has sent. Larger radii work best in singleplayer or on servers with higher view distance.
8686

87+
### Waypoints (overhaul)
88+
89+
Waypoints received a usability pass and rendering upgrades.
90+
91+
- Opening the manager
92+
- Default keybind: apostrophe ('). This triggers the command `.waypoints`.
93+
- You can also run the command `.waypoints` in chat or bind it yourself.
94+
95+
- Creating and editing
96+
- The editor shows name, coordinates (X/Y/Z), dimension, icon, visibility, lines on/off, and color.
97+
- Color picker: Pick any color, click Done, and the editor immediately reflects the new color (button text + preview square). Press Save to persist the waypoint.
98+
- Copy coordinates: In the manager list, each waypoint row includes a Copy button that places `x, y, z` on the clipboard.
99+
- Opposite: Default OFF. When ON (and applicable), the editor shows a hint below the toggle: “Opposite shows in … at (x, y, z)”. This converts Overworld <-> Nether using the usual 8× rule. (Opposite has no effect in the End.)
100+
101+
- Rendering behavior
102+
- Constant-size labels: Waypoint name and distance are rendered at a fixed on‑screen size (configurable via “Label scale”), with a constant pixel gap between the two lines. This prevents drifting/squeezing as you move.
103+
- Max label scale is 15.
104+
- Per‑waypoint “lines” toggle: Draws tracer + box around the target block when enabled.
105+
- Death waypoints: Optional automatic waypoints on death. You can toggle creating death waypoints, toggle whether they have lines, and choose their color. There’s also a setting to prune older death waypoints.
106+
107+
- Manager list quality-of-life
108+
- Color swatch: Each saved waypoint shows a small color box for quick identification.
109+
- Show/Hide and Delete refresh in place (no stacked screens), so Back only needs to be pressed once.
110+
111+
- Storage
112+
- Waypoints are stored per world/server under `wurst/waypoints/<worldId>.json` where `<worldId>` is the server address (or `singleplayer`).
113+
114+
### Breadcrumbs (rendering improvement)
115+
116+
Breadcrumbs now uses a single, true thick line.
117+
118+
- Previous versions simulated thickness by drawing multiple offset lines. This fork switches to a custom line‑strip width for a cleaner, more stable trail with less overdraw.
119+
- Settings
120+
- Color
121+
- Max sections (how many points are kept)
122+
- Section length (distance before a new point is added)
123+
- Line thickness (applied as a real line width)
124+
125+
### LogoutSpots (new)
126+
127+
Visualizes where players logged out.
128+
129+
- How it works
130+
- The hack snapshots the current player list and compares it each tick. If an entry disappears, a logout spot is recorded at that player’s last known position (bounding box).
131+
- Spots for players who rejoin are removed automatically.
132+
133+
- Rendering
134+
- Draws solid boxes (sides) plus an outline around each recorded spot.
135+
- Optional tracers from your camera to each spot’s center.
136+
- On‑screen labels with the player’s name (and adjustable name scale).
137+
138+
- Settings
139+
- Side color (box fill)
140+
- Line color (outline + tracers)
141+
- Name scale
142+
- Show tracers (on/off)
143+
87144
## License
88145

89146
This code is licensed under the GNU General Public License v3.

src/main/java/net/wurstclient/WurstRenderLayers.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,23 @@ public static RenderLayer.MultiPhase getLineStrip(boolean depthTest)
109109
{
110110
return depthTest ? LINE_STRIP : ESP_LINE_STRIP;
111111
}
112+
113+
/**
114+
* Line strip with custom width.
115+
*/
116+
public static RenderLayer.MultiPhase getLineStrip(boolean depthTest,
117+
double width)
118+
{
119+
return RenderLayer.of(
120+
depthTest
121+
? "wurst:line_strip_custom" : "wurst:esp_line_strip_custom",
122+
1536,
123+
depthTest ? WurstShaderPipelines.DEPTH_TEST_LINE_STRIP
124+
: WurstShaderPipelines.ESP_LINE_STRIP,
125+
RenderLayer.MultiPhaseParameters.builder()
126+
.lineWidth(new RenderPhase.LineWidth(
127+
java.util.OptionalDouble.of(width)))
128+
.layering(RenderLayer.VIEW_OFFSET_Z_LAYERING)
129+
.target(RenderLayer.ITEM_ENTITY_TARGET).build(false));
130+
}
112131
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (c) 2014-2025 Wurst-Imperium and contributors.
3+
*
4+
* This source code is subject to the terms of the GNU General Public
5+
* License, version 3. If a copy of the GPL was not distributed with this
6+
* file, You can obtain one at: https://www.gnu.org/licenses/gpl-3.0.txt
7+
*/
8+
package net.wurstclient.clickgui.components;
9+
10+
import java.util.Objects;
11+
12+
import net.wurstclient.clickgui.screens.WaypointsScreen;
13+
import net.wurstclient.settings.Setting;
14+
import net.wurstclient.settings.WaypointsSetting;
15+
16+
public final class WaypointsEditButton extends AbstractListEditButton
17+
{
18+
private final WaypointsSetting setting;
19+
20+
public WaypointsEditButton(WaypointsSetting setting)
21+
{
22+
this.setting = Objects.requireNonNull(setting);
23+
setWidth(getDefaultWidth());
24+
setHeight(getDefaultHeight());
25+
}
26+
27+
@Override
28+
protected void openScreen()
29+
{
30+
MC.setScreen(
31+
new WaypointsScreen(MC.currentScreen, setting.getManager()));
32+
}
33+
34+
@Override
35+
protected String getText()
36+
{
37+
return setting.getName();
38+
}
39+
40+
@Override
41+
protected Setting getSetting()
42+
{
43+
return setting;
44+
}
45+
}

src/main/java/net/wurstclient/clickgui/screens/EditColorScreen.java

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -255,35 +255,48 @@ public boolean mouseClicked(double mouseX, double mouseY, int button)
255255
if(mouseX >= paletteX && mouseX <= paletteX + paletteWidth
256256
&& mouseY >= paletteY && mouseY <= paletteY + paletteHeight)
257257
{
258-
if(paletteAsBufferedImage == null)
259-
return super.mouseClicked(mouseX, mouseY, button);
260-
261-
int x = (int)Math.round((mouseX - paletteX) / paletteWidth
262-
* paletteAsBufferedImage.getWidth());
263-
int y = (int)Math.round((mouseY - paletteY) / paletteHeight
264-
* paletteAsBufferedImage.getHeight());
265-
266-
if(x > 0 && y > 0 && x < paletteAsBufferedImage.getWidth()
267-
&& y < paletteAsBufferedImage.getHeight())
258+
if(paletteAsBufferedImage != null)
259+
{
260+
int x = (int)Math.round((mouseX - paletteX) / paletteWidth
261+
* paletteAsBufferedImage.getWidth());
262+
int y = (int)Math.round((mouseY - paletteY) / paletteHeight
263+
* paletteAsBufferedImage.getHeight());
264+
if(x > 0 && y > 0 && x < paletteAsBufferedImage.getWidth()
265+
&& y < paletteAsBufferedImage.getHeight())
266+
{
267+
int rgb = paletteAsBufferedImage.getRGB(x, y);
268+
// Always set picked color, force full alpha for consistency
269+
setColor(new Color((rgb & 0x00FFFFFF) | 0xFF000000, true));
270+
}
271+
}else
268272
{
269-
int rgb = paletteAsBufferedImage.getRGB(x, y);
270-
Color color = new Color(rgb, true);
271-
272-
// Set color if pixel has full alpha
273-
if(color.getAlpha() >= 255)
274-
setColor(color);
273+
// Fallback: compute color procedurally from position
274+
// Horizontal = hue, vertical = brightness
275+
double u = Math.max(0,
276+
Math.min(1, (mouseX - paletteX) / paletteWidth));
277+
double v = Math.max(0,
278+
Math.min(1, (mouseY - paletteY) / paletteHeight));
279+
float hue = (float)u;
280+
float sat = 1.0f;
281+
float bri = (float)(1.0 - v);
282+
int rgb = java.awt.Color.HSBtoRGB(hue, sat, bri);
283+
setColor(new Color((rgb & 0x00FFFFFF) | 0xFF000000, true));
275284
}
285+
return true;
276286
}
277-
278287
return super.mouseClicked(mouseX, mouseY, button);
279288
}
280289

281290
private void setColor(Color color)
282291
{
292+
// Update working color and UI fields without triggering listeners
293+
this.color = color;
294+
ignoreChanges = true;
283295
hexValueField.setText(ColorUtils.toHex(color).substring(1));
284296
redValueField.setText("" + color.getRed());
285297
greenValueField.setText("" + color.getGreen());
286298
blueValueField.setText("" + color.getBlue());
299+
ignoreChanges = false;
287300
}
288301

289302
@Override

0 commit comments

Comments
 (0)