Skip to content

Commit

Permalink
v1.2
Browse files Browse the repository at this point in the history
- Implemented crosshair-based pinging
- Added !mapping command for marking locations
- Testing 5-second duration and 3-second cooldown for pings
- UpdatedREADME.md with new feature details
  • Loading branch information
vexx-sm committed Sep 5, 2024
1 parent de8d2e3 commit 2e7a2f2
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 14 deletions.
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The radar uses SourceMod's HUD text functionality for rendering, making it a lig

3. **Player Position Calculation**: For each update, the plugin:
- Gets the position and angle of the player
- Calculates the relative positions of all teammates
- Calculates the relative positions/health of all teammates

4. **Radar Display**: The plugin then:
- Creates a radar background in the top-left corner of the screen
Expand All @@ -37,6 +37,11 @@ The radar uses SourceMod's HUD text functionality for rendering, making it a lig
- Teammate dots change color based on health:
- Green: Above 50% health
- Red: 50% health or below
- Ping System: Players can mark locations on the radar for their teammates
- Use `!mapping` or `sm_mapping` to ping the location you're looking at, ideally use `bind <key> "say /mapping"`.
- Pings appear as yellow exclamation marks (!) on the radar
- Pings last for 5 seconds and have a 3-second cooldown


## Requirements

Expand All @@ -55,7 +60,7 @@ The radar uses SourceMod's HUD text functionality for rendering, making it a lig
2. Edit these commented lines:

```
// Customizable settings
// Core settings
#define UPDATE_INTERVAL 0.1 // How often the radar updates (in seconds)
#define RADAR_SIZE 2560.0 // The in-game units the radar covers
#define RADAR_SCALE 0.225 // The size of the radar on the screen (0-1)
Expand All @@ -68,6 +73,11 @@ The radar uses SourceMod's HUD text functionality for rendering, making it a lig
// Radar position
#define RADAR_X 0.01 // X position of the radar (0-1)
#define RADAR_Y 0.01 // Y position of the radar (0-1)
// Ping system settings
#define MAX_PINGS 5
#define PING_DURATION 5.0
#define PING_COOLDOWN 3.0
```


Expand Down
Binary file modified plugins/team_radar.smx
Binary file not shown.
148 changes: 136 additions & 12 deletions scripting/team_radar.sp
Original file line number Diff line number Diff line change
@@ -1,38 +1,55 @@
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#include <tf2>
#include <tf2_stocks>

#pragma newdecls required

// Customizable settings

//╭──────────────────────────────────.★..─╮

// Core Settings
#define UPDATE_INTERVAL 0.1 // How often the radar updates (in seconds)
#define RADAR_SIZE 2560.0 // The in-game units the radar covers
#define RADAR_SCALE 0.225 // The size of the radar on the screen (0-1)
#define RADAR_SIZE 2560.0 // The in-game units the radar covers
#define RADAR_SCALE 0.225 // The size of the radar on the screen (0-1)

// Colors (RGBA format)
#define COLOR_SELF {255, 255, 0, 255} // Default {255, 255, 0, 255} Yellow
#define COLOR_TEAMMATE_HEALTHY {0, 255, 0, 255} // Default {0, 255, 0, 255} Green
#define COLOR_TEAMMATE_LOW {255, 0, 0, 255} // Default {255, 0, 0, 255} Red
#define COLOR_SELF {255, 255, 0, 255} // Yellow
#define COLOR_TEAMMATE_HEALTHY {0, 255, 0, 255} // Green
#define COLOR_TEAMMATE_LOW {255, 0, 0, 255} // Red
#define COLOR_PING {255, 255, 0, 255} // Yellow

// Radar position
// Customizable radar position
#define RADAR_X 0.01 // X position of the radar (0-1)
#define RADAR_Y 0.01 // Y position of the radar (0-1)

// Ping system settings
#define MAX_PINGS 5
#define PING_DURATION 5.0
#define PING_COOLDOWN 3.0

//╰─..★.───────────────────────────────────╯


public Plugin myinfo = {
name = "TF2 Team Radar",
author = "vexx-sm",
description = "Adds a basic team-only radar to Team Fortress 2.",
version = "1.1",
version = "1.2",
url = "https://github.com/vexx-sm/tf2-team-radar"
};

Handle g_hUpdateTimer;
bool g_bRadarEnabled[MAXPLAYERS + 1] = {true, ...};
float g_PingPositions[MAXPLAYERS + 1][MAX_PINGS][3];
float g_PingTimes[MAXPLAYERS + 1][MAX_PINGS];
float g_LastPingTime[MAXPLAYERS + 1];

public void OnPluginStart() {
g_hUpdateTimer = CreateTimer(UPDATE_INTERVAL, Timer_UpdateMiniMap, _, TIMER_REPEAT);
RegConsoleCmd("sm_radar", Command_ToggleRadar, "Toggle the radar on/off");
RegConsoleCmd("sm_mapping", Command_Ping, "Ping the location you're looking at.");
}

public void OnPluginEnd() {
Expand All @@ -54,6 +71,59 @@ public Action Command_ToggleRadar(int client, int args) {
return Plugin_Handled;
}

public Action Command_Ping(int client, int args)
{
if (!IsValidClient(client) || !IsPlayerAlive(client))
return Plugin_Handled;

float currentTime = GetGameTime();
if (currentTime - g_LastPingTime[client] < PING_COOLDOWN)
{
PrintToChat(client, "You must wait before pinging again.");
return Plugin_Handled;
}

float eyePos[3], eyeAng[3], endPos[3];
GetClientEyePosition(client, eyePos);
GetClientEyeAngles(client, eyeAng);

TR_TraceRayFilter(eyePos, eyeAng, MASK_SOLID, RayType_Infinite, TraceEntityFilterPlayer, client);

if (TR_DidHit())
{
TR_GetEndPosition(endPos);

// Find the oldest ping slot and replace it
int oldestIndex = 0;
float oldestTime = g_PingTimes[client][0];
for (int i = 1; i < MAX_PINGS; i++)
{
if (g_PingTimes[client][i] < oldestTime)
{
oldestIndex = i;
oldestTime = g_PingTimes[client][i];
}
}

g_PingPositions[client][oldestIndex] = endPos;
g_PingTimes[client][oldestIndex] = currentTime;
g_LastPingTime[client] = currentTime;

PrintToTeam(client, "Teammate has pinged a location!");
}
else
{
PrintToChat(client, "Couldn't find a valid position to ping.");
}

return Plugin_Handled;
}

public bool TraceEntityFilterPlayer(int entity, int contentsMask, any data)
{
return entity != data;
}

public Action Timer_UpdateMiniMap(Handle timer) {
for (int i = 1; i <= MaxClients; i++) {
if (IsValidClient(i) && IsClientInGame(i) && g_bRadarEnabled[i]) {
Expand All @@ -74,13 +144,15 @@ void UpdateMiniMap(int client) {
float y = RADAR_Y;
float w = RADAR_SCALE;
float h = RADAR_SCALE;
float centerX = x + (w / 2);
float centerY = y + (h / 2);

DrawPanel(client, x, y);

int selfColor[4] = COLOR_SELF;
DrawArrow(client, centerX, centerY, selfColor);

// Draw player's arrow in the center
float centerX = x + (w / 2);
float centerY = y + (h / 2);
DrawArrow(client, centerX, centerY, COLOR_SELF);
float currentTime = GetGameTime();

for (int i = 1; i <= MaxClients; i++) {
if (i != client && IsValidClient(i) && IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == GetClientTeam(client)) {
Expand Down Expand Up @@ -110,8 +182,39 @@ void UpdateMiniMap(int client) {
}
}
}

// Draw pings
int pingColor[4] = COLOR_PING;
for (int i = 1; i <= MaxClients; i++)
{
if (IsValidClient(i) && IsClientInGame(i) && GetClientTeam(i) == GetClientTeam(client))
{
for (int j = 0; j < MAX_PINGS; j++)
{
if (currentTime - g_PingTimes[i][j] < PING_DURATION)
{
float pingPos[3], relativePos[3];
pingPos = g_PingPositions[i][j];
SubtractVectors(pingPos, playerPos, relativePos);

float angle = ThisDegToRad(-playerAng[1] - 270);
float rotatedX = relativePos[0] * Cosine(angle) - relativePos[1] * Sine(angle);
float rotatedY = relativePos[0] * Sine(angle) + relativePos[1] * Cosine(angle);

float pingX = centerX + (rotatedX / RADAR_SIZE) * w;
float pingY = centerY - (rotatedY / RADAR_SIZE) * h;

if (pingX >= x && pingX <= x + w && pingY >= y && pingY <= y + h)
{
DrawPing(client, pingX, pingY, pingColor);
}
}
}
}
}
}


void DrawPanel(int client, float x, float y) {
Handle hud = CreateHudSynchronizer();
SetHudTextParams(x, y, UPDATE_INTERVAL + 0.1, 255, 255, 255, 0);
Expand Down Expand Up @@ -142,6 +245,27 @@ void DrawArrow(int client, float x, float y, int color[4]) {
delete hud;
}

void DrawPing(int client, float x, float y, int color[4])
{
Handle hud = CreateHudSynchronizer();
SetHudTextParams(x, y, UPDATE_INTERVAL + 0.1, color[0], color[1], color[2], color[3]);
ShowSyncHudText(client, hud, "!");
delete hud;
}


void PrintToTeam(int client, const char[] message)
{
int team = GetClientTeam(client);
for (int i = 1; i <= MaxClients; i++)
{
if (IsValidClient(i) && IsClientInGame(i) && GetClientTeam(i) == team)
{
PrintToChat(i, message);
}
}
}

bool IsValidClient(int client) {
return (client > 0 && client <= MaxClients && IsClientConnected(client));
}
Expand Down

0 comments on commit 2e7a2f2

Please sign in to comment.