Skip to content

Commit 5d95d13

Browse files
committed
Added EntityClusterESP and removed Automation Category
Credits to Nataani for EntityClusterESP
1 parent 6e5fd93 commit 5d95d13

File tree

3 files changed

+340
-3
lines changed

3 files changed

+340
-3
lines changed

src/main/java/dev/journey/PathSeeker/PathSeeker.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ public class PathSeeker extends MeteorAddon {
2222
//public static final Category Main = new Category("PathSeeker");
2323
public static final Category Hunting = new Category("PathHunting");
2424
public static final Category Render = new Category("PathRender");
25-
public static final Category Automation = new Category("PathAutomation");
2625
public static final Category Utility = new Category("PathUtils");
2726

2827
@Override
@@ -46,6 +45,7 @@ public void onInitialize() {
4645
Modules.get().add(new Pitch40Util());
4746
Modules.get().add(new NoJumpDelay());
4847
Modules.get().add(new DroppedItemESP());
48+
Modules.get().add(new EntityClusterESP());
4949
//Commands
5050

5151
Commands.add(new Stats2b2t());
@@ -70,7 +70,6 @@ public void onRegisterCategories() {
7070
Modules.registerCategory(Hunting);
7171
Modules.registerCategory(Utility);
7272
Modules.registerCategory(Render);
73-
Modules.registerCategory(Automation);
7473
}
7574

7675
public String getPackage() {

src/main/java/dev/journey/PathSeeker/modules/automation/StorageLooter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ public class StorageLooter extends Module {
338338
private float originalPitch;
339339

340340
public StorageLooter() {
341-
super(PathSeeker.Automation, "Storage-Looter", "Steals stuff from containers around you.");
341+
super(PathSeeker.Utility, "Storage-Looter", "Steals stuff from containers around you.");
342342
}
343343

344344
@EventHandler
Lines changed: 338 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,338 @@
1+
/**
2+
* ItemESP
3+
* =======
4+
* - Written by Nataani
5+
* - Pulled from the Meteorite module.
6+
* This module highlights the center-point of entity clusters.
7+
* You can configure a list of entities to consider to highlight,
8+
* customize the box appearance (fill opacity, outline, etc.),
9+
* and designate a range for the module to consider in its calculations.
10+
* The render box method was adapted from Etlian's ActivatedSpawnerDetector.
11+
* The list GUI and csv methods were adapted from Meteor's Stashfinder module.g
12+
* This module is particularly useful for identifying stacked storage vehicles like Minecart with Chest.
13+
*/
14+
15+
package dev.journey.PathSeeker.modules.render;
16+
17+
import com.google.common.reflect.TypeToken;
18+
import com.google.gson.Gson;
19+
import com.google.gson.GsonBuilder;
20+
import dev.journey.PathSeeker.PathSeeker;
21+
import meteordevelopment.meteorclient.MeteorClient;
22+
import meteordevelopment.meteorclient.events.render.Render3DEvent;
23+
import meteordevelopment.meteorclient.events.world.TickEvent;
24+
import meteordevelopment.meteorclient.gui.GuiTheme;
25+
import meteordevelopment.meteorclient.gui.widgets.WWidget;
26+
import meteordevelopment.meteorclient.gui.widgets.containers.WTable;
27+
import meteordevelopment.meteorclient.gui.widgets.containers.WVerticalList;
28+
import meteordevelopment.meteorclient.gui.widgets.pressable.WButton;
29+
import meteordevelopment.meteorclient.gui.widgets.pressable.WMinus;
30+
import meteordevelopment.meteorclient.pathing.PathManagers;
31+
import meteordevelopment.meteorclient.renderer.ShapeMode;
32+
import meteordevelopment.meteorclient.settings.*;
33+
import meteordevelopment.meteorclient.utils.Utils;
34+
import meteordevelopment.meteorclient.utils.player.ChatUtils;
35+
import meteordevelopment.meteorclient.utils.render.MeteorToast;
36+
import meteordevelopment.meteorclient.utils.render.color.Color;
37+
import meteordevelopment.meteorclient.utils.render.color.SettingColor;
38+
import meteordevelopment.meteorclient.systems.modules.Module;
39+
import meteordevelopment.orbit.EventHandler;
40+
import net.minecraft.entity.Entity;
41+
import net.minecraft.entity.EntityType;
42+
import net.minecraft.item.Items;
43+
import net.minecraft.text.Text;
44+
import net.minecraft.util.math.*;
45+
46+
import java.io.*;
47+
import java.util.*;
48+
49+
public class EntityClusterESP extends Module {
50+
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
51+
52+
private final SettingGroup sgGeneral = settings.getDefaultGroup();
53+
private final SettingGroup sgRender = settings.createGroup("Render");
54+
55+
private final Setting<Set<EntityType<?>>> entities = sgGeneral.add(new EntityTypeListSetting.Builder()
56+
.name("entities")
57+
.description("Select specific entities.")
58+
.defaultValue(EntityType.CHEST_MINECART)
59+
.build()
60+
);
61+
62+
private final Setting<Boolean> displayCoords = sgGeneral.add(new BoolSetting.Builder()
63+
.name("display-coords")
64+
.defaultValue(true)
65+
.build()
66+
);
67+
68+
private final Setting<Boolean> notifications = sgGeneral.add(new BoolSetting.Builder()
69+
.name("notifications")
70+
.defaultValue(true)
71+
.build()
72+
);
73+
74+
private final Setting<Integer> minEntities = sgGeneral.add(new IntSetting.Builder()
75+
.name("number-of-entities")
76+
.defaultValue(5)
77+
.min(2)
78+
.build()
79+
);
80+
81+
private final Setting<Double> range = sgGeneral.add(new DoubleSetting.Builder()
82+
.name("block-range")
83+
.defaultValue(10.0)
84+
.min(1)
85+
.sliderMax(32)
86+
.build()
87+
);
88+
89+
private final Setting<ShapeMode> shapeMode = sgRender.add(new EnumSetting.Builder<ShapeMode>()
90+
.name("shape-mode")
91+
.defaultValue(ShapeMode.Both)
92+
.build()
93+
);
94+
95+
private final Setting<SettingColor> sideColorSetting = sgRender.add(new ColorSetting.Builder()
96+
.name("side-color")
97+
.defaultValue(new SettingColor(0, 255, 255, 50))
98+
.build()
99+
);
100+
101+
private final Setting<SettingColor> lineColorSetting = sgRender.add(new ColorSetting.Builder()
102+
.name("line-color")
103+
.defaultValue(new SettingColor(0, 255, 255, 255))
104+
.build()
105+
);
106+
107+
private final List<Cluster> clusters = new ArrayList<>();
108+
private final Set<BlockPos> knownCenters = new HashSet<>();
109+
110+
public EntityClusterESP() {
111+
super(PathSeeker.Render, "entity-cluster-ESP", "Highlights and logs clusters of chosen entities.");
112+
}
113+
114+
@Override
115+
public void onActivate() {
116+
clusters.clear();
117+
knownCenters.clear();
118+
load();
119+
}
120+
121+
@Override
122+
public void onDeactivate() {
123+
clusters.clear();
124+
knownCenters.clear();
125+
}
126+
127+
@EventHandler
128+
private void onTick(TickEvent.Post event) {
129+
if (mc.world == null || mc.player == null) return;
130+
131+
List<Entity> chosen = new ArrayList<>();
132+
for (Entity e : mc.world.getEntities()) {
133+
if (entities.get().contains(e.getType())) {
134+
chosen.add(e);
135+
}
136+
}
137+
138+
if (!chosen.isEmpty()) {
139+
checkForClusters(chosen);
140+
}
141+
}
142+
143+
144+
@EventHandler
145+
private void onRender(Render3DEvent event) {
146+
Color sideColor = sideColorSetting.get();
147+
Color lineColor = lineColorSetting.get();
148+
double half = range.get() / 2.0;
149+
for (Cluster c : clusters) {
150+
if (!knownCenters.contains(c.centerPos)) continue;
151+
double x1 = c.centerPos.getX() - half;
152+
double y1 = c.centerPos.getY() - half;
153+
double z1 = c.centerPos.getZ() - half;
154+
double x2 = c.centerPos.getX() + half;
155+
double y2 = c.centerPos.getY() + half;
156+
double z2 = c.centerPos.getZ() + half;
157+
event.renderer.box(x1, y1, z1, x2, y2, z2, sideColor, lineColor, shapeMode.get(), 0);
158+
}
159+
}
160+
161+
private void checkForClusters(List<Entity> vehicles) {
162+
double r = range.get();
163+
int needed = minEntities.get();
164+
for (int i = 0; i < vehicles.size(); i++) {
165+
Entity primary = vehicles.get(i);
166+
List<Vec3d> cluster = new ArrayList<>();
167+
cluster.add(primary.getPos());
168+
for (int j = 0; j < vehicles.size(); j++) {
169+
if (j == i) continue;
170+
Entity other = vehicles.get(j);
171+
if (primary.squaredDistanceTo(other) <= r * r) {
172+
cluster.add(other.getPos());
173+
}
174+
}
175+
if (cluster.size() >= needed) {
176+
Vec3d center = averagePos(cluster);
177+
int cx = (int) center.x;
178+
int cy = (int) center.y;
179+
int cz = (int) center.z;
180+
BlockPos centerPos = new BlockPos(cx, cy, cz);
181+
if (!knownCenters.contains(centerPos)) {
182+
knownCenters.add(centerPos);
183+
int size = cluster.size();
184+
clusters.add(new Cluster(cx, cy, cz, size));
185+
if (notifications.get()) {
186+
mc.getToastManager().add(new MeteorToast(Items.CHEST_MINECART, "EntityClusterESP", "Cluster of " + size + " @ " + centerPos));
187+
ChatUtils.sendMsg(Text.of("Entity cluster of " + size + " found at " + centerPos));
188+
}
189+
if (displayCoords.get()) {
190+
ChatUtils.info("EntityClusterESP", "Cluster of " + size + " found at " + centerPos);
191+
}
192+
saveCsv();
193+
saveJson();
194+
}
195+
}
196+
}
197+
}
198+
199+
private Vec3d averagePos(List<Vec3d> positions) {
200+
double sx = 0, sy = 0, sz = 0;
201+
for (Vec3d p : positions) {
202+
sx += p.x;
203+
sy += p.y;
204+
sz += p.z;
205+
}
206+
return new Vec3d(sx / positions.size(), sy / positions.size(), sz / positions.size());
207+
}
208+
209+
@Override
210+
public WWidget getWidget(GuiTheme theme) {
211+
clusters.sort(Comparator.comparingInt(a -> a.y));
212+
WVerticalList list = theme.verticalList();
213+
WButton clear = list.add(theme.button("Clear")).widget();
214+
WTable table = new WTable();
215+
if (!clusters.isEmpty()) list.add(table);
216+
clear.action = () -> {
217+
clusters.clear();
218+
knownCenters.clear();
219+
table.clear();
220+
saveJson();
221+
saveCsv();
222+
};
223+
fillTable(theme, table);
224+
return list;
225+
}
226+
227+
private void fillTable(GuiTheme theme, WTable table) {
228+
for (Cluster c : clusters) {
229+
table.add(theme.label("Pos: " + c.x + ", " + c.y + ", " + c.z + " (Cnt: " + c.count + ")"));
230+
WButton gotoBtn = table.add(theme.button("Goto")).widget();
231+
gotoBtn.action = () -> {
232+
PathManagers.get().moveTo(new BlockPos(c.x, c.y, c.z), true);
233+
};
234+
WMinus delete = table.add(theme.minus()).widget();
235+
delete.action = () -> {
236+
clusters.remove(c);
237+
knownCenters.remove(c.centerPos);
238+
table.clear();
239+
fillTable(theme, table);
240+
saveJson();
241+
saveCsv();
242+
};
243+
table.row();
244+
}
245+
}
246+
247+
private static class Cluster {
248+
public int x, y, z, count;
249+
public BlockPos centerPos;
250+
public Cluster(int x, int y, int z, int count) {
251+
this.x = x;
252+
this.y = y;
253+
this.z = z;
254+
this.count = count;
255+
this.centerPos = new BlockPos(x, y, z);
256+
}
257+
@Override
258+
public boolean equals(Object o) {
259+
if (this == o) return true;
260+
if (o == null || getClass() != o.getClass()) return false;
261+
Cluster cluster = (Cluster) o;
262+
return x == cluster.x && y == cluster.y && z == cluster.z;
263+
}
264+
@Override
265+
public int hashCode() {
266+
return Objects.hash(x, y, z);
267+
}
268+
}
269+
270+
private File getCsvFile() {
271+
return new File(new File(new File(MeteorClient.FOLDER, "EntityClusterESP"), Utils.getFileWorldName()), "EntityClusterESP.csv");
272+
}
273+
274+
private File getJsonFile() {
275+
return new File(new File(new File(MeteorClient.FOLDER, "EntityClusterESP"), Utils.getFileWorldName()), "EntityClusterESP.json");
276+
}
277+
278+
private void load() {
279+
File file = getJsonFile();
280+
if (file.exists()) {
281+
try {
282+
FileReader reader = new FileReader(file);
283+
List<Cluster> data = GSON.fromJson(reader, new TypeToken<List<Cluster>>(){}.getType());
284+
reader.close();
285+
if (data != null) {
286+
clusters.addAll(data);
287+
for (Cluster c : data) {
288+
knownCenters.add(c.centerPos);
289+
}
290+
}
291+
} catch (Exception ignored) {}
292+
} else {
293+
file = getCsvFile();
294+
if (file.exists()) {
295+
try {
296+
BufferedReader reader = new BufferedReader(new FileReader(file));
297+
reader.readLine();
298+
String line;
299+
while ((line = reader.readLine()) != null) {
300+
String[] values = line.split(",");
301+
Cluster cluster = new Cluster(
302+
Integer.parseInt(values[0]),
303+
Integer.parseInt(values[1]),
304+
Integer.parseInt(values[2]),
305+
Integer.parseInt(values[3])
306+
);
307+
clusters.add(cluster);
308+
knownCenters.add(cluster.centerPos);
309+
}
310+
reader.close();
311+
} catch (Exception ignored) {}
312+
}
313+
}
314+
}
315+
316+
private void saveCsv() {
317+
try {
318+
File file = getCsvFile();
319+
file.getParentFile().mkdirs();
320+
Writer writer = new FileWriter(file);
321+
writer.write("X,Y,Z,Count\n");
322+
for (Cluster c : clusters) {
323+
writer.write(c.x + "," + c.y + "," + c.z + "," + c.count + "\n");
324+
}
325+
writer.close();
326+
} catch (IOException ignored) {}
327+
}
328+
329+
private void saveJson() {
330+
try {
331+
File file = getJsonFile();
332+
file.getParentFile().mkdirs();
333+
Writer writer = new FileWriter(file);
334+
GSON.toJson(clusters, writer);
335+
writer.close();
336+
} catch (IOException ignored) {}
337+
}
338+
}

0 commit comments

Comments
 (0)