-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
300 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
298 changes: 298 additions & 0 deletions
298
src/main/java/moe/kyuunex/fumo_utils/modules/ItemESP.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,298 @@ | ||
package moe.kyuunex.fumo_utils.modules; | ||
|
||
import meteordevelopment.meteorclient.events.render.Render2DEvent; | ||
import meteordevelopment.meteorclient.events.render.Render3DEvent; | ||
import meteordevelopment.meteorclient.renderer.Renderer2D; | ||
import meteordevelopment.meteorclient.renderer.ShapeMode; | ||
import meteordevelopment.meteorclient.settings.*; | ||
import meteordevelopment.meteorclient.systems.modules.Module; | ||
import meteordevelopment.meteorclient.utils.entity.EntityUtils; | ||
import meteordevelopment.meteorclient.utils.player.PlayerUtils; | ||
import meteordevelopment.meteorclient.utils.render.NametagUtils; | ||
import meteordevelopment.meteorclient.utils.render.WireframeEntityRenderer; | ||
import meteordevelopment.meteorclient.utils.render.color.Color; | ||
import meteordevelopment.meteorclient.utils.render.color.SettingColor; | ||
import meteordevelopment.orbit.EventHandler; | ||
import moe.kyuunex.fumo_utils.FumoUtils; | ||
import net.minecraft.entity.Entity; | ||
import net.minecraft.entity.EntityType; | ||
import net.minecraft.entity.ItemEntity; | ||
import net.minecraft.item.Item; | ||
import net.minecraft.item.Items; | ||
import net.minecraft.util.math.Box; | ||
import net.minecraft.util.math.MathHelper; | ||
import org.joml.Vector3d; | ||
|
||
import java.util.List; | ||
|
||
public class ItemESP extends Module { | ||
private final SettingGroup sgGeneral = settings.getDefaultGroup(); | ||
|
||
// General | ||
|
||
public final Setting<List<Item>> targetItems = sgGeneral.add(new ItemListSetting.Builder() | ||
.name("target-items") | ||
.description("Items to look for") | ||
.defaultValue(Items.ELYTRA) | ||
.build() | ||
); | ||
|
||
public final Setting<Mode> mode = sgGeneral.add(new EnumSetting.Builder<Mode>() | ||
.name("mode") | ||
.description("Rendering mode.") | ||
.defaultValue(Mode.Box) | ||
.build() | ||
); | ||
|
||
public final Setting<Integer> outlineWidth = sgGeneral.add(new IntSetting.Builder() | ||
.name("outline-width") | ||
.description("The width of the shader outline.") | ||
.visible(() -> mode.get() == Mode.Shader) | ||
.defaultValue(2) | ||
.range(1, 10) | ||
.sliderRange(1, 5) | ||
.build() | ||
); | ||
|
||
public final Setting<Double> glowMultiplier = sgGeneral.add(new DoubleSetting.Builder() | ||
.name("glow-multiplier") | ||
.description("Multiplier for glow effect") | ||
.visible(() -> mode.get() == Mode.Shader) | ||
.decimalPlaces(3) | ||
.defaultValue(3.5) | ||
.min(0) | ||
.sliderMax(10) | ||
.build() | ||
); | ||
|
||
public final Setting<ShapeMode> shapeMode = sgGeneral.add(new EnumSetting.Builder<ShapeMode>() | ||
.name("shape-mode") | ||
.description("How the shapes are rendered.") | ||
.visible(() -> mode.get() != Mode.Glow) | ||
.defaultValue(ShapeMode.Both) | ||
.build() | ||
); | ||
|
||
public final Setting<Double> fillOpacity = sgGeneral.add(new DoubleSetting.Builder() | ||
.name("fill-opacity") | ||
.description("The opacity of the shape fill.") | ||
.visible(() -> shapeMode.get() != ShapeMode.Lines && mode.get() != Mode.Glow) | ||
.defaultValue(0.4) | ||
.range(0, 1) | ||
.sliderMax(1) | ||
.build() | ||
); | ||
|
||
private final Setting<Double> fadeDistance = sgGeneral.add(new DoubleSetting.Builder() | ||
.name("fade-distance") | ||
.description("The distance from an entity where the color begins to fade.") | ||
.defaultValue(1) | ||
.min(0) | ||
.sliderMax(12) | ||
.build() | ||
); | ||
|
||
// Colors | ||
|
||
public final Setting<Boolean> distance = sgGeneral.add(new BoolSetting.Builder() | ||
.name("distance-colors") | ||
.description("Changes the color of tracers depending on distance.") | ||
.defaultValue(false) | ||
.build() | ||
); | ||
|
||
private final Setting<SettingColor> miscColor = sgGeneral.add(new ColorSetting.Builder() | ||
.name("misc-color") | ||
.description("The misc color.") | ||
.defaultValue(new SettingColor(255, 0, 0, 255)) | ||
.visible(() -> !distance.get()) | ||
.build() | ||
); | ||
|
||
private final Color lineColor = new Color(); | ||
private final Color sideColor = new Color(); | ||
private final Color baseColor = new Color(); | ||
|
||
private final Vector3d pos1 = new Vector3d(); | ||
private final Vector3d pos2 = new Vector3d(); | ||
private final Vector3d pos = new Vector3d(); | ||
|
||
private int count; | ||
|
||
public ItemESP() { | ||
super(FumoUtils.CATEGORY, "item-esp", "Renders specific dropped items through walls."); | ||
} | ||
|
||
// Box | ||
|
||
@EventHandler | ||
private void onRender3D(Render3DEvent event) { | ||
if (mode.get() == Mode._2D) return; | ||
|
||
count = 0; | ||
|
||
for (Entity entity : mc.world.getEntities()) { | ||
if (shouldSkip(entity)) continue; | ||
|
||
if (mode.get() == Mode.Box || mode.get() == Mode.Wireframe) drawBoundingBox(event, entity); | ||
count++; | ||
} | ||
} | ||
|
||
private void drawBoundingBox(Render3DEvent event, Entity entity) { | ||
Color color = getColor(entity); | ||
if (color != null) { | ||
lineColor.set(color); | ||
sideColor.set(color).a((int) (sideColor.a * fillOpacity.get())); | ||
} | ||
|
||
if (mode.get() == Mode.Box) { | ||
double x = MathHelper.lerp(event.tickDelta, entity.lastRenderX, entity.getX()) - entity.getX(); | ||
double y = MathHelper.lerp(event.tickDelta, entity.lastRenderY, entity.getY()) - entity.getY(); | ||
double z = MathHelper.lerp(event.tickDelta, entity.lastRenderZ, entity.getZ()) - entity.getZ(); | ||
|
||
Box box = entity.getBoundingBox(); | ||
event.renderer.box(x + box.minX, y + box.minY, z + box.minZ, x + box.maxX, y + box.maxY, z + box.maxZ, sideColor, lineColor, shapeMode.get(), 0); | ||
} else { | ||
WireframeEntityRenderer.render(event, entity, 1, sideColor, lineColor, shapeMode.get()); | ||
} | ||
} | ||
|
||
// 2D | ||
|
||
@EventHandler | ||
private void onRender2D(Render2DEvent event) { | ||
if (mode.get() != Mode._2D) return; | ||
|
||
Renderer2D.COLOR.begin(); | ||
count = 0; | ||
|
||
for (Entity entity : mc.world.getEntities()) { | ||
if (shouldSkip(entity)) continue; | ||
|
||
Box box = entity.getBoundingBox(); | ||
|
||
double x = MathHelper.lerp(event.tickDelta, entity.lastRenderX, entity.getX()) - entity.getX(); | ||
double y = MathHelper.lerp(event.tickDelta, entity.lastRenderY, entity.getY()) - entity.getY(); | ||
double z = MathHelper.lerp(event.tickDelta, entity.lastRenderZ, entity.getZ()) - entity.getZ(); | ||
|
||
// Check corners | ||
pos1.set(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE); | ||
pos2.set(0, 0, 0); | ||
|
||
// Bottom | ||
if (checkCorner(box.minX + x, box.minY + y, box.minZ + z, pos1, pos2)) continue; | ||
if (checkCorner(box.maxX + x, box.minY + y, box.minZ + z, pos1, pos2)) continue; | ||
if (checkCorner(box.minX + x, box.minY + y, box.maxZ + z, pos1, pos2)) continue; | ||
if (checkCorner(box.maxX + x, box.minY + y, box.maxZ + z, pos1, pos2)) continue; | ||
|
||
// Top | ||
if (checkCorner(box.minX + x, box.maxY + y, box.minZ + z, pos1, pos2)) continue; | ||
if (checkCorner(box.maxX + x, box.maxY + y, box.minZ + z, pos1, pos2)) continue; | ||
if (checkCorner(box.minX + x, box.maxY + y, box.maxZ + z, pos1, pos2)) continue; | ||
if (checkCorner(box.maxX + x, box.maxY + y, box.maxZ + z, pos1, pos2)) continue; | ||
|
||
// Setup color | ||
Color color = getColor(entity); | ||
if (color != null) { | ||
lineColor.set(color); | ||
sideColor.set(color).a((int) (sideColor.a * fillOpacity.get())); | ||
} | ||
|
||
// Render | ||
if (shapeMode.get() != ShapeMode.Lines && sideColor.a > 0) { | ||
Renderer2D.COLOR.quad(pos1.x, pos1.y, pos2.x - pos1.x, pos2.y - pos1.y, sideColor); | ||
} | ||
|
||
if (shapeMode.get() != ShapeMode.Sides) { | ||
Renderer2D.COLOR.line(pos1.x, pos1.y, pos1.x, pos2.y, lineColor); | ||
Renderer2D.COLOR.line(pos2.x, pos1.y, pos2.x, pos2.y, lineColor); | ||
Renderer2D.COLOR.line(pos1.x, pos1.y, pos2.x, pos1.y, lineColor); | ||
Renderer2D.COLOR.line(pos1.x, pos2.y, pos2.x, pos2.y, lineColor); | ||
} | ||
|
||
count++; | ||
} | ||
|
||
Renderer2D.COLOR.render(null); | ||
} | ||
|
||
private boolean checkCorner(double x, double y, double z, Vector3d min, Vector3d max) { | ||
pos.set(x, y, z); | ||
if (!NametagUtils.to2D(pos, 1)) return true; | ||
|
||
// Check Min | ||
if (pos.x < min.x) min.x = pos.x; | ||
if (pos.y < min.y) min.y = pos.y; | ||
if (pos.z < min.z) min.z = pos.z; | ||
|
||
// Check Max | ||
if (pos.x > max.x) max.x = pos.x; | ||
if (pos.y > max.y) max.y = pos.y; | ||
if (pos.z > max.z) max.z = pos.z; | ||
|
||
return false; | ||
} | ||
|
||
// Utils | ||
|
||
public boolean shouldSkip(Entity entity) { | ||
if (entity.getType() != EntityType.ITEM) return true; | ||
if (!(entity instanceof ItemEntity itemEntity)) return true; | ||
if (!targetItems.get().contains(itemEntity.getStack().getItem())) return true; | ||
if (entity == mc.cameraEntity && mc.options.getPerspective().isFirstPerson()) return true; | ||
return !EntityUtils.isInRenderDistance(entity); | ||
} | ||
|
||
public Color getColor(Entity entity) { | ||
double alpha = getFadeAlpha(entity); | ||
if (alpha == 0) return null; | ||
|
||
Color color = getEntityTypeColor(entity); | ||
return baseColor.set(color.r, color.g, color.b, (int) (color.a * alpha)); | ||
} | ||
|
||
private double getFadeAlpha(Entity entity) { | ||
double dist = PlayerUtils.squaredDistanceToCamera(entity.getX() + entity.getWidth() / 2, entity.getY() + entity.getEyeHeight(entity.getPose()), entity.getZ() + entity.getWidth() / 2); | ||
double fadeDist = Math.pow(fadeDistance.get(), 2); | ||
double alpha = 1; | ||
if (dist <= fadeDist * fadeDist) alpha = (float) (Math.sqrt(dist) / fadeDist); | ||
if (alpha <= 0.075) alpha = 0; | ||
return alpha; | ||
} | ||
|
||
public Color getEntityTypeColor(Entity entity) { | ||
if (distance.get()) { | ||
return EntityUtils.getColorFromDistance(entity); | ||
} else { | ||
entity.getType().getSpawnGroup(); | ||
return miscColor.get(); | ||
} | ||
} | ||
|
||
@Override | ||
public String getInfoString() { | ||
return Integer.toString(count); | ||
} | ||
|
||
public boolean isShader() { | ||
return isActive() && mode.get() == Mode.Shader; | ||
} | ||
|
||
public boolean isGlow() { | ||
return isActive() && mode.get() == Mode.Glow; | ||
} | ||
|
||
public enum Mode { | ||
Box, | ||
Wireframe, | ||
_2D, | ||
Shader, | ||
Glow; | ||
|
||
@Override | ||
public String toString() { | ||
return this == _2D ? "2D" : super.toString(); | ||
} | ||
} | ||
} |