Skip to content

Instantly share code, notes, and snippets.

@ikt32
Last active July 18, 2017 18:47
Show Gist options
  • Save ikt32/738c7182177c971aef271621088cbda4 to your computer and use it in GitHub Desktop.
Save ikt32/738c7182177c971aef271621088cbda4 to your computer and use it in GitHub Desktop.
Show ped health on their positions
/*
* Search version
* Due to having multiple entries we can do fancy stuff like fade-in,
* fade-out, depending on distance, and showing multiple boxes.
*/
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Drawing;
using GTA;
using GTA.Math;
using GTA.Native;
public class SearchCone : Script
{
public SearchCone()
{
Tick += OnTick;
}
private bool active = false;
private Vehicle lastVehicle;
bool areTheseClose(float h1, float h2, float separation)
{
var diff = Math.Abs(h1 - h2);
if (diff < separation)
return true;
if (Math.Abs(diff - 360) < separation)
return true;
return false;
}
float howClose(float h1, float h2, float separation)
{
var diff = Math.Abs(h1 - h2);
if (diff < separation)
return (separation - diff) / separation;
if (Math.Abs(diff - 360) < separation)
return (separation - Math.Abs(diff - 360)) / separation;
return 0.0f;
}
void OnTick(object sender, EventArgs e)
{
Ped player = Game.Player.Character;
Vector3 myPos = player.Position;
const float searchDist = 30.0f;
//Vehicle[] vehicles = World.GetAllVehicles();
Ped[] peds = World.GetAllPeds();
for (int i = 0; i < peds.Length; i++)
{
if (peds[i] != player)
{
Vector3 targetPos = peds[i].Position;
Vector3 direction = targetPos - myPos;
direction.Normalize();
float vehDirection = Convert.ToSingle(Math.Atan2(direction.Y, direction.X) * (180.0f / Math.PI));
float myHeading = (player.Heading + 90.0f) % 360;
bool close = areTheseClose(vehDirection, myHeading, 90.0f);
float centerCloseness = howClose(vehDirection, myHeading, 90.0f);
if (close)
{
float dist = World.GetDistance(myPos, targetPos);
if (dist < searchDist)
{
float meCloseness = (float)Math.Pow(2.0f * (searchDist - dist) / searchDist, 2.0f);
int drawAlpha = Math.Min((int)(255 * centerCloseness * meCloseness), 255);
List<string> lines = new List<string>();
lines.Add("Max: " + peds[i].MaxHealth.ToString());
lines.Add("Current: " + peds[i].Health.ToString());
Color c = Color.FromArgb(drawAlpha / 2, 0, 0, 0);
showDebugInfo3D(targetPos, lines, c);
}
}
}
}
}
void showText(float x, float y, float scale, string text, int font, Color rgba, bool outline)
{
Function.Call(Hash.SET_TEXT_FONT, font);
Function.Call(Hash.SET_TEXT_SCALE, scale, scale);
Function.Call(Hash.SET_TEXT_COLOUR, rgba.R, rgba.G, rgba.B, rgba.A);
Function.Call(Hash.SET_TEXT_WRAP, 0.0, 1.0);
Function.Call(Hash.SET_TEXT_CENTRE, 0);
if (outline) Function.Call(Hash.SET_TEXT_OUTLINE);
Function.Call(Hash._SET_TEXT_ENTRY, "STRING");
Function.Call(Hash._ADD_TEXT_COMPONENT_STRING, text);
Function.Call(Hash._DRAW_TEXT, x, y);
}
void showDebugInfo3D(Vector3 location, List<string> textLines, Color backgroundColor)
{
float height = 0.0125f;
Function.Call(Hash.SET_DRAW_ORIGIN, location.X, location.Y, location.Z, 0);
int i = 0;
foreach (var line in textLines)
{
showText(0, 0 + height * i, 0.2f, line, 0, Color.FromArgb(2* backgroundColor.A, 255, 255, 255), true);
i++;
}
float szX = 0.060f;
float szY = (height * i) + 0.02f;
Function.Call(Hash.DRAW_RECT, 0.027f, (height * i) / 2.0f, szX, szY,
backgroundColor.R, backgroundColor.G, backgroundColor.B, backgroundColor.A);
Function.Call(Hash.CLEAR_DRAW_ORIGIN);
}
}
/*
* Search version
* Due to having multiple entries we can do fancy stuff like fade-in,
* fade-out, depending on distance, and showing multiple boxes.
*/
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Drawing;
using GTA;
using GTA.Math;
using GTA.Native;
public class SearchCone : Script
{
public SearchCone()
{
Tick += OnTick;
}
private List<Tuple<float, float>> coordsOnScreen = new List<Tuple<float, float>>();
bool areTheseClose(float h1, float h2, float separation)
{
var diff = Math.Abs(h1 - h2);
if (diff < separation)
return true;
if (Math.Abs(diff - 360) < separation)
return true;
return false;
}
float howClose(float h1, float h2, float separation)
{
var diff = Math.Abs(h1 - h2);
if (diff < separation)
return (separation - diff) / separation;
if (Math.Abs(diff - 360) < separation)
return (separation - Math.Abs(diff - 360)) / separation;
return 0.0f;
}
void OnTick(object sender, EventArgs e)
{
Ped player = Game.Player.Character;
Vector3 myPos = player.Position;
IterateVehs(player, myPos, 120.0f);
IteratePeds(player, myPos, 30.0f);
IterateObjs(player, myPos, 30.0f);
coordsOnScreen.Clear();
}
private void IteratePeds(Ped player, Vector3 myPos, float searchDist)
{
Ped[] peds = World.GetNearbyPeds(myPos, searchDist);
foreach (Ped ped in peds)
{
if (ped != player)
{
Vector3 targetPos = ped.Position;
Vector3 direction = targetPos - myPos;
direction.Normalize();
float vehDirection = Convert.ToSingle(Math.Atan2(direction.Y, direction.X) * (180.0f / Math.PI));
float myHeading = (player.Heading + 90.0f) % 360;
OutputArgument x = new OutputArgument();
OutputArgument y = new OutputArgument();
bool success = Function.Call<bool>(Hash._WORLD3D_TO_SCREEN2D, targetPos.X, targetPos.Y, targetPos.Z, x, y);
bool close = areTheseClose(vehDirection, myHeading, 90.0f);
float centerCloseness = howClose(vehDirection, myHeading, 90.0f);
if (success && close)
{
if (!FitsOnScreen(x, y)) continue;
coordsOnScreen.Add(new Tuple<float, float>(x.GetResult<float>(), y.GetResult<float>()));
float dist = World.GetDistance(myPos, targetPos);
if (dist < searchDist)
{
float meCloseness = (float) Math.Pow(2.0f * (searchDist - dist) / searchDist, 2.0f);
int drawAlpha = Math.Min((int) (255 * centerCloseness * meCloseness), 255);
List<string> lines = new List<string>();
lines.Add("Max: " + ped.MaxHealth.ToString());
lines.Add("Current: " + ped.Health.ToString());
Color c = Color.FromArgb(drawAlpha / 2, 0, 0, 0);
showDebugInfo3D(targetPos, lines, c);
}
}
}
}
}
private bool FitsOnScreen(OutputArgument x, OutputArgument y)
{
bool fitsOnScreen = true;
foreach (var coord in coordsOnScreen)
{
double textDist = Math.Sqrt((coord.Item1 - x.GetResult<float>()) * (coord.Item1 - x.GetResult<float>()) +
(coord.Item2 - y.GetResult<float>()) * (coord.Item2 - y.GetResult<float>()));
if (textDist < 0.04)
{
fitsOnScreen = false;
break;
}
}
if (!fitsOnScreen)
{
return false;
}
return true;
}
private void IterateVehs(Ped player, Vector3 myPos, float searchDist)
{
Vehicle[] vehicles = World.GetNearbyVehicles(myPos, searchDist);
foreach (Vehicle veh in vehicles)
{
Vector3 targetPos = veh.Position;
Vector3 direction = targetPos - myPos;
direction.Normalize();
float vehDirection = Convert.ToSingle(Math.Atan2(direction.Y, direction.X) * (180.0f / Math.PI));
float myHeading = (player.Heading + 90.0f) % 360;
OutputArgument x = new OutputArgument();
OutputArgument y = new OutputArgument();
bool success = Function.Call<bool>(Hash._WORLD3D_TO_SCREEN2D, targetPos.X, targetPos.Y, targetPos.Z, x, y);
bool close = areTheseClose(vehDirection, myHeading, 30.0f);
float centerCloseness = howClose(vehDirection, myHeading, 30.0f);
if (success && close)
{
if (!FitsOnScreen(x, y)) continue;
coordsOnScreen.Add(new Tuple<float, float>(x.GetResult<float>(), y.GetResult<float>()));
float dist = World.GetDistance(myPos, targetPos);
if (dist < searchDist)
{
float meCloseness = (float)Math.Pow(2.0f * (searchDist - dist) / searchDist, 2.0f);
int drawAlpha = Math.Min((int)(255 * centerCloseness * meCloseness), 255);
List<string> lines = new List<string>();
lines.Add("Name: " + veh.FriendlyName);
lines.Add("Health: " + veh.Health);
lines.Add("Body: " + veh.BodyHealth);
lines.Add("Engine: " + veh.EngineHealth);
lines.Add("Fuel: " + veh.PetrolTankHealth);
Color c = Color.FromArgb(drawAlpha / 2, 0, 0, 0);
showDebugInfo3D(targetPos, lines, c);
}
}
}
}
private void IterateObjs(Ped player, Vector3 myPos, float searchDist)
{
Prop[] props = World.GetNearbyProps(myPos, searchDist);
foreach (Prop prop in props)
{
if (prop.IsInvincible || !prop.HasCollision)
{
continue;
}
Vector3 targetPos = prop.Position;
Vector3 direction = targetPos - myPos;
direction.Normalize();
float vehDirection = Convert.ToSingle(Math.Atan2(direction.Y, direction.X) * (180.0f / Math.PI));
float myHeading = (player.Heading + 90.0f) % 360;
OutputArgument x = new OutputArgument();
OutputArgument y = new OutputArgument();
bool success = Function.Call<bool>(Hash._WORLD3D_TO_SCREEN2D, targetPos.X, targetPos.Y, targetPos.Z, x, y);
bool close = areTheseClose(vehDirection, myHeading, 30.0f);
float centerCloseness = howClose(vehDirection, myHeading, 30.0f);
if (success && close)
{
if (!FitsOnScreen(x, y)) continue;
coordsOnScreen.Add(new Tuple<float, float>(x.GetResult<float>(), y.GetResult<float>()));
float dist = World.GetDistance(myPos, targetPos);
if (dist < searchDist)
{
float meCloseness = (float)Math.Pow(2.0f * (searchDist - dist) / searchDist, 2.0f);
int drawAlpha = Math.Min((int)(255 * centerCloseness * meCloseness), 255);
List<string> lines = new List<string>();
lines.Add("Hash: " + prop.GetHashCode());
lines.Add("Max Health: " + prop.MaxHealth);
lines.Add("Health: " + prop.Health);
lines.Add("Alive: " + prop.IsAlive);
Color c = Color.FromArgb(drawAlpha / 2, 0, 0, 0);
showDebugInfo3D(targetPos, lines, c);
}
}
}
}
void showText(float x, float y, float scale, string text, int font, Color rgba, bool outline)
{
Function.Call(Hash.SET_TEXT_FONT, font);
Function.Call(Hash.SET_TEXT_SCALE, scale, scale);
Function.Call(Hash.SET_TEXT_COLOUR, rgba.R, rgba.G, rgba.B, rgba.A);
Function.Call(Hash.SET_TEXT_WRAP, 0.0, 1.0);
Function.Call(Hash.SET_TEXT_CENTRE, 0);
if (outline) Function.Call(Hash.SET_TEXT_OUTLINE);
Function.Call(Hash._SET_TEXT_ENTRY, "STRING");
Function.Call(Hash._ADD_TEXT_COMPONENT_STRING, text);
Function.Call(Hash._DRAW_TEXT, x, y);
}
void showDebugInfo3D(Vector3 location, List<string> textLines, Color backgroundColor)
{
float height = 0.0125f;
Function.Call(Hash.SET_DRAW_ORIGIN, location.X, location.Y, location.Z, 0);
int i = 0;
foreach (var line in textLines)
{
showText(0, 0 + height * i, 0.2f, line, 0, Color.FromArgb(2 * backgroundColor.A, 255, 255, 255), true);
i++;
}
float szX = 0.060f;
float szY = (height * i) + 0.02f;
Function.Call(Hash.DRAW_RECT, 0.027f, (height * i) / 2.0f, szX, szY,
backgroundColor.R, backgroundColor.G, backgroundColor.B, backgroundColor.A);
Function.Call(Hash.CLEAR_DRAW_ORIGIN);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment