the initial commit to the repo.
This commit is contained in:
parent
025c032b8c
commit
1b757591b9
264 changed files with 21882 additions and 0 deletions
367
stoopid.raw/stupid.solutions.Features.ESP/TracerESP.cs
Normal file
367
stoopid.raw/stupid.solutions.Features.ESP/TracerESP.cs
Normal file
|
|
@ -0,0 +1,367 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using EFT.UI;
|
||||
using stupid.solutions.Utils;
|
||||
using UnityEngine;
|
||||
|
||||
namespace stupid.solutions.Features.ESP;
|
||||
|
||||
public class TracerESP : MonoBehaviour
|
||||
{
|
||||
private class HitMarker
|
||||
{
|
||||
public Vector3 position;
|
||||
|
||||
public float displayTime;
|
||||
|
||||
public float damage;
|
||||
|
||||
public Vector3 floatingOffset;
|
||||
|
||||
public bool isHeadshot;
|
||||
|
||||
public int playerId;
|
||||
|
||||
public HitMarker(Vector3 position, float displayTime, float damage, bool isHeadshot, int playerId)
|
||||
{
|
||||
this.position = position;
|
||||
this.displayTime = displayTime;
|
||||
this.damage = damage;
|
||||
floatingOffset = Vector3.zero;
|
||||
this.isHeadshot = isHeadshot;
|
||||
this.playerId = playerId;
|
||||
}
|
||||
}
|
||||
|
||||
private class Tracer
|
||||
{
|
||||
public List<Vector3> positions = new List<Vector3>();
|
||||
|
||||
public int fireIndex;
|
||||
|
||||
public int fragmentIndex;
|
||||
|
||||
public int randomSeed;
|
||||
|
||||
public float startTime;
|
||||
|
||||
public bool hitTarget;
|
||||
|
||||
public bool hitMarkerDrawn;
|
||||
|
||||
public Vector3? startPosition;
|
||||
|
||||
public bool startUsed;
|
||||
|
||||
public Tracer(int fireIndex, int fragmentIndex, int randomSeed, Vector3? startPosition = null)
|
||||
{
|
||||
this.fireIndex = fireIndex;
|
||||
this.fragmentIndex = fragmentIndex;
|
||||
this.randomSeed = randomSeed;
|
||||
this.startPosition = startPosition;
|
||||
startUsed = false;
|
||||
startTime = Time.time;
|
||||
hitTarget = false;
|
||||
hitMarkerDrawn = false;
|
||||
}
|
||||
|
||||
public void AddPosition(Vector3 position)
|
||||
{
|
||||
if (!hitTarget)
|
||||
{
|
||||
positions.Add(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool hitmarkerloaded;
|
||||
|
||||
private static Dictionary<int, Tracer> validProjectiles = new Dictionary<int, Tracer>();
|
||||
|
||||
private static List<HitMarker> activeHitMarkers = new List<HitMarker>();
|
||||
|
||||
private Dictionary<int, bool> playerAliveStatus = new Dictionary<int, bool>();
|
||||
|
||||
private static Dictionary<int, float> damageTimers = new Dictionary<int, float>();
|
||||
|
||||
private HashSet<int> blacklistedSeeds = new HashSet<int>();
|
||||
|
||||
private bool clearalivestatus;
|
||||
|
||||
private float hitMarkerDuration = 1f;
|
||||
|
||||
private static float hitMarkerVolume = 0.2f;
|
||||
|
||||
private float damageAccumulationTime = 0.5f;
|
||||
|
||||
private static Texture2D hitMarkerTexture;
|
||||
|
||||
private bool isReactionOnShotHooked;
|
||||
|
||||
public static TestHook ReactionOnShotHook;
|
||||
|
||||
private static MethodInfo originalMethod;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
ConsoleScreen.Log("Init GL material....");
|
||||
GameUtils.InitMaterial();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (!Settings.tracers && !Settings.HitMarkers)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (Main.GameWorld == null && clearalivestatus)
|
||||
{
|
||||
playerAliveStatus.Clear();
|
||||
clearalivestatus = false;
|
||||
}
|
||||
else if (Main.GameWorld != null && !clearalivestatus)
|
||||
{
|
||||
clearalivestatus = true;
|
||||
}
|
||||
if (Main.GameWorld == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!hitmarkerloaded && Main.bundle != null)
|
||||
{
|
||||
hitMarkerTexture = Main.bundle.LoadAsset<Texture2D>("hitmarkerImage");
|
||||
hitmarkerloaded = hitMarkerTexture != null;
|
||||
ConsoleScreen.Log((hitMarkerTexture != null) ? "Hitmarker image loaded successfully!" : "Failed to load hitmarker image!");
|
||||
}
|
||||
if (hitMarkerTexture == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (Main.OnlineGamePlayers.Count > 0)
|
||||
{
|
||||
if (!isReactionOnShotHooked && Settings.HitMarkers)
|
||||
{
|
||||
isReactionOnShotHooked = true;
|
||||
}
|
||||
_F163 obj = Main.GameWorld?.ClientBallisticCalculator;
|
||||
int activeShotsCount = obj.ActiveShotsCount;
|
||||
if (obj == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < activeShotsCount; i++)
|
||||
{
|
||||
_F16A activeShot = obj.GetActiveShot(i);
|
||||
if (activeShot == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (activeShot.PlayerProfileID == Main.LocalPlayer.ProfileId && !validProjectiles.ContainsKey(activeShot.RandomSeed))
|
||||
{
|
||||
Tracer value = new Tracer(activeShot.FireIndex, activeShot.FragmentIndex, activeShot.RandomSeed, activeShot.StartPosition);
|
||||
validProjectiles[activeShot.RandomSeed] = value;
|
||||
}
|
||||
if (validProjectiles.ContainsKey(activeShot.RandomSeed))
|
||||
{
|
||||
Tracer tracer = validProjectiles[activeShot.RandomSeed];
|
||||
if (tracer.startPosition.HasValue && !tracer.startUsed)
|
||||
{
|
||||
tracer.positions.Add(tracer.startPosition.Value);
|
||||
tracer.startUsed = true;
|
||||
}
|
||||
tracer.AddPosition(activeShot.CurrentPosition);
|
||||
}
|
||||
}
|
||||
activeHitMarkers.RemoveAll((HitMarker marker) => Time.time - marker.displayTime > hitMarkerDuration);
|
||||
validProjectiles = validProjectiles.Where((KeyValuePair<int, Tracer> keyValuePair) => Time.time - keyValuePair.Value.startTime < 5f).ToDictionary((KeyValuePair<int, Tracer> keyValuePair) => keyValuePair.Key, (KeyValuePair<int, Tracer> keyValuePair) => keyValuePair.Value);
|
||||
return;
|
||||
}
|
||||
_F163 obj2 = Main.GameWorld?.SharedBallisticsCalculator;
|
||||
int activeShotsCount2 = obj2.ActiveShotsCount;
|
||||
if (obj2 == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int num = 0; num < activeShotsCount2; num++)
|
||||
{
|
||||
_F16A activeShot2 = obj2.GetActiveShot(num);
|
||||
if (activeShot2 == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (activeShot2.PlayerProfileID == Main.LocalPlayer.ProfileId && !validProjectiles.ContainsKey(activeShot2.RandomSeed))
|
||||
{
|
||||
Tracer value2 = new Tracer(activeShot2.FireIndex, activeShot2.FragmentIndex, activeShot2.RandomSeed, activeShot2.StartPosition);
|
||||
validProjectiles[activeShot2.RandomSeed] = value2;
|
||||
}
|
||||
if (!validProjectiles.ContainsKey(activeShot2.RandomSeed))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Tracer tracer2 = validProjectiles[activeShot2.RandomSeed];
|
||||
if (tracer2.startPosition.HasValue && !tracer2.startUsed)
|
||||
{
|
||||
tracer2.positions.Add(tracer2.startPosition.Value);
|
||||
tracer2.startUsed = true;
|
||||
}
|
||||
tracer2.AddPosition(activeShot2.CurrentPosition);
|
||||
if (Main.OnlineGamePlayers.Count >= 1 || !activeShot2.HasAchievedTarget || tracer2.hitMarkerDrawn)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
tracer2.hitTarget = true;
|
||||
tracer2.hitMarkerDrawn = true;
|
||||
if (!(activeShot2.HittedBallisticCollider is BodyPartCollider { Player: var player } bodyPartCollider))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
bool flag = bodyPartCollider.BodyPartType == EBodyPart.Head;
|
||||
if (player == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int playerId = player.ProfileId.GetHashCode();
|
||||
if (playerAliveStatus.ContainsKey(playerId) && !playerAliveStatus[playerId])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
float current = player.HealthController.GetBodyPartHealth(EBodyPart.Common).Current;
|
||||
float num2 = player.HealthController.GetBodyPartHealth(EBodyPart.Common).Maximum - current;
|
||||
if (damageTimers.ContainsKey(playerId) && Time.time - damageTimers[playerId] < damageAccumulationTime)
|
||||
{
|
||||
HitMarker hitMarker = activeHitMarkers.FirstOrDefault((HitMarker m) => m.playerId == playerId);
|
||||
if (hitMarker != null)
|
||||
{
|
||||
hitMarker.damage += num2;
|
||||
hitMarker.displayTime = Time.time;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
activeHitMarkers.Add(new HitMarker(activeShot2.HitPoint, Time.time, num2, flag, playerId));
|
||||
damageTimers[playerId] = Time.time;
|
||||
}
|
||||
if (Settings.HitMarkers)
|
||||
{
|
||||
if (flag && Main.headshotsound != null)
|
||||
{
|
||||
Main.audioSourcehit.clip = Main.headshotsound;
|
||||
Main.audioSourcehit.volume = hitMarkerVolume;
|
||||
Main.audioSourcehit.Play();
|
||||
}
|
||||
else if (Main.hitMarkerSound != null)
|
||||
{
|
||||
Main.audioSourcehit.clip = Main.hitMarkerSound;
|
||||
Main.audioSourcehit.volume = hitMarkerVolume;
|
||||
Main.audioSourcehit.Play();
|
||||
}
|
||||
}
|
||||
bool isAlive = player.HealthController.IsAlive;
|
||||
playerAliveStatus[playerId] = isAlive;
|
||||
if (!isAlive)
|
||||
{
|
||||
damageTimers.Remove(playerId);
|
||||
}
|
||||
}
|
||||
activeHitMarkers.RemoveAll((HitMarker marker) => Time.time - marker.displayTime > hitMarkerDuration);
|
||||
validProjectiles = validProjectiles.Where((KeyValuePair<int, Tracer> keyValuePair) => Time.time - keyValuePair.Value.startTime < 5f).ToDictionary((KeyValuePair<int, Tracer> keyValuePair) => keyValuePair.Key, (KeyValuePair<int, Tracer> keyValuePair) => keyValuePair.Value);
|
||||
}
|
||||
|
||||
private static void ProcessOnlineHitMarker(Vector3 hitPosition, bool isHeadshot)
|
||||
{
|
||||
Vector3 position = GameUtils.WorldPointToScreenPoint(hitPosition);
|
||||
ConsoleScreen.Log($"Drawing Hitmarker at : {hitPosition} Headshot ? {isHeadshot}");
|
||||
if (position.z > 0f)
|
||||
{
|
||||
DrawHitMarker(position, 32f, isHeadshot);
|
||||
}
|
||||
}
|
||||
|
||||
private void Tracers()
|
||||
{
|
||||
if (!Settings.tracers)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (GameUtils.DrawMaterial == null)
|
||||
{
|
||||
GameUtils.InitMaterial();
|
||||
}
|
||||
Camera mainCamera = Main.MainCamera;
|
||||
if (mainCamera == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
GameUtils.DrawMaterial.SetPass(0);
|
||||
GL.PushMatrix();
|
||||
GL.LoadProjectionMatrix(mainCamera.projectionMatrix);
|
||||
GL.modelview = mainCamera.worldToCameraMatrix;
|
||||
GL.Begin(1);
|
||||
foreach (Tracer value in validProjectiles.Values)
|
||||
{
|
||||
if (value.positions.Count >= 1)
|
||||
{
|
||||
for (int i = 0; i < value.positions.Count - 1; i++)
|
||||
{
|
||||
Vector3 v = value.positions[i];
|
||||
Vector3 v2 = value.positions[i + 1];
|
||||
GL.Color(Settings.TracerColor);
|
||||
GL.Vertex(v);
|
||||
GL.Vertex(v2);
|
||||
}
|
||||
}
|
||||
}
|
||||
GL.End();
|
||||
GL.PopMatrix();
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
Tracers();
|
||||
if (!Settings.HitMarkers)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (HitMarker activeHitMarker in activeHitMarkers)
|
||||
{
|
||||
Vector3 vector = GameUtils.WorldPointToScreenPoint(activeHitMarker.position);
|
||||
if (vector.z > 0f && vector.x >= 0f && vector.x <= (float)Screen.width && vector.y >= 0f && vector.y <= (float)Screen.height)
|
||||
{
|
||||
DrawDamageNumbers(activeHitMarker, vector);
|
||||
DrawHitMarker(vector, 32f, activeHitMarker.isHeadshot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawDamageNumbers(HitMarker hitMarker, Vector3 screenPosition)
|
||||
{
|
||||
hitMarker.floatingOffset.y += Time.deltaTime * 20f;
|
||||
Vector3 vector = screenPosition + hitMarker.floatingOffset;
|
||||
vector.y = (float)Screen.height - vector.y;
|
||||
if (hitMarker.isHeadshot)
|
||||
{
|
||||
string text = "HEADSHOT";
|
||||
GUI.color = new Color(1f, 0f, 0f, 1f);
|
||||
GUI.Label(new Rect(vector.x - 10f, vector.y - 40f, 100f, 20f), text);
|
||||
}
|
||||
string text2 = "";
|
||||
if (Main.GamePlayers.Count > 0)
|
||||
{
|
||||
text2 = "- " + hitMarker.damage.ToString("F0") + " hp ";
|
||||
}
|
||||
GUI.color = Settings.HitmarkerHeadShotColor;
|
||||
GUI.Label(new Rect(vector.x - 10f, vector.y - 20f, 100f, 20f), text2);
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
|
||||
private static void DrawHitMarker(Vector3 position, float size, bool isHeadshot)
|
||||
{
|
||||
if (!(hitMarkerTexture == null))
|
||||
{
|
||||
GUI.color = (isHeadshot ? Settings.HitmarkerHeadShotColor : Settings.HitmarkerHitColor);
|
||||
GUI.DrawTexture(new Rect(position.x - size / 2f, position.y - size / 2f, size, size), hitMarkerTexture);
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue