From 3150225755206218cd3db20206206972d4a4312f Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 14 Apr 2019 22:36:06 +0300 Subject: [PATCH 01/11] Added Shavit_CanPause --- addons/sourcemod/scripting/include/shavit.inc | 17 +++++++ addons/sourcemod/scripting/shavit-core.sp | 44 +++++++++++++++++-- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/addons/sourcemod/scripting/include/shavit.inc b/addons/sourcemod/scripting/include/shavit.inc index 4157567d..158c8aab 100644 --- a/addons/sourcemod/scripting/include/shavit.inc +++ b/addons/sourcemod/scripting/include/shavit.inc @@ -66,6 +66,14 @@ enum ReplayBotType Replay_Legacy }; +enum +{ + CPR_ByConVar = (1 << 0), + CPR_NoTimer = (1 << 1), + CPR_InStartZone = (1 << 2), + CPR_NotOnGround = (1 << 3), +}; + enum { Zone_Start, @@ -1320,6 +1328,14 @@ native bool Shavit_HasStyleAccess(int client, int style); */ native bool Shavit_IsPaused(int client); +/** + * Determines whether a client is able to pause their timer or not. + * + * @param client Client index. + * @return Flags which are reasons to allow pausing or not, see CPR enum. 0 if toggling pause is allowed. + */ +native int Shavit_CanPause(int client); + /** * Use this native when printing anything in chat if it's related to the timer. * This native will auto-assign colors and a chat prefix. @@ -1373,6 +1389,7 @@ public SharedPlugin __pl_shavit = #if !defined REQUIRE_PLUGIN public void __pl_shavit_SetNTVOptional() { + MarkNativeAsOptional("Shavit_CanPause"); MarkNativeAsOptional("Shavit_ChangeClientStyle"); MarkNativeAsOptional("Shavit_DeleteReplay"); MarkNativeAsOptional("Shavit_FinishMap"); diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index 2e42b731..e4017e8c 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -165,6 +165,7 @@ public Plugin myinfo = public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) { + CreateNative("Shavit_CanPause", Native_CanPause); CreateNative("Shavit_ChangeClientStyle", Native_ChangeClientStyle); CreateNative("Shavit_FinishMap", Native_FinishMap); CreateNative("Shavit_GetBhopStyle", Native_GetBhopStyle); @@ -537,19 +538,26 @@ public Action Command_StopTimer(int client, int args) public Action Command_TogglePause(int client, int args) { - if(!IsValidClient(client) || !gA_Timers[client].bEnabled) + if(!(1 <= client <= MaxClients) || !IsClientInGame(client)) { return Plugin_Handled; } - if(Shavit_InsideZone(client, Zone_Start, gA_Timers[client].iTrack)) + int iFlags = Shavit_CanPause(client); + + if((iFlags & CPR_NoTimer) > 0) + { + return Plugin_Handled; + } + + if((iFlags & CPR_InStartZone) > 0) { Shavit_PrintToChat(client, "%T", "PauseStartZone", client, gS_ChatStrings.sText, gS_ChatStrings.sWarning, gS_ChatStrings.sText, gS_ChatStrings.sVariable, gS_ChatStrings.sText); return Plugin_Handled; } - if(!gCV_Pause.BoolValue) + if((iFlags & CPR_ByConVar) > 0) { char sCommand[16]; GetCmdArg(0, sCommand, 16); @@ -559,7 +567,7 @@ public Action Command_TogglePause(int client, int args) return Plugin_Handled; } - if(GetEntPropEnt(client, Prop_Send, "m_hGroundEntity") == -1 && GetEntityMoveType(client) != MOVETYPE_LADDER) + if((iFlags & CPR_NotOnGround) > 0) { Shavit_PrintToChat(client, "%T", "PauseNotOnGround", client, gS_ChatStrings.sWarning, gS_ChatStrings.sText); @@ -1257,6 +1265,34 @@ public int Native_StopTimer(Handle handler, int numParams) Call_Finish(); } +public int Native_CanPause(Handle handler, int numParams) +{ + int client = GetNativeCell(1); + int iFlags = 0; + + if(!gCV_Pause.BoolValue) + { + iFlags |= CPR_ByConVar; + } + + if(!gA_Timers[client].bEnabled) + { + iFlags |= CPR_NoTimer; + } + + if(Shavit_InsideZone(client, Zone_Start, gA_Timers[client].iTrack)) + { + iFlags |= CPR_InStartZone; + } + + if(GetEntPropEnt(client, Prop_Send, "m_hGroundEntity") == -1 && GetEntityMoveType(client) != MOVETYPE_LADDER) + { + iFlags |= CPR_NotOnGround; + } + + return iFlags; +} + public int Native_ChangeClientStyle(Handle handler, int numParams) { int client = GetNativeCell(1); From bac741e7f8e657ecf8393a306e9113e4ff67798c Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 14 Apr 2019 22:36:33 +0300 Subject: [PATCH 02/11] Added `teleport` parameter to Shavit_ResumeTimer --- addons/sourcemod/scripting/include/shavit.inc | 3 ++- addons/sourcemod/scripting/shavit-core.sp | 17 +++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/addons/sourcemod/scripting/include/shavit.inc b/addons/sourcemod/scripting/include/shavit.inc index 158c8aab..db9e4a2c 100644 --- a/addons/sourcemod/scripting/include/shavit.inc +++ b/addons/sourcemod/scripting/include/shavit.inc @@ -962,9 +962,10 @@ native void Shavit_PauseTimer(int client); * Resumes a player's timer. * * @param client Client index. + * @param teleport Should the player be teleported to their location prior to saving? * @noreturn */ -native void Shavit_ResumeTimer(int client); +native void Shavit_ResumeTimer(int client, bool teleport = false); /** * Deletes the specified replay file. diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index e4017e8c..a3aa0d8d 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -1396,12 +1396,25 @@ public int Native_FinishMap(Handle handler, int numParams) public int Native_PauseTimer(Handle handler, int numParams) { - PauseTimer(GetNativeCell(1)); + int client = GetNativeCell(1); + + GetClientAbsOrigin(client, gF_PauseOrigin[client]); + GetClientEyeAngles(client, gF_PauseAngles[client]); + GetEntPropVector(client, Prop_Data, "m_vecAbsVelocity", gF_PauseVelocity[client]); + + PauseTimer(client); } public int Native_ResumeTimer(Handle handler, int numParams) { - ResumeTimer(GetNativeCell(1)); + int client = GetNativeCell(1); + + ResumeTimer(client); + + if(numParams >= 2 && view_as(GetNativeCell(2))) // teleport? + { + TeleportEntity(client, gF_PauseOrigin[client], gF_PauseAngles[client], gF_PauseVelocity[client]); + } } public int Native_StopChatSound(Handle handler, int numParams) From ea670471d4f870e2cc17efa86423b5afbc97f2e5 Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 14 Apr 2019 22:36:55 +0300 Subject: [PATCH 03/11] Added pause button to KZ checkpoint menu --- addons/sourcemod/scripting/shavit-misc.sp | 34 +++++++++++++++---- .../translations/shavit-misc.phrases.txt | 4 +++ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index ccbe358a..53addc98 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -97,12 +97,6 @@ char gS_RadioCommands[][] = { "coverme", "takepoint", "holdpos", "regroup", "fol "getinpos", "stormfront", "report", "roger", "enemyspot", "needbackup", "sectorclear", "inposition", "reportingin", "getout", "negative", "enemydown", "compliment", "thanks", "cheer" }; -// cache -ConVar sv_disable_immunity_alpha = null; -ConVar mp_humanteam = null; -ConVar hostname = null; -ConVar hostport = null; - bool gB_Hide[MAXPLAYERS+1]; bool gB_Late = false; int gI_GroundEntity[MAXPLAYERS+1]; @@ -166,6 +160,12 @@ ConVar gCV_MaxCP_Segmented = null; ConVar gCV_HideChatCommands = null; ConVar gCV_PersistData = null; +// external cvars +ConVar sv_disable_immunity_alpha = null; +ConVar mp_humanteam = null; +ConVar hostname = null; +ConVar hostport = null; + // forwards Handle gH_Forwards_OnClanTagChangePre = null; Handle gH_Forwards_OnClanTagChangePost = null; @@ -1792,6 +1792,12 @@ void OpenKZCPMenu(int client) FormatEx(sDisplay, 64, "%T", "MiscCheckpointNext", client); menu.AddItem("next", sDisplay); + if((Shavit_CanPause(client) & CPR_ByConVar) == 0) + { + FormatEx(sDisplay, 64, "%T", "MiscCheckpointPause", client); + menu.AddItem("pause", sDisplay); + } + menu.ExitButton = true; menu.Display(client, MENU_TIME_FOREVER); } @@ -1843,6 +1849,22 @@ public int MenuHandler_KZCheckpoints(Menu menu, MenuAction action, int param1, i } } + else if(StrEqual(sInfo, "pause")) + { + if(Shavit_CanPause(param1) == 0) + { + if(Shavit_IsPaused(param1)) + { + Shavit_ResumeTimer(param1, true); + } + + else + { + Shavit_PauseTimer(param1); + } + } + } + OpenCheckpointsMenu(param1); } diff --git a/addons/sourcemod/translations/shavit-misc.phrases.txt b/addons/sourcemod/translations/shavit-misc.phrases.txt index ba998581..465addcc 100644 --- a/addons/sourcemod/translations/shavit-misc.phrases.txt +++ b/addons/sourcemod/translations/shavit-misc.phrases.txt @@ -149,6 +149,10 @@ { "en" "Reset checkpoints" } + "MiscCheckpointPause" + { + "en" "Pause" + } "MiscCheckpointUseAngles" { "en" "Use angles" From 7785053cc52fc95dedf5c619d7a905f72bba679c Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 14 Apr 2019 22:37:06 +0300 Subject: [PATCH 04/11] Fixed NPE when using !top before rankings are loaded --- addons/sourcemod/scripting/shavit-rankings.sp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-rankings.sp b/addons/sourcemod/scripting/shavit-rankings.sp index 46ec2474..b15b5d04 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -590,8 +590,11 @@ public Action Command_Rank(int client, int args) public Action Command_Top(int client, int args) { - gH_Top100Menu.SetTitle("%T (%d)\n ", "Top100", client, gI_RankedPlayers); - gH_Top100Menu.Display(client, 60); + if(gH_Top100Menu != null) + { + gH_Top100Menu.SetTitle("%T (%d)\n ", "Top100", client, gI_RankedPlayers); + gH_Top100Menu.Display(client, 60); + } return Plugin_Handled; } From 204dff4a32530607096a2926921a0958e84331df Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 14 Apr 2019 22:37:21 +0300 Subject: [PATCH 05/11] Removed pointless restart-round logic in timelimit --- addons/sourcemod/scripting/shavit-timelimit.sp | 3 --- 1 file changed, 3 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-timelimit.sp b/addons/sourcemod/scripting/shavit-timelimit.sp index 81cb18da..a153efe9 100644 --- a/addons/sourcemod/scripting/shavit-timelimit.sp +++ b/addons/sourcemod/scripting/shavit-timelimit.sp @@ -42,7 +42,6 @@ ConVar mp_freezetime = null; ConVar mp_ignore_round_win_conditions = null; ConVar mp_timelimit = null; ConVar mp_roundtime = null; -ConVar mp_restartgame = null; // cvars ConVar gCV_Config = null; @@ -91,7 +90,6 @@ public void OnPluginStart() mp_do_warmup_period = FindConVar("mp_do_warmup_period"); mp_freezetime = FindConVar("mp_freezetime"); mp_ignore_round_win_conditions = FindConVar("mp_ignore_round_win_conditions"); - mp_restartgame = FindConVar("mp_restartgame"); mp_timelimit = FindConVar("mp_timelimit"); mp_roundtime = FindConVar("mp_roundtime"); @@ -312,7 +310,6 @@ public void SQL_GetMapTimes(Database db, DBResultSet results, const char[] error void SetLimit(int time) { mp_timelimit.IntValue = time; - mp_restartgame.IntValue = 1; if(mp_roundtime != null) { From 7bc010b82bf289f6baa77f3b7f4737911f01236b Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 14 Apr 2019 22:37:31 +0300 Subject: [PATCH 06/11] Made cursor zoning a default. Get used to it --- addons/sourcemod/scripting/shavit-zones.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/shavit-zones.sp b/addons/sourcemod/scripting/shavit-zones.sp index bd9c3794..9959c4ce 100644 --- a/addons/sourcemod/scripting/shavit-zones.sp +++ b/addons/sourcemod/scripting/shavit-zones.sp @@ -1580,7 +1580,7 @@ void Reset(int client) gI_MapStep[client] = 0; gI_GridSnap[client] = 16; gB_SnapToWall[client] = false; - gB_CursorTracing[client] = false; + gB_CursorTracing[client] = true; gI_ZoneDatabaseID[client] = -1; for(int i = 0; i < 3; i++) From a30da28d69d68e4ef70b003accc4530561246476 Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 14 Apr 2019 22:45:07 +0300 Subject: [PATCH 07/11] Made KZ CP menu persist --- addons/sourcemod/scripting/shavit-misc.sp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index 53addc98..760f63c6 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -337,6 +337,7 @@ public void OnPluginStart() // crons CreateTimer(10.0, Timer_Cron, 0, TIMER_REPEAT); + CreateTimer(1.0, Timer_PersistKZCP, 0, TIMER_REPEAT); if(gEV_Type != Engine_TF2) { @@ -776,6 +777,19 @@ public Action Timer_Cron(Handle Timer) return Plugin_Continue; } +public Action Timer_PersistKZCP(Handle Timer) +{ + for(int i = 1; i <= MaxClients; i++) + { + if(gA_StyleSettings[gI_Style[i]].bKZCheckpoints && GetClientMenu(i) == MenuSource_None) + { + OpenKZCPMenu(i); + } + } + + return Plugin_Continue; +} + public Action Timer_Scoreboard(Handle Timer) { for(int i = 1; i <= MaxClients; i++) @@ -1798,7 +1812,7 @@ void OpenKZCPMenu(int client) menu.AddItem("pause", sDisplay); } - menu.ExitButton = true; + menu.ExitButton = false; menu.Display(client, MENU_TIME_FOREVER); } From 30264ef0927ac878a3f25f3f8c27ad02fa02cb08 Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 14 Apr 2019 23:16:09 +0300 Subject: [PATCH 08/11] Added Shavit_OnStopPre --- addons/sourcemod/scripting/include/shavit.inc | 14 ++++++++++++-- addons/sourcemod/scripting/shavit-core.sp | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/include/shavit.inc b/addons/sourcemod/scripting/include/shavit.inc index db9e4a2c..f5f90aee 100644 --- a/addons/sourcemod/scripting/include/shavit.inc +++ b/addons/sourcemod/scripting/include/shavit.inc @@ -373,6 +373,15 @@ forward void Shavit_OnRestart(int client, int track); */ forward void Shavit_OnEnd(int client, int track); +/** + * Called before a player's timer is stopped. (stop =/= finish a map) + * + * @param client Client index. + * @param track Timer track. + * @return False to prevent the timer from stopping. + */ +forward bool Shavit_OnStopPre(int client, int track); + /** * Called when a player's timer stops. (stop =/= finish a map) * @@ -681,9 +690,10 @@ native void Shavit_RestartTimer(int client, int track); * Will not teleport the player to anywhere, it's handled inside the mapzones plugin. * * @param client Client index. - * @noreturn + * @param bypass Bypass call to Shavit_OnStopPre? + * @return True if the operation went through. */ -native void Shavit_StopTimer(int client); +native bool Shavit_StopTimer(int client, bool bypass = true); /** * Deletes all map records for the specified map. diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index a3aa0d8d..7e3a613f 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -68,6 +68,7 @@ bool gB_MySQL = false; // forwards Handle gH_Forwards_Start = null; Handle gH_Forwards_Stop = null; +Handle gH_Forwards_StopPre = null; Handle gH_Forwards_FinishPre = null; Handle gH_Forwards_Finish = null; Handle gH_Forwards_OnRestart = null; @@ -215,6 +216,7 @@ public void OnPluginStart() // forwards 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_StopPre = CreateGlobalForward("Shavit_OnStopPre", ET_Event, Param_Cell, Param_Cell); 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, Param_Cell); gH_Forwards_OnRestart = CreateGlobalForward("Shavit_OnRestart", ET_Event, Param_Cell, Param_Cell); @@ -1256,6 +1258,21 @@ public int Native_StartTimer(Handle handler, int numParams) public int Native_StopTimer(Handle handler, int numParams) { int client = GetNativeCell(1); + bool bBypass = (numParams < 2 || view_as(GetNativeCell(2))); + + if(!bBypass) + { + bool bResult = true; + Call_StartForward(gH_Forwards_StopPre); + Call_PushCell(client); + Call_PushCell(gA_Timers[client].iTrack); + Call_Finish(bResult); + + if(!bResult) + { + return false; + } + } StopTimer(client); @@ -1263,6 +1280,8 @@ public int Native_StopTimer(Handle handler, int numParams) Call_PushCell(client); Call_PushCell(gA_Timers[client].iTrack); Call_Finish(); + + return true; } public int Native_CanPause(Handle handler, int numParams) From c61e6467857f1e7562f748fb97d8b1926fc24d80 Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 14 Apr 2019 23:25:08 +0300 Subject: [PATCH 09/11] Added shavit_misc_stoptimerwarning --- addons/sourcemod/scripting/shavit-core.sp | 22 +++-- addons/sourcemod/scripting/shavit-misc.sp | 94 +++++++++++++++++-- .../translations/shavit-misc.phrases.txt | 12 +++ 3 files changed, 113 insertions(+), 15 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index 7e3a613f..8eaee899 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -510,12 +510,13 @@ public Action Command_TeleportEnd(int client, int args) if(gB_Zones && (Shavit_ZoneExists(Zone_End, track) || gB_KZMap)) { - Shavit_StopTimer(client); - - Call_StartForward(gH_Forwards_OnEnd); - Call_PushCell(client); - Call_PushCell(track); - Call_Finish(); + if(Shavit_StopTimer(client, false)) + { + Call_StartForward(gH_Forwards_OnEnd); + Call_PushCell(client); + Call_PushCell(track); + Call_Finish(); + } } else @@ -533,7 +534,7 @@ public Action Command_StopTimer(int client, int args) return Plugin_Handled; } - Shavit_StopTimer(client); + Shavit_StopTimer(client, false); return Plugin_Handled; } @@ -1043,6 +1044,11 @@ void ChangeClientStyle(int client, int style, bool manual) if(manual) { + if(!Shavit_StopTimer(client, false)) + { + return; + } + Shavit_PrintToChat(client, "%T", "StyleSelection", client, gS_ChatStrings.sStyle, gS_StyleStrings[style].sStyleName, gS_ChatStrings.sText); } @@ -1061,8 +1067,6 @@ void ChangeClientStyle(int client, int style, bool manual) CallOnStyleChanged(client, gA_Timers[client].iStyle, style, manual); - StopTimer(client); - if(gCV_AllowTimerWithoutZone.BoolValue || (gB_Zones && (Shavit_ZoneExists(Zone_Start, gA_Timers[client].iTrack) || gB_KZMap))) { Call_StartForward(gH_Forwards_OnRestart); diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index 760f63c6..b590af86 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -89,6 +89,8 @@ enum struct persistent_data_t bool bPractice; } +typedef StopTimerCallback = function void (int data); + // game specific EngineVersion gEV_Type = Engine_Unknown; int gI_Ammo = -1; @@ -105,6 +107,7 @@ ArrayList gA_Advertisements = null; int gI_AdvertisementsCycle = 0; char gS_CurrentMap[192]; int gI_Style[MAXPLAYERS+1]; +Function gH_AfterWarningMenu[MAXPLAYERS+1]; player_cpcache_t gA_CheckpointsCache[MAXPLAYERS+1]; int gI_CheckpointsSettings[MAXPLAYERS+1]; @@ -159,6 +162,7 @@ ConVar gCV_MaxCP = null; ConVar gCV_MaxCP_Segmented = null; ConVar gCV_HideChatCommands = null; ConVar gCV_PersistData = null; +ConVar gCV_StopTimerWarning = null; // external cvars ConVar sv_disable_immunity_alpha = null; @@ -325,6 +329,7 @@ public void OnPluginStart() gCV_MaxCP_Segmented = CreateConVar("shavit_misc_maxcp_seg", "10", "Maximum amount of segmented checkpoints. Make this less or equal to shavit_misc_maxcp.\nNote: Very high values will result in HUGE memory usage!", 0, true, 1.0, true, 50.0); gCV_HideChatCommands = CreateConVar("shavit_misc_hidechatcmds", "1", "Hide commands from chat?\n0 - Disabled\n1 - Enabled", 0, true, 0.0, true, 1.0); gCV_PersistData = CreateConVar("shavit_misc_persistdata", "300", "How long to persist timer data for disconnected users in seconds?\n-1 - Until map change\n0 - Disabled"); + gCV_StopTimerWarning = CreateConVar("shavit_misc_stoptimerwarning", "900", "Time in seconds to display a warning before stopping the timer with noclip or !stop.\n0 - Disabled"); AutoExecConfig(); @@ -1809,7 +1814,7 @@ void OpenKZCPMenu(int client) if((Shavit_CanPause(client) & CPR_ByConVar) == 0) { FormatEx(sDisplay, 64, "%T", "MiscCheckpointPause", client); - menu.AddItem("pause", sDisplay); + menu.AddItem("pause", sDisplay, (Shavit_GetTimerStatus(client) != Timer_Stopped)? ITEMDRAW_DEFAULT:ITEMDRAW_DISABLED); } menu.ExitButton = false; @@ -2457,6 +2462,75 @@ void TeleportToCheckpoint(int client, int index, bool suppressMessage) } } +bool ShouldDisplayStopWarning(int client) +{ + return (gCV_StopTimerWarning.BoolValue && Shavit_GetTimerStatus(client) != Timer_Stopped && Shavit_GetClientTime(client) > gCV_StopTimerWarning.FloatValue); +} + +void DoNoclip(int client) +{ + Shavit_StopTimer(client); + SetEntityMoveType(client, MOVETYPE_NOCLIP); +} + +void DoStopTimer(int client) +{ + Shavit_StopTimer(client); +} + +void OpenStopWarningMenu(int client, StopTimerCallback after) +{ + gH_AfterWarningMenu[client] = after; + + Menu hMenu = new Menu(MenuHandler_StopWarning); + hMenu.SetTitle("%T\n", "StopTimerWarning", client); + + char sDisplay[64]; + FormatEx(sDisplay, 64, "%T", "StopTimerYes", client); + hMenu.AddItem("yes", sDisplay); + + FormatEx(sDisplay, 64, "%T", "StopTimerNo", client); + hMenu.AddItem("no", sDisplay); + + hMenu.ExitButton = true; + hMenu.Display(client, 30); +} + +public int MenuHandler_StopWarning(Menu menu, MenuAction action, int param1, int param2) +{ + if(action == MenuAction_Select) + { + char sInfo[8]; + menu.GetItem(param2, sInfo, 8); + + if(StrEqual(sInfo, "yes")) + { + Call_StartFunction(null, gH_AfterWarningMenu[param1]); + Call_PushCell(param1); + Call_Finish(); + } + } + + else if(action == MenuAction_End) + { + delete menu; + } + + return 0; +} + +public bool Shavit_OnStopPre(int client, int track) +{ + if(ShouldDisplayStopWarning(client)) + { + OpenStopWarningMenu(client, DoStopTimer); + + return false; + } + + return true; +} + public Action Command_Noclip(int client, int args) { if(!IsValidClient(client)) @@ -2487,12 +2561,16 @@ public Action Command_Noclip(int client, int args) if(GetEntityMoveType(client) != MOVETYPE_NOCLIP) { - if(Shavit_GetTimerStatus(client) != Timer_Stopped) + if(!ShouldDisplayStopWarning(client)) { Shavit_StopTimer(client); + SetEntityMoveType(client, MOVETYPE_NOCLIP); } - SetEntityMoveType(client, MOVETYPE_NOCLIP); + else + { + OpenStopWarningMenu(client, DoNoclip); + } } else @@ -2512,12 +2590,16 @@ public Action CommandListener_Noclip(int client, const char[] command, int args) if((gCV_NoclipMe.IntValue == 1 || (gCV_NoclipMe.IntValue == 2 && CheckCommandAccess(client, "noclipme", ADMFLAG_CHEATS))) && command[0] == '+') { - if(Shavit_GetTimerStatus(client) != Timer_Stopped) + if(!ShouldDisplayStopWarning(client)) { Shavit_StopTimer(client); + SetEntityMoveType(client, MOVETYPE_NOCLIP); + } + + else + { + OpenStopWarningMenu(client, DoNoclip); } - - SetEntityMoveType(client, MOVETYPE_NOCLIP); } else if(GetEntityMoveType(client) == MOVETYPE_NOCLIP) diff --git a/addons/sourcemod/translations/shavit-misc.phrases.txt b/addons/sourcemod/translations/shavit-misc.phrases.txt index 465addcc..c869fbd5 100644 --- a/addons/sourcemod/translations/shavit-misc.phrases.txt +++ b/addons/sourcemod/translations/shavit-misc.phrases.txt @@ -106,6 +106,18 @@ "en" "Use {1}!cp{2} to re-open the segmented checkpoints menu." } // ---------- Menus ---------- // + "StopTimerWarning" + { + "en" "Are you sure you want to stop your timer?" + } + "StopTimerYes" + { + "en" "Yes, stop my timer." + } + "StopTimerNo" + { + "en" "No, keep my timer running." + } "TeleportMenuTitle" { "en" "Teleport to:" From fb0b84878e57a23011e90448298c36446b12085a Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 14 Apr 2019 23:35:30 +0300 Subject: [PATCH 10/11] Added "noimprovement" sound type (#783) --- addons/sourcemod/configs/shavit-sounds.cfg | 1 + addons/sourcemod/scripting/include/shavit.inc | 2 +- addons/sourcemod/scripting/shavit-sounds.sp | 18 ++++++++++++++++-- addons/sourcemod/scripting/shavit-wr.sp | 18 +++++++++--------- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/addons/sourcemod/configs/shavit-sounds.cfg b/addons/sourcemod/configs/shavit-sounds.cfg index 87d7441e..e402405a 100644 --- a/addons/sourcemod/configs/shavit-sounds.cfg +++ b/addons/sourcemod/configs/shavit-sounds.cfg @@ -11,6 +11,7 @@ // world - new server WR // worst - worst record for the track/style // number - rank on map, only one per rank (example: "1" "shavit/pro.mp3"), will play for every player. overrides others +// noimprovement - time is worse than old PB "first" "shavit/fr_1.mp3" "personal" "shavit/pb_1.mp3" "world" "shavit/wr_1.mp3" diff --git a/addons/sourcemod/scripting/include/shavit.inc b/addons/sourcemod/scripting/include/shavit.inc index f5f90aee..e7dd9c4c 100644 --- a/addons/sourcemod/scripting/include/shavit.inc +++ b/addons/sourcemod/scripting/include/shavit.inc @@ -71,7 +71,7 @@ enum CPR_ByConVar = (1 << 0), CPR_NoTimer = (1 << 1), CPR_InStartZone = (1 << 2), - CPR_NotOnGround = (1 << 3), + CPR_NotOnGround = (1 << 3) }; enum diff --git a/addons/sourcemod/scripting/shavit-sounds.sp b/addons/sourcemod/scripting/shavit-sounds.sp index 7f450abe..a4caadb8 100644 --- a/addons/sourcemod/scripting/shavit-sounds.sp +++ b/addons/sourcemod/scripting/shavit-sounds.sp @@ -33,6 +33,7 @@ ArrayList gA_FirstSounds = null; ArrayList gA_PersonalSounds = null; ArrayList gA_WorldSounds = null; ArrayList gA_WorstSounds = null; +ArrayList gA_NoImprovementSounds = null; StringMap gSM_RankSounds = null; // cvars @@ -70,6 +71,7 @@ public void OnPluginStart() gA_PersonalSounds = new ArrayList(PLATFORM_MAX_PATH); gA_WorldSounds = new ArrayList(PLATFORM_MAX_PATH); gA_WorstSounds = new ArrayList(PLATFORM_MAX_PATH); + gA_NoImprovementSounds = new ArrayList(PLATFORM_MAX_PATH); gSM_RankSounds = new StringMap(); // modules @@ -103,6 +105,7 @@ public void OnMapStart() gA_PersonalSounds.Clear(); gA_WorldSounds.Clear(); gA_WorstSounds.Clear(); + gA_NoImprovementSounds.Clear(); gSM_RankSounds.Clear(); char sFile[PLATFORM_MAX_PATH]; @@ -154,9 +157,9 @@ public void OnMapStart() gA_WorstSounds.PushString(sExploded[1]); } - else if(StrEqual(sExploded[0], "worse")) + else if(StrEqual(sExploded[0], "worse") || StrEqual(sExploded[0], "noimprovement")) { - LogError("\"worse\" sounds are not supported anymore."); + gA_NoImprovementSounds.PushString(sExploded[1]); } else @@ -183,6 +186,17 @@ public void OnMapStart() delete fFile; } +public void Shavit_OnFinish(int client, int style, float time, int jumps, int strafes, float sync, int track, float oldtime, float perfs) +{ + if(oldtime != 0.0 && time > oldtime) + { + char sSound[PLATFORM_MAX_PATH]; + gA_NoImprovementSounds.GetString(GetRandomInt(0, gA_NoImprovementSounds.Length - 1), sSound, PLATFORM_MAX_PATH); + + PlayEventSound(client, false, sSound); + } +} + public void Shavit_OnFinish_Post(int client, int style, float time, int jumps, int strafes, float sync, int rank, int overwrite, int track) { float fOldTime = Shavit_GetClientPB(client, style, track); diff --git a/addons/sourcemod/scripting/shavit-wr.sp b/addons/sourcemod/scripting/shavit-wr.sp index 2b97b6a0..2fdc0fae 100644 --- a/addons/sourcemod/scripting/shavit-wr.sp +++ b/addons/sourcemod/scripting/shavit-wr.sp @@ -1999,24 +1999,24 @@ public void Shavit_OnFinish(int client, int style, float time, int jumps, int st // 0 - no query // 1 - insert // 2 - update - int overwrite = 0; + int iOverwrite = 0; if(gA_StyleSettings[style].bUnranked || Shavit_IsPracticeMode(client)) { - overwrite = 0; // ugly way of not writing to database + iOverwrite = 0; // ugly way of not writing to database } else if(gF_PlayerRecord[client][style][track] == 0.0) { - overwrite = 1; + iOverwrite = 1; } else if(time < gF_PlayerRecord[client][style][track]) { - overwrite = 2; + iOverwrite = 2; } - if(overwrite > 0 && (time < gF_WRTime[style][track] || gF_WRTime[style][track] == 0.0)) // WR? + if(iOverwrite > 0 && (time < gF_WRTime[style][track] || gF_WRTime[style][track] == 0.0)) // WR? { float oldwr = gF_WRTime[style][track]; gF_WRTime[style][track] = time; @@ -2069,14 +2069,14 @@ public void Shavit_OnFinish(int client, int style, float time, int jumps, int st char sSync[32]; // 32 because colors FormatEx(sSync, 32, (sync != -1.0)? " @ %s%.02f%%":"", gS_ChatStrings.sVariable, sync); - if(overwrite > 0) + if(iOverwrite > 0) { char sAuthID[32]; GetClientAuthId(client, AuthId_Steam3, sAuthID, 32); char sQuery[512]; - if(overwrite == 1) // insert + if(iOverwrite == 1) // insert { Shavit_PrintToChatAll("%s[%s]%s %T", gS_ChatStrings.sVariable, sTrack, gS_ChatStrings.sText, "FirstCompletion", LANG_SERVER, gS_ChatStrings.sVariable2, client, gS_ChatStrings.sText, gS_ChatStrings.sStyle, gS_StyleStrings[style].sStyleName, gS_ChatStrings.sText, gS_ChatStrings.sVariable2, sTime, gS_ChatStrings.sText, gS_ChatStrings.sVariable, iRank, gS_ChatStrings.sText, jumps, strafes, sSync, gS_ChatStrings.sText); @@ -2105,7 +2105,7 @@ public void Shavit_OnFinish(int client, int style, float time, int jumps, int st Call_PushCell(strafes); Call_PushCell(sync); Call_PushCell(iRank); - Call_PushCell(overwrite); + Call_PushCell(iOverwrite); Call_PushCell(track); Call_PushCell(oldtime); Call_PushCell(perfs); @@ -2114,7 +2114,7 @@ public void Shavit_OnFinish(int client, int style, float time, int jumps, int st gF_PlayerRecord[client][style][track] = time; } - else if(overwrite == 0 && !gA_StyleSettings[style].bUnranked) + else if(iOverwrite == 0 && !gA_StyleSettings[style].bUnranked) { Shavit_PrintToChat(client, "%s[%s]%s %T", gS_ChatStrings.sVariable, sTrack, gS_ChatStrings.sText, "WorseTime", client, gS_ChatStrings.sStyle, gS_StyleStrings[style].sStyleName, gS_ChatStrings.sText, gS_ChatStrings.sVariable2, sTime, gS_ChatStrings.sText, jumps, strafes, sSync, gS_ChatStrings.sText, sDifference); } From e607b88d21d3a502f7792822f1c59cc968596c75 Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 14 Apr 2019 22:37:34 +0300 Subject: [PATCH 11/11] 2.5.3 --- addons/sourcemod/scripting/include/shavit.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/include/shavit.inc b/addons/sourcemod/scripting/include/shavit.inc index e7dd9c4c..2fb09475 100644 --- a/addons/sourcemod/scripting/include/shavit.inc +++ b/addons/sourcemod/scripting/include/shavit.inc @@ -23,7 +23,7 @@ #endif #define _shavit_included -#define SHAVIT_VERSION "2.5.2" +#define SHAVIT_VERSION "2.5.3" #define STYLE_LIMIT 256 #define MAX_ZONES 64 #define MAX_NAME_LENGTH_SQL 32