Skip to content

Commit 57502b0

Browse files
feat: add distance-based trackers to the ESP tab (#26)
* Add distance-based tracer color functionality * Add Distance-based toggle to MenuUI * refactor: add documentation and improve color interpolation --------- Co-authored-by: Astral✨ <90265231+astra1dev@users.noreply.github.com>
1 parent 36b9f83 commit 57502b0

3 files changed

Lines changed: 82 additions & 41 deletions

File tree

src/Cheats/TracersHandler.cs

Lines changed: 77 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,107 @@
11
using UnityEngine;
22

33
namespace MalumMenu;
4+
45
public static class TracersHandler
56
{
6-
public static void drawPlayerTracer(PlayerPhysics playerPhysics){
7-
try{
8-
9-
Color color = Color.clear; // All tracers are invisible by default
7+
/// <summary>
8+
/// Draws a tracer from the local player to another player.
9+
/// </summary>
10+
/// <param name="playerPhysics">The <c>PlayerPhysics</c> of the target player.</param>
11+
public static void DrawPlayerTracer(PlayerPhysics playerPhysics)
12+
{
13+
try
14+
{
15+
var color = Color.clear; // All tracers are invisible by default
1016

11-
if (!playerPhysics.myPlayer.Data.IsDead){
12-
if (CheatToggles.tracersCrew && !playerPhysics.myPlayer.Data.Role.IsImpostor){
13-
if (CheatToggles.colorBasedTracers){
14-
color = playerPhysics.myPlayer.Data.Color; // Color-Based Tracer
15-
}else{
16-
color = playerPhysics.myPlayer.Data.Role.TeamColor; // Team-Based Tracer
17+
if (!playerPhysics.myPlayer.Data.IsDead)
18+
{
19+
if (CheatToggles.tracersCrew && !playerPhysics.myPlayer.Data.Role.IsImpostor ||
20+
CheatToggles.tracersImps && playerPhysics.myPlayer.Data.Role.IsImpostor)
21+
{
22+
if (CheatToggles.distanceBasedTracers)
23+
{
24+
color = GetDistanceBasedColor(playerPhysics.myPlayer.transform.position);
1725
}
18-
}else if (CheatToggles.tracersImps && playerPhysics.myPlayer.Data.Role.IsImpostor){
19-
if (CheatToggles.colorBasedTracers){
26+
else if (CheatToggles.colorBasedTracers)
27+
{
2028
color = playerPhysics.myPlayer.Data.Color; // Color-Based Tracer
21-
}else{
29+
}
30+
else
31+
{
2232
color = playerPhysics.myPlayer.Data.Role.TeamColor; // Team-Based Tracer
2333
}
2434
}
25-
}else{
26-
if (CheatToggles.tracersGhosts){
27-
if (CheatToggles.colorBasedTracers){
35+
}
36+
else
37+
{
38+
if (CheatToggles.tracersGhosts)
39+
{
40+
if (CheatToggles.distanceBasedTracers)
41+
{
42+
color = GetDistanceBasedColor(playerPhysics.myPlayer.transform.position);
43+
}
44+
else if (CheatToggles.colorBasedTracers)
45+
{
2846
color = playerPhysics.myPlayer.Data.Color; // Color-Based Tracer
29-
}else{
47+
}
48+
else
49+
{
3050
color = Palette.White; // Ghost Tracer (White)
3151
}
3252
}
3353
}
3454

3555
// Draw tracer between the player and LocalPlayer using the right color
3656
Utils.drawTracer(playerPhysics.myPlayer.gameObject, PlayerControl.LocalPlayer.gameObject, color);
37-
3857
}catch{}
3958
}
4059

41-
public static void drawBodyTracer(DeadBody deadBody){
42-
Color color = Color.clear; // All tracers are invisible by default
43-
44-
if (CheatToggles.tracersBodies){
45-
if (CheatToggles.colorBasedTracers){
46-
47-
// Fetch the dead body's PlayerInfo
48-
NetworkedPlayerInfo playerById = GameData.Instance.GetPlayerById(deadBody.ParentId);
49-
50-
color = playerById.Color; // Color-Based Tracer
51-
52-
}else{
60+
/// <summary>
61+
/// Draws a tracer from the local player to a dead body. Only draws tracers for unreported dead bodies.
62+
/// </summary>
63+
/// <param name="deadBody">The <c>DeadBody</c> to draw a tracer to.</param>
64+
public static void DrawBodyTracer(DeadBody deadBody)
65+
{
66+
var color = Color.clear; // All tracers are invisible by default
5367

68+
if (CheatToggles.tracersBodies)
69+
{
70+
if (CheatToggles.distanceBasedTracers)
71+
{
72+
color = GetDistanceBasedColor(deadBody.transform.position);
73+
}
74+
else if (CheatToggles.colorBasedTracers)
75+
{
76+
color = GameData.Instance.GetPlayerById(deadBody.ParentId).Color; // Color-Based Tracer
77+
}
78+
else
79+
{
5480
color = Color.yellow; // Dead Body Tracer (Yellow)
55-
5681
}
5782
}
5883

5984
// Draw tracer between the dead body and LocalPlayer using the right color
6085
Utils.drawTracer(deadBody.gameObject, PlayerControl.LocalPlayer.gameObject, color);
6186
}
62-
}
87+
88+
/// <summary>
89+
/// Gets a color based on the distance between the local player and a target position.
90+
/// Closer distances are red, medium distances are yellow, and farther distances are green.
91+
/// </summary>
92+
/// <param name="targetPosition">The position to calculate the distance from.</param>
93+
/// <returns>A Color that represents the distance (red for close, yellow for medium, green for far).</returns>
94+
private static Color GetDistanceBasedColor(Vector3 targetPosition)
95+
{
96+
const float maxDistance = 20f; // Green at 20+ units
97+
const float minDistance = 2f; // Red at 2 units or fewer
98+
99+
var distance = Vector3.Distance(targetPosition, PlayerControl.LocalPlayer.transform.position);
100+
var normalized = Mathf.InverseLerp(minDistance, maxDistance, distance);
101+
102+
// Interpolate: Red (close) -> Yellow (medium) -> Green (far)
103+
return normalized < 0.5f
104+
? Color.Lerp(Color.red, Color.yellow, normalized * 2f)
105+
: Color.Lerp(Color.yellow, Color.green, (normalized - 0.5f) * 2f);
106+
}
107+
}

src/Patches/PlayerPhysicsPatches.cs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ public static class PlayerPhysics_LateUpdate
99
{
1010
public static void Postfix(PlayerPhysics __instance)
1111
{
12-
1312
MalumESP.PlayerNametags(__instance);
1413
MalumESP.seeGhostsCheat(__instance);
1514

@@ -33,18 +32,15 @@ public static void Postfix(PlayerPhysics __instance)
3332
MalumPPMCheats.changeRolePPM();
3433
MalumPPMCheats.forceRolePPM();
3534

36-
TracersHandler.drawPlayerTracer(__instance);
35+
TracersHandler.DrawPlayerTracer(__instance);
3736

3837
GameObject[] bodyObjects = GameObject.FindGameObjectsWithTag("DeadBody");
3938
foreach(GameObject bodyObject in bodyObjects) // Finds and loops through all dead bodies
4039
{
4140
DeadBody deadBody = bodyObject.GetComponent<DeadBody>();
4241

43-
if (deadBody){
44-
if (!deadBody.Reported){ // Only draw tracers for unreported dead bodies
45-
TracersHandler.drawBodyTracer(deadBody);
46-
}
47-
}
42+
if (!deadBody || deadBody.Reported) continue; // Only draw tracers for unreported dead bodies
43+
TracersHandler.DrawBodyTracer(deadBody);
4844
}
4945

5046
try
@@ -60,7 +56,6 @@ public static void Postfix(PlayerPhysics __instance)
6056
PlayerControl.LocalPlayer.MyPhysics.GhostSpeed = Mathf.Abs(PlayerControl.LocalPlayer.MyPhysics.GhostSpeed);
6157
}
6258
}catch (NullReferenceException) {}
63-
6459
}
6560
}
6661

src/UI/MenuUI.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ private void Start()
5858
new ToggleInfo(" Impostors", () => CheatToggles.tracersImps, x => CheatToggles.tracersImps = x),
5959
new ToggleInfo(" Ghosts", () => CheatToggles.tracersGhosts, x => CheatToggles.tracersGhosts = x),
6060
new ToggleInfo(" Dead Bodies", () => CheatToggles.tracersBodies, x => CheatToggles.tracersBodies = x),
61-
new ToggleInfo(" Color-based", () => CheatToggles.colorBasedTracers, x => CheatToggles.colorBasedTracers = x)
61+
new ToggleInfo(" Color-based", () => CheatToggles.colorBasedTracers, x => CheatToggles.colorBasedTracers = x),
62+
new ToggleInfo(" Distance-based", () => CheatToggles.distanceBasedTracers, x => CheatToggles.distanceBasedTracers = x)
6263
]),
6364

6465
new SubmenuInfo("Minimap", false, [

0 commit comments

Comments
 (0)