mirror of
https://github.com/shavitush/bhoptimer.git
synced 2025-12-07 18:38:26 +00:00
Added perfect jump% measuring for scroll styles.
* Added `oldtime` and `perfs` parameters for forwards that missed them. * Added `iMeasuredJumps` and `iPerfectJumps` to snapshots. * Added a database migration to add `perfs` column. * Added perfect jumps% to CS:S keyhint HUD. Not necessary in CS:GO due to annoying limitations. * Added perfect jumps% to WR menu. * Added `Shavit_GetPerfectJumps` native.
This commit is contained in:
parent
8861c388fe
commit
8c25086471
@ -145,6 +145,8 @@ enum
|
|||||||
fServerTime,
|
fServerTime,
|
||||||
iSHSWCombination,
|
iSHSWCombination,
|
||||||
iTimerTrack,
|
iTimerTrack,
|
||||||
|
iMeasuredJumps,
|
||||||
|
iPerfectJumps,
|
||||||
TIMERSNAPSHOT_SIZE
|
TIMERSNAPSHOT_SIZE
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -386,9 +388,10 @@ forward Action Shavit_OnFinishPre(int client, any snapshot[TIMERSNAPSHOT_SIZE]);
|
|||||||
* @param sync Sync percentage (0.0 to 100.0) or -1.0 when not measured.
|
* @param sync Sync percentage (0.0 to 100.0) or -1.0 when not measured.
|
||||||
* @param track Timer track.
|
* @param track Timer track.
|
||||||
* @param oldtime The player's best time on the map before this finish.
|
* @param oldtime The player's best time on the map before this finish.
|
||||||
|
* @param perfs Perfect jump percentage (0.0 to 100.0) or 100.0 when not measured.
|
||||||
* @noreturn
|
* @noreturn
|
||||||
*/
|
*/
|
||||||
forward void Shavit_OnFinish(int client, int style, float time, int jumps, int strafes, float sync, int track, float oldtime);
|
forward void Shavit_OnFinish(int client, int style, float time, int jumps, int strafes, float sync, int track, float oldtime, float perfs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like Shavit_OnFinish, but after the insertion query was called.
|
* Like Shavit_OnFinish, but after the insertion query was called.
|
||||||
@ -403,9 +406,11 @@ forward void Shavit_OnFinish(int client, int style, float time, int jumps, int s
|
|||||||
* @param rank Rank on map.
|
* @param rank Rank on map.
|
||||||
* @param overwrite 1 - brand new record. 2 - update.
|
* @param overwrite 1 - brand new record. 2 - update.
|
||||||
* @param track Timer track.
|
* @param track Timer track.
|
||||||
|
* @param oldtime The player's best time on the map before this finish.
|
||||||
|
* @param perfs Perfect jump percentage (0.0 to 100.0) or 100.0 when not measured.
|
||||||
* @noreturn
|
* @noreturn
|
||||||
*/
|
*/
|
||||||
forward void Shavit_OnFinish_Post(int client, int style, float time, int jumps, int strafes, float sync, int rank, int overwrite, int track);
|
forward void Shavit_OnFinish_Post(int client, int style, float time, int jumps, int strafes, float sync, int rank, int overwrite, int track, float oldtime, float perfs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when there's a new WR on the map.
|
* Called when there's a new WR on the map.
|
||||||
@ -418,9 +423,11 @@ forward void Shavit_OnFinish_Post(int client, int style, float time, int jumps,
|
|||||||
* @param sync Sync percentage (0.0 to 100.0) or -1.0 when not measured.
|
* @param sync Sync percentage (0.0 to 100.0) or -1.0 when not measured.
|
||||||
* @param track Timer track.
|
* @param track Timer track.
|
||||||
* @param oldwr Time of the old WR. 0.0 if there's none.
|
* @param oldwr Time of the old WR. 0.0 if there's none.
|
||||||
|
* @param oldtime The player's best time on the map before this finish.
|
||||||
|
* @param perfs Perfect jump percentage (0.0 to 100.0) or 100.0 when not measured.
|
||||||
* @noreturn
|
* @noreturn
|
||||||
*/
|
*/
|
||||||
forward void Shavit_OnWorldRecord(int client, int style, float time, int jumps, int strafes, float sync, int track, float oldwr);
|
forward void Shavit_OnWorldRecord(int client, int style, float time, int jumps, int strafes, float sync, int track, float oldwr, float oldtime, float perfs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when an admin deletes a WR.
|
* Called when an admin deletes a WR.
|
||||||
@ -520,9 +527,11 @@ forward void Shavit_OnLeaveZone(int client, int type, int track, int id, int ent
|
|||||||
* @param strafes Amount of strafes.
|
* @param strafes Amount of strafes.
|
||||||
* @param sync Sync percentage (0.0 to 100.0) or -1.0 when not measured.
|
* @param sync Sync percentage (0.0 to 100.0) or -1.0 when not measured.
|
||||||
* @param track Timer track.
|
* @param track Timer track.
|
||||||
|
* @param oldtime The player's best time on the map before this finish.
|
||||||
|
* @param perfs Perfect jump percentage (0.0 to 100.0) or 100.0 when not measured.
|
||||||
* @noreturn
|
* @noreturn
|
||||||
*/
|
*/
|
||||||
forward void Shavit_OnWorstRecord(int client, int style, float time, int jumps, int strafes, float sync, int track);
|
forward void Shavit_OnWorstRecord(int client, int style, float time, int jumps, int strafes, float sync, int track, float oldtime, float perfs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets called when a map's tier is assigned.
|
* Gets called when a map's tier is assigned.
|
||||||
@ -661,6 +670,15 @@ native TimerStatus Shavit_GetTimerStatus(int client);
|
|||||||
*/
|
*/
|
||||||
native int Shavit_GetStrafeCount(int client);
|
native int Shavit_GetStrafeCount(int client);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the perfect jumps percentage for the player.
|
||||||
|
* Will return 100.0 if no jumps were measured.
|
||||||
|
*
|
||||||
|
* @param client Client index.
|
||||||
|
* @return Perfect jump percentage.
|
||||||
|
*/
|
||||||
|
native float Shavit_GetPerfectJumps(int client);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve strafe sync since timer start.
|
* Retrieve strafe sync since timer start.
|
||||||
* Will return 0.0 if timer isn't running or -1.0 when not measured.
|
* Will return 0.0 if timer isn't running or -1.0 when not measured.
|
||||||
@ -1183,6 +1201,7 @@ public void __pl_shavit_SetNTVOptional()
|
|||||||
MarkNativeAsOptional("Shavit_GetHUDSettings");
|
MarkNativeAsOptional("Shavit_GetHUDSettings");
|
||||||
MarkNativeAsOptional("Shavit_GetMapTier");
|
MarkNativeAsOptional("Shavit_GetMapTier");
|
||||||
MarkNativeAsOptional("Shavit_GetMapTiers");
|
MarkNativeAsOptional("Shavit_GetMapTiers");
|
||||||
|
MarkNativeAsOptional("Shavit_GetPerfectJumps");
|
||||||
MarkNativeAsOptional("Shavit_GetPlayerPB");
|
MarkNativeAsOptional("Shavit_GetPlayerPB");
|
||||||
MarkNativeAsOptional("Shavit_GetPoints");
|
MarkNativeAsOptional("Shavit_GetPoints");
|
||||||
MarkNativeAsOptional("Shavit_GetRank");
|
MarkNativeAsOptional("Shavit_GetRank");
|
||||||
|
|||||||
@ -78,6 +78,8 @@ float gF_StrafeWarning[MAXPLAYERS+1];
|
|||||||
bool gB_PracticeMode[MAXPLAYERS+1];
|
bool gB_PracticeMode[MAXPLAYERS+1];
|
||||||
int gI_SHSW_FirstCombination[MAXPLAYERS+1];
|
int gI_SHSW_FirstCombination[MAXPLAYERS+1];
|
||||||
int gI_Track[MAXPLAYERS+1];
|
int gI_Track[MAXPLAYERS+1];
|
||||||
|
int gI_MeasuredJumps[MAXPLAYERS+1];
|
||||||
|
int gI_PerfectJumps[MAXPLAYERS+1];
|
||||||
|
|
||||||
StringMap gSM_StyleCommands = null;
|
StringMap gSM_StyleCommands = null;
|
||||||
|
|
||||||
@ -132,6 +134,7 @@ char gS_ChatStrings[CHATSETTINGS_SIZE][128];
|
|||||||
bool gB_StopChatSound = false;
|
bool gB_StopChatSound = false;
|
||||||
bool gB_HookedJump = false;
|
bool gB_HookedJump = false;
|
||||||
char gS_LogPath[PLATFORM_MAX_PATH];
|
char gS_LogPath[PLATFORM_MAX_PATH];
|
||||||
|
int gI_GroundTicks[MAXPLAYERS+1];
|
||||||
|
|
||||||
// flags
|
// flags
|
||||||
int gI_StyleFlag[STYLE_LIMIT];
|
int gI_StyleFlag[STYLE_LIMIT];
|
||||||
@ -160,6 +163,7 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max
|
|||||||
CreateNative("Shavit_GetDatabase", Native_GetDatabase);
|
CreateNative("Shavit_GetDatabase", Native_GetDatabase);
|
||||||
CreateNative("Shavit_GetDB", Native_GetDB);
|
CreateNative("Shavit_GetDB", Native_GetDB);
|
||||||
CreateNative("Shavit_GetGameType", Native_GetGameType);
|
CreateNative("Shavit_GetGameType", Native_GetGameType);
|
||||||
|
CreateNative("Shavit_GetPerfectJumps", Native_GetPerfectJumps);
|
||||||
CreateNative("Shavit_GetStrafeCount", Native_GetStrafeCount);
|
CreateNative("Shavit_GetStrafeCount", Native_GetStrafeCount);
|
||||||
CreateNative("Shavit_GetStyleCount", Native_GetStyleCount);
|
CreateNative("Shavit_GetStyleCount", Native_GetStyleCount);
|
||||||
CreateNative("Shavit_GetStyleSettings", Native_GetStyleSettings);
|
CreateNative("Shavit_GetStyleSettings", Native_GetStyleSettings);
|
||||||
@ -197,7 +201,7 @@ public void OnPluginStart()
|
|||||||
gH_Forwards_Start = CreateGlobalForward("Shavit_OnStart", ET_Event, Param_Cell, Param_Cell);
|
gH_Forwards_Start = CreateGlobalForward("Shavit_OnStart", ET_Event, Param_Cell, Param_Cell);
|
||||||
gH_Forwards_Stop = CreateGlobalForward("Shavit_OnStop", ET_Event, Param_Cell, Param_Cell);
|
gH_Forwards_Stop = CreateGlobalForward("Shavit_OnStop", ET_Event, Param_Cell, Param_Cell);
|
||||||
gH_Forwards_FinishPre = CreateGlobalForward("Shavit_OnFinishPre", ET_Event, Param_Cell, Param_Array);
|
gH_Forwards_FinishPre = CreateGlobalForward("Shavit_OnFinishPre", ET_Event, Param_Cell, Param_Array);
|
||||||
gH_Forwards_Finish = CreateGlobalForward("Shavit_OnFinish", ET_Event, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell);
|
gH_Forwards_Finish = CreateGlobalForward("Shavit_OnFinish", ET_Event, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell);
|
||||||
gH_Forwards_OnRestart = CreateGlobalForward("Shavit_OnRestart", ET_Event, Param_Cell, Param_Cell);
|
gH_Forwards_OnRestart = CreateGlobalForward("Shavit_OnRestart", ET_Event, Param_Cell, Param_Cell);
|
||||||
gH_Forwards_OnEnd = CreateGlobalForward("Shavit_OnEnd", ET_Event, Param_Cell, Param_Cell);
|
gH_Forwards_OnEnd = CreateGlobalForward("Shavit_OnEnd", ET_Event, Param_Cell, Param_Cell);
|
||||||
gH_Forwards_OnPause = CreateGlobalForward("Shavit_OnPause", ET_Event, Param_Cell, Param_Cell);
|
gH_Forwards_OnPause = CreateGlobalForward("Shavit_OnPause", ET_Event, Param_Cell, Param_Cell);
|
||||||
@ -955,6 +959,8 @@ public int Native_FinishMap(Handle handler, int numParams)
|
|||||||
snapshot[fCurrentTime] = gF_PlayerTimer[client];
|
snapshot[fCurrentTime] = gF_PlayerTimer[client];
|
||||||
snapshot[iSHSWCombination] = gI_SHSW_FirstCombination[client];
|
snapshot[iSHSWCombination] = gI_SHSW_FirstCombination[client];
|
||||||
snapshot[iTimerTrack] = gI_Track[client];
|
snapshot[iTimerTrack] = gI_Track[client];
|
||||||
|
snapshot[iMeasuredJumps] = gI_MeasuredJumps[client];
|
||||||
|
snapshot[iPerfectJumps] = gI_PerfectJumps[client];
|
||||||
|
|
||||||
Action result = Plugin_Continue;
|
Action result = Plugin_Continue;
|
||||||
Call_StartForward(gH_Forwards_FinishPre);
|
Call_StartForward(gH_Forwards_FinishPre);
|
||||||
@ -972,6 +978,7 @@ public int Native_FinishMap(Handle handler, int numParams)
|
|||||||
|
|
||||||
int style = 0;
|
int style = 0;
|
||||||
int track = Track_Main;
|
int track = Track_Main;
|
||||||
|
float perfs = 100.0;
|
||||||
|
|
||||||
if(result == Plugin_Continue)
|
if(result == Plugin_Continue)
|
||||||
{
|
{
|
||||||
@ -981,6 +988,7 @@ public int Native_FinishMap(Handle handler, int numParams)
|
|||||||
Call_PushCell(gI_Strafes[client]);
|
Call_PushCell(gI_Strafes[client]);
|
||||||
Call_PushCell((gA_StyleSettings[gI_Style[client]][bSync])? (gI_GoodGains[client] == 0)? 0.0:(gI_GoodGains[client] / float(gI_TotalMeasures[client]) * 100.0):-1.0);
|
Call_PushCell((gA_StyleSettings[gI_Style[client]][bSync])? (gI_GoodGains[client] == 0)? 0.0:(gI_GoodGains[client] / float(gI_TotalMeasures[client]) * 100.0):-1.0);
|
||||||
Call_PushCell(track = gI_Track[client]);
|
Call_PushCell(track = gI_Track[client]);
|
||||||
|
perfs = (gI_MeasuredJumps[client] == 0)? 100.0:(gI_PerfectJumps[client] / float(gI_MeasuredJumps[client]) * 100.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -991,6 +999,7 @@ public int Native_FinishMap(Handle handler, int numParams)
|
|||||||
Call_PushCell(snapshot[iStrafes]);
|
Call_PushCell(snapshot[iStrafes]);
|
||||||
Call_PushCell((gA_StyleSettings[snapshot[bsStyle]][bSync])? (snapshot[iGoodGains] == 0)? 0.0:(snapshot[iGoodGains] / float(snapshot[iTotalMeasures]) * 100.0):-1.0);
|
Call_PushCell((gA_StyleSettings[snapshot[bsStyle]][bSync])? (snapshot[iGoodGains] == 0)? 0.0:(snapshot[iGoodGains] / float(snapshot[iTotalMeasures]) * 100.0):-1.0);
|
||||||
Call_PushCell(track = snapshot[iTimerTrack]);
|
Call_PushCell(track = snapshot[iTimerTrack]);
|
||||||
|
perfs = (snapshot[iMeasuredJumps] == 0)? 100.0:(snapshot[iPerfectJumps] / float(snapshot[iMeasuredJumps]) * 100.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
float oldtime = 0.0;
|
float oldtime = 0.0;
|
||||||
@ -1001,6 +1010,7 @@ public int Native_FinishMap(Handle handler, int numParams)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Call_PushCell(oldtime);
|
Call_PushCell(oldtime);
|
||||||
|
Call_PushCell(perfs);
|
||||||
Call_Finish();
|
Call_Finish();
|
||||||
|
|
||||||
StopTimer(client);
|
StopTimer(client);
|
||||||
@ -1065,6 +1075,13 @@ public int Native_RestartTimer(Handle handler, int numParams)
|
|||||||
StartTimer(client, track);
|
StartTimer(client, track);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int Native_GetPerfectJumps(Handle handler, int numParams)
|
||||||
|
{
|
||||||
|
int client = GetNativeCell(1);
|
||||||
|
|
||||||
|
return view_as<int>((gI_MeasuredJumps[client] == 0)? 100.0:(gI_PerfectJumps[client] / float(gI_MeasuredJumps[client]) * 100.0));
|
||||||
|
}
|
||||||
|
|
||||||
public int Native_GetStrafeCount(Handle handler, int numParams)
|
public int Native_GetStrafeCount(Handle handler, int numParams)
|
||||||
{
|
{
|
||||||
return gI_Strafes[GetNativeCell(1)];
|
return gI_Strafes[GetNativeCell(1)];
|
||||||
@ -1132,6 +1149,8 @@ public int Native_SaveSnapshot(Handle handler, int numParams)
|
|||||||
snapshot[fCurrentTime] = gF_PlayerTimer[client];
|
snapshot[fCurrentTime] = gF_PlayerTimer[client];
|
||||||
snapshot[iSHSWCombination] = gI_SHSW_FirstCombination[client];
|
snapshot[iSHSWCombination] = gI_SHSW_FirstCombination[client];
|
||||||
snapshot[iTimerTrack] = gI_Track[client];
|
snapshot[iTimerTrack] = gI_Track[client];
|
||||||
|
snapshot[iMeasuredJumps] = gI_MeasuredJumps[client];
|
||||||
|
snapshot[iPerfectJumps] = gI_PerfectJumps[client];
|
||||||
|
|
||||||
return SetNativeArray(2, snapshot, TIMERSNAPSHOT_SIZE);
|
return SetNativeArray(2, snapshot, TIMERSNAPSHOT_SIZE);
|
||||||
}
|
}
|
||||||
@ -1159,6 +1178,8 @@ public int Native_LoadSnapshot(Handle handler, int numParams)
|
|||||||
gI_GoodGains[client] = view_as<int>(snapshot[iGoodGains]);
|
gI_GoodGains[client] = view_as<int>(snapshot[iGoodGains]);
|
||||||
gF_PlayerTimer[client] = snapshot[fCurrentTime];
|
gF_PlayerTimer[client] = snapshot[fCurrentTime];
|
||||||
gI_SHSW_FirstCombination[client] = view_as<int>(snapshot[iSHSWCombination]);
|
gI_SHSW_FirstCombination[client] = view_as<int>(snapshot[iSHSWCombination]);
|
||||||
|
gI_MeasuredJumps[client] = view_as<int>(snapshot[iMeasuredJumps]);
|
||||||
|
gI_PerfectJumps[client] = view_as<int>(snapshot[iPerfectJumps]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Native_LogMessage(Handle plugin, int numParams)
|
public int Native_LogMessage(Handle plugin, int numParams)
|
||||||
@ -1229,6 +1250,8 @@ void StartTimer(int client, int track)
|
|||||||
gI_SHSW_FirstCombination[client] = -1;
|
gI_SHSW_FirstCombination[client] = -1;
|
||||||
gF_PlayerTimer[client] = 0.0;
|
gF_PlayerTimer[client] = 0.0;
|
||||||
gB_PracticeMode[client] = false;
|
gB_PracticeMode[client] = false;
|
||||||
|
gI_MeasuredJumps[client] = 0;
|
||||||
|
gI_PerfectJumps[client] = 0;
|
||||||
|
|
||||||
SetEntityGravity(client, view_as<float>(gA_StyleSettings[gI_Style[client]][fGravityMultiplier]));
|
SetEntityGravity(client, view_as<float>(gA_StyleSettings[gI_Style[client]][fGravityMultiplier]));
|
||||||
SetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue", view_as<float>(gA_StyleSettings[gI_Style[client]][fSpeedMultiplier]));
|
SetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue", view_as<float>(gA_StyleSettings[gI_Style[client]][fSpeedMultiplier]));
|
||||||
@ -2086,15 +2109,40 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
|
|||||||
SetEntPropVector(client, Prop_Data, "m_vecAbsVelocity", fSpeed);
|
SetEntPropVector(client, Prop_Data, "m_vecAbsVelocity", fSpeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iPButtons = buttons;
|
||||||
|
|
||||||
if(gA_StyleSettings[gI_Style[client]][bAutobhop] && gB_Auto[client] && (buttons & IN_JUMP) > 0 && mtMoveType == MOVETYPE_WALK && !bInWater)
|
if(gA_StyleSettings[gI_Style[client]][bAutobhop] && gB_Auto[client] && (buttons & IN_JUMP) > 0 && mtMoveType == MOVETYPE_WALK && !bInWater)
|
||||||
{
|
{
|
||||||
int iOldButtons = GetEntProp(client, Prop_Data, "m_nOldButtons");
|
int iOldButtons = GetEntProp(client, Prop_Data, "m_nOldButtons");
|
||||||
SetEntProp(client, Prop_Data, "m_nOldButtons", iOldButtons & ~IN_JUMP);
|
SetEntProp(client, Prop_Data, "m_nOldButtons", (iOldButtons & ~IN_JUMP));
|
||||||
|
iPButtons &= ~IN_JUMP;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(gB_DoubleSteps[client] && (buttons & IN_JUMP) == 0)
|
else if(gB_DoubleSteps[client] && (buttons & IN_JUMP) == 0)
|
||||||
{
|
{
|
||||||
buttons |= IN_JUMP;
|
iPButtons = buttons |= IN_JUMP;
|
||||||
|
}
|
||||||
|
|
||||||
|
// perf jump measuring
|
||||||
|
if(!bInWater && mtMoveType == MOVETYPE_WALK && iGroundEntity != -1)
|
||||||
|
{
|
||||||
|
gI_GroundTicks[client]++;
|
||||||
|
|
||||||
|
if((((gI_ButtonCache[client] & IN_JUMP) == 0 && (iPButtons & IN_JUMP) > 0) || iPButtons != buttons) &&
|
||||||
|
1 <= gI_GroundTicks[client] <= 8)
|
||||||
|
{
|
||||||
|
gI_MeasuredJumps[client]++;
|
||||||
|
|
||||||
|
if(gI_GroundTicks[client] == 1)
|
||||||
|
{
|
||||||
|
gI_PerfectJumps[client]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gI_GroundTicks[client] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bInStart && gB_BlockPreJump && !gA_StyleSettings[gI_Style[client]][bPrespeed] && (vel[2] > 0 || (buttons & IN_JUMP) > 0))
|
if(bInStart && gB_BlockPreJump && !gA_StyleSettings[gI_Style[client]][bPrespeed] && (vel[2] > 0 || (buttons & IN_JUMP) > 0))
|
||||||
@ -2182,7 +2230,7 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gI_ButtonCache[client] = buttons;
|
gI_ButtonCache[client] = iPButtons;
|
||||||
gF_AngleCache[client] = angles[1];
|
gF_AngleCache[client] = angles[1];
|
||||||
|
|
||||||
return Plugin_Continue;
|
return Plugin_Continue;
|
||||||
|
|||||||
@ -761,7 +761,7 @@ void UpdateHUD(int client)
|
|||||||
{
|
{
|
||||||
if(gA_StyleSettings[style][bSync])
|
if(gA_StyleSettings[style][bSync])
|
||||||
{
|
{
|
||||||
Format(sHintText, 512, "%s%s\t%T: %d (%.02f%%)", sHintText, (iSpeed < 1000)? "\t":"", "HudStrafeText", client, strafes, Shavit_GetSync(target));
|
Format(sHintText, 512, "%s%s\t%T: %d (%.01f%%)", sHintText, (iSpeed < 1000)? "\t":"", "HudStrafeText", client, strafes, Shavit_GetSync(target));
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -1075,9 +1075,16 @@ void UpdateKeyHint(int client)
|
|||||||
|
|
||||||
if(IsValidClient(target) && (target == client || (gI_HUDSettings[client] & HUD_OBSERVE) > 0))
|
if(IsValidClient(target) && (target == client || (gI_HUDSettings[client] & HUD_OBSERVE) > 0))
|
||||||
{
|
{
|
||||||
if((gI_HUDSettings[client] & HUD_SYNC) > 0 && Shavit_GetTimerStatus(target) == Timer_Running && gA_StyleSettings[Shavit_GetBhopStyle(target)][bSync] && !IsFakeClient(target) && (!gB_Zones || !Shavit_InsideZone(target, Zone_Start, -1)))
|
int style = Shavit_GetBhopStyle(target);
|
||||||
|
|
||||||
|
if((gI_HUDSettings[client] & HUD_SYNC) > 0 && Shavit_GetTimerStatus(target) == Timer_Running && gA_StyleSettings[style][bSync] && !IsFakeClient(target) && (!gB_Zones || !Shavit_InsideZone(target, Zone_Start, -1)))
|
||||||
{
|
{
|
||||||
Format(sMessage, 256, "%s%s%T: %.02f", sMessage, (strlen(sMessage) > 0)? "\n\n":"", "HudSync", client, Shavit_GetSync(target));
|
Format(sMessage, 256, "%s%s%T: %.01f", sMessage, (strlen(sMessage) > 0)? "\n\n":"", "HudSync", client, Shavit_GetSync(target));
|
||||||
|
|
||||||
|
if(!gA_StyleSettings[style][bAutobhop])
|
||||||
|
{
|
||||||
|
Format(sMessage, 256, "%s\n%T: %.1f", sMessage, "HudPerfs", client, Shavit_GetPerfectJumps(target));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((gI_HUDSettings[client] & HUD_SPECTATORS) > 0)
|
if((gI_HUDSettings[client] & HUD_SPECTATORS) > 0)
|
||||||
|
|||||||
@ -131,10 +131,10 @@ public void OnPluginStart()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// forwards
|
// forwards
|
||||||
gH_OnWorldRecord = CreateGlobalForward("Shavit_OnWorldRecord", ET_Event, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell);
|
gH_OnWorldRecord = CreateGlobalForward("Shavit_OnWorldRecord", ET_Event, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell);
|
||||||
gH_OnFinish_Post = CreateGlobalForward("Shavit_OnFinish_Post", ET_Event, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell);
|
gH_OnFinish_Post = CreateGlobalForward("Shavit_OnFinish_Post", ET_Event, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell);
|
||||||
gH_OnWRDeleted = CreateGlobalForward("Shavit_OnWRDeleted", ET_Event, Param_Cell, Param_Cell, Param_Cell);
|
gH_OnWRDeleted = CreateGlobalForward("Shavit_OnWRDeleted", ET_Event, Param_Cell, Param_Cell, Param_Cell);
|
||||||
gH_OnWorstRecord = CreateGlobalForward("Shavit_OnWorstRecord", ET_Event, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell);
|
gH_OnWorstRecord = CreateGlobalForward("Shavit_OnWorstRecord", ET_Event, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell);
|
||||||
|
|
||||||
// player commands
|
// player commands
|
||||||
RegConsoleCmd("sm_wr", Command_WorldRecord, "View the leaderboard of a map. Usage: sm_wr [map]");
|
RegConsoleCmd("sm_wr", Command_WorldRecord, "View the leaderboard of a map. Usage: sm_wr [map]");
|
||||||
@ -1671,7 +1671,7 @@ public int RRMenu_Handler(Menu m, MenuAction action, int param1, int param2)
|
|||||||
void OpenSubMenu(int client, int id)
|
void OpenSubMenu(int client, int id)
|
||||||
{
|
{
|
||||||
char[] sQuery = new char[512];
|
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, p.points, p.track 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.perfs, p.points, p.track FROM %splayertimes p JOIN %susers u ON p.auth = u.auth WHERE p.id = %d LIMIT 1;", gS_MySQLPrefix, gS_MySQLPrefix, id);
|
||||||
|
|
||||||
DataPack datapack = new DataPack();
|
DataPack datapack = new DataPack();
|
||||||
datapack.WriteCell(GetClientSerial(client));
|
datapack.WriteCell(GetClientSerial(client));
|
||||||
@ -1722,19 +1722,30 @@ public void SQL_SubMenu_Callback(Database db, DBResultSet results, const char[]
|
|||||||
menu.AddItem("-1", sDisplay);
|
menu.AddItem("-1", sDisplay);
|
||||||
|
|
||||||
// 2 - jumps
|
// 2 - jumps
|
||||||
|
int style = results.FetchInt(3);
|
||||||
int jumps = results.FetchInt(2);
|
int jumps = results.FetchInt(2);
|
||||||
FormatEx(sDisplay, 128, "%T: %d", "WRJumps", client, jumps);
|
|
||||||
|
if(gA_StyleSettings[style][bAutobhop])
|
||||||
|
{
|
||||||
|
FormatEx(sDisplay, 128, "%T: %d", "WRJumps", client, jumps);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float perfs = results.FetchFloat(9);
|
||||||
|
FormatEx(sDisplay, 128, "%T: %d (%.2f%%)", "WRJumps", client, jumps, perfs);
|
||||||
|
}
|
||||||
|
|
||||||
menu.AddItem("-1", sDisplay);
|
menu.AddItem("-1", sDisplay);
|
||||||
|
|
||||||
// 3 - style
|
// 3 - style
|
||||||
int style = results.FetchInt(3);
|
|
||||||
FormatEx(sDisplay, 128, "%T: %s", "WRStyle", client, gS_StyleStrings[style][sStyleName]);
|
FormatEx(sDisplay, 128, "%T: %s", "WRStyle", client, gS_StyleStrings[style][sStyleName]);
|
||||||
menu.AddItem("-1", sDisplay);
|
menu.AddItem("-1", sDisplay);
|
||||||
|
|
||||||
// 6 - map
|
// 6 - map
|
||||||
results.FetchString(6, sMap, 192);
|
results.FetchString(6, sMap, 192);
|
||||||
|
|
||||||
float fPoints = results.FetchFloat(9);
|
float fPoints = results.FetchFloat(10);
|
||||||
|
|
||||||
if(gB_Rankings && fPoints > 0.0)
|
if(gB_Rankings && fPoints > 0.0)
|
||||||
{
|
{
|
||||||
@ -1784,7 +1795,7 @@ public void SQL_SubMenu_Callback(Database db, DBResultSet results, const char[]
|
|||||||
menu.AddItem(sInfo, sMenuItem);
|
menu.AddItem(sInfo, sMenuItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
GetTrackName(client, results.FetchInt(10), sTrack, 32);
|
GetTrackName(client, results.FetchInt(11), sTrack, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -1921,12 +1932,12 @@ void SQL_DBConnect()
|
|||||||
|
|
||||||
if(gB_MySQL)
|
if(gB_MySQL)
|
||||||
{
|
{
|
||||||
FormatEx(sQuery, 512, "CREATE TABLE IF NOT EXISTS `%splayertimes` (`id` INT NOT NULL AUTO_INCREMENT, `auth` CHAR(32), `map` CHAR(128), `time` FLOAT, `jumps` INT, `style` TINYINT, `date` CHAR(16), `strafes` INT, `sync` FLOAT, `points` FLOAT NOT NULL DEFAULT 0, `track` TINYINT NOT NULL DEFAULT 0, PRIMARY KEY (`id`), INDEX `map` (`map`, `style`, `track`), INDEX `auth` (`auth`, `date`, `points`), INDEX `time` (`time`)) ENGINE=INNODB;", gS_MySQLPrefix);
|
FormatEx(sQuery, 512, "CREATE TABLE IF NOT EXISTS `%splayertimes` (`id` INT NOT NULL AUTO_INCREMENT, `auth` CHAR(32), `map` CHAR(128), `time` FLOAT, `jumps` INT, `style` TINYINT, `date` CHAR(16), `strafes` INT, `sync` FLOAT, `points` FLOAT NOT NULL DEFAULT 0, `track` TINYINT NOT NULL DEFAULT 0, `perfs` FLOAT DEFAULT 0, PRIMARY KEY (`id`), INDEX `map` (`map`, `style`, `track`), INDEX `auth` (`auth`, `date`, `points`), INDEX `time` (`time`)) ENGINE=INNODB;", gS_MySQLPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FormatEx(sQuery, 512, "CREATE TABLE IF NOT EXISTS `%splayertimes` (`id` INTEGER PRIMARY KEY, `auth` CHAR(32), `map` CHAR(128), `time` FLOAT, `jumps` INT, `style` TINYINT, `date` CHAR(16), `strafes` INT, `sync` FLOAT, `points` FLOAT NOT NULL DEFAULT 0, `track` TINYINT NOT NULL DEFAULT 0);", gS_MySQLPrefix);
|
FormatEx(sQuery, 512, "CREATE TABLE IF NOT EXISTS `%splayertimes` (`id` INTEGER PRIMARY KEY, `auth` CHAR(32), `map` CHAR(128), `time` FLOAT, `jumps` INT, `style` TINYINT, `date` CHAR(16), `strafes` INT, `sync` FLOAT, `points` FLOAT NOT NULL DEFAULT 0, `track` TINYINT NOT NULL DEFAULT 0, `perfs` FLOAT DEFAULT 0);", gS_MySQLPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
gH_SQL.Query(SQL_CreateTable_Callback, sQuery, 0, DBPrio_High);
|
gH_SQL.Query(SQL_CreateTable_Callback, sQuery, 0, DBPrio_High);
|
||||||
@ -1966,6 +1977,9 @@ public void SQL_CreateTable_Callback(Database db, DBResultSet results, const cha
|
|||||||
|
|
||||||
FormatEx(sQuery, 64, "SELECT track FROM %splayertimes LIMIT 1;", gS_MySQLPrefix);
|
FormatEx(sQuery, 64, "SELECT track FROM %splayertimes LIMIT 1;", gS_MySQLPrefix);
|
||||||
gH_SQL.Query(SQL_TableMigration4_Callback, sQuery);
|
gH_SQL.Query(SQL_TableMigration4_Callback, sQuery);
|
||||||
|
|
||||||
|
FormatEx(sQuery, 64, "SELECT perfs FROM %splayertimes LIMIT 1;", gS_MySQLPrefix);
|
||||||
|
gH_SQL.Query(SQL_TableMigration5_Callback, sQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SQL_TableMigration1_Callback(Database db, DBResultSet results, const char[] error, any data)
|
public void SQL_TableMigration1_Callback(Database db, DBResultSet results, const char[] error, any data)
|
||||||
@ -1996,8 +2010,6 @@ public void SQL_AlterTable1_Callback(Database db, DBResultSet results, const cha
|
|||||||
if(results == null)
|
if(results == null)
|
||||||
{
|
{
|
||||||
LogError("Timer (WR module) error! Times' table migration (1) failed. Reason: %s", error);
|
LogError("Timer (WR module) error! Times' table migration (1) failed. Reason: %s", error);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2006,8 +2018,6 @@ public void SQL_AlterTable2_Callback(Database db, DBResultSet results, const cha
|
|||||||
if(results == null)
|
if(results == null)
|
||||||
{
|
{
|
||||||
LogError("Timer (WR module) error! Times' table migration (2) failed. Reason: %s", error);
|
LogError("Timer (WR module) error! Times' table migration (2) failed. Reason: %s", error);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2026,8 +2036,6 @@ public void SQL_AlterTable3_Callback(Database db, DBResultSet results, const cha
|
|||||||
if(results == null)
|
if(results == null)
|
||||||
{
|
{
|
||||||
LogError("Timer (WR module) error! Times' table migration (3) failed. Reason: %s", error);
|
LogError("Timer (WR module) error! Times' table migration (3) failed. Reason: %s", error);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2038,11 +2046,7 @@ public void SQL_TableMigration4_Callback(Database db, DBResultSet results, const
|
|||||||
char[] sQuery = new char[256];
|
char[] sQuery = new char[256];
|
||||||
FormatEx(sQuery, 256, "ALTER TABLE `%splayertimes` ADD %s;", gS_MySQLPrefix, (gB_MySQL)? "(`track` INT NOT NULL DEFAULT 0)":"COLUMN `track` INT NOT NULL DEFAULT 0");
|
FormatEx(sQuery, 256, "ALTER TABLE `%splayertimes` ADD %s;", gS_MySQLPrefix, (gB_MySQL)? "(`track` INT NOT NULL DEFAULT 0)":"COLUMN `track` INT NOT NULL DEFAULT 0");
|
||||||
gH_SQL.Query(SQL_AlterTable4_Callback, sQuery);
|
gH_SQL.Query(SQL_AlterTable4_Callback, sQuery);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OnMapStart();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SQL_AlterTable4_Callback(Database db, DBResultSet results, const char[] error, any data)
|
public void SQL_AlterTable4_Callback(Database db, DBResultSet results, const char[] error, any data)
|
||||||
@ -2050,6 +2054,26 @@ public void SQL_AlterTable4_Callback(Database db, DBResultSet results, const cha
|
|||||||
if(results == null)
|
if(results == null)
|
||||||
{
|
{
|
||||||
LogError("Timer (WR module) error! Times' table migration (4) failed. Reason: %s", error);
|
LogError("Timer (WR module) error! Times' table migration (4) failed. Reason: %s", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SQL_TableMigration5_Callback(Database db, DBResultSet results, const char[] error, any data)
|
||||||
|
{
|
||||||
|
if(results == null)
|
||||||
|
{
|
||||||
|
char[] sQuery = new char[256];
|
||||||
|
|
||||||
|
if(gB_MySQL)
|
||||||
|
{
|
||||||
|
FormatEx(sQuery, 256, "ALTER TABLE `%splayertimes` ADD (`perfs` FLOAT DEFAULT 0);", gS_MySQLPrefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FormatEx(sQuery, 256, "ALTER TABLE `%splayertimes` ADD COLUMN `perfs` FLOAT DEFAULT 0;", gS_MySQLPrefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
gH_SQL.Query(SQL_AlterTable5_Callback, sQuery);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2057,7 +2081,19 @@ public void SQL_AlterTable4_Callback(Database db, DBResultSet results, const cha
|
|||||||
OnMapStart();
|
OnMapStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Shavit_OnFinish(int client, int style, float time, int jumps, int strafes, float sync, int track)
|
public void SQL_AlterTable5_Callback(Database db, DBResultSet results, const char[] error, any data)
|
||||||
|
{
|
||||||
|
if(results == null)
|
||||||
|
{
|
||||||
|
LogError("Timer (WR module) error! Times' table migration (5) failed. Reason: %s", error);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OnMapStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Shavit_OnFinish(int client, int style, float time, int jumps, int strafes, float sync, int track, float oldtime, float perfs)
|
||||||
{
|
{
|
||||||
char[] sTime = new char[32];
|
char[] sTime = new char[32];
|
||||||
FormatSeconds(time, sTime, 32);
|
FormatSeconds(time, sTime, 32);
|
||||||
@ -2099,6 +2135,8 @@ public void Shavit_OnFinish(int client, int style, float time, int jumps, int st
|
|||||||
Call_PushCell(sync);
|
Call_PushCell(sync);
|
||||||
Call_PushCell(track);
|
Call_PushCell(track);
|
||||||
Call_PushCell(oldwr);
|
Call_PushCell(oldwr);
|
||||||
|
Call_PushCell(oldtime);
|
||||||
|
Call_PushCell(perfs);
|
||||||
Call_Finish();
|
Call_Finish();
|
||||||
|
|
||||||
#if defined DEBUG
|
#if defined DEBUG
|
||||||
@ -2118,6 +2156,8 @@ public void Shavit_OnFinish(int client, int style, float time, int jumps, int st
|
|||||||
Call_PushCell(strafes);
|
Call_PushCell(strafes);
|
||||||
Call_PushCell(sync);
|
Call_PushCell(sync);
|
||||||
Call_PushCell(track);
|
Call_PushCell(track);
|
||||||
|
Call_PushCell(oldtime);
|
||||||
|
Call_PushCell(perfs);
|
||||||
Call_Finish();
|
Call_Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2150,14 +2190,14 @@ public void Shavit_OnFinish(int client, int style, float time, int jumps, int st
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FormatEx(sQuery, 512, "INSERT INTO %splayertimes (auth, map, time, jumps, date, style, strafes, sync, points, track) VALUES ('%s', '%s', %.03f, %d, %d, %d, %d, %.2f, 0.0, %d);", gS_MySQLPrefix, sAuthID, gS_Map, time, jumps, GetTime(), style, strafes, sync, track);
|
FormatEx(sQuery, 512, "INSERT INTO %splayertimes (auth, map, time, jumps, date, style, strafes, sync, points, track, perfs) VALUES ('%s', '%s', %.03f, %d, %d, %d, %d, %.2f, 0.0, %d, %.2f);", gS_MySQLPrefix, sAuthID, gS_Map, time, jumps, GetTime(), style, strafes, sync, track, perfs);
|
||||||
}
|
}
|
||||||
|
|
||||||
else // update
|
else // update
|
||||||
{
|
{
|
||||||
Shavit_PrintToChatAll("%s[%s]%s %T", gS_ChatStrings[sMessageVariable], sTrack, gS_ChatStrings[sMessageText], "NotFirstCompletion", LANG_SERVER, gS_ChatStrings[sMessageVariable2], client, gS_ChatStrings[sMessageText], gS_ChatStrings[sMessageStyle], gS_StyleStrings[style][sStyleName], gS_ChatStrings[sMessageText], gS_ChatStrings[sMessageVariable2], sTime, gS_ChatStrings[sMessageText], gS_ChatStrings[sMessageVariable], iRank, gS_ChatStrings[sMessageText], jumps, strafes, sSync, gS_ChatStrings[sMessageText], gS_ChatStrings[sMessageWarning], sDifference);
|
Shavit_PrintToChatAll("%s[%s]%s %T", gS_ChatStrings[sMessageVariable], sTrack, gS_ChatStrings[sMessageText], "NotFirstCompletion", LANG_SERVER, gS_ChatStrings[sMessageVariable2], client, gS_ChatStrings[sMessageText], gS_ChatStrings[sMessageStyle], gS_StyleStrings[style][sStyleName], gS_ChatStrings[sMessageText], gS_ChatStrings[sMessageVariable2], sTime, gS_ChatStrings[sMessageText], gS_ChatStrings[sMessageVariable], iRank, gS_ChatStrings[sMessageText], jumps, strafes, sSync, gS_ChatStrings[sMessageText], gS_ChatStrings[sMessageWarning], sDifference);
|
||||||
|
|
||||||
FormatEx(sQuery, 512, "UPDATE %splayertimes SET time = %.03f, jumps = %d, date = %d, strafes = %d, sync = %.02f, points = 0.0 WHERE map = '%s' AND auth = '%s' AND style = %d AND track = %d;", gS_MySQLPrefix, time, jumps, GetTime(), strafes, sync, gS_Map, sAuthID, style, track);
|
FormatEx(sQuery, 512, "UPDATE %splayertimes SET time = %.03f, jumps = %d, date = %d, strafes = %d, sync = %.02f, points = 0.0, perfs = %.2f WHERE map = '%s' AND auth = '%s' AND style = %d AND track = %d;", gS_MySQLPrefix, time, jumps, GetTime(), strafes, sync, perfs, gS_Map, sAuthID, style, track);
|
||||||
}
|
}
|
||||||
|
|
||||||
gH_SQL.Query(SQL_OnFinish_Callback, sQuery, GetClientSerial(client), DBPrio_High);
|
gH_SQL.Query(SQL_OnFinish_Callback, sQuery, GetClientSerial(client), DBPrio_High);
|
||||||
@ -2172,6 +2212,8 @@ public void Shavit_OnFinish(int client, int style, float time, int jumps, int st
|
|||||||
Call_PushCell(iRank);
|
Call_PushCell(iRank);
|
||||||
Call_PushCell(overwrite);
|
Call_PushCell(overwrite);
|
||||||
Call_PushCell(track);
|
Call_PushCell(track);
|
||||||
|
Call_PushCell(oldtime);
|
||||||
|
Call_PushCell(perfs);
|
||||||
Call_Finish();
|
Call_Finish();
|
||||||
|
|
||||||
gF_PlayerRecord[client][style][track] = time;
|
gF_PlayerRecord[client][style][track] = time;
|
||||||
|
|||||||
@ -56,6 +56,10 @@
|
|||||||
{
|
{
|
||||||
"en" "Sync"
|
"en" "Sync"
|
||||||
}
|
}
|
||||||
|
"HudPerfs"
|
||||||
|
{
|
||||||
|
"en" "Perfect jumps"
|
||||||
|
}
|
||||||
"HudPracticeMode"
|
"HudPracticeMode"
|
||||||
{
|
{
|
||||||
"en" "[PRACTICE]"
|
"en" "[PRACTICE]"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user