Skip to content

Commit b01a777

Browse files
committed
Highlight Opened Chests
1 parent 5471567 commit b01a777

File tree

3 files changed

+244
-23
lines changed

3 files changed

+244
-23
lines changed

README.md

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ I did not, nor could I copy their code directly as most are Meteor based mods. S
175175
- Adjustable ESP and Waypoint colors
176176
- Adjustable search radius
177177
- Adjustable font size
178+
- Highlight open chests with X with an adjustable color and line thickness
178179

179180
![ChestSearch](https://i.imgur.com/OXuVeF5.png)
180181

@@ -349,29 +350,12 @@ I did not, nor could I copy their code directly as most are Meteor based mods. S
349350
- Toggles for various types of events
350351
- Toggles for debugging and ESP
351352

352-
### SeedMapperHelper
353-
- UI for [my fork](https://github.com/cev-api/SeedMapper-CevAPI) of [SeedMapper](https://github.com/xpple/SeedMapper/) which covers all settings except for debug/dev mode.
354-
- Supports ESP color settings so long as you're using [my SeedMapper fork](https://github.com/cev-api/SeedMapper-CevAPI)
355-
- Supports keybinds for all settings
356-
- Run `/sm:minimap` to open a live SeedMap minimap in the top-left corner of the HUD.
357-
- Use `/sm:minimap on/off` to explicitly control whether it is shown.
358-
- The minimap:
359-
- Renders the same features you selected on the main map.
360-
- Tracks your current position in real time.
361-
- Ideal for overlaying over Xaeros Minimap (See Screenshots).
362-
- Position & size:
363-
- Move it horizontally with `/sm:config SeedMapMinimapOffsetX`
364-
- Move it vertically with `/sm:config SeedMapMinimapOffsetY`
365-
- Change width with `/sm:config SeedMapMinimapWidth`
366-
- Change height with `/sm:config SeedMapMinimapHeight`
367-
- Can be resized to cover other minimaps if needed.
368-
- Display options:
369-
- Rotate the map with the player’s facing using `/sm:config SeedMapMinimapRotateWithPlayer`
370-
- Adjust zoom independently from the main map via `/sm:config SeedMapMinimapPixelsPerBiome`
371-
- Scale feature icons with `/sm:config SeedMapMinimapIconScale`
372-
- Fine tune the background opacity with `/sm:config SeedMapMinimapOpacity` without affecting icon readability.
373-
374-
![UI](https://i.imgur.com/4b5IA0u.png)
353+
### SeedMapperHelper
354+
- UI for [my fork](https://github.com/cev-api/SeedMapper-CevAPI) of [SeedMapper](https://github.com/xpple/SeedMapper/) which covers all settings except for debug/dev mode.
355+
- Supports ESP color settings so long as you're using [my SeedMapper fork](https://github.com/cev-api/SeedMapper-CevAPI)
356+
- Supports keybinds for all settings
357+
358+
![UI](https://i.imgur.com/4b5IA0u.png)
375359

376360
## What’s changed or improved in this fork?
377361

src/main/java/net/wurstclient/hacks/ChestEspHack.java

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,16 @@
1919
import net.wurstclient.hack.Hack;
2020
import net.wurstclient.hacks.chestesp.ChestEspGroup;
2121
import net.wurstclient.hacks.chestesp.ChestEspGroupManager;
22+
import net.wurstclient.chestsearch.ChestManager;
23+
import net.wurstclient.chestsearch.ChestEntry;
2224
import net.wurstclient.settings.CheckboxSetting;
2325
import net.wurstclient.settings.EspStyleSetting;
2426
import net.wurstclient.settings.SliderSetting;
2527
import net.wurstclient.util.RenderUtils;
28+
import net.wurstclient.WurstRenderLayers;
29+
import com.mojang.blaze3d.vertex.VertexConsumer;
30+
import net.minecraft.client.renderer.MultiBufferSource;
31+
import net.minecraft.client.renderer.RenderType;
2632
import net.wurstclient.util.chunk.ChunkUtils;
2733

2834
public class ChestEspHack extends Hack implements UpdateListener,
@@ -49,6 +55,7 @@ public class ChestEspHack extends Hack implements UpdateListener,
4955
false);
5056
private final SliderSetting aboveGroundY = new SliderSetting(
5157
"Set ESP Y limit", 62, -65, 255, 1, SliderSetting.ValueDisplay.INTEGER);
58+
private java.util.List<ChestEntry> openedChests = java.util.List.of();
5259

5360
public ChestEspHack()
5461
{
@@ -112,6 +119,17 @@ public void onUpdate()
112119
int total = groups.allGroups.stream().filter(ChestEspGroup::isEnabled)
113120
.mapToInt(g -> g.getBoxes().size()).sum();
114121
foundCount = Math.min(total, 999);
122+
123+
// Always load recorded chests from ChestSearch DB so ChestESP can
124+
// mark them even if the ChestSearch UI/hack isn't "enabled".
125+
try
126+
{
127+
ChestManager mgr = new ChestManager();
128+
openedChests = mgr.all();
129+
}catch(Throwable ignored)
130+
{
131+
openedChests = java.util.List.of();
132+
}
115133
}
116134

117135
@Override
@@ -149,6 +167,192 @@ private void renderBoxes(PoseStack matrixStack)
149167
RenderUtils.drawSolidBoxes(matrixStack, boxes, quadsColor, false);
150168
RenderUtils.drawOutlinedBoxes(matrixStack, boxes, linesColor,
151169
false);
170+
171+
// If ChestSearch marking is enabled, draw an X through opened
172+
// chests that match entries in the ChestSearch DB
173+
try
174+
{
175+
var csh = net.wurstclient.WurstClient.INSTANCE
176+
.getHax().chestSearchHack;
177+
if(csh != null && csh.isMarkOpenedChest()
178+
&& !openedChests.isEmpty())
179+
{
180+
// base esp line color retained if needed
181+
String curDimFull = MC.level == null ? "overworld"
182+
: MC.level.dimension().location().toString();
183+
String curDim = MC.level == null ? "overworld"
184+
: MC.level.dimension().location().getPath();
185+
for(AABB box : boxes)
186+
{
187+
int boxMinX = (int)Math.floor(box.minX + 1e-6);
188+
int boxMaxX = (int)Math.floor(box.maxX - 1e-6);
189+
int boxMinY = (int)Math.floor(box.minY + 1e-6);
190+
int boxMaxY = (int)Math.floor(box.maxY - 1e-6);
191+
int boxMinZ = (int)Math.floor(box.minZ + 1e-6);
192+
int boxMaxZ = (int)Math.floor(box.maxZ - 1e-6);
193+
boolean matched = false;
194+
for(ChestEntry e : openedChests)
195+
{
196+
if(e == null || e.dimension == null)
197+
continue;
198+
// Accept either namespaced ("minecraft:the_nether")
199+
// or
200+
// plain path ("the_nether") dimension identifiers.
201+
String ed = e.dimension;
202+
if(!(ed.equals(curDimFull) || ed.equals(curDim)
203+
|| ed.endsWith(":" + curDim)))
204+
continue;
205+
int minX = Math.min(e.x, e.maxX);
206+
int maxX = Math.max(e.x, e.maxX);
207+
int minY = Math.min(e.y, e.maxY);
208+
int maxY = Math.max(e.y, e.maxY);
209+
int minZ = Math.min(e.z, e.maxZ);
210+
int maxZ = Math.max(e.z, e.maxZ);
211+
// check range overlap between the ESP box and
212+
// recorded chest bounds
213+
boolean overlap = boxMinX <= maxX && boxMaxX >= minX
214+
&& boxMinY <= maxY && boxMaxY >= minY
215+
&& boxMinZ <= maxZ && boxMaxZ >= minZ;
216+
if(overlap)
217+
{
218+
matched = true;
219+
break;
220+
}
221+
}
222+
if(matched)
223+
{
224+
int markColor = csh.getMarkXColorARGB();
225+
double thickness = csh.getMarkXThickness();
226+
227+
// Prepare render buffer with custom line width
228+
MultiBufferSource.BufferSource vcp =
229+
RenderUtils.getVCP();
230+
RenderType layer =
231+
WurstRenderLayers.getLines(false, thickness);
232+
VertexConsumer buffer = vcp.getBuffer(layer);
233+
PoseStack.Pose entry = matrixStack.last();
234+
Vec3 offset = RenderUtils.getCameraPos().reverse();
235+
236+
// Draw plus signs (+) centered on each face of the
237+
// box
238+
double minX = box.minX;
239+
double maxX = box.maxX;
240+
double minY = box.minY;
241+
double maxY = box.maxY;
242+
double minZ = box.minZ;
243+
double maxZ = box.maxZ;
244+
double cx = (minX + maxX) / 2.0;
245+
double cy = (minY + maxY) / 2.0;
246+
double cz = (minZ + maxZ) / 2.0;
247+
248+
double halfX = (maxX - minX) / 2.0;
249+
double halfY = (maxY - minY) / 2.0;
250+
double halfZ = (maxZ - minZ) / 2.0;
251+
252+
// Top face (Y = maxY): lines along X and Z
253+
Vec3 t1 =
254+
new Vec3(cx - halfX, maxY, cz).add(offset);
255+
Vec3 t2 =
256+
new Vec3(cx + halfX, maxY, cz).add(offset);
257+
Vec3 t3 =
258+
new Vec3(cx, maxY, cz - halfZ).add(offset);
259+
Vec3 t4 =
260+
new Vec3(cx, maxY, cz + halfZ).add(offset);
261+
RenderUtils.drawLine(entry, buffer, (float)t1.x,
262+
(float)t1.y, (float)t1.z, (float)t2.x,
263+
(float)t2.y, (float)t2.z, markColor);
264+
RenderUtils.drawLine(entry, buffer, (float)t3.x,
265+
(float)t3.y, (float)t3.z, (float)t4.x,
266+
(float)t4.y, (float)t4.z, markColor);
267+
268+
// Bottom face (Y = minY)
269+
Vec3 b1 =
270+
new Vec3(cx - halfX, minY, cz).add(offset);
271+
Vec3 b2 =
272+
new Vec3(cx + halfX, minY, cz).add(offset);
273+
Vec3 b3 =
274+
new Vec3(cx, minY, cz - halfZ).add(offset);
275+
Vec3 b4 =
276+
new Vec3(cx, minY, cz + halfZ).add(offset);
277+
RenderUtils.drawLine(entry, buffer, (float)b1.x,
278+
(float)b1.y, (float)b1.z, (float)b2.x,
279+
(float)b2.y, (float)b2.z, markColor);
280+
RenderUtils.drawLine(entry, buffer, (float)b3.x,
281+
(float)b3.y, (float)b3.z, (float)b4.x,
282+
(float)b4.y, (float)b4.z, markColor);
283+
284+
// North face (Z = minZ): lines along X and Y
285+
Vec3 n1 =
286+
new Vec3(cx - halfX, cy, minZ).add(offset);
287+
Vec3 n2 =
288+
new Vec3(cx + halfX, cy, minZ).add(offset);
289+
Vec3 n3 =
290+
new Vec3(cx, cy - halfY, minZ).add(offset);
291+
Vec3 n4 =
292+
new Vec3(cx, cy + halfY, minZ).add(offset);
293+
RenderUtils.drawLine(entry, buffer, (float)n1.x,
294+
(float)n1.y, (float)n1.z, (float)n2.x,
295+
(float)n2.y, (float)n2.z, markColor);
296+
RenderUtils.drawLine(entry, buffer, (float)n3.x,
297+
(float)n3.y, (float)n3.z, (float)n4.x,
298+
(float)n4.y, (float)n4.z, markColor);
299+
300+
// South face (Z = maxZ)
301+
Vec3 s1 =
302+
new Vec3(cx - halfX, cy, maxZ).add(offset);
303+
Vec3 s2 =
304+
new Vec3(cx + halfX, cy, maxZ).add(offset);
305+
Vec3 s3 =
306+
new Vec3(cx, cy - halfY, maxZ).add(offset);
307+
Vec3 s4 =
308+
new Vec3(cx, cy + halfY, maxZ).add(offset);
309+
RenderUtils.drawLine(entry, buffer, (float)s1.x,
310+
(float)s1.y, (float)s1.z, (float)s2.x,
311+
(float)s2.y, (float)s2.z, markColor);
312+
RenderUtils.drawLine(entry, buffer, (float)s3.x,
313+
(float)s3.y, (float)s3.z, (float)s4.x,
314+
(float)s4.y, (float)s4.z, markColor);
315+
316+
// West face (X = minX): lines along Z and Y
317+
Vec3 w1 =
318+
new Vec3(minX, cy, cz - halfZ).add(offset);
319+
Vec3 w2 =
320+
new Vec3(minX, cy, cz + halfZ).add(offset);
321+
Vec3 w3 =
322+
new Vec3(minX, cy - halfY, cz).add(offset);
323+
Vec3 w4 =
324+
new Vec3(minX, cy + halfY, cz).add(offset);
325+
RenderUtils.drawLine(entry, buffer, (float)w1.x,
326+
(float)w1.y, (float)w1.z, (float)w2.x,
327+
(float)w2.y, (float)w2.z, markColor);
328+
RenderUtils.drawLine(entry, buffer, (float)w3.x,
329+
(float)w3.y, (float)w3.z, (float)w4.x,
330+
(float)w4.y, (float)w4.z, markColor);
331+
332+
// East face (X = maxX)
333+
Vec3 e1 =
334+
new Vec3(maxX, cy, cz - halfZ).add(offset);
335+
Vec3 e2 =
336+
new Vec3(maxX, cy, cz + halfZ).add(offset);
337+
Vec3 e3 =
338+
new Vec3(maxX, cy - halfY, cz).add(offset);
339+
Vec3 e4 =
340+
new Vec3(maxX, cy + halfY, cz).add(offset);
341+
RenderUtils.drawLine(entry, buffer, (float)e1.x,
342+
(float)e1.y, (float)e1.z, (float)e2.x,
343+
(float)e2.y, (float)e2.z, markColor);
344+
RenderUtils.drawLine(entry, buffer, (float)e3.x,
345+
(float)e3.y, (float)e3.z, (float)e4.x,
346+
(float)e4.y, (float)e4.z, markColor);
347+
348+
vcp.endBatch(layer);
349+
}
350+
}
351+
}
352+
}catch(Throwable ignored)
353+
{
354+
// don't fail rendering if chestsearch isn't available
355+
}
152356
}
153357
}
154358

src/main/java/net/wurstclient/hacks/ChestSearchHack.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import net.wurstclient.settings.ColorSetting;
1313
import net.wurstclient.settings.SliderSetting;
1414
import net.wurstclient.settings.SliderSetting.ValueDisplay;
15+
import net.wurstclient.settings.CheckboxSetting;
1516

1617
public final class ChestSearchHack extends Hack
1718
{
@@ -41,6 +42,14 @@ public final class ChestSearchHack extends Hack
4142
new ColorSetting("ESP fill", new java.awt.Color(0x22FF88));
4243
private final ColorSetting espLineColor =
4344
new ColorSetting("ESP line", new java.awt.Color(0x22FF88));
45+
private final ColorSetting markXColor =
46+
new ColorSetting("Mark X color", new java.awt.Color(0xFF2222));
47+
private final SliderSetting markXThickness = new SliderSetting(
48+
"Mark X thickness", 2.0, 0.5, 6.0, 0.5, ValueDisplay.DECIMAL);
49+
private final CheckboxSetting markOpenedChest = new CheckboxSetting(
50+
"Mark opened chest",
51+
"Draw an X through chests that appear in your ChestSearch database.",
52+
true);
4453
private final SliderSetting textScale = new SliderSetting("Text scale", 1.0,
4554
0.5, 1.25, 0.05, ValueDisplay.DECIMAL);
4655

@@ -62,6 +71,30 @@ public ChestSearchHack()
6271
addSetting(waypointColor);
6372
addSetting(espFillColor);
6473
addSetting(espLineColor);
74+
addSetting(markXColor);
75+
addSetting(markXThickness);
76+
addSetting(markOpenedChest);
77+
}
78+
79+
public int getMarkXColorARGB()
80+
{
81+
return (0xFF << 24) | (markXColor.getColor().getRGB() & 0x00FFFFFF);
82+
}
83+
84+
public double getMarkXThickness()
85+
{
86+
try
87+
{
88+
return markXThickness.getValue();
89+
}catch(Throwable t)
90+
{
91+
return 2.0;
92+
}
93+
}
94+
95+
public boolean isMarkOpenedChest()
96+
{
97+
return markOpenedChest.isChecked();
6598
}
6699

67100
public int getCleanerGraceTicks()

0 commit comments

Comments
 (0)