Skip to content

Commit 7f04264

Browse files
committed
Added TridentESP
1 parent 5253272 commit 7f04264

File tree

3 files changed

+360
-0
lines changed

3 files changed

+360
-0
lines changed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,26 @@ Visualizes where players logged out.
9393
- Name scale
9494
- Show tracers (on/off)
9595

96+
### TridentESP
97+
Highlights thrown and or held tridents in the world.
98+
- Optional: highlight tridents held by other players or mobs (not your own).
99+
- Optional: color distinctions for ownership:
100+
- Your tridents
101+
- Other players’ tridents
102+
- Mobs’ tridents
103+
- Rendering styles: Boxes, Lines, or Both.
104+
- Box size modes: Accurate (tight fit) or Fancy (larger/nicer boxes).
105+
- Color options:
106+
- Fixed single color
107+
- Rainbow
108+
- Color by owner type (overrides fixed/rainbow).
109+
- Settings
110+
- Toggle held-trident highlights (players/mobs).
111+
- Choose rendering style, box size, and color mode.
112+
- Usage
113+
- Enable TridentESP from the ClickGUI → Render tab.
114+
- Adjust style, color, and ownership toggles as desired.
115+
96116
### Added keyword matches for all lists (Search, MobSearch, Nuker, SpeedNuker, NoHandClip AutoDrop, Xray etc)
97117
- Type a keyword (eg., "diamond") to populate the list with all matching blocks/mobs.
98118
- Clear list button added.

src/main/java/net/wurstclient/hack/HackList.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ public final class HackList implements UpdateListener
198198
public final WaypointsHack waypointsHack = new WaypointsHack();
199199
public final BreadcrumbsHack breadcrumbsHack = new BreadcrumbsHack();
200200
public final LogoutSpotsHack logoutSpotsHack = new LogoutSpotsHack();
201+
public final TridentEspHack tridentEspHack = new TridentEspHack();
201202

202203
private final TreeMap<String, Hack> hax =
203204
new TreeMap<>(String::compareToIgnoreCase);
Lines changed: 339 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
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.hacks;
9+
10+
import java.awt.Color;
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
14+
import net.minecraft.client.util.math.MatrixStack;
15+
import net.minecraft.entity.Entity;
16+
import net.minecraft.entity.LivingEntity;
17+
import net.minecraft.entity.player.PlayerEntity;
18+
import net.minecraft.entity.projectile.TridentEntity;
19+
import net.minecraft.item.Items;
20+
import net.minecraft.item.ItemStack;
21+
import net.minecraft.util.Arm;
22+
import net.minecraft.util.Hand;
23+
import net.minecraft.util.math.Box;
24+
import net.minecraft.util.math.Vec3d;
25+
import net.wurstclient.Category;
26+
import net.wurstclient.SearchTags;
27+
import net.wurstclient.events.CameraTransformViewBobbingListener;
28+
import net.wurstclient.events.RenderListener;
29+
import net.wurstclient.events.UpdateListener;
30+
import net.wurstclient.hack.Hack;
31+
import net.wurstclient.settings.CheckboxSetting;
32+
import net.wurstclient.settings.ColorSetting;
33+
import net.wurstclient.settings.EspBoxSizeSetting;
34+
import net.wurstclient.settings.EspStyleSetting;
35+
import net.wurstclient.util.EntityUtils;
36+
import net.wurstclient.util.RenderUtils;
37+
38+
@SearchTags({"trident esp", "TridentTracers", "trident tracers"})
39+
public final class TridentEspHack extends Hack implements UpdateListener,
40+
CameraTransformViewBobbingListener, RenderListener
41+
{
42+
private final EspStyleSetting style = new EspStyleSetting();
43+
private final EspBoxSizeSetting boxSize = new EspBoxSizeSetting(
44+
"\u00a7lAccurate\u00a7r mode shows the exact hitbox.\n"
45+
+ "\u00a7lFancy\u00a7r mode shows larger boxes that look better.");
46+
47+
// Color controls (like Search): single fixed color or rainbow
48+
private final CheckboxSetting useFixedColor =
49+
new CheckboxSetting("Use fixed color",
50+
"Enable to use a fixed color instead of rainbow.", false);
51+
private final ColorSetting fixedColor = new ColorSetting("Fixed color",
52+
"Color used when \"Use fixed color\" is enabled.", Color.CYAN);
53+
54+
// Distinguish by owner type (self, other player, mob)
55+
private final CheckboxSetting colorByOwner = new CheckboxSetting(
56+
"Color by owner type",
57+
"When enabled, uses different colors depending on who threw/holds the trident.",
58+
false);
59+
private final ColorSetting selfColor = new ColorSetting("Your tridents",
60+
"Color for your own thrown/held tridents.", new Color(0x55FF55));
61+
private final ColorSetting otherPlayerColor =
62+
new ColorSetting("Other players",
63+
"Color for tridents from other players.", new Color(0xFF5555));
64+
private final ColorSetting mobColor = new ColorSetting("Mobs",
65+
"Color for tridents from mobs.", new Color(0xFFFF55));
66+
67+
// Include tridents currently held by others
68+
private final CheckboxSetting includeHeld = new CheckboxSetting(
69+
"Highlight held tridents",
70+
"Also highlight when a trident is currently held by another player or mob.",
71+
false);
72+
73+
// Cached per-tick results
74+
private final ArrayList<TridentEntity> thrown = new ArrayList<>();
75+
private final ArrayList<LivingEntity> holders = new ArrayList<>();
76+
77+
public TridentEspHack()
78+
{
79+
super("TridentESP");
80+
setCategory(Category.RENDER);
81+
addSetting(style);
82+
addSetting(boxSize);
83+
addSetting(useFixedColor);
84+
addSetting(fixedColor);
85+
addSetting(colorByOwner);
86+
addSetting(selfColor);
87+
addSetting(otherPlayerColor);
88+
addSetting(mobColor);
89+
addSetting(includeHeld);
90+
}
91+
92+
@Override
93+
protected void onEnable()
94+
{
95+
EVENTS.add(UpdateListener.class, this);
96+
EVENTS.add(CameraTransformViewBobbingListener.class, this);
97+
EVENTS.add(RenderListener.class, this);
98+
}
99+
100+
@Override
101+
protected void onDisable()
102+
{
103+
EVENTS.remove(UpdateListener.class, this);
104+
EVENTS.remove(CameraTransformViewBobbingListener.class, this);
105+
EVENTS.remove(RenderListener.class, this);
106+
thrown.clear();
107+
holders.clear();
108+
}
109+
110+
@Override
111+
public void onUpdate()
112+
{
113+
thrown.clear();
114+
holders.clear();
115+
116+
for(Entity e : MC.world.getEntities())
117+
{
118+
if(e instanceof TridentEntity)
119+
thrown.add((TridentEntity)e);
120+
if(includeHeld.isChecked() && e instanceof LivingEntity)
121+
{
122+
LivingEntity le = (LivingEntity)e;
123+
if(le == MC.player)
124+
continue; // "another player or a mob" only
125+
if(isHoldingTrident(le))
126+
holders.add(le);
127+
}
128+
}
129+
}
130+
131+
private boolean isHoldingTrident(LivingEntity e)
132+
{
133+
ItemStack main = e.getMainHandStack();
134+
ItemStack off = e.getOffHandStack();
135+
return (main != null && main.getItem() == Items.TRIDENT)
136+
|| (off != null && off.getItem() == Items.TRIDENT);
137+
}
138+
139+
@Override
140+
public void onCameraTransformViewBobbing(
141+
CameraTransformViewBobbingEvent event)
142+
{
143+
if(style.hasLines())
144+
event.cancel();
145+
}
146+
147+
@Override
148+
public void onRender(MatrixStack matrixStack, float partialTicks)
149+
{
150+
if(!style.hasBoxes() && !style.hasLines())
151+
return;
152+
153+
if(colorByOwner.isChecked())
154+
renderByOwner(matrixStack, partialTicks);
155+
else
156+
renderSingleColor(matrixStack, partialTicks);
157+
}
158+
159+
private void renderSingleColor(MatrixStack matrixStack, float partialTicks)
160+
{
161+
int lineColor;
162+
if(useFixedColor.isChecked())
163+
lineColor = fixedColor.getColorI(0x80);
164+
else
165+
lineColor =
166+
RenderUtils.toIntColor(RenderUtils.getRainbowColor(), 0.5F);
167+
168+
if(style.hasBoxes())
169+
{
170+
List<Box> boxes = new ArrayList<>();
171+
for(TridentEntity t : thrown)
172+
boxes.add(
173+
applyExtraSize(EntityUtils.getLerpedBox(t, partialTicks)));
174+
for(LivingEntity h : holders)
175+
{
176+
Box handBox = getHeldTridentBox(h, partialTicks);
177+
if(handBox != null)
178+
boxes.add(applyExtraSize(handBox));
179+
}
180+
if(!boxes.isEmpty())
181+
RenderUtils.drawOutlinedBoxes(matrixStack, boxes, lineColor,
182+
false);
183+
}
184+
185+
if(style.hasLines())
186+
{
187+
List<Vec3d> ends = new ArrayList<>();
188+
for(TridentEntity t : thrown)
189+
ends.add(EntityUtils.getLerpedBox(t, partialTicks).getCenter());
190+
for(LivingEntity h : holders)
191+
{
192+
Vec3d hand = getHeldTridentPos(h, partialTicks);
193+
if(hand != null)
194+
ends.add(hand);
195+
}
196+
if(!ends.isEmpty())
197+
RenderUtils.drawTracers(matrixStack, partialTicks, ends,
198+
lineColor, false);
199+
}
200+
}
201+
202+
private void renderByOwner(MatrixStack matrixStack, float partialTicks)
203+
{
204+
ArrayList<Box> selfBoxes = new ArrayList<>();
205+
ArrayList<Box> playerBoxes = new ArrayList<>();
206+
ArrayList<Box> mobBoxes = new ArrayList<>();
207+
ArrayList<Vec3d> selfEnds = new ArrayList<>();
208+
ArrayList<Vec3d> playerEnds = new ArrayList<>();
209+
ArrayList<Vec3d> mobEnds = new ArrayList<>();
210+
211+
for(TridentEntity t : thrown)
212+
{
213+
Entity owner = t.getOwner();
214+
Box box = applyExtraSize(EntityUtils.getLerpedBox(t, partialTicks));
215+
Vec3d end = box.getCenter();
216+
if(owner instanceof PlayerEntity)
217+
{
218+
if(owner == MC.player)
219+
{
220+
selfBoxes.add(box);
221+
selfEnds.add(end);
222+
}else
223+
{
224+
playerBoxes.add(box);
225+
playerEnds.add(end);
226+
}
227+
}else if(owner instanceof LivingEntity)
228+
{
229+
mobBoxes.add(box);
230+
mobEnds.add(end);
231+
}else
232+
{
233+
// Unknown owner: treat as other player color for visibility
234+
playerBoxes.add(box);
235+
playerEnds.add(end);
236+
}
237+
}
238+
239+
if(includeHeld.isChecked())
240+
{
241+
for(LivingEntity h : holders)
242+
{
243+
Box handBox = getHeldTridentBox(h, partialTicks);
244+
Vec3d end = getHeldTridentPos(h, partialTicks);
245+
if(handBox == null || end == null)
246+
continue;
247+
if(h instanceof PlayerEntity)
248+
{
249+
playerBoxes.add(applyExtraSize(handBox));
250+
playerEnds.add(end);
251+
}else
252+
{
253+
mobBoxes.add(applyExtraSize(handBox));
254+
mobEnds.add(end);
255+
}
256+
}
257+
}
258+
259+
// Draw grouped to allow per-group colors
260+
int selfCol = selfColor.getColorI(0x80);
261+
int playerCol = otherPlayerColor.getColorI(0x80);
262+
int mobCol = mobColor.getColorI(0x80);
263+
264+
if(style.hasBoxes())
265+
{
266+
if(!selfBoxes.isEmpty())
267+
RenderUtils.drawOutlinedBoxes(matrixStack, selfBoxes, selfCol,
268+
false);
269+
if(!playerBoxes.isEmpty())
270+
RenderUtils.drawOutlinedBoxes(matrixStack, playerBoxes,
271+
playerCol, false);
272+
if(!mobBoxes.isEmpty())
273+
RenderUtils.drawOutlinedBoxes(matrixStack, mobBoxes, mobCol,
274+
false);
275+
}
276+
277+
if(style.hasLines())
278+
{
279+
if(!selfEnds.isEmpty())
280+
RenderUtils.drawTracers(matrixStack, partialTicks, selfEnds,
281+
selfCol, false);
282+
if(!playerEnds.isEmpty())
283+
RenderUtils.drawTracers(matrixStack, partialTicks, playerEnds,
284+
playerCol, false);
285+
if(!mobEnds.isEmpty())
286+
RenderUtils.drawTracers(matrixStack, partialTicks, mobEnds,
287+
mobCol, false);
288+
}
289+
}
290+
291+
private Box applyExtraSize(Box box)
292+
{
293+
double extra = boxSize.getExtraSize() / 2.0;
294+
return box.offset(0, extra, 0).expand(extra);
295+
}
296+
297+
// New helpers: approximate where the held trident is, and make a small box
298+
// there
299+
private Vec3d getHeldTridentPos(LivingEntity e, float partialTicks)
300+
{
301+
Hand hand = null;
302+
if(!e.getMainHandStack().isEmpty()
303+
&& e.getMainHandStack().isOf(Items.TRIDENT))
304+
hand = Hand.MAIN_HAND;
305+
else if(!e.getOffHandStack().isEmpty()
306+
&& e.getOffHandStack().isOf(Items.TRIDENT))
307+
hand = Hand.OFF_HAND;
308+
if(hand == null)
309+
return null;
310+
311+
// Base position at entity feet (lerped), then add eye height - 0.1
312+
Vec3d base = EntityUtils.getLerpedPos(e, partialTicks);
313+
double yawRad = Math.toRadians(e.getYaw());
314+
315+
// Determine which side the given hand is on.
316+
Arm mainArm = Arm.RIGHT;
317+
if(e instanceof PlayerEntity pe)
318+
mainArm = pe.getMainArm();
319+
boolean rightSide = (mainArm == Arm.RIGHT && hand == Hand.MAIN_HAND)
320+
|| (mainArm == Arm.LEFT && hand == Hand.OFF_HAND);
321+
double side = rightSide ? -1 : 1;
322+
323+
double eyeH = e.getEyeHeight(e.getPose());
324+
double offX = Math.cos(yawRad) * 0.16 * side;
325+
double offY = eyeH - 0.1;
326+
double offZ = Math.sin(yawRad) * 0.16 * side;
327+
return base.add(offX, offY, offZ);
328+
}
329+
330+
private Box getHeldTridentBox(LivingEntity e, float partialTicks)
331+
{
332+
Vec3d c = getHeldTridentPos(e, partialTicks);
333+
if(c == null)
334+
return null;
335+
// Small cube around hand
336+
double r = 0.18; // half-size
337+
return new Box(c.x - r, c.y - r, c.z - r, c.x + r, c.y + r, c.z + r);
338+
}
339+
}

0 commit comments

Comments
 (0)