Modify rankings system to use tiers and reduce weighting (#71)

This commit is contained in:
shavitush 2016-08-08 02:23:06 +03:00
parent 0d8b5db880
commit f3474d2d4c
7 changed files with 394 additions and 620 deletions

View File

@ -119,6 +119,7 @@ Replay
- [x] Make replay bots dead if there's no replay data loaded.
- [x] Clear player cache on spawn/death.
- [x] Add admin interface. (delete replay data, `sm_deletereplay` for RCON admins.
- [ ] Bonus replay for default style.
Stats
--
@ -132,8 +133,8 @@ Stats
- [x] Redo *everything*.
- [x] Add 'last online' field.
- [x] Add `Shavit_GetWRCount(int client)`.
- [x] Stop calculating points on the fly and grab everything from the table.
- [ ] Rework on points sorting and show weighting percentages.
- [ ] Stop calculating points on the fly and grab everything from the table.
Miscellaneous
--
@ -172,16 +173,18 @@ Rankings **(NEW!)**
- [x] Add natives. `float Shavit_GetPoints(int client)` `int Shavit_GetRank(int client)` `void Shavit_GetMapValues(float &points, float &idealtime)`
- [x] Add native that checks the total amount of players with over 0 points.
- [x] Add map tiers. `sm_tier` `sm_settier`
- [ ] Redirect to stats menu from `sm_top`.
- [ ] Deprecate the tables, use a `playertimes` column for map points and a `users` column for total points.
- [ ] Find a way to update newly calculated points for all records on a map with the least amount of queries possible.
- [ ] Remove idealtime and use the WR time for the default time instead.
- [ ] Remove deleted records from `playerpoints`.
- [x] Redirect to stats menu from `sm_top`.
- [x] Deprecate the tables, use a `playertimes` column for map points and a `users` column for total points.
- [x] Find a way to update newly calculated points for all records on a map with the least amount of queries possible.
- [x] Remove idealtime and use the WR time for the default time instead.
- [x] Remove deleted records from `playerpoints`.
- [x] Update every player's total points once per map. (MySQL only)
Web Interface
--
- [x] Implement points.
- [x] Compatibility for unix timestamps.
- [ ] Compatibility for new points.
Chat **(NEW!)**
--
@ -220,7 +223,7 @@ World Records
- [x] Add `sm_recent` `sm_recentrecords` `sm_rr`.
- [x] Add strafes/sync to the WR menu where available.
- [x] Add 'player stats' to submenu.
- [ ] Grab points from `playertimes` instead of calculating on the fly.
- [x] Grab points from `playertimes` instead of calculating on the fly.
- [ ] Add `sm_bwr` `sm_bonuswr` `sm_bonusworldrecord`.
Time Limits

View File

@ -167,7 +167,7 @@ char gS_ShortBhopStyles[MAX_STYLES][] =
#if defined USES_STYLE_MULTIPLIERS
// ranking system
float gI_RankingMultipliers[MAX_STYLES] =
float gF_RankingMultipliers[MAX_STYLES] =
{
1.00, // Normal
1.30, // Sideways
@ -670,27 +670,6 @@ native float Shavit_GetPoints(int client);
*/
native int Shavit_GetRank(int client);
/**
* Gets ranking values for the current map.
* See CalculatePoints() in shavit-rankings.
*
* @param points Reference to map points. -1.0 if not set.
* @param idealtime Reference to ideal time. 0.0 if not set.
* @noreturn
*/
native void Shavit_GetMapValues(float &points, float &idealtime);
/**
* Gets ranking values for a given map.
* See CalculatePoints() in shavit-rankings.
*
* @param map Map to get values from.
* @param points Reference to map points. -1.0 if not set.
* @param idealtime Reference to ideal time. 0.0 if not set.
* @noreturn
*/
native void Shavit_GetGivenMapValues(const char[] map, float &points, float &idealtime);
/**
* Gets the amount of players with over 0 points.
*
@ -698,17 +677,6 @@ native void Shavit_GetGivenMapValues(const char[] map, float &points, float &ide
*/
native int Shavit_GetRankedPlayers();
/**
* Calculates points for given time, style, ideal time and points for the ideal time.
*
* @param time Time.
* @param idealtime Ideal time.
* @param style Bhop style.
* @param mappoints Points for the ideal time
* @return Calculated poiints.
*/
native float Shavit_CalculatePoints(float time, BhopStyle style, float idealtime, float mappoints);
/**
* Force an HUD update for a player. Requires shavit-hud.
*
@ -795,15 +763,12 @@ public SharedPlugin __pl_shavit =
#if !defined REQUIRE_PLUGIN
public void __pl_shavit_SetNTVOptional()
{
MarkNativeAsOptional("Shavit_CalculatePoints");
MarkNativeAsOptional("Shavit_FinishMap");
MarkNativeAsOptional("Shavit_ForceHUDUpdate");
MarkNativeAsOptional("Shavit_FormatChat");
MarkNativeAsOptional("Shavit_GetBhopStyle");
MarkNativeAsOptional("Shavit_GetClientTime");
MarkNativeAsOptional("Shavit_GetClientJumps");
MarkNativeAsOptional("Shavit_GetGivenMapValues");
MarkNativeAsOptional("Shavit_GetMapValues");
MarkNativeAsOptional("Shavit_GetPlayerPB");
MarkNativeAsOptional("Shavit_GetPoints");
MarkNativeAsOptional("Shavit_GetRank");

View File

@ -261,6 +261,8 @@ public void LoadChatCache(int client)
strcopy(gS_Cached_ClanTag[client], 32, sBuffer);
}
}
UpdateClanTag(client);
}
public void ResetCache()

View File

@ -978,8 +978,8 @@ public void SQL_DBConnect()
gH_SQL.Driver.GetIdentifier(sDriver, 8);
gB_MySQL = StrEqual(sDriver, "mysql", false);
char[] sQuery = new char[256];
FormatEx(sQuery, 256, "CREATE TABLE IF NOT EXISTS `%susers` (`auth` VARCHAR(32) NOT NULL, `name` VARCHAR(32), `country` VARCHAR(128), `ip` VARCHAR(64), `lastlogin` %s NOT NULL DEFAULT -1, PRIMARY KEY (`auth`));", gS_MySQLPrefix, gB_MySQL? "INT":"INTEGER");
char[] sQuery = new char[512];
FormatEx(sQuery, 512, "CREATE TABLE IF NOT EXISTS `%susers` (`auth` VARCHAR(32) NOT NULL, `name` VARCHAR(32), `country` VARCHAR(128), `ip` VARCHAR(64), `lastlogin` %s NOT NULL DEFAULT -1, `points` FLOAT NOT NULL DEFAULT 0, PRIMARY KEY (`auth`));", gS_MySQLPrefix, gB_MySQL? "INT":"INTEGER");
// CREATE TABLE IF NOT EXISTS
gH_SQL.Query(SQL_CreateTable_Callback, sQuery);
@ -997,6 +997,9 @@ public void SQL_CreateTable_Callback(Database db, DBResultSet results, const cha
char[] sQuery = new char[64];
FormatEx(sQuery, 64, "SELECT lastlogin FROM %susers LIMIT 1;", gS_MySQLPrefix);
gH_SQL.Query(SQL_TableMigration1_Callback, sQuery, 0, DBPrio_High);
FormatEx(sQuery, 64, "SELECT points FROM %susers LIMIT 1;", gS_MySQLPrefix);
gH_SQL.Query(SQL_TableMigration2_Callback, sQuery, 0, DBPrio_High);
}
public void SQL_TableMigration1_Callback(Database db, DBResultSet results, const char[] error, any data)
@ -1019,6 +1022,26 @@ public void SQL_AlterTable1_Callback(Database db, DBResultSet results, const cha
}
}
public void SQL_TableMigration2_Callback(Database db, DBResultSet results, const char[] error, any data)
{
if(results == null)
{
char[] sQuery = new char[128];
FormatEx(sQuery, 128, "ALTER TABLE `%susers` ADD %s;", gS_MySQLPrefix, gB_MySQL? "(`points` FLOAT NOT NULL DEFAULT 0)":"COLUMN `points` FLOAT NOT NULL DEFAULT 0");
gH_SQL.Query(SQL_AlterTable2_Callback, sQuery);
}
}
public void SQL_AlterTable2_Callback(Database db, DBResultSet results, const char[] error, any data)
{
if(results == null)
{
LogError("Timer error! Table alteration 2 (core) failed. Reason: %s", error);
return;
}
}
public void PreThink(int client)
{
sv_airaccelerate.IntValue = (gI_StyleProperties[gBS_Style[client]] & STYLE_100AA)? 100:gI_CachedDefaultAA;

File diff suppressed because it is too large Load Diff

View File

@ -294,14 +294,13 @@ public Action OpenStatsMenu(int client, const char[] authid)
if(gB_Rankings)
{
FormatEx(sQuery, 2048, "SELECT a.clears, b.maps, c.wrs, d.name, d.country, d.lastlogin, e.rank, f.points FROM " ...
FormatEx(sQuery, 2048, "SELECT a.clears, b.maps, c.wrs, d.name, d.country, d.lastlogin, d.points, e.rank FROM " ...
"(SELECT COUNT(*) clears FROM (SELECT id FROM %splayertimes WHERE auth = '%s' GROUP BY map) s LIMIT 1) a " ...
"JOIN (SELECT COUNT(*) maps FROM (SELECT id FROM %smapzones GROUP BY map) s LIMIT 1) b " ...
"JOIN (SELECT COUNT(*) wrs FROM (SELECT s.auth FROM (SELECT style, auth, MIN(time) FROM %splayertimes GROUP BY map, style) s WHERE style = 0) ss WHERE ss.auth = '%s' LIMIT 1) c " ...
"JOIN (SELECT name, country, lastlogin FROM %susers WHERE auth = '%s' LIMIT 1) d " ...
"JOIN (SELECT COUNT(*) rank FROM %suserpoints up LEFT JOIN %susers u ON up.auth = u.auth WHERE up.points >= (SELECT points FROM %suserpoints WHERE auth = '%s' LIMIT 1) ORDER BY up.points DESC LIMIT 1) e " ...
"JOIN (SELECT points FROM %suserpoints WHERE auth = '%s' LIMIT 1) f " ...
"LIMIT 1;", gS_MySQLPrefix, authid, gS_MySQLPrefix, gS_MySQLPrefix, authid, gS_MySQLPrefix, authid, gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix, authid, gS_MySQLPrefix, authid);
"JOIN (SELECT name, country, lastlogin, points FROM %susers WHERE auth = '%s' LIMIT 1) d " ...
"JOIN (SELECT COUNT(*) rank FROM %susers WHERE points >= (SELECT points FROM %susers WHERE auth = '%s' LIMIT 1) ORDER BY points DESC LIMIT 1) e " ...
"LIMIT 1;", gS_MySQLPrefix, authid, gS_MySQLPrefix, gS_MySQLPrefix, authid, gS_MySQLPrefix, authid, gS_MySQLPrefix, gS_MySQLPrefix, authid);
}
else
@ -356,8 +355,8 @@ public void OpenStatsMenuCallback(Database db, DBResultSet results, const char[]
if(gB_Rankings)
{
iRank = results.FetchInt(6);
fPoints = results.FetchFloat(7);
fPoints = results.FetchFloat(6);
iRank = results.FetchInt(7);
}
char[] sRankingString = new char[64];
@ -492,7 +491,7 @@ public void ShowMaps(int client)
if(gI_MapType[client] == MAPSDONE)
{
FormatEx(sQuery, 512, "SELECT a.map, a.time, a.jumps, a.id, COUNT(b.map) + 1 rank FROM %splayertimes a LEFT JOIN %splayertimes b ON a.time > b.time AND a.map = b.map AND a.style = b.style WHERE a.auth = '%s' AND a.style = %d GROUP BY a.map ORDER BY a.map;", gS_MySQLPrefix, gS_MySQLPrefix, gS_TargetAuth[client], view_as<int>(gBS_Style[client]));
FormatEx(sQuery, 512, "SELECT a.map, a.time, a.jumps, a.id, COUNT(b.map) + 1 rank, a.points FROM %splayertimes a LEFT JOIN %splayertimes b ON a.time > b.time AND a.map = b.map AND a.style = b.style WHERE a.auth = '%s' AND a.style = %d GROUP BY a.map ORDER BY a.%s;", gS_MySQLPrefix, gS_MySQLPrefix, gS_TargetAuth[client], view_as<int>(gBS_Style[client]), (gB_Rankings)? "points":"map");
}
else
@ -554,22 +553,14 @@ public void ShowMapsCallback(Database db, DBResultSet results, const char[] erro
char[] sTime = new char[32];
FormatSeconds(fTime, sTime, 32);
bool bPoints = false;
float fPoints = results.FetchFloat(5);
if(gB_Rankings)
if(gB_Rankings && fPoints > 0.0)
{
float fPoints = 0.0;
float fIdealTime = -1.0;
Shavit_GetGivenMapValues(sMap, fPoints, fIdealTime);
if(fPoints != -1.0 && fIdealTime != 0.0)
{
FormatEx(sDisplay, 192, "[#%d] %s - %s (%.03f points)", iRank, sMap, sTime, Shavit_CalculatePoints(fTime, gBS_Style[client], fIdealTime, fPoints));
bPoints = true;
}
FormatEx(sDisplay, 192, "[#%d] %s - %s (%.03f points)", iRank, sMap, sTime, fPoints);
}
if(!bPoints)
else
{
FormatEx(sDisplay, 192, "[#%d] %s - %s (%d jumps)", iRank, sMap, sTime, iJumps);
}
@ -612,7 +603,7 @@ public int MenuHandler_ShowMaps(Menu m, MenuAction action, int param1, int param
}
char[] sQuery = new char[512];
FormatEx(sQuery, 512, "SELECT u.name, p.time, p.jumps, p.style, u.auth, p.date, p.map, p.strafes, p.sync FROM %splayertimes p JOIN %susers u ON p.auth = u.auth WHERE p.id = '%s' LIMIT 1;", gS_MySQLPrefix, gS_MySQLPrefix, sInfo);
FormatEx(sQuery, 512, "SELECT u.name, p.time, p.jumps, p.style, u.auth, p.date, p.map, p.strafes, p.sync, p.points FROM %splayertimes p JOIN %susers u ON p.auth = u.auth WHERE p.id = '%s' LIMIT 1;", gS_MySQLPrefix, gS_MySQLPrefix, sInfo);
gH_SQL.Query(SQL_SubMenu_Callback, sQuery, GetClientSerial(param1));
}
@ -682,17 +673,12 @@ public void SQL_SubMenu_Callback(Database db, DBResultSet results, const char[]
// 6 - map
results.FetchString(6, sMap, 256);
if(gB_Rankings)
{
float fPoints = 0.0;
float fIdealTime = -1.0;
Shavit_GetGivenMapValues(sMap, fPoints, fIdealTime);
float fPoints = results.FetchFloat(9);
if(fPoints != -1.0 && fIdealTime != 0.0)
{
FormatEx(sDisplay, 192, "Points: %.03f", Shavit_CalculatePoints(fTime, bsStyle, fIdealTime, fPoints));
m.AddItem("-1", sDisplay);
}
if(gB_Rankings && fPoints > 0.0)
{
FormatEx(sDisplay, 192, "Points: %.03f", fPoints);
m.AddItem("-1", sDisplay);
}
// 5 - date

View File

@ -517,22 +517,6 @@ public int MenuHandler_DeleteAll(Menu m, MenuAction action, int param1, int para
return 0;
}
for(int i = 0; i < MAX_STYLES; i++)
{
if(gI_StyleProperties[i] & STYLE_UNRANKED)
{
continue;
}
if(gF_WRTime[i] != 0.0)
{
Call_StartForward(gH_OnWRDeleted);
Call_PushCell(i);
Call_PushCell(-1);
Call_Finish();
}
}
char[] sQuery = new char[256];
FormatEx(sQuery, 256, "DELETE FROM %splayertimes WHERE map = '%s';", gS_MySQLPrefix, gS_Map);
@ -706,13 +690,10 @@ public int DeleteConfirm_Handler(Menu m, MenuAction action, int param1, int para
continue;
}
if(gF_WRTime[i] != 0.0)
{
Call_StartForward(gH_OnWRDeleted);
Call_PushCell(i);
Call_PushCell(iRecordID);
Call_Finish();
}
Call_StartForward(gH_OnWRDeleted);
Call_PushCell(i);
Call_PushCell(iRecordID);
Call_Finish();
}
char[] sQuery = new char[256];
@ -778,6 +759,19 @@ public void DeleteAll_Callback(Database db, DBResultSet results, const char[] er
return;
}
for(int i = 0; i < MAX_STYLES; i++)
{
if(gI_StyleProperties[i] & STYLE_UNRANKED)
{
continue;
}
Call_StartForward(gH_OnWRDeleted);
Call_PushCell(i);
Call_PushCell(-1);
Call_Finish();
}
Shavit_PrintToChat(client, "Deleted ALL records for \"%s\".", gS_Map);
}
@ -1032,7 +1026,7 @@ public Action Command_RecentRecords(int client, int args)
}
char[] sQuery = new char[512];
FormatEx(sQuery, 512, "SELECT p.id, p.map, u.name, MIN(p.time), p.jumps, p.style FROM %splayertimes p JOIN %susers u ON p.auth = u.auth GROUP BY p.map, p.style ORDER BY date DESC LIMIT %d;", gS_MySQLPrefix, gS_MySQLPrefix, gCV_RecentLimit.IntValue);
FormatEx(sQuery, 512, "SELECT p.id, p.map, u.name, MIN(p.time), p.jumps, p.style, p.points FROM %splayertimes p JOIN %susers u ON p.auth = u.auth GROUP BY p.map, p.style ORDER BY date DESC LIMIT %d;", gS_MySQLPrefix, gS_MySQLPrefix, gCV_RecentLimit.IntValue);
gH_SQL.Query(SQL_RR_Callback, sQuery, GetClientSerial(client), DBPrio_High);
@ -1075,25 +1069,16 @@ public void SQL_RR_Callback(Database db, DBResultSet results, const char[] error
int iJumps = results.FetchInt(4);
BhopStyle bsStyle = view_as<BhopStyle>(results.FetchInt(5));
float fPoints = results.FetchFloat(6);
char[] sDisplay = new char[192];
bool bPoints = false;
if(gB_Rankings)
if(gB_Rankings && fPoints > 0.0)
{
float fPoints = 0.0;
float fIdealTime = -1.0;
Shavit_GetGivenMapValues(sMap, fPoints, fIdealTime);
if(fPoints != -1.0 && fIdealTime != 0.0)
{
FormatEx(sDisplay, 192, "[%s] %s - %s @ %s (%.03f points)", gS_ShortBhopStyles[bsStyle], sDisplayMap, sName, sTime, Shavit_CalculatePoints(fTime, bsStyle, fIdealTime, fPoints));
bPoints = true;
}
FormatEx(sDisplay, 192, "[%s] %s - %s @ %s (%.03f points)", gS_ShortBhopStyles[bsStyle], sDisplayMap, sName, sTime, fPoints);
}
if(!bPoints)
else
{
FormatEx(sDisplay, 192, "[%s] %s - %s @ %s (%d jump%s)", gS_ShortBhopStyles[bsStyle], sDisplayMap, sName, sTime, iJumps, (iJumps != 1)? "s":"");
}
@ -1110,7 +1095,6 @@ public void SQL_RR_Callback(Database db, DBResultSet results, const char[] error
}
m.ExitButton = true;
m.Display(client, 60);
}
@ -1153,7 +1137,7 @@ public int RRMenu_Handler(Menu m, MenuAction action, int param1, int param2)
public void OpenSubMenu(int client, int id)
{
char[] sQuery = new char[512];
FormatEx(sQuery, 512, "SELECT u.name, p.time, p.jumps, p.style, u.auth, p.date, p.map, p.strafes, p.sync FROM %splayertimes p JOIN %susers u ON p.auth = u.auth WHERE p.id = %d LIMIT 1;", gS_MySQLPrefix, gS_MySQLPrefix, id);
FormatEx(sQuery, 512, "SELECT u.name, p.time, p.jumps, p.style, u.auth, p.date, p.map, p.strafes, p.sync, p.points FROM %splayertimes p JOIN %susers u ON p.auth = u.auth WHERE p.id = %d LIMIT 1;", gS_MySQLPrefix, gS_MySQLPrefix, id);
gH_SQL.Query(SQL_SubMenu_Callback, sQuery, GetClientSerial(client), DBPrio_High);
}
@ -1210,17 +1194,12 @@ public void SQL_SubMenu_Callback(Database db, DBResultSet results, const char[]
results.FetchString(6, sMap, 192);
GetMapDisplayName(sMap, sDisplayMap, 192);
if(gB_Rankings)
{
float fPoints = 0.0;
float fIdealTime = -1.0;
Shavit_GetGivenMapValues(sMap, fPoints, fIdealTime);
float fPoints = results.FetchFloat(9);
if(fPoints != -1.0 && fIdealTime != 0.0)
{
FormatEx(sDisplay, 128, "Points: %.03f", Shavit_CalculatePoints(fTime, bsStyle, fIdealTime, fPoints));
m.AddItem("-1", sDisplay);
}
if(gB_Rankings && fPoints > 0.0)
{
FormatEx(sDisplay, 128, "Points: %.03f", fPoints);
m.AddItem("-1", sDisplay);
}
// 4 - steamid3
@ -1337,8 +1316,8 @@ public void SQL_DBConnect()
gH_SQL.Driver.GetIdentifier(sDriver, 8);
gB_MySQL = StrEqual(sDriver, "mysql", false);
char[] sQuery = new char[256];
FormatEx(sQuery, 256, "CREATE TABLE IF NOT EXISTS `%splayertimes` (`id` %s, `auth` VARCHAR(32), `map` VARCHAR(192), `time` FLOAT, `jumps` INT, `style` INT, `date` VARCHAR(32), `strafes` INT, `sync` FLOAT%s);", gS_MySQLPrefix, gB_MySQL? "INT NOT NULL AUTO_INCREMENT":"INTEGER PRIMARY KEY", gB_MySQL? ", PRIMARY KEY (`id`)":"");
char[] sQuery = new char[512];
FormatEx(sQuery, 512, "CREATE TABLE IF NOT EXISTS `%splayertimes` (`id` %s, `auth` VARCHAR(32), `map` VARCHAR(192), `time` FLOAT, `jumps` INT, `style` INT, `date` VARCHAR(32), `strafes` INT, `sync` FLOAT, `points` FLOAT NOT NULL DEFAULT 0%s);", gS_MySQLPrefix, gB_MySQL? "INT NOT NULL AUTO_INCREMENT":"INTEGER PRIMARY KEY", gB_MySQL? ", PRIMARY KEY (`id`)":"");
gH_SQL.Query(SQL_CreateTable_Callback, sQuery, 0, DBPrio_High);
}
@ -1372,6 +1351,9 @@ public void SQL_CreateTable_Callback(Database db, DBResultSet results, const cha
FormatEx(sQuery, 64, "ALTER TABLE %splayertimes MODIFY date VARCHAR(32);", gS_MySQLPrefix);
gH_SQL.Query(SQL_AlterTable2_Callback, sQuery);
}
FormatEx(sQuery, 64, "SELECT points FROM %splayertimes LIMIT 1;", gS_MySQLPrefix);
gH_SQL.Query(SQL_TableMigration3_Callback, sQuery);
}
public void SQL_TableMigration1_Callback(Database db, DBResultSet results, const char[] error, any data)
@ -1417,6 +1399,26 @@ public void SQL_AlterTable2_Callback(Database db, DBResultSet results, const cha
}
}
public void SQL_TableMigration3_Callback(Database db, DBResultSet results, const char[] error, any data)
{
if(results == null)
{
char[] sQuery = new char[256];
FormatEx(sQuery, 256, "ALTER TABLE `%splayertimes` ADD %s;", gS_MySQLPrefix, gB_MySQL? "(`points` FLOAT NOT NULL DEFAULT 0)":"COLUMN `points` FLOAT NOT NULL DEFAULT 0");
gH_SQL.Query(SQL_AlterTable3_Callback, sQuery);
}
}
public void SQL_AlterTable3_Callback(Database db, DBResultSet results, const char[] error, any data)
{
if(results == null)
{
LogError("Timer (WR module) error! Times' table migration (3) failed. Reason: %s", error);
return;
}
}
public void Shavit_OnFinish(int client, BhopStyle style, float time, int jumps, int strafes, float sync)
{
char[] sTime = new char[32];
@ -1442,10 +1444,10 @@ public void Shavit_OnFinish(int client, BhopStyle style, float time, int jumps,
overwrite = 2;
}
int iRank = GetRankForTime(style, time);
if(overwrite > 0 && (time < gF_WRTime[style] || gF_WRTime[style] == 0.0)) // WR?
{
gF_WRTime[style] = time;
Call_StartForward(gH_OnWorldRecord);
Call_PushCell(client);
Call_PushCell(style);
@ -1458,6 +1460,8 @@ public void Shavit_OnFinish(int client, BhopStyle style, float time, int jumps,
UpdateWRCache();
}
int iRank = GetRankForTime(style, time);
float fDifference = (gF_PlayerRecord[client][style] - time);
if(fDifference < 0.0)
@ -1513,11 +1517,6 @@ public void Shavit_OnFinish(int client, BhopStyle style, float time, int jumps,
Call_Finish();
gF_PlayerRecord[client][style] = time;
if(time < gF_WRTime[style])
{
gF_WRTime[style] = time;
}
}
else if(overwrite == 0 && !(gI_StyleProperties[style] & STYLE_UNRANKED))
@ -1570,6 +1569,7 @@ public void SQL_UpdateLeaderboards_Callback(Database db, DBResultSet results, co
for(int i = 0; i < MAX_STYLES; i++)
{
gI_RecordAmount[i] = 0;
gA_LeaderBoard[i].Clear();
}
@ -1599,6 +1599,11 @@ public void SQL_UpdateLeaderboards_Callback(Database db, DBResultSet results, co
public int GetRankForTime(BhopStyle style, float time)
{
if(time < gF_WRTime[style])
{
return 1;
}
for(int i = 0; i < gI_RecordAmount[style]; i++)
{
if(time < gA_LeaderBoard[style].Get(i))