Skip to content

Commit

Permalink
VX_TRACKER: Add r_tracker_inconsole_colored_weapon (#893)
Browse files Browse the repository at this point in the history
* VX_TRACKER: Add r_tracker_inconsole_colored_weapon

* Add RGBToString declaration

* Include utils.h in fragstats.c
  • Loading branch information
osm committed Feb 25, 2024
1 parent 39a0c62 commit 37b8530
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 32 deletions.
17 changes: 17 additions & 0 deletions help_variables.json
Original file line number Diff line number Diff line change
Expand Up @@ -16802,6 +16802,23 @@
}
]
},
"r_tracker_inconsole_colored_weapon": {
"default": "0",
"desc": "Use colored weapon string in death messages",
"group-id": "40",
"remarks": "The colors will be selected from r_tracker_color_good, r_tracker_color_bad, r_tracker_color_myfrag and r_tracker_color_fragonme",
"type": "enum",
"values": [
{
"description": "Weapon text will not be colored",
"name": "0"
},
{
"description": "Weapon text will be colored",
"name": "1"
}
]
},
"r_tracker_messages": {
"default": "20",
"desc": "Maximum number of custom frag messages to be displayed in extra frag messages window.",
Expand Down
136 changes: 136 additions & 0 deletions src/fragstats.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h"
#include "vx_stuff.h"
#include "vx_tracker.h"
#include "utils.h"

cvar_t cl_parsefrags = {"cl_parseFrags", "1"};
cvar_t cl_showFragsMessages = {"con_fragmessages", "1"};
Expand All @@ -32,6 +33,26 @@ cvar_t cl_useimagesinfraglog = {"cl_useimagesinfraglog", "0"};
#define FUH_FRAGFILE_VERSION_1_00 "1.00" /* for compatibility with fuh */
#define FRAGFILE_VERSION_1_00 "ezquake-1.00" /* fuh suggest such format */

// The following values are fetched from nquake.pk3 and
// misc/fragfile/fragfile.dat respectively.
#define EZQUAKE_SG_QUAD "&c06fQ&r-sg"
#define EZQUAKE_SSG_QUAD "&c06fQ&r-ssg"
#define EZQUAKE_SNG_QUAD "&c06fQ&r-sng"
#define EZQUAKE_RL_QUAD "&c06fQ&r-rl"
#define EZQUAKE_LG_QUAD "&c06fQ&r-lg"
#define EZQUAKE_QUAD "&c06fQ&r-"
#define NQUAKE_SG_QUAD "sg &c06fQ&r"
#define NQUAKE_SSG_QUAD "ssg &c06fQ&r"
#define NQUAKE_SNG_QUAD "sng &c06fQ&r"
#define NQUAKE_RL_QUAD "rl &c06fQ&r"
#define NQUAKE_LG_QUAD "lg &c06fQ&r"
#define NQUAKE_QUAD " &c06fQ&r"
#define WEAPON_CLASS_SG "sg"
#define WEAPON_CLASS_SSG "ssg"
#define WEAPON_CLASS_SNG "sng"
#define WEAPON_CLASS_RL "rl"
#define WEAPON_CLASS_LG "lg"

void Update_FlagStatus(int player_num, char *team, qbool got_flag);

typedef enum msgtype_s {
Expand All @@ -55,6 +76,9 @@ typedef struct wclass_s {
char *name;
char *shortname;
char *imagename;
char *colorname;
int colorname_rgb_offset;
qbool colorname_skip;
} wclass_t;

typedef struct fragmsg_s {
Expand Down Expand Up @@ -158,6 +182,9 @@ static void InitFragDefs(qbool restart)
Q_free(wclasses[i].name);
Q_free(wclasses[i].shortname);
Q_free(wclasses[i].imagename);

if (wclasses[i].colorname != NULL)
Q_free(wclasses[i].colorname);
}

memset(&fragdefs, 0, sizeof(fragdefs));
Expand Down Expand Up @@ -302,6 +329,10 @@ static void LoadFragFile(char *filename, qbool quiet)
wclasses[num_wclasses].name = Q_strdup(Cmd_Argv(3));
wclasses[num_wclasses].shortname = Q_strdup(Cmd_Argv(4));
wclasses[num_wclasses].imagename = Q_strdup(Cmd_Argv(5));
wclasses[num_wclasses].colorname = NULL;
wclasses[num_wclasses].colorname_rgb_offset = -1;
wclasses[num_wclasses].colorname_skip = false;

num_wclasses++;
} else if ( !strcasecmp(Cmd_Argv(1), "OBITUARY") || !strcasecmp(Cmd_Argv(1), "OBIT")) {

Expand Down Expand Up @@ -845,6 +876,111 @@ char *GetWeaponName (int num)
return "Unknown";
}

static void InitColoredWeapon (int num, const byte *color)
{
char *original_weapon, *weapon, *prefix = NULL, *suffix = NULL;
int original_weapon_len = 0, weapon_len = 0, prefix_len = 0;

original_weapon = GetWeaponName(num);
original_weapon_len = strlen(original_weapon);

// Check whether or not the original_weapon is a known string that we
// need to handle in a specific way.
//
// The code supports the ezquake and nquake fragfile.dat values for quad
// related weapons.
//
// We store the offset to 'R' in the "c&RGB" string so that we easily
// can overwrite the RGB value later on.
if (strcmp(original_weapon, EZQUAKE_SG_QUAD) == 0) {
weapon = WEAPON_CLASS_SG;
prefix = EZQUAKE_QUAD;
wclasses[num].colorname_rgb_offset = 11;
} else if (strcmp(original_weapon, EZQUAKE_SSG_QUAD) == 0) {
weapon = WEAPON_CLASS_SSG;
prefix = EZQUAKE_QUAD;
wclasses[num].colorname_rgb_offset = 11;
} else if (strcmp(original_weapon, EZQUAKE_SNG_QUAD) == 0) {
weapon = WEAPON_CLASS_SNG;
prefix = EZQUAKE_QUAD;
wclasses[num].colorname_rgb_offset = 11;
} else if (strcmp(original_weapon, EZQUAKE_RL_QUAD) == 0) {
weapon = WEAPON_CLASS_RL;
prefix = EZQUAKE_QUAD;
wclasses[num].colorname_rgb_offset = 11;
} else if (strcmp(original_weapon, EZQUAKE_LG_QUAD) == 0) {
weapon = WEAPON_CLASS_LG;
prefix = EZQUAKE_QUAD;
wclasses[num].colorname_rgb_offset = 11;
} else if (strcmp(original_weapon, NQUAKE_SG_QUAD) == 0) {
weapon = WEAPON_CLASS_SG;
suffix = NQUAKE_QUAD;
wclasses[num].colorname_rgb_offset = 2;
} else if (strcmp(original_weapon, NQUAKE_SSG_QUAD) == 0) {
weapon = WEAPON_CLASS_SSG;
suffix = NQUAKE_QUAD;
wclasses[num].colorname_rgb_offset = 2;
} else if (strcmp(original_weapon, NQUAKE_SNG_QUAD) == 0) {
weapon = WEAPON_CLASS_SNG;
suffix = NQUAKE_QUAD;
wclasses[num].colorname_rgb_offset = 2;
} else if (strcmp(original_weapon, NQUAKE_RL_QUAD) == 0) {
weapon = WEAPON_CLASS_RL;
suffix = NQUAKE_QUAD;
wclasses[num].colorname_rgb_offset = 2;
} else if (strcmp(original_weapon, NQUAKE_LG_QUAD) == 0) {
weapon = WEAPON_CLASS_LG;
suffix = NQUAKE_QUAD;
wclasses[num].colorname_rgb_offset = 2;
} else if ((strstr(original_weapon, "&c")) == NULL) {
// No fancy formatting is applied to the weapon.
weapon = original_weapon;
wclasses[num].colorname_rgb_offset = 2;
} else {
// This case covers an unknown name that contains a "&c"
// sequence. These weapon strings will be ignored.
wclasses[num].colorname_skip = true;
return;
}

// Allocate and initialize the memory for the colored weapon string.
// We'll use the original weapon length + 8 additional bytes. The 8
// bytes are for "&cRGB", "&r" and a trailing '\0' character.
wclasses[num].colorname = Q_malloc(original_weapon_len + 8);
memset(wclasses[num].colorname, 0, original_weapon_len + 8);

if (prefix != NULL) {
prefix_len = strlen(prefix);
memcpy(wclasses[num].colorname, prefix, prefix_len);
}

weapon_len = strlen(weapon);
memcpy(wclasses[num].colorname + prefix_len, "&cRGB", 5);
memcpy(wclasses[num].colorname + prefix_len + 5, weapon, weapon_len);
memcpy(wclasses[num].colorname + prefix_len + 5 + weapon_len, "&r", 2);

if (suffix != NULL) {
memcpy(wclasses[num].colorname + prefix_len + 5 + weapon_len + 2, suffix, strlen(suffix));
}
}

char *GetColoredWeaponName (int num, const byte *color)
{
char rgb[3];

if (!wclasses[num].colorname_skip && wclasses[num].colorname == NULL)
InitColoredWeapon(num, color);

if (wclasses[num].colorname_skip)
return GetWeaponName(num);

// Convert color to string and overwrite the RGB values.
RGBToString(color, rgb);
memcpy(wclasses[num].colorname + wclasses[num].colorname_rgb_offset, rgb, 3);

return wclasses[num].colorname;
}

const char* GetWeaponImageName(int num)
{
if (wclasses[num].imagename && wclasses[num].imagename[0]) {
Expand Down
6 changes: 6 additions & 0 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,12 @@ byte* StringToRGB(char *s)
return rgb;
}

void RGBToString(const byte *rgb, char *s) {
s[0] = '0' + (rgb[0] / 255) * 9.0f;
s[1] = '0' + (rgb[1] / 255) * 9.0f;
s[2] = '0' + (rgb[2] / 255) * 9.0f;
}

/*
float f[10];
int size = sizeof(f)/sizeof(f[0]);
Expand Down
1 change: 1 addition & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ char *SecondsToHourString(int time);
char *ColorNameToRGBString(char *color_name);
byte *StringToRGB(char *s);
int StringToRGB_W(char *s, byte *rgb);
void RGBToString(const byte *rgb, char *s);
void TrackerStringToRGB_W(const char *s, byte *rgb);
int ParseFloats(char *s, float *f, int *f_size);

Expand Down
71 changes: 39 additions & 32 deletions src/vx_tracker.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,37 +90,38 @@ static int max_active_tracks = 0;
static void VXSCR_DrawTrackerString(float x_pos, float y_pos, float width, int name_width, qbool proportional, float scale, float image_scale, qbool align_right);
static void OnChange_TrackerNameWidth(cvar_t* var, char* value, qbool* cancel);

cvar_t r_tracker = {"r_tracker", "1"};
cvar_t amf_tracker_flags = {"r_tracker_flags", "0"};
cvar_t amf_tracker_frags = {"r_tracker_frags", "1"};
cvar_t amf_tracker_streaks = {"r_tracker_streaks", "0"};
cvar_t amf_tracker_time = {"r_tracker_time", "4"};
cvar_t amf_tracker_messages = {"r_tracker_messages", "20"};
static cvar_t amf_tracker_pickups = {"r_tracker_pickups", "0"};
cvar_t amf_tracker_align_right = {"r_tracker_align_right", "1"};
cvar_t amf_tracker_scale = {"r_tracker_scale", "1"};
static cvar_t amf_tracker_inconsole = {"r_tracker_inconsole", "0"};
static cvar_t amf_tracker_x = {"r_tracker_x", "0"};
static cvar_t amf_tracker_y = {"r_tracker_y", "0"};
static cvar_t amf_tracker_frame_color = {"r_tracker_frame_color", "0 0 0 0", CVAR_COLOR};
static cvar_t amf_tracker_images_scale = {"r_tracker_images_scale", "1"};
static cvar_t amf_tracker_color_good = {"r_tracker_color_good", "090", CVAR_TRACKERCOLOR }; // good news
static cvar_t amf_tracker_color_bad = {"r_tracker_color_bad", "900", CVAR_TRACKERCOLOR }; // bad news
static cvar_t amf_tracker_color_tkgood = {"r_tracker_color_tkgood", "990", CVAR_TRACKERCOLOR }; // team kill, not on ur team
static cvar_t amf_tracker_color_tkbad = {"r_tracker_color_tkbad", "009", CVAR_TRACKERCOLOR }; // team kill, on ur team
static cvar_t amf_tracker_color_myfrag = {"r_tracker_color_myfrag", "090", CVAR_TRACKERCOLOR }; // use this color for frag which u done
static cvar_t amf_tracker_color_fragonme = {"r_tracker_color_fragonme", "900", CVAR_TRACKERCOLOR }; // use this color when u frag someone
static cvar_t amf_tracker_color_suicide = {"r_tracker_color_suicide", "900", CVAR_TRACKERCOLOR }; // use this color when u suicides
static cvar_t amf_tracker_string_suicides = {"r_tracker_string_suicides", " (suicides)"};
static cvar_t amf_tracker_string_died = {"r_tracker_string_died", " (died)"};
static cvar_t amf_tracker_string_teammate = {"r_tracker_string_teammate", "teammate"};
static cvar_t amf_tracker_string_enemy = {"r_tracker_string_enemy", "enemy"};
static cvar_t amf_tracker_string_inconsole_prefix = {"r_tracker_string_inconsole_prefix", ""};
static cvar_t amf_tracker_name_width = {"r_tracker_name_width", "0", 0, OnChange_TrackerNameWidth};
static cvar_t amf_tracker_own_frag_prefix = {"r_tracker_own_frag_prefix", "You fragged "};
static cvar_t amf_tracker_positive_enemy_suicide = {"r_tracker_positive_enemy_suicide", "0"}; // Medar wanted it to be customizable
static cvar_t amf_tracker_positive_enemy_vs_enemy = {"r_tracker_positive_enemy_vs_enemy", "0"};
static cvar_t amf_tracker_proportional = {"r_tracker_proportional", "0"};
cvar_t r_tracker = {"r_tracker", "1"};
cvar_t amf_tracker_flags = {"r_tracker_flags", "0"};
cvar_t amf_tracker_frags = {"r_tracker_frags", "1"};
cvar_t amf_tracker_streaks = {"r_tracker_streaks", "0"};
cvar_t amf_tracker_time = {"r_tracker_time", "4"};
cvar_t amf_tracker_messages = {"r_tracker_messages", "20"};
static cvar_t amf_tracker_pickups = {"r_tracker_pickups", "0"};
cvar_t amf_tracker_align_right = {"r_tracker_align_right", "1"};
cvar_t amf_tracker_scale = {"r_tracker_scale", "1"};
static cvar_t amf_tracker_inconsole = {"r_tracker_inconsole", "0"};
static cvar_t amf_tracker_inconsole_colored_weapon = {"r_tracker_inconsole_colored_weapon", "0"};
static cvar_t amf_tracker_x = {"r_tracker_x", "0"};
static cvar_t amf_tracker_y = {"r_tracker_y", "0"};
static cvar_t amf_tracker_frame_color = {"r_tracker_frame_color", "0 0 0 0", CVAR_COLOR};
static cvar_t amf_tracker_images_scale = {"r_tracker_images_scale", "1"};
static cvar_t amf_tracker_color_good = {"r_tracker_color_good", "090", CVAR_TRACKERCOLOR }; // good news
static cvar_t amf_tracker_color_bad = {"r_tracker_color_bad", "900", CVAR_TRACKERCOLOR }; // bad news
static cvar_t amf_tracker_color_tkgood = {"r_tracker_color_tkgood", "990", CVAR_TRACKERCOLOR }; // team kill, not on ur team
static cvar_t amf_tracker_color_tkbad = {"r_tracker_color_tkbad", "009", CVAR_TRACKERCOLOR }; // team kill, on ur team
static cvar_t amf_tracker_color_myfrag = {"r_tracker_color_myfrag", "090", CVAR_TRACKERCOLOR }; // use this color for frag which u done
static cvar_t amf_tracker_color_fragonme = {"r_tracker_color_fragonme", "900", CVAR_TRACKERCOLOR }; // use this color when u frag someone
static cvar_t amf_tracker_color_suicide = {"r_tracker_color_suicide", "900", CVAR_TRACKERCOLOR }; // use this color when u suicides
static cvar_t amf_tracker_string_suicides = {"r_tracker_string_suicides", " (suicides)"};
static cvar_t amf_tracker_string_died = {"r_tracker_string_died", " (died)"};
static cvar_t amf_tracker_string_teammate = {"r_tracker_string_teammate", "teammate"};
static cvar_t amf_tracker_string_enemy = {"r_tracker_string_enemy", "enemy"};
static cvar_t amf_tracker_string_inconsole_prefix = {"r_tracker_string_inconsole_prefix", ""};
static cvar_t amf_tracker_name_width = {"r_tracker_name_width", "0", 0, OnChange_TrackerNameWidth};
static cvar_t amf_tracker_own_frag_prefix = {"r_tracker_own_frag_prefix", "You fragged "};
static cvar_t amf_tracker_positive_enemy_suicide = {"r_tracker_positive_enemy_suicide", "0"}; // Medar wanted it to be customizable
static cvar_t amf_tracker_positive_enemy_vs_enemy = {"r_tracker_positive_enemy_vs_enemy", "0"};
static cvar_t amf_tracker_proportional = {"r_tracker_proportional", "0"};

#define MAX_TRACKERMESSAGES 30
#define MAX_TRACKER_MSG_LEN 500
Expand Down Expand Up @@ -189,6 +190,7 @@ void InitTracker(void)
Cvar_Register(&amf_tracker_streaks);
Cvar_Register(&amf_tracker_messages);
Cvar_Register(&amf_tracker_inconsole);
Cvar_Register(&amf_tracker_inconsole_colored_weapon);
Cvar_Register(&amf_tracker_time);
Cvar_Register(&amf_tracker_align_right);
Cvar_Register(&amf_tracker_x);
Expand Down Expand Up @@ -532,12 +534,17 @@ static void VX_TrackerAddWeaponTextSplit(const char* lhs_text, int weapon, const
{
trackmsg_t* msg;
int i;
char *weapon_text;

if (((!lhs_text || !lhs_text[0]) && (!rhs_text || !rhs_text[0])) || CL_Demo_SkipMessage(true)) {
return;
}

if (!VX_TrackerStringPrintSegments(lhs_text, GetWeaponName(weapon), rhs_text, NULL)) {
weapon_text = amf_tracker_inconsole_colored_weapon.integer == 0
? GetWeaponName(weapon)
: GetColoredWeaponName(weapon, weapon_color);

if (!VX_TrackerStringPrintSegments(lhs_text, weapon_text, rhs_text, NULL)) {
return;
}

Expand Down
1 change: 1 addition & 0 deletions src/vx_tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ void VX_TrackerFlagDrop(int count);
void VX_TrackerFlagCapture(int count);

char* GetWeaponName(int num);
char* GetColoredWeaponName(int num, const byte *color);
const char* GetWeaponImageName(int num);
const char* GetWeaponTextName(int num);
void VX_TrackerThink(void);
Expand Down

0 comments on commit 37b8530

Please sign in to comment.