From 189f16fcc45e8190bcc0b134f3faf20fc2e7567c Mon Sep 17 00:00:00 2001 From: OciXCrom Date: Thu, 30 Aug 2018 18:41:49 +0200 Subject: [PATCH 1/5] Add stat constants in plugins (#522) * Add stat constants in plugins * Add missing include in dodstats.sma * Fix misplaced HIT_RIGHTLEG constant --- plugins/cstrike/csstats.sma | 4 +- plugins/cstrike/stats_logging.sma | 6 +- plugins/cstrike/statsx.sma | 173 ++++++++++++++---------------- plugins/dod/dodstats.sma | 11 +- plugins/dod/stats.sma | 66 ++++++------ plugins/dod/stats_logging.sma | 6 +- plugins/tfc/stats.sma | 50 ++++----- plugins/tfc/stats_logging.sma | 6 +- plugins/tfc/tfcstats.sma | 4 +- plugins/ts/stats.sma | 50 ++++----- plugins/ts/stats_logging.sma | 10 +- plugins/ts/tsstats.sma | 4 +- 12 files changed, 191 insertions(+), 199 deletions(-) diff --git a/plugins/cstrike/csstats.sma b/plugins/cstrike/csstats.sma index 5c5cf4f2..904b68ac 100755 --- a/plugins/cstrike/csstats.sma +++ b/plugins/cstrike/csstats.sma @@ -33,5 +33,5 @@ * Returning cellmin as value in get_score function * makes that rank won't be saved. */ -public get_score(stats[11], body[8]) - return stats[0] - stats[1] - stats[3] // kills - deaths - teamkills +public get_score(stats[11], body[MAX_BODYHITS]) + return stats[STATSX_KILLS] - stats[STATSX_DEATHS] - stats[STATSX_TEAMKILLS] // kills - deaths - teamkills diff --git a/plugins/cstrike/stats_logging.sma b/plugins/cstrike/stats_logging.sma index 02c5bbeb..44241512 100755 --- a/plugins/cstrike/stats_logging.sma +++ b/plugins/cstrike/stats_logging.sma @@ -37,7 +37,7 @@ public client_disconnected(id) remove_task(id) - new szTeam[16], szName[MAX_NAME_LENGTH], szAuthid[32], iStats[8], iHits[8], szWeapon[24] + new szTeam[16], szName[MAX_NAME_LENGTH], szAuthid[32], iStats[STATSX_MAX_STATS], iHits[MAX_BODYHITS], szWeapon[24] new iUserid = get_user_userid(id) new _max = xmod_get_maxweapons() @@ -52,9 +52,9 @@ public client_disconnected(id) xmod_get_wpnname(i, szWeapon, charsmax(szWeapon)) log_message("^"%s<%d><%s><%s>^" triggered ^"weaponstats^" (weapon ^"%s^") (shots ^"%d^") (hits ^"%d^") (kills ^"%d^") (headshots ^"%d^") (tks ^"%d^") (damage ^"%d^") (deaths ^"%d^")", - szName, iUserid, szAuthid, szTeam, szWeapon, iStats[4], iStats[5], iStats[0], iStats[2], iStats[3], iStats[6], iStats[1]) + szName, iUserid, szAuthid, szTeam, szWeapon, iStats[STATSX_SHOTS], iStats[STATSX_HITS], iStats[STATSX_KILLS], iStats[STATSX_HEADSHOTS], iStats[STATSX_TEAMKILLS], iStats[STATSX_DAMAGE], iStats[STATSX_DEATHS]) log_message("^"%s<%d><%s><%s>^" triggered ^"weaponstats2^" (weapon ^"%s^") (head ^"%d^") (chest ^"%d^") (stomach ^"%d^") (leftarm ^"%d^") (rightarm ^"%d^") (leftleg ^"%d^") (rightleg ^"%d^")", - szName, iUserid, szAuthid, szTeam, szWeapon, iHits[1], iHits[2], iHits[3], iHits[4], iHits[5], iHits[6], iHits[7]) + szName, iUserid, szAuthid, szTeam, szWeapon, iHits[HIT_HEAD], iHits[HIT_CHEST], iHits[HIT_STOMACH], iHits[HIT_LEFTARM], iHits[HIT_RIGHTARM], iHits[HIT_LEFTLEG], iHits[HIT_RIGHTLEG]) } } diff --git a/plugins/cstrike/statsx.sma b/plugins/cstrike/statsx.sma index bfe8e433..f8a2df71 100755 --- a/plugins/cstrike/statsx.sma +++ b/plugins/cstrike/statsx.sma @@ -78,17 +78,8 @@ public SpecRankInfo = 0 // displays rank info when spectating #define MAX_TEXT_LENGTH 255 #define MAX_BUFFER_LENGTH 2047 -// User stats parms id -#define STATS_KILLS 0 -#define STATS_DEATHS 1 -#define STATS_HS 2 -#define STATS_TKS 3 -#define STATS_SHOTS 4 -#define STATS_HITS 5 -#define STATS_DAMAGE 6 - // Global player flags. -new BODY_PART[8][] = +new BODY_PART[MAX_BODYHITS][] = { "WHOLEBODY", "HEAD", @@ -140,14 +131,14 @@ new g_pHudFreezeLimit = 0 new Float:g_fStartGame = 0.0 new g_izTeamScore[MAX_TEAMS] = {0, ...} new g_izTeamEventScore[MAX_TEAMS] = {0, ...} -new g_izTeamRndStats[MAX_TEAMS][8] -new g_izTeamGameStats[MAX_TEAMS][8] +new g_izTeamRndStats[MAX_TEAMS][STATSX_MAX_STATS] +new g_izTeamGameStats[MAX_TEAMS][STATSX_MAX_STATS] new g_izUserUserID[MAX_PLAYERS + 1] = {0, ...} new g_izUserAttackerDistance[MAX_PLAYERS + 1] = {0, ...} new g_izUserVictimDistance[MAX_PLAYERS + 1][MAX_PLAYERS + 1] new g_izUserRndName[MAX_PLAYERS + 1][MAX_NAME_LENGTH] -new g_izUserRndStats[MAX_PLAYERS + 1][8] -new g_izUserGameStats[MAX_PLAYERS + 1][8] +new g_izUserRndStats[MAX_PLAYERS + 1][STATSX_MAX_STATS] +new g_izUserGameStats[MAX_PLAYERS + 1][STATSX_MAX_STATS] // Common buffer to improve performance, as Small always zero-initializes all vars new g_sBuffer[MAX_BUFFER_LENGTH + 1] = "" @@ -291,14 +282,14 @@ public cmdHudTest(id) #endif // Stats formulas -Float:accuracy(izStats[8]) +Float:accuracy(izStats[STATSX_MAX_STATS]) { - return izStats[STATS_SHOTS] ? (100.0 * float(izStats[STATS_HITS]) / float(izStats[STATS_SHOTS])) : (0.0); + return izStats[STATSX_SHOTS] ? (100.0 * float(izStats[STATSX_HITS]) / float(izStats[STATSX_SHOTS])) : (0.0); } -Float:effec(izStats[8]) +Float:effec(izStats[STATSX_MAX_STATS]) { - return izStats[STATS_KILLS] ? (100.0 * float(izStats[STATS_KILLS]) / float(izStats[STATS_KILLS] + izStats[STATS_DEATHS])) : (0.0); + return izStats[STATSX_KILLS] ? (100.0 * float(izStats[STATSX_KILLS]) / float(izStats[STATSX_KILLS] + izStats[STATSX_DEATHS])) : (0.0); } // Distance formula (metric) @@ -332,7 +323,7 @@ get_config_cvars() // Get and format attackers header and list. get_attackers(id, sBuffer[MAX_BUFFER_LENGTH + 1]) { - new izStats[8], izBody[8] + new izStats[STATSX_MAX_STATS], izBody[MAX_BODYHITS] new iAttacker new iFound, iLen @@ -342,13 +333,13 @@ get_attackers(id, sBuffer[MAX_BUFFER_LENGTH + 1]) // Get and format header. Add killing attacker statistics if user is dead. // Make sure shots is greater than zero or division by zero will occur. // To print a '%', 4 of them must done in a row. - izStats[STATS_SHOTS] = 0 + izStats[STATSX_SHOTS] = 0 iAttacker = g_izKilled[id][KILLED_KILLER_ID] if (iAttacker) get_user_astats(id, iAttacker, izStats, izBody) - if (izStats[STATS_SHOTS] && ShowFullStats) + if (izStats[STATSX_SHOTS] && ShowFullStats) { get_user_name(iAttacker, t_sName, charsmax(t_sName)) iLen = formatex(sBuffer, charsmax(sBuffer), "%L -- %s -- %0.2f%% %L:^n", id, "ATTACKERS", t_sName, accuracy(izStats), id, "ACC") @@ -364,20 +355,20 @@ get_attackers(id, sBuffer[MAX_BUFFER_LENGTH + 1]) iFound = 1 get_user_name(iAttacker, t_sName, charsmax(t_sName)) - if (izStats[STATS_KILLS]) + if (izStats[STATSX_KILLS]) { if (!ShowDistHS) - iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L / %s^n", t_sName, izStats[STATS_HITS], id, "HIT_S", - izStats[STATS_DAMAGE], id, "DMG", t_sWpn) - else if (izStats[STATS_HS]) - iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L / %s / %0.0f m / HS^n", t_sName, izStats[STATS_HITS], id, "HIT_S", - izStats[STATS_DAMAGE], id, "DMG", t_sWpn, distance(g_izUserAttackerDistance[id])) + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L / %s^n", t_sName, izStats[STATSX_HITS], id, "HIT_S", + izStats[STATSX_DAMAGE], id, "DMG", t_sWpn) + else if (izStats[STATSX_HEADSHOTS]) + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L / %s / %0.0f m / HS^n", t_sName, izStats[STATSX_HITS], id, "HIT_S", + izStats[STATSX_DAMAGE], id, "DMG", t_sWpn, distance(g_izUserAttackerDistance[id])) else - iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L / %s / %0.0f m^n", t_sName, izStats[STATS_HITS], id, "HIT_S", - izStats[STATS_DAMAGE], id, "DMG", t_sWpn, distance(g_izUserAttackerDistance[id])) + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L / %s / %0.0f m^n", t_sName, izStats[STATSX_HITS], id, "HIT_S", + izStats[STATSX_DAMAGE], id, "DMG", t_sWpn, distance(g_izUserAttackerDistance[id])) } else - iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L^n", t_sName, izStats[STATS_HITS], id, "HIT_S", izStats[STATS_DAMAGE], id, "DMG") + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L^n", t_sName, izStats[STATSX_HITS], id, "HIT_S", izStats[STATSX_DAMAGE], id, "DMG") } } @@ -390,7 +381,7 @@ get_attackers(id, sBuffer[MAX_BUFFER_LENGTH + 1]) // Get and format victims header and list get_victims(id, sBuffer[MAX_BUFFER_LENGTH + 1]) { - new izStats[8], izBody[8] + new izStats[STATSX_MAX_STATS], izBody[MAX_BODYHITS] new iVictim new iFound, iLen @@ -400,10 +391,10 @@ get_victims(id, sBuffer[MAX_BUFFER_LENGTH + 1]) // Get and format header. // Make sure shots is greater than zero or division by zero will occur. // To print a '%', 4 of them must done in a row. - izStats[STATS_SHOTS] = 0 + izStats[STATSX_SHOTS] = 0 get_user_vstats(id, 0, izStats, izBody) - if (izStats[STATS_SHOTS]) + if (izStats[STATSX_SHOTS]) iLen = formatex(sBuffer, charsmax(sBuffer), "%L -- %0.2f%% %L:^n", id, "VICTIMS", accuracy(izStats), id, "ACC") else iLen = formatex(sBuffer, charsmax(sBuffer), "%L:^n", id, "VICTIMS") @@ -415,20 +406,20 @@ get_victims(id, sBuffer[MAX_BUFFER_LENGTH + 1]) iFound = 1 get_user_name(iVictim, t_sName, charsmax(t_sName)) - if (izStats[STATS_DEATHS]) + if (izStats[STATSX_DEATHS]) { if (!ShowDistHS) - iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L / %s^n", t_sName, izStats[STATS_HITS], id, "HIT_S", - izStats[STATS_DAMAGE], id, "DMG", t_sWpn) - else if (izStats[STATS_HS]) - iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L / %s / %0.0f m / HS^n", t_sName, izStats[STATS_HITS], id, "HIT_S", - izStats[STATS_DAMAGE], id, "DMG", t_sWpn, distance(g_izUserVictimDistance[id][iVictim])) + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L / %s^n", t_sName, izStats[STATSX_HITS], id, "HIT_S", + izStats[STATSX_DAMAGE], id, "DMG", t_sWpn) + else if (izStats[STATSX_HEADSHOTS]) + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L / %s / %0.0f m / HS^n", t_sName, izStats[STATSX_HITS], id, "HIT_S", + izStats[STATSX_DAMAGE], id, "DMG", t_sWpn, distance(g_izUserVictimDistance[id][iVictim])) else - iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L / %s / %0.0f m^n", t_sName, izStats[STATS_HITS], id, "HIT_S", - izStats[STATS_DAMAGE], id, "DMG", t_sWpn, distance(g_izUserVictimDistance[id][iVictim])) + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L / %s / %0.0f m^n", t_sName, izStats[STATSX_HITS], id, "HIT_S", + izStats[STATSX_DAMAGE], id, "DMG", t_sWpn, distance(g_izUserVictimDistance[id][iVictim])) } else - iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L^n", t_sName, izStats[STATS_HITS], id, "HIT_S", izStats[STATS_DAMAGE], id, "DMG") + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%s -- %d %L / %d %L^n", t_sName, izStats[STATSX_HITS], id, "HIT_S", izStats[STATSX_DAMAGE], id, "DMG") } } @@ -448,23 +439,23 @@ get_kill_info(id, iKiller, sBuffer[MAX_BUFFER_LENGTH + 1]) if (iKiller && iKiller != id) { - new izAStats[8], izABody[8], izVStats[8], iaVBody[8] + new izAStats[STATSX_MAX_STATS], izABody[MAX_BODYHITS], izVStats[STATSX_MAX_STATS], iaVBody[MAX_BODYHITS] iFound = 1 get_user_name(iKiller, t_sName, charsmax(t_sName)) - izAStats[STATS_HITS] = 0 - izAStats[STATS_DAMAGE] = 0 + izAStats[STATSX_HITS] = 0 + izAStats[STATSX_DAMAGE] = 0 t_sWpn[0] = 0 get_user_astats(id, iKiller, izAStats, izABody, t_sWpn, charsmax(t_sWpn)) - izVStats[STATS_HITS] = 0 - izVStats[STATS_DAMAGE] = 0 + izVStats[STATSX_HITS] = 0 + izVStats[STATSX_DAMAGE] = 0 get_user_vstats(id, iKiller, izVStats, iaVBody) iLen = formatex(sBuffer, charsmax(sBuffer), "%L^n", id, "KILLED_YOU_DIST", t_sName, t_sWpn, distance(g_izUserAttackerDistance[id])) - iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%L^n", id, "DID_DMG_HITS", izAStats[STATS_DAMAGE], izAStats[STATS_HITS], g_izKilled[id][KILLED_KILLER_HEALTH], g_izKilled[id][KILLED_KILLER_ARMOUR]) - iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%L^n", id, "YOU_DID_DMG", izVStats[STATS_DAMAGE], izVStats[STATS_HITS]) + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%L^n", id, "DID_DMG_HITS", izAStats[STATSX_DAMAGE], izAStats[STATSX_HITS], g_izKilled[id][KILLED_KILLER_HEALTH], g_izKilled[id][KILLED_KILLER_ARMOUR]) + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%L^n", id, "YOU_DID_DMG", izVStats[STATSX_DAMAGE], izVStats[STATSX_HITS]) } return iFound @@ -482,11 +473,11 @@ add_most_disruptive(id, sBuffer[MAX_BUFFER_LENGTH + 1]) // Find player. for (iPlayer = 1; iPlayer <= MaxClients; iPlayer++) { - if (g_izUserRndStats[iPlayer][STATS_DAMAGE] >= iMaxDamage && (g_izUserRndStats[iPlayer][STATS_DAMAGE] > iMaxDamage || g_izUserRndStats[iPlayer][STATS_HS] > iMaxHeadShots)) + if (g_izUserRndStats[iPlayer][STATSX_DAMAGE] >= iMaxDamage && (g_izUserRndStats[iPlayer][STATSX_DAMAGE] > iMaxDamage || g_izUserRndStats[iPlayer][STATSX_HEADSHOTS] > iMaxHeadShots)) { iMaxDamageId = iPlayer - iMaxDamage = g_izUserRndStats[iPlayer][STATS_DAMAGE] - iMaxHeadShots = g_izUserRndStats[iPlayer][STATS_HS] + iMaxDamage = g_izUserRndStats[iPlayer][STATSX_DAMAGE] + iMaxHeadShots = g_izUserRndStats[iPlayer][STATSX_HEADSHOTS] } } @@ -499,7 +490,7 @@ add_most_disruptive(id, sBuffer[MAX_BUFFER_LENGTH + 1]) new Float:fRndAcc = accuracy(g_izUserRndStats[iPlayer]) formatex(t_sText, charsmax(t_sText), "%L: %s^n%d %L / %d %L -- %0.2f%% %L / %0.2f%% %L^n", id, "MOST_DMG", g_izUserRndName[iPlayer], - g_izUserRndStats[iPlayer][STATS_HITS], id, "HIT_S", iMaxDamage, id, "DMG", fGameEff, id, "EFF", fRndAcc, id, "ACC") + g_izUserRndStats[iPlayer][STATSX_HITS], id, "HIT_S", iMaxDamage, id, "DMG", fGameEff, id, "EFF", fRndAcc, id, "ACC") add(sBuffer, charsmax(sBuffer), t_sText) } @@ -518,11 +509,11 @@ add_best_score(id, sBuffer[MAX_BUFFER_LENGTH + 1]) // Find player for (iPlayer = 1; iPlayer <= MaxClients; iPlayer++) { - if (g_izUserRndStats[iPlayer][STATS_KILLS] >= iMaxKills && (g_izUserRndStats[iPlayer][STATS_KILLS] > iMaxKills || g_izUserRndStats[iPlayer][STATS_HS] > iMaxHeadShots)) + if (g_izUserRndStats[iPlayer][STATSX_KILLS] >= iMaxKills && (g_izUserRndStats[iPlayer][STATSX_KILLS] > iMaxKills || g_izUserRndStats[iPlayer][STATSX_HEADSHOTS] > iMaxHeadShots)) { iMaxKillsId = iPlayer - iMaxKills = g_izUserRndStats[iPlayer][STATS_KILLS] - iMaxHeadShots = g_izUserRndStats[iPlayer][STATS_HS] + iMaxKills = g_izUserRndStats[iPlayer][STATSX_KILLS] + iMaxHeadShots = g_izUserRndStats[iPlayer][STATSX_HEADSHOTS] } } @@ -582,8 +573,8 @@ save_team_chatscore(id, sBuffer[MAX_TEXT_LENGTH + 1]) // Get and format total stats. add_total_stats(id, sBuffer[MAX_BUFFER_LENGTH + 1]) { - formatex(t_sText, charsmax(t_sText), "%L: %d %L / %d hs -- %d %L / %d %L^n", id, "TOTAL", g_izUserRndStats[0][STATS_KILLS], id, "KILL_S", - g_izUserRndStats[0][STATS_HS], g_izUserRndStats[0][STATS_HITS], id, "HITS", g_izUserRndStats[0][STATS_SHOTS], id, "SHOT_S") + formatex(t_sText, charsmax(t_sText), "%L: %d %L / %d hs -- %d %L / %d %L^n", id, "TOTAL", g_izUserRndStats[0][STATSX_KILLS], id, "KILL_S", + g_izUserRndStats[0][STATSX_HEADSHOTS], g_izUserRndStats[0][STATSX_HITS], id, "HITS", g_izUserRndStats[0][STATSX_SHOTS], id, "SHOT_S") add(sBuffer, charsmax(sBuffer), t_sText) } @@ -594,12 +585,12 @@ add_attacker_hits(id, iAttacker, sBuffer[MAX_BUFFER_LENGTH + 1]) if (iAttacker && iAttacker != id) { - new izStats[8], izBody[8], iLen + new izStats[STATSX_MAX_STATS], izBody[MAX_BODYHITS], iLen - izStats[STATS_HITS] = 0 + izStats[STATSX_HITS] = 0 get_user_astats(id, iAttacker, izStats, izBody) - if (izStats[STATS_HITS]) + if (izStats[STATSX_HITS]) { iFound = 1 iLen = strlen(sBuffer) @@ -627,18 +618,18 @@ format_kill_ainfo(id, iKiller, sBuffer[MAX_BUFFER_LENGTH + 1]) if (iKiller && iKiller != id) { - new izStats[8], izBody[8] + new izStats[STATSX_MAX_STATS], izBody[MAX_BODYHITS] new iLen iFound = 1 get_user_name(iKiller, t_sName, charsmax(t_sName)) - izStats[STATS_HITS] = 0 + izStats[STATSX_HITS] = 0 get_user_astats(id, iKiller, izStats, izBody, t_sWpn, charsmax(t_sWpn)) iLen = formatex(sBuffer, charsmax(sBuffer), "%L (%dhp, %dap) >>", id, "KILLED_BY_WITH", t_sName, t_sWpn, distance(g_izUserAttackerDistance[id]), g_izKilled[id][KILLED_KILLER_HEALTH], g_izKilled[id][KILLED_KILLER_ARMOUR]) - if (izStats[STATS_HITS]) + if (izStats[STATSX_HITS]) { for (new i = 1; i < sizeof(izBody); i++) { @@ -661,24 +652,24 @@ format_kill_ainfo(id, iKiller, sBuffer[MAX_BUFFER_LENGTH + 1]) format_kill_vinfo(id, iKiller, sBuffer[MAX_BUFFER_LENGTH + 1]) { new iFound = 0 - new izStats[8] - new izBody[8] + new izStats[STATSX_MAX_STATS] + new izBody[MAX_BODYHITS] new iLen - izStats[STATS_HITS] = 0 - izStats[STATS_DAMAGE] = 0 + izStats[STATSX_HITS] = 0 + izStats[STATSX_DAMAGE] = 0 get_user_vstats(id, iKiller, izStats, izBody) if (iKiller && iKiller != id) { iFound = 1 get_user_name(iKiller, t_sName, charsmax(t_sName)) - iLen = formatex(sBuffer, charsmax(sBuffer), "%L >>", id, "YOU_HIT", t_sName, izStats[STATS_HITS], izStats[STATS_DAMAGE]) + iLen = formatex(sBuffer, charsmax(sBuffer), "%L >>", id, "YOU_HIT", t_sName, izStats[STATSX_HITS], izStats[STATSX_DAMAGE]) } else - iLen = formatex(sBuffer, charsmax(sBuffer), "%L >>", id, "LAST_RES", izStats[STATS_HITS], izStats[STATS_DAMAGE]) + iLen = formatex(sBuffer, charsmax(sBuffer), "%L >>", id, "LAST_RES", izStats[STATSX_HITS], izStats[STATSX_DAMAGE]) - if (izStats[STATS_HITS]) + if (izStats[STATSX_HITS]) { for (new i = 1; i < sizeof(izBody); i++) { @@ -698,7 +689,7 @@ format_kill_vinfo(id, iKiller, sBuffer[MAX_BUFFER_LENGTH + 1]) format_top15(id, sBuffer[MAX_BUFFER_LENGTH + 1]) { new iMax = get_statsnum() - new izStats[8], izBody[8] + new izStats[STATSX_MAX_STATS], izBody[MAX_BODYHITS] new iLen = 0 if (iMax > 15) @@ -724,16 +715,16 @@ format_top15(id, sBuffer[MAX_BUFFER_LENGTH + 1]) get_stats(i, izStats, izBody, t_sName, charsmax(t_sName)) replace_string(t_sName, charsmax(t_sName), "<", "[") replace_string(t_sName, charsmax(t_sName), ">", "]") - iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%2d %-22.22s %6d %6d %6d %6d %4d %3.0f%% %3.0f%%^n", i + 1, t_sName, izStats[STATS_KILLS], - izStats[STATS_DEATHS], izStats[STATS_HITS], izStats[STATS_SHOTS], izStats[STATS_HS], effec(izStats), accuracy(izStats)) + iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%2d %-22.22s %6d %6d %6d %6d %4d %3.0f%% %3.0f%%^n", i + 1, t_sName, izStats[STATSX_KILLS], + izStats[STATSX_DEATHS], izStats[STATSX_HITS], izStats[STATSX_SHOTS], izStats[STATSX_HEADSHOTS], effec(izStats), accuracy(izStats)) } } // Get and format rank stats. format_rankstats(id, sBuffer[MAX_BUFFER_LENGTH + 1], iMyId = 0) { - new izStats[8] = {0, ...} - new izBody[8] + new izStats[STATSX_MAX_STATS] = {0, ...} + new izBody[MAX_BODYHITS] new iRankPos, iLen new lKills[16], lDeaths[16], lHits[16], lShots[16], lDamage[16], lEff[16], lAcc[16] @@ -752,10 +743,10 @@ format_rankstats(id, sBuffer[MAX_BUFFER_LENGTH + 1], iMyId = 0) iLen = formatex(sBuffer, charsmax(sBuffer), "
")
 	iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%L %L^n^n", id, (!iMyId || iMyId == id) ? "YOUR" : "PLAYERS", id, "RANK_IS", iRankPos, get_statsnum())
 	iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%6s: %d  (%d with hs)^n%6s: %d^n%6s: %d^n%6s: %d^n%6s: %d^n%6s: %0.2f%%^n%6s: %0.2f%%^n^n",
-					lKills, izStats[STATS_KILLS], izStats[STATS_HS], lDeaths, izStats[STATS_DEATHS], lHits, izStats[STATS_HITS], lShots, izStats[STATS_SHOTS],
-					lDamage, izStats[STATS_DAMAGE], lEff, effec(izStats), lAcc, accuracy(izStats))
+					lKills, izStats[STATSX_KILLS], izStats[STATSX_HEADSHOTS], lDeaths, izStats[STATSX_DEATHS], lHits, izStats[STATSX_HITS], lShots, izStats[STATSX_SHOTS],
+					lDamage, izStats[STATSX_DAMAGE], lEff, effec(izStats), lAcc, accuracy(izStats))
 
-	new L_BODY_PART[8][32]
+	new L_BODY_PART[MAX_BODYHITS][32]
 
 	for (new i = 1; i < sizeof(L_BODY_PART); i++)
 	{
@@ -763,15 +754,15 @@ format_rankstats(id, sBuffer[MAX_BUFFER_LENGTH + 1], iMyId = 0)
 	}
 
 	iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%10s:^n%10s: %d^n%10s: %d^n%10s: %d^n%10s: %d^n%10s: %d^n%10s: %d^n%10s: %d", "HITS",
-					L_BODY_PART[1], izBody[1], L_BODY_PART[2], izBody[2], L_BODY_PART[3], izBody[3], L_BODY_PART[4], izBody[4], L_BODY_PART[5],
-					izBody[5], L_BODY_PART[6], izBody[6], L_BODY_PART[7], izBody[7])
+					L_BODY_PART[HIT_HEAD], izBody[HIT_HEAD], L_BODY_PART[HIT_CHEST], izBody[HIT_CHEST], L_BODY_PART[HIT_STOMACH], izBody[HIT_STOMACH], L_BODY_PART[HIT_LEFTARM], izBody[HIT_LEFTARM], L_BODY_PART[HIT_RIGHTARM],
+					izBody[HIT_RIGHTARM], L_BODY_PART[HIT_LEFTLEG], izBody[HIT_LEFTLEG], L_BODY_PART[HIT_RIGHTLEG], izBody[HIT_RIGHTLEG])
 }
 
 // Get and format stats.
 format_stats(id, sBuffer[MAX_BUFFER_LENGTH + 1])
 {
-	new izStats[8] = {0, ...}
-	new izBody[8]
+	new izStats[STATSX_MAX_STATS] = {0, ...}
+	new izBody[MAX_BODYHITS]
 	new iWeapon, iLen
 	new lKills[16], lDeaths[16], lHits[16], lShots[16], lDamage[16], lEff[16], lAcc[16], lWeapon[16]
 
@@ -791,8 +782,8 @@ format_stats(id, sBuffer[MAX_BUFFER_LENGTH + 1])
 
 	iLen = formatex(sBuffer, charsmax(sBuffer), "
")
 	iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%6s: %d  (%d with hs)^n%6s: %d^n%6s: %d^n%6s: %d^n%6s: %d^n%6s: %0.2f%%^n%6s: %0.2f%%^n^n",
-					lKills, izStats[STATS_KILLS], izStats[STATS_HS], lDeaths, izStats[STATS_DEATHS], lHits, izStats[STATS_HITS], lShots, izStats[STATS_SHOTS],
-					lDamage, izStats[STATS_DAMAGE], lEff, effec(izStats), lAcc, accuracy(izStats))
+					lKills, izStats[STATSX_KILLS], izStats[STATSX_HEADSHOTS], lDeaths, izStats[STATSX_DEATHS], lHits, izStats[STATSX_HITS], lShots, izStats[STATSX_SHOTS],
+					lDamage, izStats[STATSX_DAMAGE], lEff, effec(izStats), lAcc, accuracy(izStats))
 	iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%-12.12s  %6s  %6s  %6s  %6s  %6s  %4s^n", lWeapon, lKills, lDeaths, lHits, lShots, lDamage, lAcc)
 
 	for (iWeapon = 1; iWeapon < xmod_get_maxweapons() && charsmax(sBuffer) - iLen > 0 ; iWeapon++)
@@ -800,8 +791,8 @@ format_stats(id, sBuffer[MAX_BUFFER_LENGTH + 1])
 		if (get_user_wstats(id, iWeapon, izStats, izBody))
 		{
 			xmod_get_wpnname(iWeapon, t_sWpn, charsmax(t_sWpn))
-			iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%-12.12s  %6d  %6d  %6d  %6d  %6d  %3.0f%%^n", t_sWpn, izStats[STATS_KILLS], izStats[STATS_DEATHS],
-							izStats[STATS_HITS], izStats[STATS_SHOTS], izStats[STATS_DAMAGE], accuracy(izStats))
+			iLen += formatex(sBuffer[iLen], charsmax(sBuffer) - iLen, "%-12.12s  %6d  %6d  %6d  %6d  %6d  %3.0f%%^n", t_sWpn, izStats[STATSX_KILLS], izStats[STATSX_DEATHS],
+							izStats[STATSX_HITS], izStats[STATSX_SHOTS], izStats[STATSX_DAMAGE], accuracy(izStats))
 		}
 	}
 }
@@ -1045,7 +1036,7 @@ public cmdRank(id)
 		return PLUGIN_HANDLED
 	}
 
-	new izStats[8], izBody[8]
+	new izStats[STATSX_MAX_STATS], izBody[MAX_BODYHITS]
 	new iRankPos, iRankMax
 	new Float:fEff, Float:fAcc
 
@@ -1055,7 +1046,7 @@ public cmdRank(id)
 	fEff = effec(izStats)
 	fAcc = accuracy(izStats)
 
-	client_print(id, print_chat, "* %L", id, "YOUR_RANK_IS", iRankPos, iRankMax, izStats[STATS_KILLS], izStats[STATS_HITS], fEff, fAcc)
+	client_print(id, print_chat, "* %L", id, "YOUR_RANK_IS", iRankPos, iRankMax, izStats[STATSX_KILLS], izStats[STATSX_HITS], fEff, fAcc)
 
 	return PLUGIN_CONTINUE
 }
@@ -1443,7 +1434,7 @@ kill_stats(id)
 	g_fzShowUserStatsTime[id] = get_gametime()
 
 	// Add user death stats to user round stats
-	new izStats[8], izBody[8]
+	new izStats[STATSX_MAX_STATS], izBody[MAX_BODYHITS]
 	new iTeam, i
 	new iKiller
 
@@ -1651,7 +1642,7 @@ public eventShowRank(id)
 
 		if (is_user_connected(iPlayer))
 		{
-			new izStats[8], izBody[8]
+			new izStats[STATSX_MAX_STATS], izBody[MAX_BODYHITS]
 			new iRankPos, iRankMax
 
 			get_user_name(iPlayer, t_sName, charsmax(t_sName))
diff --git a/plugins/dod/dodstats.sma b/plugins/dod/dodstats.sma
index ebc94f21..aeaa4404 100755
--- a/plugins/dod/dodstats.sma
+++ b/plugins/dod/dodstats.sma
@@ -28,13 +28,14 @@
  */
 
 #include 
+#include 
 
-#define KILLS	stats[0]
-#define DEATHS	stats[1]
-#define TK		stats[3]
-#define SCORE	stats[7]
+#define KILLS	stats[DODX_KILLS]
+#define DEATHS	stats[DODX_DEATHS]
+#define TK		stats[DODX_TEAMKILLS]
+#define SCORE	stats[DODX_POINTS]
 
-public get_score(stats[9],body[8]){
+public get_score(stats[DODX_MAX_STATS],body[MAX_BODYHITS]){
 	if (!DEATHS)
 		DEATHS = 1
 
diff --git a/plugins/dod/stats.sma b/plugins/dod/stats.sma
index 79aee492..e1796240 100755
--- a/plugins/dod/stats.sma
+++ b/plugins/dod/stats.sma
@@ -86,7 +86,7 @@ new g_center1_sync
 new g_center2_sync
 new g_left_sync
 
-new g_bodyParts[8][] = { 
+new g_bodyParts[MAX_BODYHITS][] = { 
                         "WHOLEBODY",
                         "HEAD",
                         "CHEST",
@@ -294,19 +294,19 @@ public cmdStats(id){
 
 /* build list of attackers */ 
 getAttackers(id) { 
-  new name[MAX_NAME_LENGTH],wpn[32], stats[9],body[8],found=0 
+  new name[MAX_NAME_LENGTH],wpn[32], stats[DODX_MAX_STATS],body[MAX_BODYHITS],found=0 
   new pos = format(g_Buffer,charsmax(g_Buffer),"%L^n",id,"ATTACKERS") 
   for(new a = 1; a <= MaxClients; ++a){ 
 
     if(get_user_astats(id,a,stats,body,wpn,charsmax(wpn)))
     { 
       found = 1 
-      if (stats[0]) 
+      if (stats[DODX_KILLS]) 
         format(wpn,charsmax(wpn)," -- %s",wpn) 
       else 
         wpn[0] = 0 
       get_user_name(a,name,charsmax(name)) 
-      pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%s -- %d %L / %d %L%s^n",name,stats[6],id,"DMG",stats[5],id,"HIT_S",wpn) 
+      pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%s -- %d %L / %d %L%s^n",name,stats[DODX_DAMAGE],id,"DMG",stats[DODX_HITS],id,"HIT_S",wpn) 
     } 
   } 
   return found 
@@ -315,18 +315,18 @@ getAttackers(id) {
 
 /* build list of victims */ 
 getVictims(id) { 
-  new name[MAX_NAME_LENGTH],wpn[32], stats[9],body[8],found=0 
+  new name[MAX_NAME_LENGTH],wpn[32], stats[DODX_MAX_STATS],body[MAX_BODYHITS],found=0 
   new pos = format(g_Buffer,charsmax(g_Buffer),"%L^n",id,"VICTIMS") 
   for(new a = 1; a <= MaxClients; ++a){ 
     if(get_user_vstats(id,a,stats,body,wpn,charsmax(wpn)))
     { 
       found = 1 
-      if (stats[1]) 
+      if (stats[DODX_DEATHS]) 
         format(wpn,charsmax(wpn)," -- %s",wpn) 
       else 
         wpn[0] = 0 
       get_user_name(a,name,charsmax(name)) 
-      pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%s -- %d %L / %d %L%s^n",name,stats[6],id,"DMG",stats[5],id,"HITS",wpn) 
+      pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%s -- %d %L / %d %L%s^n",name,stats[DODX_DAMAGE],id,"DMG",stats[DODX_HITS],id,"HITS",wpn) 
     } 
   } 
   return found 
@@ -334,7 +334,7 @@ getVictims(id) {
 
 /* build list of hita for AV List */ 
 getHits(id,killer) { 
-  new stats[9], body[8], pos = 0 
+  new stats[DODX_MAX_STATS], body[MAX_BODYHITS], pos = 0 
   g_Buffer[0] = 0 
   get_user_astats(id,killer,stats,body) 
   for(new a = 1; a < sizeof(body); ++a) 
@@ -344,7 +344,7 @@ getHits(id,killer) {
 
 /* build list of hits for say hp */ 
 getMyHits(id,killed) { 
-  new name[MAX_NAME_LENGTH], stats[9], body[8], found = 0 
+  new name[MAX_NAME_LENGTH], stats[DODX_MAX_STATS], body[MAX_BODYHITS], found = 0 
   get_user_name(killed,name,charsmax(name)) 
   new pos = format(g_Buffer,charsmax(g_Buffer),"%L",id,"YOU_HIT",name) 
   get_user_vstats(id,killed,stats,body) 
@@ -367,13 +367,13 @@ public cmdKiller(id) {
     return PLUGIN_HANDLED 
   } 
   if (g_Killers[id][0]) { 
-    new name[MAX_NAME_LENGTH], stats[9], body[8], wpn[32], mstats[9], mbody[8] 
+    new name[MAX_NAME_LENGTH], stats[DODX_MAX_STATS], body[MAX_BODYHITS], wpn[32], mstats[DODX_MAX_STATS], mbody[MAX_BODYHITS] 
     get_user_name(g_Killers[id][0],name,charsmax(name)) 
     get_user_astats(id,g_Killers[id][0],stats,body,wpn,charsmax(wpn)) 
     get_user_vstats(id,g_Killers[id][0],mstats,mbody) 
     client_print(id,print_chat,"%L",id,"KILL_INFO1", name,wpn,float(g_Killers[id][2]) * 0.0254 ) 
-    client_print(id,print_chat,"%L",id,"KILL_INFO2", stats[6],stats[5], g_Killers[id][1] ) 
-    client_print(id,print_chat,"%L",id,"KILL_INFO3", mstats[6], mstats[5] ) 
+    client_print(id,print_chat,"%L",id,"KILL_INFO2", stats[DODX_DAMAGE],stats[DODX_HITS], g_Killers[id][1] ) 
+    client_print(id,print_chat,"%L",id,"KILL_INFO3", mstats[DODX_DAMAGE], mstats[DODX_HITS] ) 
 
     if (getMyHits(id,g_Killers[id][0])) client_print(id,print_chat,"%L",id,"KILL_INFO4",g_Buffer) 
   } 
@@ -479,7 +479,7 @@ public round_end(){
 
   if ( !EndRoundStats ) return PLUGIN_CONTINUE
 
-  new g_Buffer2[1024], len, players[MAX_PLAYERS], pnum, stats[9],bodyhits[8]
+  new g_Buffer2[1024], len, players[MAX_PLAYERS], pnum, stats[DODX_MAX_STATS],bodyhits[MAX_BODYHITS]
   get_players( players , pnum ) 
 
 
@@ -488,25 +488,25 @@ public round_end(){
 
   for(new i = 0; i < pnum; ++i){
      get_user_rstats( players[i],stats, bodyhits )
-     if ( stats[7] > score ){
+     if ( stats[DODX_POINTS] > score ){
         who1 = players[i]
-        score = stats[7]
+        score = stats[DODX_POINTS]
      }  
   }
   for(new i = 0; i < pnum; ++i){
      get_user_rstats( players[i],stats, bodyhits )
-     if ( stats[0] > kills ){
+     if ( stats[DODX_KILLS] > kills ){
         who2 = players[i]
-        kills = stats[0]
-        hs = stats[2]
+        kills = stats[DODX_KILLS]
+        hs = stats[DODX_HEADSHOTS]
      }  
   }
   for(new i = 0; i < pnum; ++i){
      get_user_rstats( players[i],stats, bodyhits )
-     if ( stats[6] > damage ){
+     if ( stats[DODX_DAMAGE] > damage ){
         who3 = players[i]
-        hits = stats[5]
-        damage = stats[6]
+        hits = stats[DODX_HITS]
+        damage = stats[DODX_DAMAGE]
      }  
   }
 
@@ -632,15 +632,15 @@ public client_death(killer,victim,wpnindex,hitplace,TK)
 
 
   if ( ShowKiller && !(!get_cvar_num("dodstats_rankbots") &&  (is_user_bot(killer) || is_user_bot(victim)))  ){ 
-    new stats[9], body[8], wpn[32], mstats[9], mbody[8] 
+    new stats[DODX_MAX_STATS], body[MAX_BODYHITS], wpn[32], mstats[DODX_MAX_STATS], mbody[MAX_BODYHITS] 
   
     get_user_astats(victim,killer,stats,body,wpn,charsmax(wpn)) 
     get_user_vstats(victim,killer,mstats,mbody) 
     set_hudmessage(220,80,0,0.05,0.15,0, statstime, 12.0, 1.0, 2.0, -1) 
     getHits(victim,killer) 
     show_hudmessage(victim,"%L%L%L%L",victim,"KILL_INFO1",killer_name,wpn,float(g_Killers[victim][2]) * 0.0254,
-			/*2*/ victim,"KILL_INFO2",stats[6],stats[5],g_Killers[victim][1],
-			/*3*/ victim,"KILL_INFO3",mstats[6],mstats[5],
+			/*2*/ victim,"KILL_INFO2",stats[DODX_DAMAGE],stats[DODX_HITS],g_Killers[victim][1],
+			/*3*/ victim,"KILL_INFO3",mstats[DODX_DAMAGE],mstats[DODX_HITS],
 			/*4*/ victim,"KILL_INFO4",g_Buffer ) 
   } 
 
@@ -919,7 +919,7 @@ public cmdStatsMe(id){
 }
 
 displayStats_steam(id,dest) {
- new name[MAX_NAME_LENGTH], stats[9], body[8]
+ new name[MAX_NAME_LENGTH], stats[DODX_MAX_STATS], body[MAX_BODYHITS]
  get_user_wstats(id,0,stats,body)
 
  new pos = copy(g_Buffer,charsmax(g_Buffer),"
")
@@ -927,7 +927,7 @@ displayStats_steam(id,dest) {
                dest,"M_KILLS",dest,"M_DEATHS",dest,"M_SCORE",dest,"M_TKS",dest,"M_HITS",dest,"M_SHOTS",dest,"M_HS")
 
  pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%d%d%d%d%d%d%d


", - stats[0],stats[1],stats[7],stats[3],stats[5],stats[4],stats[2]) + stats[DODX_KILLS],stats[DODX_DEATHS],stats[DODX_POINTS],stats[DODX_TEAMKILLS],stats[DODX_HITS],stats[DODX_SHOTS],stats[DODX_HEADSHOTS]) pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"", dest,"M_WEAPON",dest,"M_SHOTS",dest,"M_HITS",dest,"M_DAMAGE",dest,"M_KILLS",dest,"M_DEATHS") @@ -935,10 +935,10 @@ displayStats_steam(id,dest) { for(new a = 1; a < DODMAX_WEAPONS; ++a) { if (get_user_wstats(id,a,stats,body)){ if ( xmod_is_melee_wpn(a) ) - stats[4] = -1; + stats[DODX_SHOTS] = -1; xmod_get_wpnname(a,name,charsmax(name)) pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"^n", - name,stats[4],stats[5],stats[6],stats[0],stats[1]) + name,stats[DODX_SHOTS],stats[DODX_HITS],stats[DODX_DAMAGE],stats[DODX_KILLS],stats[DODX_DEATHS]) } } copy(g_Buffer[pos],charsmax(g_Buffer)-pos,"
%L%L%L%L%L%L
%s%d%d%d%d%d
") @@ -958,7 +958,7 @@ public cmdRank(id){ } displayRank_steam(id,dest) { - new name[MAX_NAME_LENGTH], stats[9], body[8] + new name[MAX_NAME_LENGTH], stats[DODX_MAX_STATS], body[MAX_BODYHITS] new rank_pos = get_user_stats(id,stats,body) new pos = copy(g_Buffer,charsmax(g_Buffer),"
")
@@ -968,9 +968,9 @@ displayRank_steam(id,dest) {
 
  pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,
                "%d%d%d%d%d%d%d

", - stats[0],stats[1],stats[7],stats[3],stats[5],stats[4],stats[2]) + stats[DODX_KILLS],stats[DODX_DEATHS],stats[DODX_POINTS],stats[DODX_TEAMKILLS],stats[DODX_HITS],stats[DODX_SHOTS],stats[DODX_HEADSHOTS]) - pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%L^n%L: %d^n%L: %d^n%L: %d^n%L: %d^n%L: %d^n%L: %d^n%L: %d^n",dest,"M_HITS",dest,g_bodyParts[1],body[1],dest,g_bodyParts[2],body[2],dest,g_bodyParts[3],body[3],dest,g_bodyParts[4],body[4],dest,g_bodyParts[5],body[5],dest,g_bodyParts[6],body[6],dest,g_bodyParts[7],body[7]) + pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%L^n%L: %d^n%L: %d^n%L: %d^n%L: %d^n%L: %d^n%L: %d^n%L: %d^n",dest,"M_HITS",dest,g_bodyParts[HIT_HEAD],body[HIT_HEAD],dest,g_bodyParts[HIT_CHEST],body[HIT_CHEST],dest,g_bodyParts[HIT_STOMACH],body[HIT_STOMACH],dest,g_bodyParts[HIT_LEFTARM],body[HIT_LEFTARM],dest,g_bodyParts[HIT_RIGHTARM],body[HIT_RIGHTARM],dest,g_bodyParts[HIT_LEFTLEG],body[HIT_LEFTLEG],dest,g_bodyParts[HIT_RIGHTLEG],body[HIT_RIGHTLEG]) pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%L %d %L %d",dest,(id==dest)?"M_YOUR_RANK_IS":"M_THEIR_RANK_IS", rank_pos,dest,"M_OF",get_statsnum()) @@ -997,7 +997,7 @@ public cmdTop15(id) { /* get top 15 */ getTop15_steam(id){ - new stats[9], body[8], name[MAX_NAME_LENGTH] + new stats[DODX_MAX_STATS], body[MAX_BODYHITS], name[MAX_NAME_LENGTH] new pos = copy(g_Buffer,charsmax(g_Buffer),"
")
 
@@ -1012,7 +1012,7 @@ getTop15_steam(id){
     replace_all(name, charsmax(name), "<", "[")
     replace_all(name, charsmax(name), ">", "]")
     pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%d.%s%d%d%d%d%d%d%d^n",
-		a+1,name,stats[0],stats[1],stats[7],stats[3],stats[5],stats[4],stats[2])
+		a+1,name,stats[DODX_KILLS],stats[DODX_DEATHS],stats[DODX_POINTS],stats[DODX_TEAMKILLS],stats[DODX_HITS],stats[DODX_SHOTS],stats[DODX_HEADSHOTS])
   }
   pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"
") diff --git a/plugins/dod/stats_logging.sma b/plugins/dod/stats_logging.sma index 8e6bc071..e1b322b3 100755 --- a/plugins/dod/stats_logging.sma +++ b/plugins/dod/stats_logging.sma @@ -24,7 +24,7 @@ public plugin_init() public client_disconnected(id) { if ( is_user_bot( id ) || !is_user_connected(id) || !isDSMActive() ) return PLUGIN_CONTINUE remove_task( id ) - new szTeam[16],szName[MAX_NAME_LENGTH],szAuthid[32], iStats[9], iHits[8], szWeapon[16] + new szTeam[16],szName[MAX_NAME_LENGTH],szAuthid[32], iStats[DODX_MAX_STATS], iHits[MAX_BODYHITS], szWeapon[16] new iUserid = get_user_userid( id ) get_user_info(id,"team", szTeam, charsmax(szTeam) ) szTeam[0] -= 32; @@ -34,9 +34,9 @@ public client_disconnected(id) { if( get_user_wstats( id , i ,iStats , iHits ) ) { xmod_get_wpnlogname( i , szWeapon , charsmax(szWeapon) ) log_message("^"%s<%d><%s><%s>^" triggered ^"weaponstats^" (weapon ^"%s^") (shots ^"%d^") (hits ^"%d^") (kills ^"%d^") (headshots ^"%d^") (tks ^"%d^") (damage ^"%d^") (deaths ^"%d^") (score ^"%d^")", - szName,iUserid,szAuthid,szTeam,szWeapon,iStats[4],iStats[5],iStats[0], iStats[2],iStats[3],iStats[6],iStats[1],iStats[7]) + szName,iUserid,szAuthid,szTeam,szWeapon,iStats[DODX_SHOTS],iStats[DODX_HITS],iStats[DODX_KILLS], iStats[DODX_HEADSHOTS],iStats[DODX_TEAMKILLS],iStats[DODX_DAMAGE],iStats[DODX_DEATHS],iStats[DODX_POINTS]) log_message("^"%s<%d><%s><%s>^" triggered ^"weaponstats2^" (weapon ^"%s^") (head ^"%d^") (chest ^"%d^") (stomach ^"%d^") (leftarm ^"%d^") (rightarm ^"%d^") (leftleg ^"%d^") (rightleg ^"%d^")", - szName,iUserid,szAuthid,szTeam,szWeapon,iHits[1],iHits[2],iHits[3], iHits[4],iHits[5],iHits[6],iHits[7]) + szName,iUserid,szAuthid,szTeam,szWeapon,iHits[HIT_HEAD],iHits[HIT_CHEST],iHits[HIT_STOMACH], iHits[HIT_LEFTARM],iHits[HIT_RIGHTARM],iHits[HIT_LEFTLEG],iHits[HIT_RIGHTLEG]) } } new iTime = get_user_time( id , 1 ) diff --git a/plugins/tfc/stats.sma b/plugins/tfc/stats.sma index ad4b4122..cfbb3cf3 100755 --- a/plugins/tfc/stats.sma +++ b/plugins/tfc/stats.sma @@ -75,7 +75,7 @@ new g_center2_sync new g_left_sync new g_damage_sync -new g_bodyParts[8][] = { +new g_bodyParts[MAX_BODYHITS][] = { "whole body", "head", "chest", @@ -220,18 +220,18 @@ public cmdStatsMe(id){ } displayStats(id,dest) { - new name[32], stats[8], body[8] + new name[32], stats[STATSX_MAX_STATS], body[MAX_BODYHITS] get_user_wstats(id,0,stats,body) new pos = format(g_Buffer,charsmax(g_Buffer),"Kills: %d^nDeaths: %d^nTKs: %d^nDamage: %d^nHits: %d^nShots: %d^n^n", - stats[0],stats[1],stats[3],stats[6],stats[5],stats[4]) + stats[STATSX_KILLS],stats[STATSX_DEATHS],stats[STATSX_TEAMKILLS],stats[STATSX_DAMAGE],stats[STATSX_HITS],stats[STATSX_SHOTS]) new a for( a = 1; a < TFCMAX_WEAPONS; a++) { if (get_user_wstats(id,a,stats,body)){ if ( xmod_is_melee_wpn(a) ) - stats[4] = -1; + stats[STATSX_SHOTS] = -1; xmod_get_wpnname(a,name,charsmax(name)) pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%s shots: %d hits: %d damage: %d kills: %d deaths: %d^n", - name,stats[4],stats[5],stats[6],stats[0],stats[1]) + name,stats[STATSX_SHOTS],stats[STATSX_HITS],stats[STATSX_DAMAGE],stats[STATSX_KILLS],stats[STATSX_DEATHS]) } } get_user_name(id,name,charsmax(name)) @@ -248,13 +248,13 @@ public cmdRank(id){ } displayRank(id,dest) { - new name[MAX_NAME_LENGTH], stats[8], body[8] + new name[MAX_NAME_LENGTH], stats[STATSX_MAX_STATS], body[MAX_BODYHITS] new rank_pos = get_user_stats(id,stats,body) new pos = format(g_Buffer,charsmax(g_Buffer),"Kills: %d^nDeaths: %d^nTKs: %d^nDamage: %d^nHits: %d^nShots: %d^n^n", - stats[0],stats[1],stats[3],stats[6],stats[5],stats[4]) + stats[STATSX_KILLS],stats[STATSX_DEATHS],stats[STATSX_TEAMKILLS],stats[STATSX_DAMAGE],stats[STATSX_HITS],stats[STATSX_SHOTS]) pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"Hits:^n%s: %d^n%s: %d^n%s: %d^n%s: %d^n%s: %d^n%s: %d^n%s: %d^n^n", - g_bodyParts[1],body[1],g_bodyParts[2],body[2],g_bodyParts[3],body[3], g_bodyParts[4],body[4], - g_bodyParts[5],body[5],g_bodyParts[6],body[6],g_bodyParts[7],body[7]) + g_bodyParts[HIT_HEAD],body[HIT_HEAD],g_bodyParts[HIT_CHEST],body[HIT_CHEST],g_bodyParts[HIT_STOMACH],body[HIT_STOMACH], g_bodyParts[HIT_LEFTARM],body[HIT_LEFTARM], + g_bodyParts[HIT_RIGHTARM],body[HIT_RIGHTARM],g_bodyParts[HIT_LEFTLEG],body[HIT_LEFTLEG],g_bodyParts[HIT_RIGHTLEG],body[HIT_RIGHTLEG]) format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%s rank is %d of %d",(id==dest)?"Your":"His", rank_pos,get_statsnum()) get_user_name(id,name,charsmax(name)) show_motd(dest,g_Buffer,name) @@ -272,7 +272,7 @@ public cmdTop15(id) { /* get top 15 */ getTop15(){ - new stats[8], body[8], name[MAX_NAME_LENGTH] + new stats[STATSX_MAX_STATS], body[MAX_BODYHITS], name[MAX_NAME_LENGTH] new pos = copy(g_Buffer,charsmax(g_Buffer),"# nick kills/deaths TKs hits/shots/headshots^n") new imax = get_statsnum() if (imax > 15) imax = 15 @@ -280,7 +280,7 @@ getTop15(){ get_stats(a,stats,body,name,charsmax(name)) replace_all(name, charsmax(name), "<", "[") replace_all(name, charsmax(name), ">", "]") - pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%2d. %-28.27s %d/%d %d %d/%d/%d^n",a+1,name,stats[0],stats[1],stats[3],stats[5],stats[4],stats[2]) + pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%2d. %-28.27s %d/%d %d %d/%d/%d^n",a+1,name,stats[STATSX_KILLS],stats[STATSX_DEATHS],stats[STATSX_TEAMKILLS],stats[STATSX_HITS],stats[STATSX_SHOTS],stats[STATSX_HEADSHOTS]) } } @@ -318,18 +318,18 @@ public cmdStats(id){ /* build list of attackers */ getAttackers(id) { - new name[MAX_NAME_LENGTH],wpn[32], stats[8],body[8],found=0 + new name[MAX_NAME_LENGTH],wpn[32], stats[STATSX_MAX_STATS],body[MAX_BODYHITS],found=0 new pos = copy(g_Buffer,charsmax(g_Buffer),"Attackers:^n") for(new a = 1; a <= MaxClients; ++a){ if(get_user_astats(id,a,stats,body,wpn,charsmax(wpn))){ found = 1 - if (stats[0]) + if (stats[STATSX_KILLS]) format(wpn,charsmax(wpn)," -- %s",wpn) else wpn[0] = 0 get_user_name(a,name,charsmax(name)) - pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%s -- %d dmg / %d hit(s)%s^n",name,stats[6],stats[5],wpn) + pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%s -- %d dmg / %d hit(s)%s^n",name,stats[STATSX_DAMAGE],stats[STATSX_HITS],wpn) } } return found @@ -338,17 +338,17 @@ getAttackers(id) { /* build list of victims */ getVictims(id) { - new name[MAX_NAME_LENGTH],wpn[32], stats[8],body[8],found=0 + new name[MAX_NAME_LENGTH],wpn[32], stats[STATSX_MAX_STATS],body[MAX_BODYHITS],found=0 new pos = copy(g_Buffer,charsmax(g_Buffer),"Victims:^n") for(new a = 1; a <= MaxClients; ++a){ if(get_user_vstats(id,a,stats,body,wpn,charsmax(wpn))){ found = 1 - if (stats[1]) + if (stats[STATSX_DEATHS]) format(wpn,charsmax(wpn)," -- %s",wpn) else wpn[0] = 0 get_user_name(a,name,charsmax(name)) - pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%s -- %d dmg / %d hit(s)%s^n",name,stats[6],stats[5],wpn) + pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%s -- %d dmg / %d hit(s)%s^n",name,stats[STATSX_DAMAGE],stats[STATSX_HITS],wpn) } } return found @@ -356,7 +356,7 @@ getVictims(id) { /* build list of hita for AV List */ getHits(id,killer) { - new stats[8], body[8], pos = 0 + new stats[STATSX_MAX_STATS], body[MAX_BODYHITS], pos = 0 g_Buffer[0] = 0 get_user_astats(id,killer,stats,body) for(new a = 1; a < sizeof(body); ++a) @@ -367,7 +367,7 @@ getHits(id,killer) { /* build list of hits for say hp */ getMyHits(id,killed) { - new name[MAX_NAME_LENGTH], stats[8], body[8], found = 0 + new name[MAX_NAME_LENGTH], stats[STATSX_MAX_STATS], body[MAX_BODYHITS], found = 0 get_user_name(killed,name,charsmax(name)) new pos = format(g_Buffer,charsmax(g_Buffer),"You hit %s in:",name) get_user_vstats(id,killed,stats,body) @@ -390,14 +390,14 @@ public cmdKiller(id) { return PLUGIN_HANDLED } if (g_Killers[id][0]) { - new name[MAX_NAME_LENGTH], stats[8], body[8], wpn[32], mstats[8], mbody[8] + new name[MAX_NAME_LENGTH], stats[STATSX_MAX_STATS], body[MAX_BODYHITS], wpn[32], mstats[STATSX_MAX_STATS], mbody[MAX_BODYHITS] get_user_name(g_Killers[id][0],name,charsmax(name)) get_user_astats(id,g_Killers[id][0],stats,body,wpn,charsmax(wpn)) client_print(id,print_chat,"%s killed you with %s from distance of %.2f meters", name,wpn,float(g_Killers[id][3]) * 0.0254 ) client_print(id,print_chat,"He did %d damage to you with %d hit%s and still had %dhp and %dap", - stats[6],stats[5],(stats[5]==1)?"":"s" , g_Killers[id][1],g_Killers[id][2] ) + stats[STATSX_DAMAGE],stats[STATSX_HITS],(stats[STATSX_HITS]==1)?"":"s" , g_Killers[id][1],g_Killers[id][2] ) if ( get_user_vstats(id,g_Killers[id][0],mstats,mbody) ) { - client_print(id,print_chat,"You did %d damage to him with %d hit%s",mstats[6], mstats[5],(mstats[5]==1)?"":"s" ) + client_print(id,print_chat,"You did %d damage to him with %d hit%s",mstats[STATSX_DAMAGE], mstats[STATSX_HITS],(mstats[STATSX_HITS]==1)?"":"s" ) getMyHits(id,g_Killers[id][0]) client_print(id,print_chat, "%s", g_Buffer) } @@ -527,15 +527,15 @@ public client_death(killer,victim,wpnindex,hitplace,TK){ if ( ShowKiller && !(!get_cvar_num("tfcstats_rankbots") && (is_user_bot(killer) || is_user_bot(killer))) ){ - new stats[8], body[8], wpn[32], mstats[8], mbody[8] + new stats[STATSX_MAX_STATS], body[MAX_BODYHITS], wpn[32], mstats[STATSX_MAX_STATS], mbody[MAX_BODYHITS] get_user_astats(victim,killer,stats,body,wpn,charsmax(wpn)) get_user_vstats(victim,killer,mstats,mbody) set_hudmessage(220,80,0,0.05,0.15,0, statstime, 12.0, 1.0, 2.0, -1) getHits(victim,killer) show_hudmessage(victim,"%s killed you with %s^nfrom distance of %.2f meters.^nHe did %d damage to you with %d hit(s)^nand still has %dhp and %dap.^nYou did %d damage to him with %d hit(s).^nHe hits you in:^n%s", - killer_name,wpn,float(g_Killers[victim][3]) * 0.0254, stats[6],stats[5], - g_Killers[victim][1],g_Killers[victim][2], mstats[6],mstats[5],g_Buffer ) + killer_name,wpn,float(g_Killers[victim][3]) * 0.0254, stats[STATSX_DAMAGE],stats[STATSX_HITS], + g_Killers[victim][1],g_Killers[victim][2], mstats[STATSX_DAMAGE],mstats[STATSX_HITS],g_Buffer ) } if ( KillerHp ){ diff --git a/plugins/tfc/stats_logging.sma b/plugins/tfc/stats_logging.sma index e844803d..e28850b6 100755 --- a/plugins/tfc/stats_logging.sma +++ b/plugins/tfc/stats_logging.sma @@ -23,7 +23,7 @@ public plugin_init() public client_disconnected(id) { if ( is_user_bot( id ) ) return PLUGIN_CONTINUE remove_task( id ) - new szTeam[16],szName[MAX_NAME_LENGTH],szAuthid[32], iStats[8], iHits[8], szWeapon[24] + new szTeam[16],szName[MAX_NAME_LENGTH],szAuthid[32], iStats[STATSX_MAX_STATS], iHits[MAX_BODYHITS], szWeapon[24] new iUserid = get_user_userid( id ) get_user_team(id, szTeam, charsmax(szTeam) ) get_user_name(id, szName , charsmax(szName) ) @@ -33,9 +33,9 @@ public client_disconnected(id) { xmod_get_wpnlogname( i , szWeapon , charsmax(szWeapon) ) log_message("^"%s<%d><%s><%s>^" triggered ^"weaponstats^" (weapon ^"%s^") (shots ^"%d^") (hits ^"%d^") (kills ^"%d^") (headshots ^"%d^") (tks ^"%d^") (damage ^"%d^") (deaths ^"%d^")", - szName,iUserid,szAuthid,szTeam,szWeapon,iStats[4],iStats[5],iStats[0], iStats[2],iStats[3],iStats[6],iStats[1]) + szName,iUserid,szAuthid,szTeam,szWeapon,iStats[STATSX_SHOTS],iStats[STATSX_HITS],iStats[STATSX_KILLS], iStats[STATSX_HEADSHOTS],iStats[STATSX_TEAMKILLS],iStats[STATSX_DAMAGE],iStats[STATSX_DEATHS]) log_message("^"%s<%d><%s><%s>^" triggered ^"weaponstats2^" (weapon ^"%s^") (head ^"%d^") (chest ^"%d^") (stomach ^"%d^") (leftarm ^"%d^") (rightarm ^"%d^") (leftleg ^"%d^") (rightleg ^"%d^")", - szName,iUserid,szAuthid,szTeam,szWeapon,iHits[1],iHits[2],iHits[3], iHits[4],iHits[5],iHits[6],iHits[7]) + szName,iUserid,szAuthid,szTeam,szWeapon,iHits[HIT_HEAD],iHits[HIT_CHEST],iHits[HIT_STOMACH], iHits[HIT_LEFTARM],iHits[HIT_RIGHTARM],iHits[HIT_LEFTLEG],iHits[HIT_RIGHTLEG]) } } new iTime = get_user_time( id , 1 ) diff --git a/plugins/tfc/tfcstats.sma b/plugins/tfc/tfcstats.sma index 5dc4d980..2f7083fd 100755 --- a/plugins/tfc/tfcstats.sma +++ b/plugins/tfc/tfcstats.sma @@ -28,7 +28,7 @@ #include -public get_score(stats[8],body[8]) +public get_score(stats[STATSX_MAX_STATS],body[MAX_BODYHITS]) { - return stats[0] - stats[1] /* kills - deaths */ + return stats[STATSX_KILLS] - stats[STATSX_DEATHS] /* kills - deaths */ } diff --git a/plugins/ts/stats.sma b/plugins/ts/stats.sma index 2209d4a7..6dfe0891 100755 --- a/plugins/ts/stats.sma +++ b/plugins/ts/stats.sma @@ -67,7 +67,7 @@ new Float:g_DeathStats[MAX_PLAYERS + 1] new g_center1_sync new g_damage_sync -new g_bodyParts[8][] = {"whole body","head","chest","stomach","left arm","right arm","left leg","right leg"} +new g_bodyParts[MAX_BODYHITS][] = {"whole body","head","chest","stomach","left arm","right arm","left leg","right leg"} new g_HeMessages[4][] = { "%s sends a little gift to %s", @@ -165,17 +165,17 @@ public cmdStatsMe(id){ } public displayStats(id,dest) { - new name[32], stats[8], body[8] + new name[32], stats[STATSX_MAX_STATS], body[MAX_BODYHITS] get_user_wstats(id,0,stats,body) new pos = format(g_Buffer,charsmax(g_Buffer),"Kills: %d^nDeaths: %d^nTKs: %d^nDamage: %d^nHits: %d^nShots: %d^n^n", - stats[0],stats[1],stats[3],stats[6],stats[5],stats[4]) + stats[STATSX_KILLS],stats[STATSX_DEATHS],stats[STATSX_TEAMKILLS],stats[STATSX_DAMAGE],stats[STATSX_HITS],stats[STATSX_SHOTS]) for(new a = 1; a < TSMAX_WEAPONS; ++a) { if (get_user_wstats(id,a,stats,body)){ if ( xmod_is_melee_wpn(a) ) - stats[4] = -1; + stats[STATSX_SHOTS] = -1; xmod_get_wpnname(a,name,charsmax(name)) pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%s shots: %d hits: %d damage: %d kills: %d deaths: %d^n", - name,stats[4],stats[5],stats[6],stats[0],stats[1]) + name,stats[STATSX_SHOTS],stats[STATSX_HITS],stats[STATSX_DAMAGE],stats[STATSX_KILLS],stats[STATSX_DEATHS]) } } get_user_name(id,name,charsmax(name)) @@ -193,13 +193,13 @@ public cmdRank(id){ } displayRank(id,dest) { - new name[MAX_NAME_LENGTH], stats[8], body[8] + new name[MAX_NAME_LENGTH], stats[STATSX_MAX_STATS], body[MAX_BODYHITS] new rank_pos = get_user_stats(id,stats,body) new pos = format(g_Buffer,charsmax(g_Buffer),"Kills: %d^nDeaths: %d^nTKs: %d^nDamage: %d^nHits: %d^nShots: %d^n^n", - stats[0],stats[1],stats[3],stats[6],stats[5],stats[4]) + stats[STATSX_KILLS],stats[STATSX_DEATHS],stats[STATSX_TEAMKILLS],stats[STATSX_DAMAGE],stats[STATSX_HITS],stats[STATSX_SHOTS]) pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"Hits:^n%s: %d^n%s: %d^n%s: %d^n%s: %d^n%s: %d^n%s: %d^n%s: %d^n^n", - g_bodyParts[1],body[1],g_bodyParts[2],body[2],g_bodyParts[3],body[3], g_bodyParts[4],body[4], - g_bodyParts[5],body[5],g_bodyParts[6],body[6],g_bodyParts[7],body[7]) + g_bodyParts[HIT_HEAD],body[HIT_HEAD],g_bodyParts[HIT_CHEST],body[HIT_CHEST],g_bodyParts[HIT_STOMACH],body[HIT_STOMACH], g_bodyParts[HIT_LEFTARM],body[HIT_LEFTARM], + g_bodyParts[HIT_RIGHTARM],body[HIT_RIGHTARM],g_bodyParts[HIT_LEFTLEG],body[HIT_LEFTLEG],g_bodyParts[HIT_RIGHTLEG],body[HIT_RIGHTLEG]) format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%s rank is %d of %d",(id==dest)?"Your":"His", rank_pos,get_statsnum()) get_user_name(id,name,charsmax(name)) show_motd(dest,g_Buffer,name) @@ -217,7 +217,7 @@ public cmdTop15(id) { /* get top 15 */ getTop15(){ - new stats[8], body[8], name[MAX_NAME_LENGTH] + new stats[STATSX_MAX_STATS], body[MAX_BODYHITS], name[MAX_NAME_LENGTH] new pos = copy(g_Buffer,charsmax(g_Buffer),"# nick kills/deaths TKs hits/shots/headshots^n") new imax = get_statsnum() if (imax > 15) imax = 15 @@ -225,7 +225,7 @@ getTop15(){ get_stats(a,stats,body,name,charsmax(name)) replace_all(name, charsmax(name), "<", "[") replace_all(name, charsmax(name), ">", "]") - pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%2d. %-28.27s %d/%d %d %d/%d/%d^n",a+1,name,stats[0],stats[1],stats[3],stats[5],stats[4],stats[2]) + pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%2d. %-28.27s %d/%d %d %d/%d/%d^n",a+1,name,stats[STATSX_KILLS],stats[STATSX_DEATHS],stats[STATSX_TEAMKILLS],stats[STATSX_HITS],stats[STATSX_SHOTS],stats[STATSX_HEADSHOTS]) } } @@ -260,17 +260,17 @@ public cmdStats(id){ /* build list of attackers */ getAttackers(id) { - new name[MAX_NAME_LENGTH],wpn[32], stats[8],body[8],found=0 + new name[MAX_NAME_LENGTH],wpn[32], stats[STATSX_MAX_STATS],body[MAX_BODYHITS],found=0 new pos = copy(g_Buffer,charsmax(g_Buffer),"Attackers:^n") for(new a = 1; a <= MaxClients; ++a){ if(get_user_astats(id,a,stats,body,wpn,charsmax(wpn))){ found = 1 - if (stats[0]) + if (stats[STATSX_KILLS]) format(wpn,charsmax(wpn)," -- %s",wpn) else wpn[0] = 0 get_user_name(a,name,charsmax(name)) - pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%s -- %d dmg / %d hit(s)%s^n",name,stats[6],stats[5],wpn) + pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%s -- %d dmg / %d hit(s)%s^n",name,stats[STATSX_DAMAGE],stats[STATSX_HITS],wpn) } } return found @@ -278,17 +278,17 @@ getAttackers(id) { /* build list of victims */ getVictims(id) { - new name[MAX_NAME_LENGTH],wpn[32], stats[8],body[8],found=0 + new name[MAX_NAME_LENGTH],wpn[32], stats[STATSX_MAX_STATS],body[MAX_BODYHITS],found=0 new pos = copy(g_Buffer,charsmax(g_Buffer),"Victims:^n") for(new a = 1; a <= MaxClients; ++a){ if(get_user_vstats(id,a,stats,body,wpn,charsmax(wpn))){ found = 1 - if (stats[1]) + if (stats[STATSX_DEATHS]) format(wpn,charsmax(wpn)," -- %s",wpn) else wpn[0] = 0 get_user_name(a,name,charsmax(name)) - pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%s -- %d dmg / %d hit(s)%s^n",name,stats[6],stats[5],wpn) + pos += format(g_Buffer[pos],charsmax(g_Buffer)-pos,"%s -- %d dmg / %d hit(s)%s^n",name,stats[STATSX_DAMAGE],stats[STATSX_HITS],wpn) } } return found @@ -296,7 +296,7 @@ getVictims(id) { /* build list of hita for AV List */ getHits(id,killer) { - new stats[8], body[8], pos = 0 + new stats[STATSX_MAX_STATS], body[MAX_BODYHITS], pos = 0 g_Buffer[0] = 0 get_user_astats(id,killer,stats,body) for(new a = 1; a < sizeof(body); ++a) @@ -307,7 +307,7 @@ getHits(id,killer) { /* build list of hits for say hp */ getMyHits(id,killed) { - new name[MAX_NAME_LENGTH], stats[8], body[8], found = 0 + new name[MAX_NAME_LENGTH], stats[STATSX_MAX_STATS], body[MAX_BODYHITS], found = 0 get_user_name(killed,name,charsmax(name)) new pos = format(g_Buffer,charsmax(g_Buffer),"You hit %s in:",name) get_user_vstats(id,killed,stats,body) @@ -450,15 +450,15 @@ public client_death(killer,victim,wpnindex,hitplace,TK){ DisplayKillInfo(victim){ if ( ShowKiller ){ - new name[MAX_NAME_LENGTH], stats[8], body[8], wpn[32], mstats[8], mbody[8] + new name[MAX_NAME_LENGTH], stats[STATSX_MAX_STATS], body[MAX_BODYHITS], wpn[32], mstats[STATSX_MAX_STATS], mbody[MAX_BODYHITS] get_user_name(g_Killers[victim][0],name,charsmax(name)) get_user_astats(victim,g_Killers[victim][0],stats,body,wpn,charsmax(wpn)) get_user_vstats(victim,g_Killers[victim][0],mstats,mbody) set_hudmessage(220,80,0,0.05,0.15,0, 6.0, 12.0, 1.0, 2.0, -1) getHits(victim,g_Killers[victim][0]) show_hudmessage(victim,"%s killed you with %s^nfrom distance of %.2f meters.^nHe did %d damage to you with %d hit(s)^nand still has %dhp.^nYou did %d damage to him with %d hit(s).^nHe hits you in:^n%s", - name,wpn,float(g_Killers[victim][2]) * 0.0254, stats[6],stats[5], - g_Killers[victim][1], mstats[6],mstats[5],g_Buffer ) + name,wpn,float(g_Killers[victim][2]) * 0.0254, stats[STATSX_DAMAGE],stats[STATSX_HITS], + g_Killers[victim][1], mstats[STATSX_DAMAGE],mstats[STATSX_HITS],g_Buffer ) } } @@ -503,14 +503,14 @@ public cmdKiller(id) { return PLUGIN_HANDLED } if (g_Killers[id][0]) { - new name[MAX_NAME_LENGTH], stats[8], body[8], wpn[32], mstats[8], mbody[8] + new name[MAX_NAME_LENGTH], stats[STATSX_MAX_STATS], body[MAX_BODYHITS], wpn[32], mstats[STATSX_MAX_STATS], mbody[MAX_BODYHITS] get_user_name(g_Killers[id][0],name,charsmax(name)) get_user_astats(id,g_Killers[id][0],stats,body,wpn,charsmax(wpn)) get_user_vstats(id,g_Killers[id][0],mstats,mbody) client_print(id,print_chat,"%s killed you with %s from distance of %.2f meters", name,wpn,float(g_Killers[id][2]) * 0.0254 ) client_print(id,print_chat,"He did %d damage to you with %d hit(s) and still had %dhp", - stats[6],stats[5], g_Killers[id][1] ) - client_print(id,print_chat,"You did %d damage to him with %d hit(s)",mstats[6], mstats[5] ) + stats[STATSX_DAMAGE],stats[STATSX_HITS], g_Killers[id][1] ) + client_print(id,print_chat,"You did %d damage to him with %d hit(s)",mstats[STATSX_DAMAGE], mstats[STATSX_HITS] ) if (getMyHits(id,g_Killers[id][0])) client_print(id,print_chat, "%s", g_Buffer) } else { diff --git a/plugins/ts/stats_logging.sma b/plugins/ts/stats_logging.sma index bb8b651e..34381b02 100755 --- a/plugins/ts/stats_logging.sma +++ b/plugins/ts/stats_logging.sma @@ -25,7 +25,7 @@ public plugin_init() public client_disconnected(id) { if ( is_user_bot( id ) ) return PLUGIN_CONTINUE remove_task( id ) - new szTeam[16],szName[MAX_NAME_LENGTH],szAuthid[32], iStats[8], iHits[8], szWeapon[16] + new szTeam[16],szName[MAX_NAME_LENGTH],szAuthid[32], iStats[STATSX_MAX_STATS], iHits[MAX_BODYHITS], szWeapon[16] new iUserid = get_user_userid( id ) // team @@ -37,12 +37,12 @@ public client_disconnected(id) { if( get_user_wstats( id , i ,iStats , iHits ) ) { xmod_get_wpnlogname( i , szWeapon , charsmax(szWeapon) ) log_message("^"%s<%d><%s><%s>^" triggered ^"weaponstats^" (weapon ^"%s^") (shots ^"%d^") (hits ^"%d^") (kills ^"%d^") (headshots ^"%d^") (tks ^"%d^") (damage ^"%d^") (deaths ^"%d^")", - szName,iUserid,szAuthid,szTeam,szWeapon,iStats[4],iStats[5],iStats[0], - iStats[2],iStats[3],iStats[6],iStats[1]) + szName,iUserid,szAuthid,szTeam,szWeapon,iStats[STATSX_SHOTS],iStats[STATSX_HITS],iStats[STATSX_KILLS], + iStats[STATSX_HEADSHOTS],iStats[STATSX_TEAMKILLS],iStats[STATSX_DAMAGE],iStats[STATSX_DEATHS]) log_message("^"%s<%d><%s><%s>^" triggered ^"weaponstats2^" (weapon ^"%s^") (head ^"%d^") (chest ^"%d^") (stomach ^"%d^") (leftarm ^"%d^") (rightarm ^"%d^") (leftleg ^"%d^") (rightleg ^"%d^")", - szName,iUserid,szAuthid,szTeam,szWeapon,iHits[1],iHits[2],iHits[3], - iHits[4],iHits[5],iHits[6],iHits[7]) + szName,iUserid,szAuthid,szTeam,szWeapon,iHits[HIT_HEAD],iHits[HIT_CHEST],iHits[HIT_STOMACH], + iHits[HIT_LEFTARM],iHits[HIT_RIGHTARM],iHits[HIT_LEFTLEG],iHits[HIT_RIGHTLEG]) } } new iTime = get_user_time( id , 1 ) diff --git a/plugins/ts/tsstats.sma b/plugins/ts/tsstats.sma index f60dadd5..91151f10 100755 --- a/plugins/ts/tsstats.sma +++ b/plugins/ts/tsstats.sma @@ -28,7 +28,7 @@ #include -public get_score(stats[8],body[8]) +public get_score(stats[STATSX_MAX_STATS],body[MAX_BODYHITS]) { - return stats[0] - stats[1] - stats[3] /* kills - deaths - TKs */ + return stats[STATSX_KILLS] - stats[STATSX_DEATHS] - stats[STATSX_TEAMKILLS] /* kills - deaths - TKs */ } From 76378fd5d0083986bf1328cd3b9afdd8c885c9b5 Mon Sep 17 00:00:00 2001 From: justgo97 Date: Thu, 30 Aug 2018 17:43:05 +0100 Subject: [PATCH 2/5] Add get_playersnum_ex (#517) * Allow get_players to get the players num only * used empty brackets instead of zero * Add get_playersnum_ex stock to amxmisc.inc * Added missing empty brackets * Remove brackets from get_players * Fixed a typo in function description * Change letters to flags in get_playersnum_ex description --- plugins/include/amxmisc.inc | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/plugins/include/amxmisc.inc b/plugins/include/amxmisc.inc index 772b7f00..96fb92a8 100755 --- a/plugins/include/amxmisc.inc +++ b/plugins/include/amxmisc.inc @@ -863,9 +863,37 @@ stock set_task_ex(Float:time, const function[], id = 0, const any:parameter[] = * * @noreturn */ -stock get_players_ex(players[MAX_PLAYERS], &num, GetPlayersFlags:flags = GetPlayers_None, const team[] = "") +stock get_players_ex(players[MAX_PLAYERS] = {}, &num, GetPlayersFlags:flags = GetPlayers_None, const team[] = "") { new strFlags[10]; get_flags(_:flags, strFlags, charsmax(strFlags)); get_players(players, num, strFlags, team); } + +/** + * Returns the number of clients on the server that match the specified flags. + * + * @note Example retrieving all alive CTs: + * new AliveCt = get_playersnum_ex(GetPlayers_ExcludeDead | GetPlayers_MatchTeam, "CT") + * + * @param flags Optional filtering flags (enum GetPlayersFlags); valid flags are: + * GetPlayers_None - No filter (Default) + * GetPlayers_ExcludeDead - do not include dead clients + * GetPlayers_ExcludeAlive - do not include alive clients + * GetPlayers_ExcludeBots - do not include bots + * GetPlayers_ExcludeHuman - do not include human clients + * GetPlayers_MatchTeam - match with team + * GetPlayers_MatchNameSubstring - match with part of name + * GetPlayers_CaseInsensitive - match case insensitive + * GetPlayers_ExcludeHLTV - do not include HLTV proxies + * GetPlayers_IncludeConnecting - include connecting clients + * @param team String to match against if the GetPlayers_MatchTeam or GetPlayers_MatchNameSubstring flag is specified + * + * @return Number of clients on the server that match the specified flags + */ +stock get_playersnum_ex(GetPlayersFlags:flags = GetPlayers_None, const team[] = "") +{ + new PlayersNum; + get_players_ex(_, PlayersNum, flags, team); + return PlayersNum; +} From 6e9947b64faabc5d1c0b3cfac626021e8ed48fd9 Mon Sep 17 00:00:00 2001 From: Vincent Herbet Date: Thu, 30 Aug 2018 18:49:42 +0200 Subject: [PATCH 3/5] Sanitize load_amxscript() and add load_amxscript_ex/MF_LoadAmxScriptEx() requiring error max length (#530) * Add a saner version of load_amxscript and use SafeStrcpy/Sprintf * Reflect the change in core * Add LoadAmxScriptEx API function * Reflect the change in CSX * Reflect the change in DodX * Reflect the change in TFCX * Reflect the change in TSX * Add few comments --- amxmodx/CPlugin.cpp | 10 +++--- amxmodx/CPlugin.h | 4 +-- amxmodx/amxmodx.h | 1 + amxmodx/modules.cpp | 58 +++++++++++++++++++------------ modules/cstrike/csx/CRank.cpp | 4 +-- modules/cstrike/csx/CRank.h | 2 +- modules/cstrike/csx/meta_api.cpp | 2 +- modules/dod/dodx/CRank.cpp | 4 +-- modules/dod/dodx/CRank.h | 2 +- modules/dod/dodx/moduleconfig.cpp | 2 +- modules/tfcx/CRank.cpp | 4 +-- modules/tfcx/CRank.h | 2 +- modules/tfcx/moduleconfig.cpp | 2 +- modules/ts/tsx/CRank.cpp | 4 +-- modules/ts/tsx/CRank.h | 2 +- modules/ts/tsx/moduleconfig.cpp | 2 +- public/sdk/amxxmodule.cpp | 5 ++- public/sdk/amxxmodule.h | 3 ++ 18 files changed, 66 insertions(+), 47 deletions(-) diff --git a/amxmodx/CPlugin.cpp b/amxmodx/CPlugin.cpp index 34731d49..eee6d6e6 100755 --- a/amxmodx/CPlugin.cpp +++ b/amxmodx/CPlugin.cpp @@ -18,14 +18,14 @@ extern const char *no_function; -CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error, int debug) +CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error, size_t maxLength, int debug) { CPlugin** a = &head; while (*a) a = &(*a)->next; - *a = new CPlugin(pCounter++, path, name, error, debug); + *a = new CPlugin(pCounter++, path, name, error, maxLength, debug); return (*a); } @@ -137,7 +137,7 @@ int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn) continue; } - CPlugin* plugin = loadPlugin(pluginsDir, pluginName, error, debugFlag); + CPlugin* plugin = loadPlugin(pluginsDir, pluginName, error, sizeof(error), debugFlag); if (plugin->getStatusCode() == ps_bad_load) { @@ -267,7 +267,7 @@ const char* CPluginMngr::CPlugin::getStatus() const return "error"; } -CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, int d) : name(n), title(n), m_pNullStringOfs(nullptr), m_pNullVectorOfs(nullptr) +CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, size_t m, int d) : name(n), title(n), m_pNullStringOfs(nullptr), m_pNullVectorOfs(nullptr) { const char* unk = "unknown"; @@ -280,7 +280,7 @@ CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, int char* path = build_pathname_r(file, sizeof(file), "%s/%s", p, n); code = 0; memset(&amx, 0, sizeof(AMX)); - int err = load_amxscript(&amx, &code, path, e, d); + int err = load_amxscript_ex(&amx, &code, path, e, m, d); if (err == AMX_ERR_NONE) { diff --git a/amxmodx/CPlugin.h b/amxmodx/CPlugin.h index 791c3a4c..849ce4ca 100755 --- a/amxmodx/CPlugin.h +++ b/amxmodx/CPlugin.h @@ -66,7 +66,7 @@ public: CPlugin* next; int id; - CPlugin(int i, const char* p, const char* n, char* e, int d); + CPlugin(int i, const char* p, const char* n, char* e, size_t m, int d); ~CPlugin(); bool m_Debug; @@ -122,7 +122,7 @@ public: // Interface - CPlugin* loadPlugin(const char* path, const char* name, char* error, int debug); + CPlugin* loadPlugin(const char* path, const char* name, char* error, size_t maxLength, int debug); void unloadPlugin(CPlugin** a); int loadPluginsFromFile(const char* filename, bool warn=true); diff --git a/amxmodx/amxmodx.h b/amxmodx/amxmodx.h index 58d0c32a..7216793a 100755 --- a/amxmodx/amxmodx.h +++ b/amxmodx/amxmodx.h @@ -284,6 +284,7 @@ extern "C" size_t get_amxstring_r(AMX *amx, cell amx_addr, char *destination, in int amxstring_len(cell* cstr); int load_amxscript(AMX* amx, void** program, const char* path, char error[64], int debug); +int load_amxscript_ex(AMX* amx, void** program, const char* path, char *error, size_t maxLength, int debug); int set_amxnatives(AMX* amx, char error[64]); int set_amxstring(AMX *amx, cell amx_addr, const char *source, int max); int set_amxstring_simple(cell *dest, const char *source, int max); diff --git a/amxmodx/modules.cpp b/amxmodx/modules.cpp index 2fe002d6..4f1e5fe3 100755 --- a/amxmodx/modules.cpp +++ b/amxmodx/modules.cpp @@ -108,7 +108,7 @@ static binlogfuncs_t logfuncs = }; #endif -int load_amxscript(AMX *amx, void **program, const char *filename, char error[64], int debug) +int load_amxscript_internal(AMX *amx, void **program, const char *filename, char *error, size_t maxLength, int debug) { *error = 0; size_t bufSize; @@ -127,7 +127,7 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 if (!*program) { - strcpy(error, "Failed to allocate memory"); + ke::SafeStrcpy(error, maxLength, "Failed to allocate memory"); return (amx->error = AMX_ERR_MEMORY); } @@ -140,31 +140,31 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 case CAmxxReader::Err_None: break; case CAmxxReader::Err_FileOpen: - strcpy(error, "Plugin file open error"); + ke::SafeStrcpy(error, maxLength, "Plugin file open error"); return (amx->error = AMX_ERR_NOTFOUND); case CAmxxReader::Err_FileRead: - strcpy(error, "Plugin file read error"); + ke::SafeStrcpy(error, maxLength, "Plugin file read error"); return (amx->error = AMX_ERR_NOTFOUND); case CAmxxReader::Err_InvalidParam: - strcpy(error, "Internal error: Invalid parameter"); + ke::SafeStrcpy(error, maxLength, "Internal error: Invalid parameter"); return (amx->error = AMX_ERR_NOTFOUND); case CAmxxReader::Err_FileInvalid: - strcpy(error, "Invalid Plugin"); + ke::SafeStrcpy(error, maxLength, "Invalid Plugin"); return (amx->error = AMX_ERR_FORMAT); case CAmxxReader::Err_SectionNotFound: - strcpy(error, "Searched section not found (.amxx)"); + ke::SafeStrcpy(error, maxLength, "Searched section not found (.amxx)"); return (amx->error = AMX_ERR_NOTFOUND); case CAmxxReader::Err_DecompressorInit: - strcpy(error, "Decompressor initialization failed"); + ke::SafeStrcpy(error, maxLength, "Decompressor initialization failed"); return (amx->error = AMX_ERR_INIT); case CAmxxReader::Err_Decompress: - strcpy(error, "Internal error: Decompress"); + ke::SafeStrcpy(error, maxLength, "Internal error: Decompress"); return (amx->error = AMX_ERR_NOTFOUND); case CAmxxReader::Err_OldFile: - strcpy(error, "Plugin uses deprecated format. Update compiler"); + ke::SafeStrcpy(error, maxLength, "Plugin uses deprecated format. Update compiler"); return (amx->error = AMX_ERR_FORMAT); default: - strcpy(error, "Unknown error"); + ke::SafeStrcpy(error, maxLength, "Unknown error"); return (amx->error = AMX_ERR_NOTFOUND); } } else { @@ -178,7 +178,7 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 if (magic != AMX_MAGIC) { - strcpy(error, "Invalid Plugin"); + ke::SafeStrcpy(error, maxLength, "Invalid Plugin"); return (amx->error = AMX_ERR_FORMAT); } @@ -191,7 +191,7 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 { if ((hdr->file_version < CUR_FILE_VERSION)) { - sprintf(error, "Plugin needs newer debug version info"); + ke::SafeStrcpy(error, maxLength, "Plugin needs newer debug version info"); return (amx->error = AMX_ERR_VERSION); } else if ((hdr->flags & AMX_FLAG_DEBUG) != 0) @@ -209,13 +209,13 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 { dbg_FreeInfo(pDbg); delete pDbg; - sprintf(error, "Debug loading error %d", err); + ke::SafeSprintf(error, maxLength, "Debug loading error %d", err); return (amx->error = AMX_ERR_INIT); } amx->flags |= AMX_FLAG_DEBUG; } else { - sprintf(error, "Plugin not compiled with debug option"); + ke::SafeStrcpy(error, maxLength, "Plugin not compiled with debug option"); return (amx->error = AMX_ERR_INIT); } } else { @@ -238,7 +238,7 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 delete pDbg; } - sprintf(error, "Load error %d (invalid file format or version)", err); + ke::SafeSprintf(error, maxLength, "Load error %d (invalid file format or version)", err); return (amx->error = AMX_ERR_INIT); } @@ -276,7 +276,7 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 { delete[] np; delete[] rt; - strcpy(error, "Failed to initialize JIT'd plugin"); + ke::SafeStrcpy(error, maxLength, "Failed to initialize JIT'd plugin"); return (amx->error = AMX_ERR_INIT); } @@ -307,14 +307,14 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 if (*program == 0) { - strcpy(error, "Failed to allocate memory"); + ke::SafeStrcpy(error, maxLength, "Failed to allocate memory"); return (amx->error = AMX_ERR_MEMORY); } } else { delete[] np; delete[] rt; - sprintf(error, "Failed to initialize plugin (%d)", err); + ke::SafeSprintf(error, maxLength, "Failed to initialize plugin (%d)", err); return (amx->error = AMX_ERR_INIT_JIT); } @@ -325,7 +325,7 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 if (!script) { - ke::SafeSprintf(error, 64, "Failed to allocate memory for script"); + ke::SafeStrcpy(error, maxLength, "Failed to allocate memory for script"); return (amx->error = AMX_ERR_MEMORY); } @@ -341,7 +341,7 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 { if (amx_Register(amx, core_Natives, -1) != AMX_ERR_NONE) { - sprintf(error, "Plugin uses an unknown function (name \"%s\") - check your modules.ini.", no_function); + ke::SafeSprintf(error, maxLength, "Plugin uses an unknown function (name \"%s\") - check your modules.ini.", no_function); return (amx->error = AMX_ERR_NOTFOUND); } } else { @@ -352,6 +352,17 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 return (amx->error = AMX_ERR_NONE); } +int load_amxscript_ex(AMX *amx, void **program, const char *filename, char *error, size_t maxLength, int debug) +{ + return load_amxscript_internal(amx, program, filename, error, maxLength, debug); +} + +// Deprecated. Use load_amxscript_ex() or MF_LoadAmxScriptEx() for modules. This function is kept to maintain backward compatibility. +int load_amxscript(AMX *amx, void **program, const char *filename, char error[64], int debug) +{ + return load_amxscript_internal(amx, program, filename, error, 64 /* error max length */, debug); +} + const char *StrCaseStr(const char *as, const char *bs) { static char a[256]; @@ -1759,9 +1770,10 @@ void Module_CacheFunctions() REGISTER_FUNC("GetAmxScriptName", MNF_GetAmxScriptName) REGISTER_FUNC("FindAmxScriptByName", MNF_FindAmxScriptByName) REGISTER_FUNC("FindAmxScriptByAmx", MNF_FindAmxScriptByAmx) - REGISTER_FUNC("LoadAmxScript", load_amxscript) + REGISTER_FUNC("LoadAmxScript", load_amxscript) // Deprecated. Please use LoadAmxScriptEx instead. + REGISTER_FUNC("LoadAmxScriptEx", load_amxscript_ex) REGISTER_FUNC("UnloadAmxScript", unload_amxscript) - + // String / mem in amx scripts support REGISTER_FUNC("SetAmxString", set_amxstring) REGISTER_FUNC("SetAmxStringUTF8Char", set_amxstring_utf8_char) diff --git a/modules/cstrike/csx/CRank.cpp b/modules/cstrike/csx/CRank.cpp index b05bccfe..433b581b 100644 --- a/modules/cstrike/csx/CRank.cpp +++ b/modules/cstrike/csx/CRank.cpp @@ -139,9 +139,9 @@ void RankSystem::clear(){ -bool RankSystem::loadCalc(const char* filename, char* error) +bool RankSystem::loadCalc(const char* filename, char* error, size_t maxLength) { - if ((MF_LoadAmxScript(&calc.amx,&calc.code,filename,error,0)!=AMX_ERR_NONE)|| + if ((MF_LoadAmxScriptEx(&calc.amx,&calc.code,filename, error, maxLength, 0)!=AMX_ERR_NONE)|| (MF_AmxAllot(&calc.amx, 11 , &calc.amxAddr1, &calc.physAddr1)!=AMX_ERR_NONE)|| (MF_AmxAllot(&calc.amx, 8 , &calc.amxAddr2, &calc.physAddr2)!=AMX_ERR_NONE)|| (MF_AmxFindPublic(&calc.amx,"get_score",&calc.func)!=AMX_ERR_NONE)){ diff --git a/modules/cstrike/csx/CRank.h b/modules/cstrike/csx/CRank.h index ec5e8248..af076612 100644 --- a/modules/cstrike/csx/CRank.h +++ b/modules/cstrike/csx/CRank.h @@ -110,7 +110,7 @@ public: void saveRank( const char* filename ); void loadRank( const char* filename ); RankStats* findEntryInRank(const char* unique, const char* name, bool isip=false); - bool loadCalc(const char* filename, char* error); + bool loadCalc(const char* filename, char* error, size_t maxLength); inline int getRankNum( ) const { return rankNum; } void clear(); void unloadCalc(); diff --git a/modules/cstrike/csx/meta_api.cpp b/modules/cstrike/csx/meta_api.cpp index f438d84f..ca0ff231 100644 --- a/modules/cstrike/csx/meta_api.cpp +++ b/modules/cstrike/csx/meta_api.cpp @@ -421,7 +421,7 @@ void OnAmxxAttach(){ if ( path && *path ) { char error[128]; - g_rank.loadCalc( MF_BuildPathname("%s",path) , error ); + g_rank.loadCalc( MF_BuildPathname("%s",path) , error, sizeof(error)); } if ( !g_rank.begin() ) diff --git a/modules/dod/dodx/CRank.cpp b/modules/dod/dodx/CRank.cpp index 8a5b7462..e8f49272 100644 --- a/modules/dod/dodx/CRank.cpp +++ b/modules/dod/dodx/CRank.cpp @@ -128,9 +128,9 @@ void RankSystem::clear(){ } } -bool RankSystem::loadCalc(const char* filename, char* error) +bool RankSystem::loadCalc(const char* filename, char* error, size_t maxLength) { - if ((MF_LoadAmxScript(&calc.amx,&calc.code,filename,error,0)!=AMX_ERR_NONE)|| + if ((MF_LoadAmxScriptEx(&calc.amx,&calc.code,filename, error, maxLength, 0)!=AMX_ERR_NONE)|| (MF_AmxAllot(&calc.amx, 8 , &calc.amxAddr1, &calc.physAddr1)!=AMX_ERR_NONE)|| (MF_AmxAllot(&calc.amx, 8 , &calc.amxAddr2, &calc.physAddr2)!=AMX_ERR_NONE)|| (MF_AmxFindPublic(&calc.amx,"get_score",&calc.func)!=AMX_ERR_NONE)){ diff --git a/modules/dod/dodx/CRank.h b/modules/dod/dodx/CRank.h index f354eedc..265f6eb1 100644 --- a/modules/dod/dodx/CRank.h +++ b/modules/dod/dodx/CRank.h @@ -104,7 +104,7 @@ public: void saveRank( const char* filename ); void loadRank( const char* filename ); RankStats* findEntryInRank(const char* unique, const char* name , bool isip = false); - bool loadCalc(const char* filename, char* error); + bool loadCalc(const char* filename, char* error, size_t maxLength); inline int getRankNum( ) const { return rankNum; } void clear(); void unloadCalc(); diff --git a/modules/dod/dodx/moduleconfig.cpp b/modules/dod/dodx/moduleconfig.cpp index ffa0e2e8..00606bfb 100644 --- a/modules/dod/dodx/moduleconfig.cpp +++ b/modules/dod/dodx/moduleconfig.cpp @@ -471,7 +471,7 @@ void OnAmxxAttach() if ( path && *path ) { char error[128]; - g_rank.loadCalc( MF_BuildPathname("%s",path) , error ); + g_rank.loadCalc( MF_BuildPathname("%s",path) , error, sizeof(error)); } if ( !g_rank.begin() ) diff --git a/modules/tfcx/CRank.cpp b/modules/tfcx/CRank.cpp index 5276bcec..6c0a6fd5 100644 --- a/modules/tfcx/CRank.cpp +++ b/modules/tfcx/CRank.cpp @@ -127,9 +127,9 @@ void RankSystem::clear(){ } } -bool RankSystem::loadCalc(const char* filename, char* error) +bool RankSystem::loadCalc(const char* filename, char* error, size_t maxLength) { - if ((MF_LoadAmxScript(&calc.amx,&calc.code,filename,error,0)!=AMX_ERR_NONE)|| + if ((MF_LoadAmxScriptEx(&calc.amx,&calc.code,filename, error, maxLength, 0)!=AMX_ERR_NONE)|| (MF_AmxAllot(&calc.amx, 8 , &calc.amxAddr1, &calc.physAddr1)!=AMX_ERR_NONE)|| (MF_AmxAllot(&calc.amx, 8 , &calc.amxAddr2, &calc.physAddr2)!=AMX_ERR_NONE)|| (MF_AmxFindPublic(&calc.amx,"get_score",&calc.func)!=AMX_ERR_NONE)){ diff --git a/modules/tfcx/CRank.h b/modules/tfcx/CRank.h index 575e9d42..737cc310 100644 --- a/modules/tfcx/CRank.h +++ b/modules/tfcx/CRank.h @@ -102,7 +102,7 @@ public: void saveRank( const char* filename ); void loadRank( const char* filename ); RankStats* findEntryInRank(const char* unique, const char* name , bool isip = false); - bool loadCalc(const char* filename, char* error); + bool loadCalc(const char* filename, char* error, size_t maxLength); inline int getRankNum( ) const { return rankNum; } void clear(); void unloadCalc(); diff --git a/modules/tfcx/moduleconfig.cpp b/modules/tfcx/moduleconfig.cpp index 0fff9b90..0b8bd5dd 100644 --- a/modules/tfcx/moduleconfig.cpp +++ b/modules/tfcx/moduleconfig.cpp @@ -330,7 +330,7 @@ void OnAmxxAttach() { if ( path && *path ) { char error[128]; - g_rank.loadCalc( MF_BuildPathname("%s",path) , error ); + g_rank.loadCalc( MF_BuildPathname("%s",path), error, sizeof(error)); } if ( !g_rank.begin() ) { diff --git a/modules/ts/tsx/CRank.cpp b/modules/ts/tsx/CRank.cpp index 0a439788..2cb8603e 100644 --- a/modules/ts/tsx/CRank.cpp +++ b/modules/ts/tsx/CRank.cpp @@ -127,9 +127,9 @@ void RankSystem::clear(){ } } -bool RankSystem::loadCalc(const char* filename, char* error) +bool RankSystem::loadCalc(const char* filename, char* error, size_t maxLength) { - if ((MF_LoadAmxScript(&calc.amx,&calc.code,filename,error,0)!=AMX_ERR_NONE)|| + if ((MF_LoadAmxScriptEx(&calc.amx,&calc.code,filename, error, maxLength, 0)!=AMX_ERR_NONE)|| (MF_AmxAllot(&calc.amx, 8 , &calc.amxAddr1, &calc.physAddr1)!=AMX_ERR_NONE)|| (MF_AmxAllot(&calc.amx, 8 , &calc.amxAddr2, &calc.physAddr2)!=AMX_ERR_NONE)|| (MF_AmxFindPublic(&calc.amx,"get_score",&calc.func)!=AMX_ERR_NONE)){ diff --git a/modules/ts/tsx/CRank.h b/modules/ts/tsx/CRank.h index 149796b0..b6cc3ac1 100644 --- a/modules/ts/tsx/CRank.h +++ b/modules/ts/tsx/CRank.h @@ -102,7 +102,7 @@ public: void saveRank( const char* filename ); void loadRank( const char* filename ); RankStats* findEntryInRank(const char* unique, const char* name , bool isip = false ); - bool loadCalc(const char* filename, char* error); + bool loadCalc(const char* filename, char* error, size_t maxLength); inline int getRankNum( ) const { return rankNum; } void clear(); void unloadCalc(); diff --git a/modules/ts/tsx/moduleconfig.cpp b/modules/ts/tsx/moduleconfig.cpp index 158d1789..3beb8323 100644 --- a/modules/ts/tsx/moduleconfig.cpp +++ b/modules/ts/tsx/moduleconfig.cpp @@ -344,7 +344,7 @@ void OnAmxxAttach() if ( path && *path ) { char error[128]; - g_rank.loadCalc( MF_BuildPathname("%s",path) , error ); + g_rank.loadCalc( MF_BuildPathname("%s",path), error, sizeof(error)); } if ( !g_rank.begin() ) { diff --git a/public/sdk/amxxmodule.cpp b/public/sdk/amxxmodule.cpp index c01a0268..1be7b24b 100644 --- a/public/sdk/amxxmodule.cpp +++ b/public/sdk/amxxmodule.cpp @@ -2399,6 +2399,7 @@ PFN_AMX_EXECV g_fn_AmxExecv; PFN_AMX_ALLOT g_fn_AmxAllot; PFN_AMX_FINDPUBLIC g_fn_AmxFindPublic; PFN_LOAD_AMXSCRIPT g_fn_LoadAmxScript; +PFN_LOAD_AMXSCRIPT_EX g_fn_LoadAmxScriptEx; PFN_UNLOAD_AMXSCRIPT g_fn_UnloadAmxScript; PFN_REAL_TO_CELL g_fn_RealToCell; PFN_CELL_TO_REAL g_fn_CellToReal; @@ -2491,7 +2492,8 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc) REQFUNC("GetAmxScript", g_fn_GetAmxScript, PFN_GET_AMXSCRIPT); REQFUNC("FindAmxScriptByAmx", g_fn_FindAmxScriptByAmx, PFN_FIND_AMXSCRIPT_BYAMX); REQFUNC("FindAmxScriptByName", g_fn_FindAmxScriptByName, PFN_FIND_AMXSCRIPT_BYNAME); - REQFUNC("LoadAmxScript", g_fn_LoadAmxScript, PFN_LOAD_AMXSCRIPT); + REQFUNC("LoadAmxScript", g_fn_LoadAmxScript, PFN_LOAD_AMXSCRIPT); // Deprecated. Please use LoadAmxScriptEx instead. + REQFUNC("LoadAmxScriptEx", g_fn_LoadAmxScriptEx, PFN_LOAD_AMXSCRIPT_EX); REQFUNC("UnloadAmxScript", g_fn_UnloadAmxScript, PFN_UNLOAD_AMXSCRIPT); REQFUNC("GetAmxScriptName", g_fn_GetAmxScriptName, PFN_GET_AMXSCRIPTNAME); @@ -2695,6 +2697,7 @@ void ValidateMacros_DontCallThis_Smiley() MF_AmxFindPublic(0, 0, 0); MF_AmxAllot(0, 0, 0, 0); MF_LoadAmxScript(0, 0, 0, 0, 0); + MF_LoadAmxScriptEx(0, 0, 0, 0, 0, 0); MF_UnloadAmxScript(0, 0); MF_RegisterSPForward(0, 0, 0, 0, 0, 0); MF_RegisterSPForwardByName(0, 0, 0, 0, 0, 0); diff --git a/public/sdk/amxxmodule.h b/public/sdk/amxxmodule.h index bdcddde4..ea635af0 100644 --- a/public/sdk/amxxmodule.h +++ b/public/sdk/amxxmodule.h @@ -2199,6 +2199,7 @@ typedef int (*PFN_AMX_ALLOT) (AMX* /*amx*/, int /*length*/, cell* /*amx_ad typedef int (*PFN_AMX_FINDPUBLIC) (AMX* /*amx*/, const char* /*func name*/, int* /*index*/); typedef int (*PFN_AMX_FINDNATIVE) (AMX* /*amx*/, const char* /*func name*/, int* /*index*/); typedef int (*PFN_LOAD_AMXSCRIPT) (AMX* /*amx*/, void** /*code*/, const char* /*path*/, char[64] /*error info*/, int /* debug */); +typedef int (*PFN_LOAD_AMXSCRIPT_EX) (AMX* /*amx*/, void** /*code*/, const char* /*path*/, char* /*error info*/, size_t /* max length */, int /* debug */); typedef int (*PFN_UNLOAD_AMXSCRIPT) (AMX* /*amx*/,void** /*code*/); typedef cell (*PFN_REAL_TO_CELL) (REAL /*x*/); typedef REAL (*PFN_CELL_TO_REAL) (cell /*x*/); @@ -2274,6 +2275,7 @@ extern PFN_AMX_EXEC g_fn_AmxExec; extern PFN_AMX_ALLOT g_fn_AmxAllot; extern PFN_AMX_FINDPUBLIC g_fn_AmxFindPublic; extern PFN_LOAD_AMXSCRIPT g_fn_LoadAmxScript; +extern PFN_LOAD_AMXSCRIPT_EX g_fn_LoadAmxScriptEx; extern PFN_UNLOAD_AMXSCRIPT g_fn_UnloadAmxScript; extern PFN_REAL_TO_CELL g_fn_RealToCell; extern PFN_CELL_TO_REAL g_fn_CellToReal; @@ -2437,6 +2439,7 @@ void MF_LogError(AMX *amx, int err, const char *fmt, ...); #define MF_AmxAllot g_fn_AmxAllot #define MF_AmxFindNative g_fn_AmxFindNative #define MF_LoadAmxScript g_fn_LoadAmxScript +#define MF_LoadAmxScriptEx g_fn_LoadAmxScriptEx #define MF_UnloadAmxScript g_fn_UnloadAmxScript #define MF_MergeDefinitionFile g_fn_MergeDefinition_File #define amx_ctof g_fn_CellToReal From 1a2dd9e7eaeefa4726a5813f31a4672279163599 Mon Sep 17 00:00:00 2001 From: Vincent Herbet Date: Thu, 30 Aug 2018 19:16:19 +0200 Subject: [PATCH 4/5] Update Fun module (#421) * Fun: Replace ENTINDEX with TypeConversion for consistency * Fun: Add a class wrapping player's data * Fun: Make TraceLine a post forward Reason: as it is it breaks plugins hooking TraceLine because of the original game call is being superceded and other modules can't catch it. It looks like it's this way from the very start fun module has been introduced 13 years ago before. Fakemeta module comes a little later. * Fun: Clean up code * Fun: Toggle PlayerPreThink forward on demand * Fun: Toggle TraceLine forward on demand * Fun: Add HITZONE* constants for use with set/get_user_hitzone() * Fun: Refactor a litte the player class * Fun: Clean up a little more * Fun: Fix typo in set_user_hitzones from previous commit --- modules/fun/fun.cpp | 799 +++++++++++++++---------------------- modules/fun/fun.h | 174 +++++++- modules/fun/moduleconfig.h | 6 +- plugins/include/fun.inc | 29 +- 4 files changed, 514 insertions(+), 494 deletions(-) diff --git a/modules/fun/fun.cpp b/modules/fun/fun.cpp index 44e42790..33a1e377 100644 --- a/modules/fun/fun.cpp +++ b/modules/fun/fun.cpp @@ -11,590 +11,464 @@ // Fun Module // -#include #include "fun.h" #include -/* - JGHG says: - - Ok this is what I use below, it may probably not be right with all natives etc but I try to maintain this style to natives. - Note that this is still very much subject to change, regarding return values etc! - (Ok I haven't checked all natives that they comply with this yet, this is just a model I'm working on and which I might implement soon.) - - static cell AMX_NATIVE_CALL nativename(AMX *amx, cell *params) // nativename(argument1, argument2); = 2 params - { - // Description what this native does. <--- Description what this native does - // params[1] = argument1 <--- Description of each argument, so we don't have to allocate new variables and can - // params[2] = argument2 <--- use the ones in params[n] directly, to save some time. - - // Check receiver and sender validity. <--- Check ents, maybe need to do this better and more proper later? - CHECK_PLAYER(params[1]) - CHECK_PLAYER(params[2]) - - // Get * pointer. - edict_t *pPlayer = MF_GetPlayerEdict(params[1]); <--- Players require a different function than INDEXENT because of an HLSDK bug - - return 1 <--- If native succeeded, return 1, if the native isn't supposed to return a specific value. - Note: Should be able to do: if (thenative()) and it should return false when it fails, and true when succeeds... is -1 treated as false, or is 0 a must? - } -*/ - -char g_bodyhits[33][33]; // where can the guy in the first dimension hit the people in the 2nd dimension? :-) -bool g_silent[33]; // used for set_user_footsteps() - HLTypeConversion TypeConversion; +CPlayers Players; -// ######## Utils: -void FUNUTIL_ResetPlayer(int index) +// native get_client_listen(receiver, sender) +static cell AMX_NATIVE_CALL get_client_listening(AMX *amx, cell *params) { - //MF_PrintSrvConsole("Resetting player index %d! maxclients: %d\n", index, gpGlobals->maxClients); - for (int i = 1; i <= gpGlobals->maxClients; i++) { - g_bodyhits[index][i] = (char)((1<v.takedamage = 0.0; // 0.0, the player doesn't seem to be able to get hurt. - } - else { - // Disable godmode - pPlayer->v.takedamage = 2.0; // 2.0 seems to be standard value? - } + pPlayer->v.takedamage = params[arg_godmode] != 0 ? DAMAGE_NO : DAMAGE_AIM; return 1; } -static cell AMX_NATIVE_CALL get_user_godmode(AMX *amx, cell *params) // get_user_godmode(index); = 1 param +// native get_user_godmode(index) +static cell AMX_NATIVE_CALL get_user_godmode(AMX *amx, cell *params) { - /* Returns 1 if godmode is set. */ - // params[1] = index + enum args { arg_count, arg_user }; - // Check index. - CHECK_PLAYER(params[1]); + CHECK_PLAYER(params[arg_user]); - // Get player pointer. - edict_t *pPlayer = TypeConversion.id_to_edict(params[1]); + const auto pPlayer = TypeConversion.id_to_edict(params[arg_user]); - int godmode = 0; - - if (pPlayer->v.takedamage == 0.0) { - // God mode is enabled - godmode = 1; - } - - return godmode; + return pPlayer->v.takedamage == DAMAGE_NO; } -static cell AMX_NATIVE_CALL give_item(AMX *amx, cell *params) // native give_item(index, const item[]); = 2 params +// native give_item(index, const item[]) +static cell AMX_NATIVE_CALL give_item(AMX *amx, cell *params) { - /* Gives item to player, name of item can start - * with weapon_, ammo_ and item_. This event - * is announced with proper message to all players. */ - // params[1] = index - // params[2] = item... + enum args { arg_count, arg_index, arg_item }; - // Check index. - CHECK_PLAYER(params[1]); + CHECK_PLAYER(params[arg_index]); - // Get player pointer. - edict_t *pPlayer = TypeConversion.id_to_edict(params[1]); + auto itemLength = 0; + const auto item = MF_GetAmxString(amx, params[arg_item], 1, &itemLength); - // Create item entity pointer - edict_t *pItemEntity; - - // Make an "intstring" out of 2nd parameter - int length; - const char *szItem = MF_GetAmxString(amx, params[2], 1, &length); - - //check for valid item - if (strncmp(szItem, "weapon_", 7) && - strncmp(szItem, "ammo_", 5) && - strncmp(szItem, "item_", 5) && - strncmp(szItem, "tf_weapon_", 10) - ) { + if (!itemLength + ||(strncmp(item, "weapon_", 7) != 0 + && strncmp(item, "ammo_", 5) != 0 + && strncmp(item, "item_", 5) != 0 + && strncmp(item, "tf_weapon_", 10) != 0)) + { return 0; } - //string_t item = MAKE_STRING(szItem); - string_t item = ALLOC_STRING(szItem); // Using MAKE_STRING makes "item" contents get lost when we leave this scope! ALLOC_STRING seems to allocate properly... - // Create the entity, returns to pointer - pItemEntity = CREATE_NAMED_ENTITY(item); + auto pEntity = CREATE_NAMED_ENTITY(ALLOC_STRING(item)); - if (FNullEnt(pItemEntity)) { - MF_LogError(amx, AMX_ERR_NATIVE, "Item \"%s\" failed to create", szItem); + if (FNullEnt(pEntity)) + { + MF_LogError(amx, AMX_ERR_NATIVE, "Item \"%s\" failed to create", item); return 0; } - //VARS(pItemEntity)->origin = VARS(pPlayer)->origin; // nice to do VARS(ent)->origin instead of ent->v.origin? :-I - //I'm not sure, normally I use macros too =P - pItemEntity->v.origin = pPlayer->v.origin; - pItemEntity->v.spawnflags |= SF_NORESPAWN; //SF_NORESPAWN; + const auto pPlayer = TypeConversion.id_to_edict(params[arg_index]); - MDLL_Spawn(pItemEntity); + pEntity->v.origin = pPlayer->v.origin; + pEntity->v.spawnflags |= SF_NORESPAWN; - int save = pItemEntity->v.solid; + MDLL_Spawn(pEntity); - MDLL_Touch(pItemEntity, ENT(pPlayer)); + const auto oldSolid = pEntity->v.solid; - //The problem with the original give_item was the - // item was not removed. I had tried this but it - // did not work. OLO's implementation is better. - /* - int iEnt = ENTINDEX(pItemEntity->v.owner); - if (iEnt > 32 || iEnt <1 ) { - MDLL_Think(pItemEntity); - }*/ + MDLL_Touch(pEntity, pPlayer); - if (pItemEntity->v.solid == save) { - REMOVE_ENTITY(pItemEntity); - //the function did not fail - we're just deleting the item + if (pEntity->v.solid == oldSolid) + { + REMOVE_ENTITY(pEntity); // The function did not fail - we're just deleting the item return -1; } - return ENTINDEX(pItemEntity); + return TypeConversion.edict_to_id(pEntity); } -static cell AMX_NATIVE_CALL spawn(AMX *amx, cell *params) // spawn(id) = 1 param +// native spawn(index) +static cell AMX_NATIVE_CALL spawn(AMX *amx, cell *params) { - // Spawns an entity, this can be a user/player -> spawns at spawnpoints, or created entities seems to need this as a final "kick" into the game? :-) - // params[1] = entity to spawn + enum args { arg_count, arg_index }; - CHECK_ENTITY(params[1]); + CHECK_ENTITY(params[arg_index]); - edict_t *pEnt = TypeConversion.id_to_edict(params[1]); + const auto pEntity = TypeConversion.id_to_edict(params[arg_index]); - MDLL_Spawn(pEnt); + MDLL_Spawn(pEntity); return 1; } -static cell AMX_NATIVE_CALL set_user_health(AMX *amx, cell *params) // set_user_health(index, health); = 2 arguments +// native set_user_health(index, health) +static cell AMX_NATIVE_CALL set_user_health(AMX *amx, cell *params) { - // Sets user health. If health is 0 and below, also kill... - // params[1] = index - // params[2] = health + enum args { arg_count, arg_index, arg_health }; - // Check index - CHECK_PLAYER(params[1]); + CHECK_PLAYER(params[arg_index]); - // Fetch player pointer - edict_t *pPlayer = TypeConversion.id_to_edict(params[1]); + const auto pPlayer = TypeConversion.id_to_edict(params[arg_index]); + const auto health = float(params[arg_health]); - // Kill if health too low. - if (params[2] > 0) - pPlayer->v.health = float(params[2]); + if (health > 0.0f) + { + pPlayer->v.health = health; + } else + { MDLL_ClientKill(pPlayer); + } return 1; } -static cell AMX_NATIVE_CALL set_user_frags(AMX *amx, cell *params) // set_user_frags(index, frags); = 2 arguments +// native set_user_frags(index, frags) +static cell AMX_NATIVE_CALL set_user_frags(AMX *amx, cell *params) { - // Sets user frags. - // params[1] = index - // params[2] = frags + enum args { arg_count, arg_index, arg_frags }; - // Check index - CHECK_PLAYER(params[1]); + CHECK_PLAYER(params[arg_index]); - // Fetch player pointer - edict_t *pPlayer = TypeConversion.id_to_edict(params[1]); + const auto pPlayer = TypeConversion.id_to_edict(params[arg_index]); - pPlayer->v.frags = params[2]; + pPlayer->v.frags = float(params[arg_frags]); return 1; } -static cell AMX_NATIVE_CALL set_user_armor(AMX *amx, cell *params) // set_user_armor(index, armor); = 2 arguments +// native set_user_armor(index, armor) +static cell AMX_NATIVE_CALL set_user_armor(AMX *amx, cell *params) { - // Sets user armor. - // params[1] = index - // params[2] = armor + enum args { arg_count, arg_index, arg_armor }; - // Check index - CHECK_PLAYER(params[1]); + CHECK_PLAYER(params[arg_index]); - // Fetch player pointer - edict_t *pPlayer = TypeConversion.id_to_edict(params[1]); + const auto pPlayer = TypeConversion.id_to_edict(params[arg_index]); - pPlayer->v.armorvalue = params[2]; + pPlayer->v.armorvalue = float(params[arg_armor]); return 1; } -static cell AMX_NATIVE_CALL set_user_origin(AMX *amx, cell *params) // set_user_origin(index, origin[3]); = 2 arguments +// native set_user_origin(index, const origin[3]) +static cell AMX_NATIVE_CALL set_user_origin(AMX *amx, cell *params) { - // Sets user origin. - // params[1] = index - // params[2] = origin + enum args { arg_count, arg_index, arg_origin }; - // Check index - CHECK_PLAYER(params[1]); + CHECK_PLAYER(params[arg_index]); - // Fetch player pointer - edict_t *pPlayer = TypeConversion.id_to_edict(params[1]); - - cell *newVectorCell = MF_GetAmxAddr(amx, params[2]); + auto pPlayer = TypeConversion.id_to_edict(params[arg_index]); + const auto pVector = MF_GetAmxAddr(amx, params[arg_origin]); SET_SIZE(pPlayer, pPlayer->v.mins, pPlayer->v.maxs); - SET_ORIGIN(pPlayer, Vector((float)newVectorCell[0], (float)newVectorCell[1], (float)newVectorCell[2])); - - return 1; -} - -static cell AMX_NATIVE_CALL set_user_rendering(AMX *amx, cell *params) // set_user_rendering(index, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16); = 7 arguments -{ - // Sets user rendering. - // params[1] = index - // params[2] = fx - // params[3] = r - // params[4] = g - // params[5] = b - // params[6] = render - // params[7] = amount - - // Check index - CHECK_PLAYER(params[1]); - - // Fetch player pointer - edict_t *pPlayer = TypeConversion.id_to_edict(params[1]); - - pPlayer->v.renderfx = params[2]; - Vector newVector = Vector(float(params[3]), float(params[4]), float(params[5])); - pPlayer->v.rendercolor = newVector; - pPlayer->v.rendermode = params[6]; - pPlayer->v.renderamt = params[7]; - - return 1; -} - -static cell AMX_NATIVE_CALL get_user_rendering(AMX *amx, cell *params) // get_user_rendering(index, &fx = kRenderFxNone, &r = 0, &g = 0, &b = 0, &render = kRenderNormal, &amount = 0); = 7 arguments -{ - // Gets user rendering. - // params[1] = index - // params[2] = fx - // params[3] = r - // params[4] = g - // params[5] = b - // params[6] = render - // params[7] = amount - - // Check index - CHECK_PLAYER(params[1]); - - // Fetch player pointer - edict_t *pPlayer = TypeConversion.id_to_edict(params[1]); - - *MF_GetAmxAddr(amx, params[2]) = pPlayer->v.renderfx; - *MF_GetAmxAddr(amx, params[3]) = pPlayer->v.rendercolor[0]; - *MF_GetAmxAddr(amx, params[4]) = pPlayer->v.rendercolor[1]; - *MF_GetAmxAddr(amx, params[5]) = pPlayer->v.rendercolor[2]; - *MF_GetAmxAddr(amx, params[6]) = pPlayer->v.rendermode; - *MF_GetAmxAddr(amx, params[7]) = pPlayer->v.renderamt; - - return 1; -} - -static cell AMX_NATIVE_CALL set_user_maxspeed(AMX *amx, cell *params) // set_user_maxspeed(index, Float:speed = -1.0) = 2 arguments -{ - // Sets user maxspeed. - // params[1] = index - // params[2] = speed (should be -1.0 if not specified) (JGHG: unspecified parameters seems to always be -1.0!) - - REAL fNewSpeed = amx_ctof(params[2]); - - // Check index - CHECK_PLAYER(params[1]); - - // Fetch player pointer - edict_t *pPlayer = TypeConversion.id_to_edict(params[1]); - - SETCLIENTMAXSPEED(pPlayer, fNewSpeed); - pPlayer->v.maxspeed = fNewSpeed; + SET_ORIGIN(pPlayer, Vector(float(pVector[0]), float(pVector[1]), float(pVector[2]))); return 1; } -static cell AMX_NATIVE_CALL get_user_maxspeed(AMX *amx, cell *params) // Float:get_user_maxspeed(index) = 1 argument +// native set_user_rendering(index, fx = kRenderFxNone, r = 0, g = 0, b = 0, render = kRenderNormal, amount = 0) +static cell AMX_NATIVE_CALL set_user_rendering(AMX *amx, cell *params) { - // Gets user maxspeed. - // params[1] = index + enum args { arg_count, arg_index, arg_fx, arg_red, arg_green, arg_blue, arg_render, arg_amount }; - // Check index - CHECK_PLAYER(params[1]); + CHECK_PLAYER(params[arg_index]); - // Fetch player pointer - edict_t *pPlayer = TypeConversion.id_to_edict(params[1]); + auto pPlayer = TypeConversion.id_to_edict(params[arg_index]); + + pPlayer->v.renderfx = params[arg_fx]; + pPlayer->v.rendercolor = Vector(float(params[arg_red]), float(params[arg_green]), float(params[arg_blue])); + pPlayer->v.rendermode = params[arg_render]; + pPlayer->v.renderamt = float(params[arg_amount]); + + return 1; +} + +// get_user_rendering(index, &fx = kRenderFxNone, &r = 0, &g = 0, &b = 0, &render = kRenderNormal, &amount = 0); +static cell AMX_NATIVE_CALL get_user_rendering(AMX *amx, cell *params) +{ + enum args { arg_count, arg_index, arg_fx, arg_red, arg_green, arg_blue, arg_render, arg_amount }; + + CHECK_PLAYER(params[arg_index]); + + auto pPlayer = TypeConversion.id_to_edict(params[arg_index]); + + *MF_GetAmxAddr(amx, params[arg_fx]) = pPlayer->v.renderfx; + *MF_GetAmxAddr(amx, params[arg_red]) = pPlayer->v.rendercolor[0]; + *MF_GetAmxAddr(amx, params[arg_green]) = pPlayer->v.rendercolor[1]; + *MF_GetAmxAddr(amx, params[arg_blue]) = pPlayer->v.rendercolor[2]; + *MF_GetAmxAddr(amx, params[arg_render]) = pPlayer->v.rendermode; + *MF_GetAmxAddr(amx, params[arg_amount]) = pPlayer->v.renderamt; + + return 1; +} + +// native set_user_maxspeed(index, Float:speed = -1.0) +static cell AMX_NATIVE_CALL set_user_maxspeed(AMX *amx, cell *params) +{ + enum args { arg_count, arg_index, arg_speed }; + + CHECK_PLAYER(params[arg_index]); + + const auto pPlayer = TypeConversion.id_to_edict(params[arg_index]); + const auto newSpeed = amx_ctof(params[arg_speed]); + + SETCLIENTMAXSPEED(pPlayer, newSpeed); + pPlayer->v.maxspeed = newSpeed; + + return 1; +} + +// native Float:get_user_maxspeed(index) +static cell AMX_NATIVE_CALL get_user_maxspeed(AMX *amx, cell *params) +{ + enum args { arg_count, arg_index }; + + CHECK_PLAYER(params[arg_index]); + + const auto pPlayer = TypeConversion.id_to_edict(params[arg_index]); return amx_ftoc(pPlayer->v.maxspeed); } -static cell AMX_NATIVE_CALL set_user_gravity(AMX *amx, cell *params) // set_user_gravity(index, Float:gravity = 1.0) = 2 arguments +// native set_user_gravity(index, Float:gravity = 1.0) +static cell AMX_NATIVE_CALL set_user_gravity(AMX *amx, cell *params) { - // Sets user gravity. - // params[1] = index - // params[2] = gravity (=-1.0) - // Check index - CHECK_PLAYER(params[1]); + enum args { arg_count, arg_index, arg_gravity }; - // Fetch player pointer - edict_t *pPlayer = TypeConversion.id_to_edict(params[1]); + CHECK_PLAYER(params[arg_index]); - pPlayer->v.gravity = amx_ctof(params[2]); + const auto pPlayer = TypeConversion.id_to_edict(params[arg_index]); + + pPlayer->v.gravity = amx_ctof(params[arg_gravity]); return 1; } -static cell AMX_NATIVE_CALL get_user_gravity(AMX *amx, cell *params) // Float:get_user_gravity(index) = 1 argument +// native Float:get_user_gravity(index) +static cell AMX_NATIVE_CALL get_user_gravity(AMX *amx, cell *params) { - // Gets user gravity. - // params[1] = index + enum args { arg_count, arg_index }; - // Check index - CHECK_PLAYER(params[1]); + CHECK_PLAYER(params[arg_index]); - // Fetch player pointer - edict_t *pPlayer = TypeConversion.id_to_edict(params[1]); + const auto pPlayer = TypeConversion.id_to_edict(params[arg_index]); - return amx_ftoc(pPlayer->v.gravity); + return amx_ftoc(pPlayer->v.gravity); } -static cell AMX_NATIVE_CALL set_user_hitzones(AMX *amx, cell *params) // set_user_hitzones(index = 0, target = 0, body = 255); = 3 arguments +// native set_user_hitzones(index = 0, target = 0, body = HITZONES_DEFAULT) +static cell AMX_NATIVE_CALL set_user_hitzones(AMX *amx, cell *params) { - // Sets user hitzones. - // params[1] = the one(s) who shoot(s), shooter - int shooter = params[1]; + enum args { arg_count, arg_attacker, arg_target, arg_hitzones }; - // params[2] = the one getting hit - int gettingHit = params[2]; + const int attacker = params[arg_attacker]; + const int target = params[arg_target]; + const int hitzones = params[arg_hitzones]; - // params[3] = specified hit zones - int hitzones = params[3]; - - //set_user_hitzones(id, 0, 0) // Makes ID not able to shoot EVERYONE - id can shoot on 0 (all) at 0 - //set_user_hitzones(0, id, 0) // Makes EVERYONE not able to shoot ID - 0 (all) can shoot id at 0 - if (shooter == 0 && gettingHit == 0) { - for (int i = 1; i <= gpGlobals->maxClients; i++) { - for (int j = 1; j <= gpGlobals->maxClients; j++) { - g_bodyhits[i][j] = hitzones; - } - //g_zones_toHit[i] = hitzones; - //g_zones_getHit[i] = hitzones; - } + if (attacker == 0 && target == 0) + { + Players.SetEveryoneBodyHits(hitzones); } - else if (shooter == 0 && gettingHit != 0) { - // "All" shooters, target (gettingHit) should be existing player id - CHECK_PLAYER(gettingHit); - // Where can all hit gettingHit? - for (int i = 1; i <= gpGlobals->maxClients; i++) - g_bodyhits[i][gettingHit] = hitzones; + else if (attacker == 0 && target != 0) + { + CHECK_PLAYER(target); + + Players.SetAttackersBodyHits(target, hitzones); } - else if (shooter != 0 && gettingHit == 0) { - // Shooter can hit all in bodyparts. - CHECK_PLAYER(shooter); - for (int i = 1; i <= gpGlobals->maxClients; i++) - g_bodyhits[shooter][i] = hitzones; + else if (attacker != 0 && target == 0) + { + CHECK_PLAYER(attacker); + + Players.SetTargetsBodyHits(attacker, hitzones); } - else { - // Specified, where can player A hit player B? - CHECK_PLAYER(shooter); - CHECK_PLAYER(gettingHit); - g_bodyhits[shooter][gettingHit] = hitzones; - } - - return 1; -} - -static cell AMX_NATIVE_CALL get_user_hitzones(AMX *amx, cell *params) // get_user_hitzones(index, target); = 2 arguments -{ - int shooter = params[1]; - CHECK_PLAYER(shooter); - int target = params[2]; - CHECK_PLAYER(target); - return g_bodyhits[shooter][target]; -} - -static cell AMX_NATIVE_CALL set_user_noclip(AMX *amx, cell *params) // set_user_noclip(index, noclip = 0); = 2 arguments -{ - // Sets user to no clipping mode. - // params[1] = index - // params[2] = no clip or not... - - // Check index - CHECK_PLAYER(params[1]); - - // Fetch player pointer - edict_t *pPlayer = TypeConversion.id_to_edict(params[1]); - - if (params[2] == 1) - pPlayer->v.movetype = MOVETYPE_NOCLIP; else - pPlayer->v.movetype = MOVETYPE_WALK; + { + CHECK_PLAYER(attacker); + CHECK_PLAYER(target); + + Players.SetBodyHits(attacker, target, hitzones); + } + + g_pengfuncsTable_Post->pfnTraceLine = Players.HaveBodyHits() ? TraceLine_Post : nullptr; return 1; } -static cell AMX_NATIVE_CALL get_user_noclip(AMX *amx, cell *params) // get_user_noclip(index); = 1 argument +// native get_user_hitzones(index, target) +static cell AMX_NATIVE_CALL get_user_hitzones(AMX *amx, cell *params) { - // Gets user noclip. - // params[1] = index + enum args { arg_count, arg_attacker, arg_target }; - // Check index - CHECK_PLAYER(params[1]); + const auto attacker = params[arg_attacker]; - // Fetch player pointer - edict_t *pPlayer = TypeConversion.id_to_edict(params[1]); + CHECK_PLAYER(attacker); + + const auto target = params[arg_target]; + + CHECK_PLAYER(target); + + return Players[attacker].GetBodyHits(target); +} + +// native set_user_noclip(index, noclip = 0) +static cell AMX_NATIVE_CALL set_user_noclip(AMX *amx, cell *params) +{ + enum args { arg_count, arg_index, arg_noclip }; + + CHECK_PLAYER(params[arg_index]); + + const auto pPlayer = TypeConversion.id_to_edict(params[arg_index]); + + pPlayer->v.movetype = params[arg_noclip] != 0 ? MOVETYPE_NOCLIP : MOVETYPE_WALK; + + return 1; +} + +// native get_user_noclip(index) +static cell AMX_NATIVE_CALL get_user_noclip(AMX *amx, cell *params) +{ + enum args { arg_count, arg_index }; + + CHECK_PLAYER(params[arg_index]); + + const auto pPlayer = TypeConversion.id_to_edict(params[arg_index]); return pPlayer->v.movetype == MOVETYPE_NOCLIP; } -// JustinHoMi made this one originally -static cell AMX_NATIVE_CALL set_user_footsteps(AMX *amx, cell *params) // set_user_footsteps(id, set = 1); = 2 params +// native set_user_footsteps(id, set = 1) +static cell AMX_NATIVE_CALL set_user_footsteps(AMX *amx, cell *params) { - // Gives player silent footsteps. - // if set=0 it will return footsteps to normal - // params[1] = index of player - // params[2] = 0 = normal footstep sound, 1 = silent slippers + enum args { arg_count, arg_index, arg_footsteps }; - // Check index - CHECK_PLAYER(params[1]); + const auto index = params[arg_index]; - // Fetch player pointer - edict_t *pPlayer = TypeConversion.id_to_edict(params[1]); + CHECK_PLAYER(index); - if (params[2]) { + const auto pPlayer = TypeConversion.id_to_edict(index); + + if (params[arg_footsteps] != 0) + { pPlayer->v.flTimeStepSound = 999; - g_silent[params[1]] = true; + Players[index].SetSilentFootsteps(true); + + g_pFunctionTable->pfnPlayerPreThink = PlayerPreThink; } - else { + else + { pPlayer->v.flTimeStepSound = STANDARDTIMESTEPSOUND; - g_silent[params[1]] = false; + Players[index].SetSilentFootsteps(false); + + if (g_pFunctionTable->pfnPlayerPreThink && !Players.HaveSilentFootsteps()) + { + g_pFunctionTable->pfnPlayerPreThink = nullptr; + } } return 1; } +// native get_user_footsteps(index) static cell AMX_NATIVE_CALL get_user_footsteps(AMX *amx, cell *params) { - CHECK_PLAYER(params[1]); + enum args { arg_count, arg_index }; - return g_silent[params[1]]; + const auto index = params[arg_index]; + + CHECK_PLAYER(index); + + return Players[index].HasSilentFootsteps(); } -// SidLuke -static cell AMX_NATIVE_CALL strip_user_weapons(AMX *amx, cell *params) // index +// native strip_user_weapons(index) +static cell AMX_NATIVE_CALL strip_user_weapons(AMX *amx, cell *params) { - CHECK_PLAYER(params[1]); + enum args { arg_count, arg_index }; - edict_t* pPlayer = TypeConversion.id_to_edict(params[1]); + const auto index = params[arg_index]; - string_t item = MAKE_STRING("player_weaponstrip"); - edict_t *pent = CREATE_NAMED_ENTITY(item); + CHECK_PLAYER(index); - if (FNullEnt(pent)) + const auto pPlayer = TypeConversion.id_to_edict(index); + const auto pEntity = CREATE_NAMED_ENTITY(MAKE_STRING("player_weaponstrip")); + + if (FNullEnt(pEntity)) { return 0; } - MDLL_Spawn(pent); - MDLL_Use(pent, pPlayer); - REMOVE_ENTITY(pent); + MDLL_Spawn(pEntity); + MDLL_Use(pEntity, pPlayer); + REMOVE_ENTITY(pEntity); - *reinterpret_cast(MF_PlayerPropAddr(params[1], Player_CurrentWeapon)) = 0; + *reinterpret_cast(MF_PlayerPropAddr(index, Player_CurrentWeapon)) = 0; return 1; } -AMX_NATIVE_INFO fun_Exports[] = { - {"get_client_listen", get_client_listening}, - {"set_client_listen", set_client_listening}, - {"set_user_godmode", set_user_godmode}, - {"get_user_godmode", get_user_godmode}, - {"set_user_health", set_user_health}, - {"give_item", give_item}, - {"spawn", spawn}, - {"set_user_frags", set_user_frags}, - {"set_user_armor", set_user_armor}, - {"set_user_origin", set_user_origin}, - {"set_user_rendering", set_user_rendering}, - {"get_user_rendering", get_user_rendering}, - {"set_user_maxspeed", set_user_maxspeed}, - {"get_user_maxspeed", get_user_maxspeed}, - {"set_user_gravity", set_user_gravity}, - {"get_user_gravity", get_user_gravity}, - {"get_user_footsteps", get_user_footsteps}, - {"set_user_hitzones", set_user_hitzones}, - {"get_user_hitzones", get_user_hitzones}, - {"set_user_noclip", set_user_noclip}, - {"get_user_noclip", get_user_noclip}, - {"set_user_footsteps", set_user_footsteps}, - {"strip_user_weapons", strip_user_weapons}, - /////////////////// <--- 19 chars max in current small version - {NULL, NULL} + +AMX_NATIVE_INFO fun_Exports[] = +{ + { "get_client_listen" , get_client_listening }, + { "set_client_listen" , set_client_listening }, + { "set_user_godmode" , set_user_godmode }, + { "get_user_godmode" , get_user_godmode }, + { "set_user_health" , set_user_health }, + { "give_item" , give_item }, + { "spawn" , spawn }, + { "set_user_frags" , set_user_frags }, + { "set_user_armor" , set_user_armor }, + { "set_user_origin" , set_user_origin }, + { "set_user_rendering", set_user_rendering }, + { "get_user_rendering", get_user_rendering }, + { "set_user_maxspeed" , set_user_maxspeed }, + { "get_user_maxspeed" , get_user_maxspeed }, + { "set_user_gravity" , set_user_gravity }, + { "get_user_gravity" , get_user_gravity }, + { "get_user_footsteps", get_user_footsteps }, + { "set_user_hitzones" , set_user_hitzones }, + { "get_user_hitzones" , get_user_hitzones }, + { "set_user_noclip" , set_user_noclip }, + { "get_user_noclip" , get_user_noclip }, + { "set_user_footsteps", set_user_footsteps }, + { "strip_user_weapons", strip_user_weapons }, + { nullptr , nullptr } }; -/******************************************************************************************/ + void PlayerPreThink(edict_t *pEntity) { - if (g_silent[ENTINDEX(pEntity)]) { - pEntity->v.flTimeStepSound = 999; + const auto index = TypeConversion.edict_to_id(pEntity); + + if (Players[index].HasSilentFootsteps()) + { + pEntity->v.flTimeStepSound = 999; RETURN_META(MRES_HANDLED); } @@ -603,76 +477,51 @@ void PlayerPreThink(edict_t *pEntity) int ClientConnect(edict_t *pPlayer, const char *pszName, const char *pszAddress, char szRejectReason[128]) { - // Reset stuff: - FUNUTIL_ResetPlayer(ENTINDEX(pPlayer)); + const auto index = TypeConversion.edict_to_id(pPlayer); + + Players[index].Clear(); RETURN_META_VALUE(MRES_IGNORED, 0); } -void TraceLine(const float *v1, const float *v2, int fNoMonsters, edict_t *shooter, TraceResult *ptr) { - TRACE_LINE(v1, v2, fNoMonsters, shooter, ptr); - if ( ptr->pHit && (ptr->pHit->v.flags& (FL_CLIENT | FL_FAKECLIENT)) - && shooter && (shooter->v.flags & (FL_CLIENT | FL_FAKECLIENT)) ) { - int shooterIndex = ENTINDEX(shooter); - if ( !(g_bodyhits[shooterIndex][ENTINDEX(ptr->pHit)] & (1<iHitgroup)) ) +void TraceLine_Post(const float *v1, const float *v2, int fNoMonsters, edict_t *shooter, TraceResult *ptr) +{ + if (ptr->pHit && (ptr->pHit->v.flags & (FL_CLIENT | FL_FAKECLIENT)) + && shooter && (shooter->v.flags & (FL_CLIENT | FL_FAKECLIENT)) ) + { + const auto shooterIndex = TypeConversion.edict_to_id(shooter); + const auto targetIndex = TypeConversion.edict_to_id(ptr->pHit); + + if (!(Players[shooterIndex].GetBodyHits(targetIndex) & (1 << ptr->iHitgroup))) + { ptr->flFraction = 1.0; + RETURN_META(MRES_HANDLED); + } } - RETURN_META(MRES_SUPERCEDE); + + RETURN_META(MRES_IGNORED); } -//int g_hitIndex, g_canTargetGetHit, g_canShooterHitThere; -//void TraceLine(const float *v1, const float *v2, int fNoMonsters, edict_t *shooter, TraceResult *ptr) { -// if (!pentToSkip || (pentToSkip->v.flags & (FL_CLIENT | FL_FAKECLIENT)) == false || pentToSkip->v.deadflag != DEAD_NO) -// RETURN_META(MRES_IGNORED); -// -// TRACE_LINE(v1, v2, fNoMonsters, shooter, ptr); // Filter shooter -// -// if (!ptr->pHit || (ptr->pHit->v.flags & (FL_CLIENT | FL_FAKECLIENT)) == false ) -// RETURN_META(MRES_SUPERCEDE); -// -// g_hitIndex = ENTINDEX(ptr->pHit); -// //bool blocked = false; -// g_canTargetGetHit = g_zones_getHit[g_hitIndex] & (1 << ptr->iHitgroup); -// g_canShooterHitThere = g_zones_toHit[ENTINDEX(shooter)] & (1 << ptr->iHitgroup); -// -// if (!g_canTargetGetHit || !g_canShooterHitThere) { -// ptr->flFraction = 1.0; // set to not hit anything (1.0 = shot doesn't hit anything) -// //blocked = true; -// } -// /* -// if (blocked) { -// MF_PrintSrvConsole("%s was blocked from hitting %s: %d and %d\n", MF_GetPlayerName(ENTINDEX(pentToSkip)), MF_GetPlayerName(hitIndex), canTargetGetHit, canShooterHitThere); -// } -// else { -// MF_PrintSrvConsole("%s was NOT blocked from hitting %s: %d and %d\n", MF_GetPlayerName(ENTINDEX(pentToSkip)), MF_GetPlayerName(hitIndex), canTargetGetHit, canShooterHitThere); -// } -// */ -// -// RETURN_META(MRES_SUPERCEDE); -//} - void OnAmxxAttach() { MF_AddNatives(fun_Exports); } -// The content of OnPluginsLoaded() was moved from OnAmxxAttach with AMXx 1.5 because for some reason gpGlobals->maxClients wasn't -// initialized to its proper value until some time after OnAmxxAttach(). In OnAmxxAttach() it always showed 0. /JGHG -void OnPluginsLoaded() { - // Reset stuff - hopefully this should - for (int i = 1; i <= gpGlobals->maxClients; i++) { - // Reset all hitzones - FUNUTIL_ResetPlayer(i); - } +void OnPluginsLoaded() +{ + Players.Clear(); TypeConversion.init(); + + g_pFunctionTable->pfnPlayerPreThink = nullptr; + g_pengfuncsTable_Post->pfnTraceLine = nullptr; } -/* -void ClientConnectFakeBot(int index) + +void ServerDeactivate() { - FUNUTIL_ResetPlayer(index); - //MF_Log("A bot connects, forwarded to fun! The bot is %d!", index); - //CPlayer* player; + g_pFunctionTable->pfnPlayerPreThink = nullptr; + g_pengfuncsTable_Post->pfnTraceLine = nullptr; + + RETURN_META(MRES_IGNORED); } -*/ diff --git a/modules/fun/fun.h b/modules/fun/fun.h index 7b9f4fdc..75e391b1 100644 --- a/modules/fun/fun.h +++ b/modules/fun/fun.h @@ -11,7 +11,9 @@ // Fun Module // -#include "amxxmodule.h" +#pragma once + +#include // Fun-specific defines below #define GETCLIENTLISTENING (*g_engfuncs.pfnVoice_GetClientListening) @@ -29,19 +31,181 @@ #define HITGROUP_RIGHTARM 5 // 32 #define HITGROUP_LEFTLEG 6 // 64 #define HITGROUP_RIGHTLEG 7 // 128 +#define HITGROUP_MAX 8 + +extern DLL_FUNCTIONS *g_pFunctionTable; +extern enginefuncs_t *g_pengfuncsTable_Post; + +void PlayerPreThink(edict_t *pEntity); +void TraceLine_Post(const float *v1, const float *v2, int fNoMonsters, edict_t *shooter, TraceResult *ptr); + +static const auto kHitGroupsBits = (1 << HITGROUP_MAX) - 1; +static const auto kMaxClients = 32u; + +class CPlayer +{ + public: + + CPlayer() + { + Clear(); + } + + public: + + bool HasBodyHits() const + { + for (auto i = 1; i <= gpGlobals->maxClients; ++i) + { + if (GetBodyHits(i) != kHitGroupsBits) + { + return true; + } + } + + return false; + } + + int GetBodyHits(const int other) const + { + return bodyHits_[other]; + } + + void SetBodyHits(const int other, const int flags) + { + bodyHits_[other] = flags; + } + + void SetBodyHits(const int flags) + { + memset(bodyHits_, flags, sizeof bodyHits_); + } + + public: + + bool HasSilentFootsteps() const + { + return silentFootsteps_; + } + + void SetSilentFootsteps(const bool state) + { + silentFootsteps_ = state; + } + + public: + + void Clear() + { + SetBodyHits(kHitGroupsBits); + SetSilentFootsteps(false); + } + + private: + + int bodyHits_[kMaxClients + 1] {}; + bool silentFootsteps_ {}; +}; + +class CPlayers +{ + using Internal = CPlayer; + + public: + + bool HaveBodyHits() const + { + for (auto i = 1; i <= gpGlobals->maxClients; ++i) + { + if (players_[i].HasBodyHits()) + { + return true; + } + } + + return false; + } + + void SetBodyHits(const int attacker, const int target, const int flags) + { + players_[attacker].SetBodyHits(target, flags); + } + + void SetTargetsBodyHits(const int attacker, const int flags) + { + players_[attacker].SetBodyHits(flags); + } + + void SetAttackersBodyHits(const int target, const int flags) + { + for (auto i = 1; i <= gpGlobals->maxClients; ++i) + { + players_[i].SetBodyHits(target, flags); + } + } + + void SetEveryoneBodyHits(const int flags) + { + for (auto i = 1; i <= gpGlobals->maxClients; ++i) + { + players_[i].SetBodyHits(flags); + } + } + + public: + + bool HaveSilentFootsteps() const + { + for (auto i = 1; i <= gpGlobals->maxClients; ++i) + { + if (players_[i].HasSilentFootsteps()) + { + return true; + } + } + + return false; + } + + public: + + void Clear() + { + for (auto i = 1; i <= gpGlobals->maxClients; ++i) + { + players_[i].Clear(); + } + } + + public: + + Internal& operator [](const size_t index) + { + return players_[index]; + } + + const Internal& operator [](const size_t index) const + { + return players_[index]; + } + + private: + + Internal players_[kMaxClients + 1]; +}; #define CHECK_ENTITY(x) \ - if (x < 0 || x > gpGlobals->maxEntities) { \ + if ((x) < 0 || (x) > gpGlobals->maxEntities) { \ MF_LogError(amx, AMX_ERR_NATIVE, "Entity out of range (%d)", x); \ return 0; \ } else { \ - if (x <= gpGlobals->maxClients) { \ + if ((x) <= gpGlobals->maxClients) { \ if (!MF_IsPlayerIngame(x)) { \ MF_LogError(amx, AMX_ERR_NATIVE, "Invalid player %d (not in-game)", x); \ return 0; \ } \ } else { \ - if (x != 0 && FNullEnt(TypeConversion.id_to_edict(x))) { \ + if ((x) != 0 && FNullEnt(TypeConversion.id_to_edict(x))) { \ MF_LogError(amx, AMX_ERR_NATIVE, "Invalid entity %d", x); \ return 0; \ } \ @@ -49,7 +213,7 @@ } #define CHECK_PLAYER(x) \ - if (x < 1 || x > gpGlobals->maxClients) { \ + if ((x) < 1 || (x) > gpGlobals->maxClients) { \ MF_LogError(amx, AMX_ERR_NATIVE, "Player out of range (%d)", x); \ return 0; \ } else { \ diff --git a/modules/fun/moduleconfig.h b/modules/fun/moduleconfig.h index 06c8b963..292fb31d 100644 --- a/modules/fun/moduleconfig.h +++ b/modules/fun/moduleconfig.h @@ -119,8 +119,8 @@ // #define FN_ClientCommand ClientCommand /* pfnClientCommand() (wd) Player has sent a command (typed or from a bind) */ // #define FN_ClientUserInfoChanged ClientUserInfoChanged /* pfnClientUserInfoChanged() (wd) Client has updated their setinfo structure */ // #define FN_ServerActivate ServerActivate /* pfnServerActivate() (wd) Server is starting a new map */ -// #define FN_ServerDeactivate ServerDeactivate /* pfnServerDeactivate() (wd) Server is leaving the map (shutdown or changelevel); SDK2 */ -#define FN_PlayerPreThink PlayerPreThink /* pfnPlayerPreThink() */ +#define FN_ServerDeactivate ServerDeactivate /* pfnServerDeactivate() (wd) Server is leaving the map (shutdown or changelevel); SDK2 */ +// #define FN_PlayerPreThink PlayerPreThink /* pfnPlayerPreThink() */ // #define FN_PlayerPostThink PlayerPostThink /* pfnPlayerPostThink() */ // #define FN_StartFrame StartFrame /* pfnStartFrame() */ // #define FN_ParmsNewLevel ParmsNewLevel /* pfnParmsNewLevel() */ @@ -232,7 +232,7 @@ // #define FN_SetOrigin SetOrigin // #define FN_EmitSound EmitSound // #define FN_EmitAmbientSound EmitAmbientSound -#define FN_TraceLine TraceLine +// #define FN_TraceLine TraceLine // #define FN_TraceToss TraceToss // #define FN_TraceMonsterHull TraceMonsterHull // #define FN_TraceHull TraceHull diff --git a/plugins/include/fun.inc b/plugins/include/fun.inc index a68213a8..f9deff44 100755 --- a/plugins/include/fun.inc +++ b/plugins/include/fun.inc @@ -21,6 +21,21 @@ #pragma loadlib fun #endif + +/** + * Parts of body for hits, for use with set_user_hitzones(). + */ +const HITZONE_GENERIC = (1 << HIT_GENERIC); // 1 +const HITZONE_HEAD = (1 << HIT_HEAD); // 2 +const HITZONE_CHEST = (1 << HIT_CHEST); // 4 +const HITZONE_STOMATCH = (1 << HIT_STOMATCH); // 8 +const HITZONE_LEFTARM = (1 << HIT_LEFTARM); // 16 +const HITZONE_RIGHTARM = (1 << HIT_RIGHTARM); // 32 +const HITZONE_LEFTLEG = (1 << HIT_LEFTLEG); // 64 +const HITZONE_RIGHTLEG = (1 << HIT_RIGHTLEG); // 128 +const HITZONES_DEFAULT = HITZONE_GENERIC | HITZONE_HEAD | HITZONE_CHEST | HITZONE_STOMATCH | + HITZONE_LEFTARM | HITZONE_RIGHTARM | HITZONE_LEFTLEG | HITZONE_RIGHTLEG; // 255 + /** * Tells whether receiver hears sender via voice communication. * @@ -169,26 +184,18 @@ native give_item(index, const item[]); * * @param index Client index * @param target The target player - * @param body A bitsum of the body parts that can/can't be shot: - * 1 - generic - * 2 - head - * 4 - chest - * 8 - stomach - * 16 - left arm - * 32 - right arm - * 64 - left leg - * 128 - right leg + * @param body A bitsum of the body parts that can/can't be shot. See HITZONE* constants. * * @noreturn * @error If player is not connected or not within the range * of 1 to MaxClients. */ -native set_user_hitzones(index = 0, target = 0, body = 255); +native set_user_hitzones(index = 0, target = 0, body = HITZONES_DEFAULT); /** * Gets the set of hit zone "rules" between @index and @target players. * - * @note For the body part bitsum take a look at the set_user_hitzones() native. + * @note For the body part bitsum, see HITZONE* constants. * * @param index Client index * @param target The target player From 879b061bc835ec1ed1a43855a74b54b2f4ab370a Mon Sep 17 00:00:00 2001 From: OciXCrom Date: Thu, 30 Aug 2018 20:26:39 +0200 Subject: [PATCH 5/5] Make the "body" param in get_user_aiming() optional (#532) * Make the body param optional * Add HIT_ constant note --- plugins/include/amxmodx.inc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/include/amxmodx.inc b/plugins/include/amxmodx.inc index a60bd0ad..98630819 100755 --- a/plugins/include/amxmodx.inc +++ b/plugins/include/amxmodx.inc @@ -1010,6 +1010,7 @@ native get_user_attacker(index, ...); * * @note If the trace does not hit a client, id and body will be set to 0. * @note If the trace hits nothing within the specified distance, 0 is returned. + * @note For a list of possible body hitplaces see the HIT_* constants in amxconst.inc. * * @param index Client index to trace aim from * @param id Variable to store hit client index (if applicable) @@ -1020,7 +1021,7 @@ native get_user_attacker(index, ...); * @error If the client index is not within the range of 1 to * MaxClients, an error will be thrown. */ -native Float:get_user_aiming(index, &id, &body, dist = 9999); +native Float:get_user_aiming(index, &id, &body = HIT_GENERIC, dist = 9999); /** * Returns the client's frags.