Last active
July 18, 2017 18:47
-
-
Save ikt32/738c7182177c971aef271621088cbda4 to your computer and use it in GitHub Desktop.
Show ped health on their positions
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
/* | |
* 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); | |
} | |
} |
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
/* | |
* 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