From 05258480d536a3928105948482d25bcfce7fcefc Mon Sep 17 00:00:00 2001 From: shavit Date: Wed, 10 Jan 2018 10:44:47 +0200 Subject: [PATCH 01/38] Added configuration for replay data folder. (#570) --- addons/sourcemod/configs/shavit-replay.cfg | 8 ++++++ addons/sourcemod/scripting/shavit-replay.sp | 29 ++++++++++++++------- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/addons/sourcemod/configs/shavit-replay.cfg b/addons/sourcemod/configs/shavit-replay.cfg index 9ffc3dcd..ca38182d 100644 --- a/addons/sourcemod/configs/shavit-replay.cfg +++ b/addons/sourcemod/configs/shavit-replay.cfg @@ -30,4 +30,12 @@ "centralstyle" "!replay" "centralstyletag" "!replay" "unloaded" "{style} - N/A" + + // Replay data folder. This is where replays are loaded from and saved to. + // Note: To use a path outside of the game directory, you will have to get out of it with "../". + // Edit at your own risk. + // + // Variables: + // {SM} - SourceMod folder. If this variable isn't included, you will have to specify the full path. + "replayfolder" "{SM}/data/replaybot" } \ No newline at end of file diff --git a/addons/sourcemod/scripting/shavit-replay.sp b/addons/sourcemod/scripting/shavit-replay.sp index 468d7064..08efffbe 100644 --- a/addons/sourcemod/scripting/shavit-replay.sp +++ b/addons/sourcemod/scripting/shavit-replay.sp @@ -64,6 +64,8 @@ enum EngineVersion gEV_Type = Engine_Unknown; // cache +char gS_ReplayFolder[PLATFORM_MAX_PATH]; + int gI_ReplayTick[STYLE_LIMIT]; int gI_ReplayBotClient[STYLE_LIMIT]; ArrayList gA_Frames[STYLE_LIMIT][TRACKS_SIZE]; @@ -557,8 +559,19 @@ bool LoadStyling() kv.GetString("centralstyletag", gS_ReplayStrings[sReplayCentralStyleTag], MAX_NAME_LENGTH, ""); kv.GetString("unloaded", gS_ReplayStrings[sReplayUnloaded], MAX_NAME_LENGTH, ""); + char[] sFolder = new char[PLATFORM_MAX_PATH]; + kv.GetString("replayfolder", sFolder, PLATFORM_MAX_PATH, "{SM}/data/replaybot"); + delete kv; + if(StrContains(sFolder, "{SM}") != -1) + { + ReplaceString(sFolder, PLATFORM_MAX_PATH, "{SM}/", ""); + BuildPath(Path_SM, sFolder, PLATFORM_MAX_PATH, "%s", sFolder); + } + + strcopy(gS_ReplayFolder, PLATFORM_MAX_PATH, sFolder); + return true; } @@ -678,12 +691,9 @@ public void OnMapStart() gI_ExpectedBots = 0; - char[] sPath = new char[PLATFORM_MAX_PATH]; - BuildPath(Path_SM, sPath, PLATFORM_MAX_PATH, "data/replaybot"); - - if(!DirExists(sPath)) + if(!DirExists(gS_ReplayFolder)) { - CreateDirectory(sPath, 511); + CreateDirectory(gS_ReplayFolder, 511); } for(int i = 0; i < gI_Styles; i++) @@ -697,7 +707,8 @@ public void OnMapStart() continue; } - BuildPath(Path_SM, sPath, PLATFORM_MAX_PATH, "data/replaybot/%d", i); + char[] sPath = new char[PLATFORM_MAX_PATH]; + FormatEx(sPath, PLATFORM_MAX_PATH, "%s/%d", gS_ReplayFolder, i); if(!DirExists(sPath)) { @@ -772,7 +783,7 @@ bool DefaultLoadReplay(int style, int track) FormatEx(sTrack, 4, "_%d", track); char[] sPath = new char[PLATFORM_MAX_PATH]; - BuildPath(Path_SM, sPath, PLATFORM_MAX_PATH, "data/replaybot/%d/%s%s.replay", style, gS_Map, (track > 0)? sTrack:""); + FormatEx(sPath, PLATFORM_MAX_PATH, "%s/%d/%s%s.replay", gS_ReplayFolder, style, gS_Map, (track > 0)? sTrack:""); return LoadReplay(style, track, sPath); } @@ -911,7 +922,7 @@ bool SaveReplay(int style, int track, float time, char[] authid, char[] name) FormatEx(sTrack, 4, "_%d", track); char[] sPath = new char[PLATFORM_MAX_PATH]; - BuildPath(Path_SM, sPath, PLATFORM_MAX_PATH, "data/replaybot/%d/%s%s.replay", style, gS_Map, (track > 0)? sTrack:""); + FormatEx(sPath, PLATFORM_MAX_PATH, "%s/%d/%s%s.replay", gS_ReplayFolder, style, gS_Map, (track > 0)? sTrack:""); if(FileExists(sPath)) { @@ -953,7 +964,7 @@ bool DeleteReplay(int style, int track) FormatEx(sTrack, 4, "_%d", track); char[] sPath = new char[PLATFORM_MAX_PATH]; - BuildPath(Path_SM, sPath, PLATFORM_MAX_PATH, "data/replaybot/%d/%s%s.replay", style, gS_Map, (track > 0)? sTrack:""); + FormatEx(sPath, PLATFORM_MAX_PATH, "%s/%d/%s%s.replay", gS_ReplayFolder, style, gS_Map, (track > 0)? sTrack:""); if(!FileExists(sPath) || !DeleteFile(sPath)) { From 9b0aad658345c22c9650fb3619014941643480ce Mon Sep 17 00:00:00 2001 From: shavit Date: Sat, 13 Jan 2018 09:34:17 +0200 Subject: [PATCH 02/38] Fix formatting issue with top-left HUD. --- addons/sourcemod/scripting/shavit-hud.sp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-hud.sp b/addons/sourcemod/scripting/shavit-hud.sp index 8861fc4b..46208363 100644 --- a/addons/sourcemod/scripting/shavit-hud.sp +++ b/addons/sourcemod/scripting/shavit-hud.sp @@ -1022,20 +1022,20 @@ void UpdateTopLeftHUD(int client, bool wait) char[] sPBTime = new char[16]; FormatSeconds(fPBTime, sPBTime, MAX_NAME_LENGTH); - char[] sTopLeft = new char[64]; + char[] sTopLeft = new char[128]; if(fPBTime != 0.0) { - FormatEx(sTopLeft, 64, "WR: %s (%s)\n%T: %s (#%d)", sWRTime, sWRName, "HudBestText", client, sPBTime, (Shavit_GetRankForTime(style, fPBTime, track) - 1)); + FormatEx(sTopLeft, 128, "WR: %s (%s)\n%T: %s (#%d)", sWRTime, sWRName, "HudBestText", client, sPBTime, (Shavit_GetRankForTime(style, fPBTime, track) - 1)); } else { - FormatEx(sTopLeft, 64, "WR: %s (%s)", sWRTime, sWRName); + FormatEx(sTopLeft, 128, "WR: %s (%s)", sWRTime, sWRName); } SetHudTextParams(0.01, 0.01, 2.5, 255, 255, 255, 255); - ShowSyncHudText(client, gH_HUD, sTopLeft); + ShowSyncHudText(client, gH_HUD, "%s", sTopLeft); } } } From 27e0dad8ad68861e0a07337b412892e0ed1ad786 Mon Sep 17 00:00:00 2001 From: shavit Date: Sat, 13 Jan 2018 09:34:33 +0200 Subject: [PATCH 03/38] Conut >> Count --- addons/sourcemod/scripting/shavit-stats.sp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-stats.sp b/addons/sourcemod/scripting/shavit-stats.sp index 956df33d..e8dd28cd 100644 --- a/addons/sourcemod/scripting/shavit-stats.sp +++ b/addons/sourcemod/scripting/shavit-stats.sp @@ -84,7 +84,7 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max { // natives CreateNative("Shavit_OpenStatsMenu", Native_OpenStatsMenu); - CreateNative("Shavit_GetWRCount", Native_GetWRConut); + CreateNative("Shavit_GetWRCount", Native_GetWRCount); RegPluginLibrary("shavit-stats"); @@ -843,7 +843,7 @@ public int Native_OpenStatsMenu(Handle handler, int numParams) OpenStatsMenu(client, gS_TargetAuth[client]); } -public int Native_GetWRConut(Handle handler, int numParams) +public int Native_GetWRCount(Handle handler, int numParams) { return gI_WRAmount[GetNativeCell(1)]; } From a61cfadfd2a6accd4b2f44aded3b6476de1b5985 Mon Sep 17 00:00:00 2001 From: shavit Date: Sat, 13 Jan 2018 09:35:21 +0200 Subject: [PATCH 04/38] Fixed an issue with WR menu record count. The menu would show the amount of records for the current map rather than grab it from the map itself. --- addons/sourcemod/scripting/shavit-wr.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/shavit-wr.sp b/addons/sourcemod/scripting/shavit-wr.sp index 5865b186..9a93fb6d 100644 --- a/addons/sourcemod/scripting/shavit-wr.sp +++ b/addons/sourcemod/scripting/shavit-wr.sp @@ -1449,7 +1449,7 @@ public void SQL_WR_Callback(Database db, DBResultSet results, const char[] error else { - FormatEx(sRanks, 32, "(#%d/%d)", iMyRank, gI_RecordAmount[gBS_LastWR[client]]); + FormatEx(sRanks, 32, "(#%d/%d)", iMyRank, iRecords); } char[] sTrack = new char[32]; From 13b243f1d7fca5586e387891351a3b0b6efe1c08 Mon Sep 17 00:00:00 2001 From: shavit Date: Sat, 13 Jan 2018 09:35:41 +0200 Subject: [PATCH 05/38] Adjusted the grid visualisation's alpha. --- addons/sourcemod/scripting/shavit-zones.sp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-zones.sp b/addons/sourcemod/scripting/shavit-zones.sp index 4e3f2d66..49bcd398 100644 --- a/addons/sourcemod/scripting/shavit-zones.sp +++ b/addons/sourcemod/scripting/shavit-zones.sp @@ -2077,7 +2077,7 @@ public Action Timer_Draw(Handle Timer, any data) { origin[2] -= gF_Height; - TE_SetupBeamPoints(vPlayerOrigin, origin, gI_BeamSprite, gI_HaloSprite, 0, 0, 0.1, 1.0, 1.0, 0, 0.0, {255, 255, 255, 230}, 0); + TE_SetupBeamPoints(vPlayerOrigin, origin, gI_BeamSprite, gI_HaloSprite, 0, 0, 0.1, 1.0, 1.0, 0, 0.0, {255, 255, 255, 75}, 0); TE_SendToAll(0.0); // visualize grid snap @@ -2092,7 +2092,7 @@ public Action Timer_Draw(Handle Timer, any data) snap2 = origin; snap2[i] += (gI_GridSnap[client] / 2); - TE_SetupBeamPoints(snap1, snap2, gI_BeamSprite, gI_HaloSprite, 0, 0, 0.1, 1.0, 1.0, 0, 0.0, {255, 255, 255, 230}, 0); + TE_SetupBeamPoints(snap1, snap2, gI_BeamSprite, gI_HaloSprite, 0, 0, 0.1, 1.0, 1.0, 0, 0.0, {255, 255, 255, 75}, 0); TE_SendToAll(0.0); } } From 59b5664439269fc3ad4a0d84d9761837dd4af0a0 Mon Sep 17 00:00:00 2001 From: shavit Date: Sat, 13 Jan 2018 09:48:23 +0200 Subject: [PATCH 06/38] Added Shavit_GetReplayBotType and ReplayStatus enum. (#574) --- addons/sourcemod/scripting/include/shavit.inc | 20 ++++++++++++++++--- addons/sourcemod/scripting/shavit-replay.sp | 6 ++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/addons/sourcemod/scripting/include/shavit.inc b/addons/sourcemod/scripting/include/shavit.inc index 0948258b..c21d22b2 100644 --- a/addons/sourcemod/scripting/include/shavit.inc +++ b/addons/sourcemod/scripting/include/shavit.inc @@ -44,7 +44,7 @@ // for reference, not used anymore // game types -enum ServerGame(+=1) +enum ServerGame { Game_CSS = 0, Game_CSGO, @@ -52,14 +52,14 @@ enum ServerGame(+=1) }; // status -enum TimerStatus(+=1) +enum TimerStatus { Timer_Stopped = 0, Timer_Running, Timer_Paused }; -enum ReplayStatus(+=1) +enum ReplayStatus { Replay_Start = 0, Replay_Running, @@ -67,6 +67,12 @@ enum ReplayStatus(+=1) Replay_Idle }; +enum ReplayBotType +{ + Replay_Central = 0, + Replay_Legacy +}; + enum { sStyleName, @@ -786,6 +792,13 @@ native int Shavit_GetReplayBotStyle(int client); */ native int Shavit_GetReplayBotTrack(int client); +/** + * Gets the replay bot type setting of the server. + * + * @return See ReplayBotType enum. + */ +native ReplayBotType Shavit_GetReplayBotType(); + /** * Retrieve the replay bot's current played frame. * @@ -1125,6 +1138,7 @@ public void __pl_shavit_SetNTVOptional() MarkNativeAsOptional("Shavit_GetReplayBotIndex"); MarkNativeAsOptional("Shavit_GetReplayBotStyle"); MarkNativeAsOptional("Shavit_GetReplayBotTrack"); + MarkNativeAsOptional("Shavit_GetReplayBotType"); MarkNativeAsOptional("Shavit_GetReplayData"); MarkNativeAsOptional("Shavit_GetReplayFrameCount"); MarkNativeAsOptional("Shavit_GetReplayLength"); diff --git a/addons/sourcemod/scripting/shavit-replay.sp b/addons/sourcemod/scripting/shavit-replay.sp index 08efffbe..fcb65c30 100644 --- a/addons/sourcemod/scripting/shavit-replay.sp +++ b/addons/sourcemod/scripting/shavit-replay.sp @@ -140,6 +140,7 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max CreateNative("Shavit_GetReplayBotIndex", Native_GetReplayBotIndex); CreateNative("Shavit_GetReplayBotStyle", Native_GetReplayBotStyle); CreateNative("Shavit_GetReplayBotTrack", Native_GetReplayBotTrack); + CreateNative("Shavit_GetReplayBotType", Native_GetReplayBotType); CreateNative("Shavit_GetReplayData", Native_GetReplayData); CreateNative("Shavit_GetReplayFrameCount", Native_GetReplayFrameCount); CreateNative("Shavit_GetReplayLength", Native_GetReplayLength); @@ -421,6 +422,11 @@ public int Native_GetReplayBotTrack(Handle handler, int numParams) return GetReplayTrack(GetNativeCell(1)); } +public int Native_GetReplayBotType(Handle handler, int numParams) +{ + return view_as((gB_CentralBot)? Replay_Central:Replay_Legacy); +} + public void Shavit_OnDatabaseLoaded() { gH_SQL = Shavit_GetDatabase(); From 03074283ab4c0eb008605e232ac5447395041bab Mon Sep 17 00:00:00 2001 From: shavit Date: Sat, 13 Jan 2018 09:54:25 +0200 Subject: [PATCH 07/38] Changed arg-less !spec to automatically forward to replay bot. (#574) --- addons/sourcemod/scripting/shavit-misc.sp | 16 +++++++++++++--- addons/sourcemod/scripting/shavit-replay.sp | 5 +++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index 1d920fea..cc9372d7 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -1178,19 +1178,29 @@ public Action Command_Spec(int client, int args) CleanSwitchTeam(client, 1, false); + int target = -1; + if(args > 0) { char[] sArgs = new char[MAX_TARGET_LENGTH]; GetCmdArgString(sArgs, MAX_TARGET_LENGTH); - int iTarget = FindTarget(client, sArgs, false, false); + target = FindTarget(client, sArgs, false, false); - if(iTarget == -1) + if(target == -1) { return Plugin_Handled; } + } - SetEntPropEnt(client, Prop_Send, "m_hObserverTarget", iTarget); + else if(gB_Replay) + { + target = Shavit_GetReplayBotIndex(0); + } + + if(IsValidClient(target, true)) + { + SetEntPropEnt(client, Prop_Send, "m_hObserverTarget", target); } return Plugin_Handled; diff --git a/addons/sourcemod/scripting/shavit-replay.sp b/addons/sourcemod/scripting/shavit-replay.sp index fcb65c30..c26d9f73 100644 --- a/addons/sourcemod/scripting/shavit-replay.sp +++ b/addons/sourcemod/scripting/shavit-replay.sp @@ -250,6 +250,11 @@ public int Native_GetReplayBotCurrentFrame(Handle handler, int numParams) public int Native_GetReplayBotIndex(Handle handler, int numParams) { + if(gB_CentralBot) + { + return gA_CentralCache[iCentralClient]; + } + return gI_ReplayBotClient[GetNativeCell(1)]; } From 1fcb7993fe3de7af0bc16da495cfd07bb7709c04 Mon Sep 17 00:00:00 2001 From: shavit Date: Tue, 16 Jan 2018 10:15:41 +0200 Subject: [PATCH 08/38] Added `oldtime` parameter to Shavit_OnFinish --- addons/sourcemod/scripting/include/shavit.inc | 3 ++- addons/sourcemod/scripting/shavit-core.sp | 20 +++++++++++++++---- addons/sourcemod/scripting/shavit-rankings.sp | 4 ++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/addons/sourcemod/scripting/include/shavit.inc b/addons/sourcemod/scripting/include/shavit.inc index c21d22b2..12153ac2 100644 --- a/addons/sourcemod/scripting/include/shavit.inc +++ b/addons/sourcemod/scripting/include/shavit.inc @@ -360,9 +360,10 @@ forward Action Shavit_OnFinishPre(int client, any snapshot[TIMERSNAPSHOT_SIZE]); * @param strafes Amount of strafes. * @param sync Sync percentage (0.0 to 100.0) or -1.0 when not measured. * @param track Timer track. + * @param oldtime The player's best time on the map before this finish. * @noreturn */ -forward void Shavit_OnFinish(int client, int style, float time, int jumps, int strafes, float sync, int track); +forward void Shavit_OnFinish(int client, int style, float time, int jumps, int strafes, float sync, int track, float oldtime); /** * Like Shavit_OnFinish, but after the insertion query was called. diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index e06280fc..69ef1e32 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -193,7 +193,7 @@ public void OnPluginStart() 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_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); + 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_OnRestart = CreateGlobalForward("Shavit_OnRestart", 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); @@ -1035,25 +1035,37 @@ public int Native_FinishMap(Handle handler, int numParams) Call_StartForward(gH_Forwards_Finish); Call_PushCell(client); + int style = 0; + int track = Track_Main; + if(result == Plugin_Continue) { - Call_PushCell(gBS_Style[client]); + Call_PushCell(style = gBS_Style[client]); Call_PushCell(CalculateTime(client)); Call_PushCell(gI_Jumps[client]); Call_PushCell(gI_Strafes[client]); Call_PushCell((gA_StyleSettings[gBS_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]); } else { - Call_PushCell(snapshot[bsStyle]); + Call_PushCell(style = snapshot[bsStyle]); Call_PushCell(snapshot[fCurrentTime]); Call_PushCell(snapshot[iJumps]); 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(track = snapshot[iTimerTrack]); } - Call_PushCell(gI_Track[client]); + float oldtime = 0.0; + + if(gB_WR) + { + Shavit_GetPlayerPB(client, style, oldtime, track); + } + + Call_PushCell(oldtime); Call_Finish(); StopTimer(client); diff --git a/addons/sourcemod/scripting/shavit-rankings.sp b/addons/sourcemod/scripting/shavit-rankings.sp index 53ab3078..19f1e744 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -755,8 +755,8 @@ public void SQL_Recalculate_Callback(Database db, DBResultSet results, const cha int serial = data.ReadCell(); int size = data.ReadCell(); - char[] sMap = new char[size + 1]; - ReadPackString(data, sMap, size + 1); + char[] sMap = new char[size+1]; + data.ReadString(sMap, size+1); int track = data.ReadCell(); int style = data.ReadCell(); From 56d37bb871b58d1d927e2be32e15abd28010a946 Mon Sep 17 00:00:00 2001 From: shavit Date: Tue, 16 Jan 2018 11:47:34 +0200 Subject: [PATCH 09/38] Added 'infinite checkpoints' (#575) * Soft cap is 1000 to avoid going above the set heap size. Also fixes: * Adds entity flags to checkpoint data. * Only sets your movetype to the one in the checkpoint data if it's either the walk or ladder types, so you can save while noclipping but teleport normally. --- addons/sourcemod/scripting/shavit-misc.sp | 261 ++++++++++++++-------- 1 file changed, 166 insertions(+), 95 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index cc9372d7..8c08c4c2 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -33,15 +33,33 @@ #undef REQUIRE_PLUGIN #include +// this one is here because enum structs don't work with new syntax +enum CheckpointsCache +{ + Float:fCPPosition[3], + Float:fCPAngles[3], + Float:fCPVelocity[3], + MoveType:mtCPMoveType, + Float:fCPGravity, + Float:fCPSpeed, + Float:fCPStamina, + bool:bCPDucking, + iCPFlags, + any:aCPSnapshot[TIMERSNAPSHOT_SIZE], + String:sCPTargetname[32], + PCPCACHE_SIZE +} + #pragma newdecls required #pragma semicolon 1 +#pragma dynamic 131072 #define CP_ANGLES (1 << 0) #define CP_VELOCITY (1 << 1) #define CP_DEFAULT (CP_ANGLES|CP_VELOCITY) -#define CP_MAX 64 // this is the amount i'm willing to go for +#define CP_MAX 1000 // segmented runs shouldn't even reach 1k jumps on any map anyways // game specific EngineVersion gEV_Type = Engine_Unknown; @@ -51,24 +69,6 @@ char gS_RadioCommands[][] = {"coverme", "takepoint", "holdpos", "regroup", "foll "getinpos", "stormfront", "report", "roger", "enemyspot", "needbackup", "sectorclear", "inposition", "reportingin", "getout", "negative", "enemydown", "compliment", "thanks", "cheer"}; -// enums -enum -{ - iCheckpoints, - iCurrentCheckpoint, - CHECKPOINTSCACHE_SIZE -}; - -enum -{ - iCPMoveType, - fCPGravity, - fCPSpeed, - fCPStamina, - bCPDucking, - PCHECKPOINTSCACHE_SIZE -}; - // cache ConVar sv_disable_immunity_alpha = null; ConVar sv_footsteps = null; @@ -84,12 +84,16 @@ int gI_AdvertisementsCycle = 0; char gS_CurrentMap[192]; int gBS_Style[MAXPLAYERS+1]; -float gF_Checkpoints[MAXPLAYERS+1][CP_MAX][3][3]; // 3 - position, angles, velocity +enum +{ + iCheckpoints, + iCurrentCheckpoint, + CPCACHE_SIZE +}; + +int gI_CheckpointsCache[MAXPLAYERS+1][CPCACHE_SIZE]; int gI_CheckpointsSettings[MAXPLAYERS+1]; -any gA_PlayerCheckPointsCache[MAXPLAYERS+1][CP_MAX][PCHECKPOINTSCACHE_SIZE]; -any gA_CheckpointsSnapshots[MAXPLAYERS+1][CP_MAX][TIMERSNAPSHOT_SIZE]; -any gA_CheckpointsCache[MAXPLAYERS+1][CHECKPOINTSCACHE_SIZE]; -char gS_CheckpointsTargetname[MAXPLAYERS+1][CP_MAX][32]; +StringMap gSM_Checkpoints = null; // save states float gF_SaveStateData[MAXPLAYERS+1][3][3]; @@ -232,6 +236,7 @@ public void OnPluginStart() RegConsoleCmd("sm_save", Command_Save, "Saves checkpoint (default: 1). Usage: sm_save [number]"); RegConsoleCmd("sm_tele", Command_Tele, "Teleports to checkpoint (default: 1). Usage: sm_tele [number]"); gH_CheckpointsCookie = RegClientCookie("shavit_checkpoints", "Checkpoints settings", CookieAccess_Protected); + gSM_Checkpoints = new StringMap(); gI_Ammo = FindSendPropInfo("CCSPlayer", "m_iAmmo"); @@ -503,6 +508,8 @@ public void OnConfigsExecuted() public void OnMapStart() { + gSM_Checkpoints.Clear(); + GetCurrentMap(gS_CurrentMap, 192); GetMapDisplayName(gS_CurrentMap, gS_CurrentMap, 192); @@ -987,42 +994,24 @@ public void OnClientPutInServer(int client) } } +public void OnClientDisconnect(int client) +{ + ResetCheckpoints(client); +} + void ResetCheckpoints(int client) { - for(int i = 0; i < sizeof(gF_Checkpoints[]); i++) + int serial = GetClientSerial(client); + char[] key = new char[32]; + + for(int i = 0; i < gI_CheckpointsCache[client][iCheckpoints]; i++) { - for(int j = 0; j < sizeof(gF_Checkpoints[][]); j++) - { - gF_Checkpoints[client][i][j] = NULL_VECTOR; - } + FormatEx(key, 32, "%d_%d", serial, i); + gSM_Checkpoints.Remove(key); } - for(int i = 0; i < CP_MAX; i++) - { - gA_CheckpointsSnapshots[client][i][bTimerEnabled] = false; - gA_CheckpointsSnapshots[client][i][fStartTime] = 0.0; - gA_CheckpointsSnapshots[client][i][fCurrentTime] = 0.0; - gA_CheckpointsSnapshots[client][i][fPauseStartTime] = 0.0; - gA_CheckpointsSnapshots[client][i][fPauseTotalTime] = 0.0; - gA_CheckpointsSnapshots[client][i][bClientPaused] = false; - gA_CheckpointsSnapshots[client][i][iJumps] = 0; - gA_CheckpointsSnapshots[client][i][bsStyle] = 0; - gA_CheckpointsSnapshots[client][i][iStrafes] = 0; - gA_CheckpointsSnapshots[client][i][iTotalMeasures] = 0; - gA_CheckpointsSnapshots[client][i][iGoodGains] = 0; - gA_CheckpointsSnapshots[client][i][iSHSWCombination] = -1; - - gA_PlayerCheckPointsCache[client][i][iCPMoveType] = MOVETYPE_WALK; - gA_PlayerCheckPointsCache[client][i][fCPGravity] = 1.0; - gA_PlayerCheckPointsCache[client][i][fCPSpeed] = 1.0; - gA_PlayerCheckPointsCache[client][i][fCPStamina] = 1.0; - gA_PlayerCheckPointsCache[client][i][bCPDucking] = false; - - strcopy(gS_CheckpointsTargetname[client][i], 32, ""); - } - - gA_CheckpointsCache[client][iCheckpoints] = 0; - gA_CheckpointsCache[client][iCurrentCheckpoint] = 1; + gI_CheckpointsCache[client][iCheckpoints] = 0; + gI_CheckpointsCache[client][iCurrentCheckpoint] = 1; } public Action OnTakeDamage(int victim, int attacker) @@ -1444,11 +1433,11 @@ public Action Command_Save(int client, int args) { bool bSaved = false; - if(gA_CheckpointsCache[client][iCheckpoints] < CP_MAX) + if(gI_CheckpointsCache[client][iCheckpoints] < CP_MAX) { - if((bSaved = SaveCheckpoint(client, gA_CheckpointsCache[client][iCheckpoints]))) + if((bSaved = SaveCheckpoint(client, gI_CheckpointsCache[client][iCheckpoints]))) { - gA_CheckpointsCache[client][iCurrentCheckpoint] = ++gA_CheckpointsCache[client][iCheckpoints]; + gI_CheckpointsCache[client][iCurrentCheckpoint] = ++gI_CheckpointsCache[client][iCheckpoints]; } } @@ -1456,13 +1445,13 @@ public Action Command_Save(int client, int args) { if((bSaved = SaveCheckpoint(client, (CP_MAX - 1)))) { - gA_CheckpointsCache[client][iCurrentCheckpoint] = CP_MAX; + gI_CheckpointsCache[client][iCurrentCheckpoint] = CP_MAX; } } if(bSaved) { - Shavit_PrintToChat(client, "%T", "MiscCheckpointsSaved", client, gA_CheckpointsCache[client][iCurrentCheckpoint], + Shavit_PrintToChat(client, "%T", "MiscCheckpointsSaved", client, gI_CheckpointsCache[client][iCurrentCheckpoint], gS_ChatStrings[sMessageVariable], gS_ChatStrings[sMessageText], gS_ChatStrings[sMessageVariable], gS_ChatStrings[sMessageText]); } } @@ -1486,7 +1475,7 @@ public Action Command_Tele(int client, int args) return Plugin_Handled; } - int index = (gA_CheckpointsCache[client][iCurrentCheckpoint] - 1); + int index = (gI_CheckpointsCache[client][iCurrentCheckpoint] - 1); if(args > 0) { @@ -1501,7 +1490,13 @@ public Action Command_Tele(int client, int args) } } - if(IsNullVector(gF_Checkpoints[client][index][0])) + CheckpointsCache cpcache[PCPCACHE_SIZE]; + GetCheckpoint(client, index, cpcache); + + float pos[3]; + CopyArray(cpcache[fCPPosition], pos, 3); + + if(IsNullVector(pos)) { Shavit_PrintToChat(client, "%T", "MiscCheckpointsEmpty", client, (index + 1), gS_ChatStrings[sMessageWarning], gS_ChatStrings[sMessageText]); @@ -1526,12 +1521,12 @@ public Action OpenCheckpointsMenu(int client, int item) menu.SetTitle("%T\n%T\n ", "MiscCheckpointMenu", client, "MiscCheckpointWarning", client); char[] sDisplay = new char[64]; - FormatEx(sDisplay, 64, "%T", "MiscCheckpointSave", client, (gA_CheckpointsCache[client][iCheckpoints] + 1)); - menu.AddItem("save", sDisplay, (gA_CheckpointsCache[client][iCheckpoints] < CP_MAX)? ITEMDRAW_DEFAULT:ITEMDRAW_DISABLED); + FormatEx(sDisplay, 64, "%T", "MiscCheckpointSave", client, (gI_CheckpointsCache[client][iCheckpoints] + 1)); + menu.AddItem("save", sDisplay, (gI_CheckpointsCache[client][iCheckpoints] < CP_MAX)? ITEMDRAW_DEFAULT:ITEMDRAW_DISABLED); - if(gA_CheckpointsCache[client][iCheckpoints] > 0) + if(gI_CheckpointsCache[client][iCheckpoints] > 0) { - FormatEx(sDisplay, 64, "%T", "MiscCheckpointTeleport", client, gA_CheckpointsCache[client][iCurrentCheckpoint]); + FormatEx(sDisplay, 64, "%T", "MiscCheckpointTeleport", client, gI_CheckpointsCache[client][iCurrentCheckpoint]); menu.AddItem("tele", sDisplay, ITEMDRAW_DEFAULT); } @@ -1570,20 +1565,20 @@ public int MenuHandler_Checkpoints(Menu menu, MenuAction action, int param1, int { if(action == MenuAction_Select) { - int current = gA_CheckpointsCache[param1][iCurrentCheckpoint]; + int current = gI_CheckpointsCache[param1][iCurrentCheckpoint]; switch(param2) { case 0: { // fight an exploit - if(gA_CheckpointsCache[param1][iCheckpoints] >= CP_MAX) + if(gI_CheckpointsCache[param1][iCheckpoints] >= CP_MAX) { return 0; } - SaveCheckpoint(param1, gA_CheckpointsCache[param1][iCheckpoints]); - gA_CheckpointsCache[param1][iCurrentCheckpoint] = ++gA_CheckpointsCache[param1][iCheckpoints]; + SaveCheckpoint(param1, gI_CheckpointsCache[param1][iCheckpoints]); + gI_CheckpointsCache[param1][iCurrentCheckpoint] = ++gI_CheckpointsCache[param1][iCheckpoints]; } case 1: @@ -1595,15 +1590,21 @@ public int MenuHandler_Checkpoints(Menu menu, MenuAction action, int param1, int { if(current > 1) { - gA_CheckpointsCache[param1][iCurrentCheckpoint]--; + gI_CheckpointsCache[param1][iCurrentCheckpoint]--; } } case 3: { - if(current < CP_MAX && !IsNullVector(gF_Checkpoints[param1][current][0])) + CheckpointsCache cpcache[PCPCACHE_SIZE]; + GetCheckpoint(param1, current, cpcache); + + float pos[3]; + CopyArray(cpcache[fCPPosition], pos, 3); + + if(current < CP_MAX && !IsNullVector(pos)) { - gA_CheckpointsCache[param1][iCurrentCheckpoint]++; + gI_CheckpointsCache[param1][iCurrentCheckpoint]++; } } @@ -1667,25 +1668,50 @@ bool SaveCheckpoint(int client, int index) return false; } - GetClientAbsOrigin(target, gF_Checkpoints[client][index][0]); - GetClientEyeAngles(target, gF_Checkpoints[client][index][1]); - GetEntPropVector(target, Prop_Data, "m_vecAbsVelocity", gF_Checkpoints[client][index][2]); - GetEntPropString(target, Prop_Data, "m_iName", gS_CheckpointsTargetname[client][index], 32); + CheckpointsCache cpcache[PCPCACHE_SIZE]; + float temp[3]; - gA_PlayerCheckPointsCache[client][index][iCPMoveType] = GetEntityMoveType(target); - gA_PlayerCheckPointsCache[client][index][fCPGravity] = GetEntityGravity(target); - gA_PlayerCheckPointsCache[client][index][fCPSpeed] = GetEntPropFloat(target, Prop_Send, "m_flLaggedMovementValue"); - gA_PlayerCheckPointsCache[client][index][fCPStamina] = GetEntPropFloat(target, Prop_Send, "m_flStamina"); - gA_PlayerCheckPointsCache[client][index][bCPDucking] = (GetClientButtons(target) & IN_DUCK) > 0; + GetClientAbsOrigin(target, temp); + CopyArray(temp, cpcache[fCPPosition], 3); - Shavit_SaveSnapshot(target, gA_CheckpointsSnapshots[client][index]); + GetClientEyeAngles(target, temp); + CopyArray(temp, cpcache[fCPAngles], 3); + + GetEntPropVector(target, Prop_Data, "m_vecAbsVelocity", temp); + CopyArray(temp, cpcache[fCPVelocity], 3); + + GetEntPropString(target, Prop_Data, "m_iName", cpcache[sCPTargetname], 32); + + cpcache[mtCPMoveType] = GetEntityMoveType(target); + cpcache[fCPGravity] = GetEntityGravity(target); + cpcache[fCPSpeed] = GetEntPropFloat(target, Prop_Send, "m_flLaggedMovementValue"); + cpcache[fCPStamina] = (gEV_Type != Engine_TF2)? GetEntPropFloat(target, Prop_Send, "m_flStamina"):0.0; + cpcache[bCPDucking] = (GetClientButtons(target) & IN_DUCK) > 0; + cpcache[iCPFlags] = GetEntityFlags(target); + + any snapshot[TIMERSNAPSHOT_SIZE]; + Shavit_SaveSnapshot(target, snapshot); + CopyArray(snapshot, cpcache[aCPSnapshot], TIMERSNAPSHOT_SIZE); + + SetCheckpoint(client, index, cpcache); return true; } void TeleportToCheckpoint(int client, int index, bool suppressMessage) { - if(index < 0 || index >= CP_MAX || IsNullVector(gF_Checkpoints[client][index][0])) + if(index < 0 || index >= CP_MAX) + { + return; + } + + CheckpointsCache cpcache[PCPCACHE_SIZE]; + GetCheckpoint(client, index, cpcache); + + float pos[3]; + CopyArray(cpcache[fCPPosition], pos, 3); + + if(IsNullVector(pos)) { return; } @@ -1699,7 +1725,7 @@ void TeleportToCheckpoint(int client, int index, bool suppressMessage) bool bDucking = (GetClientButtons(client) & IN_DUCK) > 0; - if(gA_PlayerCheckPointsCache[client][index][bCPDucking] != bDucking) + if(cpcache[bCPDucking] != bDucking) { Shavit_PrintToChat(client, "%T", (bDucking)? "MiscCheckpointsCrouchOff":"MiscCheckpointsCrouchOn", client, gS_ChatStrings[sMessageWarning], gS_ChatStrings[sMessageText]); @@ -1714,17 +1740,38 @@ void TeleportToCheckpoint(int client, int index, bool suppressMessage) } Shavit_SetPracticeMode(client, true, !bInStart); - Shavit_LoadSnapshot(client, gA_CheckpointsSnapshots[client][index]); - TeleportEntity(client, gF_Checkpoints[client][index][0], - ((gI_CheckpointsSettings[client] & CP_ANGLES) > 0)? gF_Checkpoints[client][index][1]:NULL_VECTOR, - ((gI_CheckpointsSettings[client] & CP_VELOCITY) > 0)? gF_Checkpoints[client][index][2]:NULL_VECTOR); + any snapshot[TIMERSNAPSHOT_SIZE]; + CopyArray(cpcache[aCPSnapshot], snapshot, TIMERSNAPSHOT_SIZE); + Shavit_LoadSnapshot(client, snapshot); - SetEntityMoveType(client, view_as(gA_PlayerCheckPointsCache[client][index][iCPMoveType])); - SetEntityGravity(client, view_as(gA_PlayerCheckPointsCache[client][index][fCPGravity])); - SetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue", view_as(gA_PlayerCheckPointsCache[client][index][fCPSpeed])); - SetEntPropFloat(client, Prop_Send, "m_flStamina", view_as(gA_PlayerCheckPointsCache[client][index][fCPStamina])); - DispatchKeyValue(client, "targetname", gS_CheckpointsTargetname[client][index]); + float ang[3]; + CopyArray(cpcache[fCPAngles], ang, 3); + + float vel[3]; + CopyArray(cpcache[fCPVelocity], vel, 3); + + TeleportEntity(client, pos, + ((gI_CheckpointsSettings[client] & CP_ANGLES) > 0)? ang:NULL_VECTOR, + ((gI_CheckpointsSettings[client] & CP_VELOCITY) > 0)? vel:NULL_VECTOR); + + MoveType mt = cpcache[mtCPMoveType]; + + if(mt == MOVETYPE_LADDER || mt == MOVETYPE_WALK) + { + SetEntityMoveType(client, mt); + } + + SetEntityGravity(client, cpcache[fCPGravity]); + SetEntityFlags(client, cpcache[iCPFlags]); + + SetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue", cpcache[fCPSpeed]); + DispatchKeyValue(client, "targetname", cpcache[sCPTargetname]); + + if(gEV_Type != Engine_TF2) + { + SetEntPropFloat(client, Prop_Send, "m_flStamina", cpcache[fCPStamina]); + } if(!suppressMessage) { @@ -2223,7 +2270,7 @@ public Action Shotgun_Shot(const char[] te_name, const int[] Players, int numCli { TE_WriteNum("m_weapon", TE_ReadNum("m_weapon")); } - + TE_WriteNum("m_iMode", TE_ReadNum("m_iMode")); TE_WriteNum("m_iSeed", TE_ReadNum("m_iSeed")); TE_WriteNum("m_iPlayer", (client - 1)); @@ -2412,6 +2459,22 @@ void SaveState(int client) gB_SaveStates[client] = true; } +bool GetCheckpoint(int client, int index, CheckpointsCache cpcache[PCPCACHE_SIZE]) +{ + char[] sKey = new char[32]; + FormatEx(sKey, 32, "%d_%d", GetClientSerial(client), index); + + return gSM_Checkpoints.GetArray(sKey, cpcache[0], view_as(PCPCACHE_SIZE)); +} + +bool SetCheckpoint(int client, int index, CheckpointsCache cpcache[PCPCACHE_SIZE]) +{ + char[] sKey = new char[32]; + FormatEx(sKey, 32, "%d_%d", GetClientSerial(client), index); + + return gSM_Checkpoints.SetArray(sKey, cpcache[0], view_as(PCPCACHE_SIZE)); +} + void UpdateFootsteps(int client) { if(sv_footsteps != null) @@ -2422,6 +2485,14 @@ void UpdateFootsteps(int client) } } +void CopyArray(const any[] from, any[] to, int size) +{ + for(int i = 0; i < size; i++) + { + to[i] = from[i]; + } +} + #if SOURCEMOD_V_MAJOR == 1 && SOURCEMOD_V_MINOR < 9 bool IsNullVector(float vec[3]) { From 314406c203736113a2dec56ade1fbbd2ff17de3c Mon Sep 17 00:00:00 2001 From: shavit Date: Tue, 16 Jan 2018 12:04:44 +0200 Subject: [PATCH 10/38] Record entity flags and movetypes in replays. (#579) --- addons/sourcemod/scripting/shavit-replay.sp | 46 +++++++++++++++++---- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-replay.sp b/addons/sourcemod/scripting/shavit-replay.sp index c26d9f73..80a51cea 100644 --- a/addons/sourcemod/scripting/shavit-replay.sp +++ b/addons/sourcemod/scripting/shavit-replay.sp @@ -31,8 +31,8 @@ #define REPLAY_FORMAT_V2 "{SHAVITREPLAYFORMAT}{V2}" #define REPLAY_FORMAT_FINAL "{SHAVITREPLAYFORMAT}{FINAL}" -#define REPLAY_FORMAT_SUBVERSION 0x01 // for compatibility, if i ever update this code again -#define CELLS_PER_FRAME 6 // origin[3], angles[2], buttons +#define REPLAY_FORMAT_SUBVERSION 0x02 +#define CELLS_PER_FRAME 8 // origin[3], angles[2], buttons, flags, movetype // #define DEBUG @@ -71,7 +71,7 @@ int gI_ReplayBotClient[STYLE_LIMIT]; ArrayList gA_Frames[STYLE_LIMIT][TRACKS_SIZE]; float gF_StartTick[STYLE_LIMIT]; ReplayStatus gRS_ReplayStatus[STYLE_LIMIT]; -any gA_FrameCache[STYLE_LIMIT][TRACKS_SIZE][3]; // int frame_count, float time, bool new_format +any gA_FrameCache[STYLE_LIMIT][TRACKS_SIZE][4]; // int frame_count, float time, bool new_format, int replay_version char gS_ReplayNames[STYLE_LIMIT][TRACKS_SIZE][MAX_NAME_LENGTH]; bool gB_ForciblyStopped = false; @@ -818,8 +818,7 @@ bool LoadReplay(int style, int track, const char[] path) if(StrEqual(sExplodedHeader[1], REPLAY_FORMAT_FINAL)) // hopefully, the last of them { - // uncomment if ever needed - // int iSubVersion = StringToInt(sExplodedHeader[0]); + gA_FrameCache[style][track][3] = StringToInt(sExplodedHeader[0]); int iTemp = 0; fFile.ReadInt32(iTemp); @@ -850,11 +849,19 @@ bool LoadReplay(int style, int track, const char[] path) gH_SQL.Query(SQL_GetUserName_Callback, sQuery, pack, DBPrio_High); } - any[] aReplayData = new any[CELLS_PER_FRAME]; + int cells = 8; + + // backwards compatibility + if(gA_FrameCache[style][track][3] == 0x01) + { + cells = 6; + } + + any[] aReplayData = new any[cells]; for(int i = 0; i < gA_FrameCache[style][track][0]; i++) { - if(fFile.Read(aReplayData, CELLS_PER_FRAME, 4) >= 0) + if(fFile.Read(aReplayData, cells, 4) >= 0) { gA_Frames[style][track].Set(i, view_as(aReplayData[0]), 0); gA_Frames[style][track].Set(i, view_as(aReplayData[1]), 1); @@ -862,6 +869,12 @@ bool LoadReplay(int style, int track, const char[] path) gA_Frames[style][track].Set(i, view_as(aReplayData[3]), 3); gA_Frames[style][track].Set(i, view_as(aReplayData[4]), 4); gA_Frames[style][track].Set(i, view_as(aReplayData[5]), 5); + + if(gA_FrameCache[style][track][3] >= 0x02) + { + gA_Frames[style][track].Set(i, view_as(aReplayData[6]), 6); + gA_Frames[style][track].Set(i, view_as(aReplayData[7]), 7); + } } } @@ -1452,6 +1465,23 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3 buttons = gA_Frames[style][track].Get(gI_ReplayTick[style], 5); + if(gA_FrameCache[style][track][3] >= 0x02) + { + SetEntityFlags(client, gA_Frames[style][track].Get(gI_ReplayTick[style], 6)); + + MoveType mt = gA_Frames[style][track].Get(gI_ReplayTick[style], 7); + + if(mt == MOVETYPE_WALK || mt == MOVETYPE_LADDER) + { + SetEntityMoveType(client, mt); + } + + else + { + SetEntityMoveType(client, MOVETYPE_NOCLIP); + } + } + float vecVelocity[3]; MakeVectorFromPoints(vecCurrentPosition, vecPosition, vecVelocity); ScaleVector(vecVelocity, gF_Tickrate); @@ -1495,6 +1525,8 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3 gA_PlayerFrames[client].Set(gI_PlayerFrames[client], angles[1], 4); gA_PlayerFrames[client].Set(gI_PlayerFrames[client], buttons, 5); + gA_PlayerFrames[client].Set(gI_PlayerFrames[client], GetEntityFlags(client), 6); + gA_PlayerFrames[client].Set(gI_PlayerFrames[client], GetEntityMoveType(client), 7); gI_PlayerFrames[client]++; } From 6690947e5fb1b137267d195fb9d79ba11fe7e8b6 Mon Sep 17 00:00:00 2001 From: shavit Date: Thu, 18 Jan 2018 18:24:47 +0200 Subject: [PATCH 11/38] Added track letter ("{tr}") to scoreboard tag. (#584) --- addons/sourcemod/scripting/shavit-misc.sp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index 6e6167b0..4022c41e 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -160,7 +160,7 @@ int gI_NoclipMe = true; float gF_AdvertisementInterval = 600.0; bool gB_Checkpoints = true; int gI_RemoveRagdolls = 1; -char gS_ClanTag[32] = "{styletag} :: {time}"; +char gS_ClanTag[32] = "{tr}{styletag} :: {time}"; bool gB_DropAll = true; bool gB_ResetTargetname = false; bool gB_RestoreStates = false; @@ -306,7 +306,7 @@ public void OnPluginStart() gCV_AdvertisementInterval = CreateConVar("shavit_misc_advertisementinterval", "600.0", "Interval between each chat advertisement.\nConfiguration file for those is configs/shavit-advertisements.cfg.\nSet to 0.0 to disable.\nRequires server restart for changes to take effect.", 0, true, 0.0); gCV_Checkpoints = CreateConVar("shavit_misc_checkpoints", "1", "Allow players to save and teleport to checkpoints.", 0, true, 0.0, true, 1.0); gCV_RemoveRagdolls = CreateConVar("shavit_misc_removeragdolls", "1", "Remove ragdolls after death?\n0 - Disabled\n1 - Only remove replay bot ragdolls.\n2 - Remove all ragdolls.", 0, true, 0.0, true, 2.0); - gCV_ClanTag = CreateConVar("shavit_misc_clantag", "{styletag} :: {time}", "Custom clantag for players.\n0 - Disabled\n{styletag} - style settings from shavit-styles.cfg.\n{style} - style name.\n{time} - formatted time.", 0); + gCV_ClanTag = CreateConVar("shavit_misc_clantag", "{tr}{styletag} :: {time}", "Custom clantag for players.\n0 - Disabled\n{styletag} - style settings from shavit-styles.cfg.\n{style} - style name.\n{time} - formatted time.\n{tr} - first letter of track, if not default.", 0); gCV_DropAll = CreateConVar("shavit_misc_dropall", "1", "Allow all weapons to be dropped?\n0 - Disabled\n1 - Enabled", 0, true, 0.0, true, 1.0); gCV_ResetTargetname = CreateConVar("shavit_misc_resettargetname", "0", "Reset the player's targetname upon timer start?\nRecommended to leave disabled. Enable via per-map configs when necessary.\n0 - Disabled\n1 - Enabled", 0, true, 0.0, true, 1.0); gCV_RestoreStates = CreateConVar("shavit_misc_restorestates", "0", "Save the players' timer/position etc.. when they die/change teams,\nand load the data when they spawn?\n0 - Disabled\n1 - Enabled", 0, true, 0.0, true, 1.0); @@ -878,11 +878,20 @@ void UpdateClanTag(int client) } } + int track = Shavit_GetClientTrack(client); + char[] sTrack = new char[3]; + + if(track != Track_Main) + { + GetTrackName(client, track, sTrack, 3); + } + char[] sCustomTag = new char[32]; strcopy(sCustomTag, 32, gS_ClanTag); ReplaceString(sCustomTag, 32, "{style}", gS_StyleStrings[gBS_Style[client]][sStyleName]); ReplaceString(sCustomTag, 32, "{styletag}", gS_StyleStrings[gBS_Style[client]][sClanTag]); ReplaceString(sCustomTag, 32, "{time}", sTime); + ReplaceString(sCustomTag, 32, "{tr}", sTrack); CS_SetClientClanTag(client, sCustomTag); } @@ -2275,7 +2284,7 @@ public Action Shotgun_Shot(const char[] te_name, const int[] Players, int numCli { TE_WriteNum("m_weapon", TE_ReadNum("m_weapon")); } - + TE_WriteNum("m_iMode", TE_ReadNum("m_iMode")); TE_WriteNum("m_iSeed", TE_ReadNum("m_iSeed")); TE_WriteNum("m_iPlayer", (client - 1)); From e6d09e9bc2456d9f82e38ab0ba45db4fbb6120e8 Mon Sep 17 00:00:00 2001 From: shavit Date: Thu, 18 Jan 2018 18:57:12 +0200 Subject: [PATCH 12/38] Added scroll pad to CS:GO HUD --- addons/sourcemod/scripting/shavit-hud.sp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/shavit-hud.sp b/addons/sourcemod/scripting/shavit-hud.sp index 46208363..d05f0b70 100644 --- a/addons/sourcemod/scripting/shavit-hud.sp +++ b/addons/sourcemod/scripting/shavit-hud.sp @@ -876,7 +876,20 @@ void UpdateKeyOverlay(int client, Panel panel, bool &draw) int buttons = gI_Buttons[target]; char[] sPanelLine = new char[128]; - FormatEx(sPanelLine, 128, "[%s] [%s]\n   %s\n%s  %s  %s", + + int style = (IsFakeClient(target))? Shavit_GetReplayBotStyle(target):Shavit_GetBhopStyle(target); + + if(style < 0 || style > gI_Styles) + { + style = 0; + } + + if(gB_BhopStats && !gA_StyleSettings[style][bAutobhop]) + { + FormatEx(sPanelLine, 64, " %d%s%d\n", gI_ScrollCount[target], (gI_ScrollCount[target] > 9)? " ":" ", gI_LastScrollCount[target]); + } + + Format(sPanelLine, 128, "%s[%s] [%s]\n   %s\n%s  %s  %s", sPanelLine, (buttons & IN_JUMP) > 0? "J":"ー", (buttons & IN_DUCK) > 0? "C":"ー", (buttons & IN_FORWARD) > 0? "W":"ー", (buttons & IN_MOVELEFT) > 0? "A":"ー", (buttons & IN_BACK) > 0? "S":"ー", (buttons & IN_MOVERIGHT) > 0? "D":"ー"); From 9b5e4ad85db41914e7ee0b521faeaa85436b7749 Mon Sep 17 00:00:00 2001 From: shavit Date: Thu, 18 Jan 2018 19:19:51 +0200 Subject: [PATCH 13/38] Some CS:GO HUD tweaks (#584) * Removed some clutter from center HUD. * Added display for non-default tracks. * Removed pause text, but changed the time's color when paused. * Very minor optimization. * Changed the HUD update speed to avoid skips. * Adjusted spacing of the zone HUD to look better in CS:GO. I think these changes look fine, I hope everyone enjoys them. --- addons/sourcemod/scripting/shavit-hud.sp | 34 +++++++++--------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-hud.sp b/addons/sourcemod/scripting/shavit-hud.sp index d05f0b70..fe4f7983 100644 --- a/addons/sourcemod/scripting/shavit-hud.sp +++ b/addons/sourcemod/scripting/shavit-hud.sp @@ -135,7 +135,7 @@ public void OnPluginStart() AutoExecConfig(); // cron - CreateTimer(0.10, UpdateHUD_Timer, INVALID_HANDLE, TIMER_REPEAT); + CreateTimer(0.05, UpdateHUD_Timer, INVALID_HANDLE, TIMER_REPEAT); // commands RegConsoleCmd("sm_hud", Command_HUD, "Opens the HUD settings menu"); @@ -635,7 +635,7 @@ void UpdateHUD(int client) { if(gEV_Type == Engine_CSGO) { - FormatEx(sHintText, 64, "%T\n\t%T: %d", ((gI_GradientColors[0] << 16) + (gI_GradientColors[1] << 8) + (gI_GradientColors[2])), "HudStartZone", client, "HudSpeedText", client, iSpeed); + FormatEx(sHintText, 128, " %T\n\t %T: %d", ((gI_GradientColors[0] << 16) + (gI_GradientColors[1] << 8) + (gI_GradientColors[2])), "HudStartZone", client, "HudSpeedText", client, iSpeed); } else @@ -649,7 +649,7 @@ void UpdateHUD(int client) { if(gEV_Type == Engine_CSGO) { - FormatEx(sHintText, 64, "%T\n\t%T: %d", ((gI_GradientColors[0] << 16) + (gI_GradientColors[1] << 8) + (gI_GradientColors[2])), "HudEndZone", client, "HudSpeedText", client, iSpeed); + FormatEx(sHintText, 128, " %T\n\t %T: %d", ((gI_GradientColors[0] << 16) + (gI_GradientColors[1] << 8) + (gI_GradientColors[2])), "HudEndZone", client, "HudSpeedText", client, iSpeed); } else @@ -667,6 +667,8 @@ void UpdateHUD(int client) else if((gI_HUDSettings[client] & HUD_CENTER) > 0) { int track = Shavit_GetClientTrack(target); + char[] sTrack = new char[32]; + GetTrackName(client, track, sTrack, 32); if(!IsFakeClient(target)) { @@ -690,7 +692,7 @@ void UpdateHUD(int client) if(gEV_Type == Engine_CSGO) { - strcopy(sHintText, 512, ""); + strcopy(sHintText, 512, ""); if(status >= Timer_Running) { @@ -698,7 +700,7 @@ void UpdateHUD(int client) if(status == Timer_Paused) { - strcopy(sColor, 8, "FF0000"); + strcopy(sColor, 8, "A9C5E8"); } else if(time < fWR || fWR == 0.0) @@ -716,16 +718,15 @@ void UpdateHUD(int client) strcopy(sColor, 8, "FF0000"); } - char[] sPauseItem = new char[64]; - FormatEx(sPauseItem, 64, "%T\t", "HudPaused", client); + if(track != Track_Main) + { + Format(sHintText, 512, "%s[%s] ", sHintText, sTrack); + } - char[] sUnpausedItem = new char[64]; - FormatEx(sUnpausedItem, 64, "%s (%d)\t", sTime, rank); - - Format(sHintText, 512, "%s%T: %s", sHintText, "HudTimeText", client, sColor, (status == Timer_Paused)? sPauseItem:sUnpausedItem); + Format(sHintText, 512, "%s%s (%d)", sHintText, sColor, sTime, rank); } - if(fPB > 0.0) + else if(fPB > 0.0) { Format(sHintText, 512, "%s%T: %s (#%d)", sHintText, "HudBestText", client, sPB, (Shavit_GetRankForTime(style, fPB, track) - 1)); } @@ -754,8 +755,6 @@ void UpdateHUD(int client) Format(sHintText, 512, "%s%s\t%T: %d", sHintText, (iSpeed < 1000)? "\t":"", "HudStrafeText", client, strafes); } } - - Format(sHintText, 512, "%s", sHintText); } else @@ -782,9 +781,6 @@ void UpdateHUD(int client) if(track != Track_Main) { - char[] sTrack = new char[32]; - GetTrackName(client, track, sTrack, 32); - Format(sHintText, 512, "%s\n%s", sHintText, sTrack); } } @@ -825,11 +821,8 @@ void UpdateHUD(int client) char[] sReplayLength = new char[32]; FormatSeconds(fReplayLength, sReplayLength, 32, false); - char[] sTrack = new char[32]; - if(track != Track_Main) { - GetTrackName(client, track, sTrack, 32); Format(sTrack, 32, "(%s) ", sTrack); } @@ -839,7 +832,6 @@ void UpdateHUD(int client) Format(sHintText, 512, "%s\t%s %T", sHintText, gS_StyleStrings[style][sHTMLColor], gS_StyleStrings[style][sStyleName], "ReplayText", client); Format(sHintText, 512, "%s\n\t%T: %s / %s", sHintText, "HudTimeText", client, sReplayTime, sReplayLength); Format(sHintText, 512, "%s\n\t%T: %d", sHintText, "HudSpeedText", client, iSpeed); - Format(sHintText, 512, "%s", sHintText); } else From 271f2ea9ed9b118448abcfa942d679f0bcc8c8d6 Mon Sep 17 00:00:00 2001 From: shavit Date: Thu, 18 Jan 2018 19:58:06 +0200 Subject: [PATCH 14/38] Introduced 'shavit_hud_ticksperupdate' - Dropped timers for updates in order to allow better precision. --- addons/sourcemod/scripting/shavit-hud.sp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-hud.sp b/addons/sourcemod/scripting/shavit-hud.sp index fe4f7983..af7bae13 100644 --- a/addons/sourcemod/scripting/shavit-hud.sp +++ b/addons/sourcemod/scripting/shavit-hud.sp @@ -46,6 +46,7 @@ int gI_Cycle = 0; int gI_GradientColors[3]; int gI_GradientDirection = -1; int gI_Styles = 0; +int gI_Tickrate = 0; Handle gH_HUDCookie = null; int gI_HUDSettings[MAXPLAYERS+1]; @@ -63,9 +64,11 @@ Handle gH_HUD = null; // plugin cvars ConVar gCV_GradientStepSize = null; +ConVar gCV_TicksPerUpdate = null; // cached cvars int gI_GradientStepSize = 5; +int gI_TicksPerUpdate = 20; // timer settings char gS_StyleStrings[STYLE_LIMIT][STYLESTRINGS_SIZE][128]; @@ -101,6 +104,7 @@ public void OnPluginStart() // game-specific gEV_Type = GetEngineVersion(); + gI_Tickrate = RoundToZero(1.0 / GetTickInterval()); if(IsSource2013(gEV_Type)) { @@ -130,13 +134,13 @@ public void OnPluginStart() // plugin convars gCV_GradientStepSize = CreateConVar("shavit_hud_gradientstepsize", "15", "How fast should the start/end HUD gradient be?\nThe number is the amount of color change per 0.1 seconds.\nThe higher the number the faster the gradient.", 0, true, 1.0, true, 255.0); + gCV_TicksPerUpdate = CreateConVar("shavit_hud_ticksperupdate", "20", "How often (in ticks) should the HUD update?\nPlay around with this value until you find the best for your server.\nThe maximum value is your tickrate.", 0, true, 1.0, true, float(gI_Tickrate)); + gCV_GradientStepSize.AddChangeHook(OnConVarChanged); + gCV_TicksPerUpdate.AddChangeHook(OnConVarChanged); AutoExecConfig(); - // cron - CreateTimer(0.05, UpdateHUD_Timer, INVALID_HANDLE, TIMER_REPEAT); - // commands RegConsoleCmd("sm_hud", Command_HUD, "Opens the HUD settings menu"); RegConsoleCmd("sm_options", Command_HUD, "Opens the HUD settings menu (alias for sm_hud"); @@ -164,6 +168,7 @@ public void OnPluginStart() public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue) { gI_GradientStepSize = gCV_GradientStepSize.IntValue; + gI_TicksPerUpdate = gCV_TicksPerUpdate.IntValue; } public void OnMapStart() @@ -476,7 +481,15 @@ public int MenuHandler_HUD(Menu menu, MenuAction action, int param1, int param2) return 0; } -public Action UpdateHUD_Timer(Handle Timer) +public void OnGameFrame() +{ + if(GetGameTickCount() % (gI_Tickrate / gI_TicksPerUpdate) == 0) + { + Cron(); + } +} + +void Cron() { if(++gI_Cycle >= 65535) { @@ -567,8 +580,6 @@ public Action UpdateHUD_Timer(Handle Timer) TriggerHUDUpdate(i); } - - return Plugin_Continue; } void TriggerHUDUpdate(int client, bool keysonly = false) // keysonly because CS:S lags when you send too many usermessages From 757e9de8c6bbebb3b60d41d534af007524c0eeee Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 22 Jan 2018 18:33:47 +0200 Subject: [PATCH 15/38] Fixed zone offset being wrong for point 1 (#585) --- addons/sourcemod/scripting/shavit-misc.sp | 2 +- addons/sourcemod/scripting/shavit-zones.sp | 29 +++++++++++++--------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index 4022c41e..8e6d9c02 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -2275,7 +2275,7 @@ public Action Shotgun_Shot(const char[] te_name, const int[] Players, int numCli TE_WriteFloat("m_vecAngles[0]", TE_ReadFloat("m_vecAngles[0]")); TE_WriteFloat("m_vecAngles[1]", TE_ReadFloat("m_vecAngles[1]")); - if(gEV_Type == Engine_CSS) + if(IsSource2013(gEV_Type)) { TE_WriteNum("m_iWeaponID", TE_ReadNum("m_iWeaponID")); } diff --git a/addons/sourcemod/scripting/shavit-zones.sp b/addons/sourcemod/scripting/shavit-zones.sp index 49bcd398..0a42c5e5 100644 --- a/addons/sourcemod/scripting/shavit-zones.sp +++ b/addons/sourcemod/scripting/shavit-zones.sp @@ -2143,31 +2143,36 @@ void DrawZone(float points[8][3], int color[4], float life, float width, bool fl } } -// by blacky +// original by blacky // creates 3d box from 2 points void CreateZonePoints(float point[8][3], float offset = 0.0) { - float center[2]; - center[0] = ((point[0][0] + point[7][0]) / 2); - center[1] = ((point[0][1] + point[7][1]) / 2); - - for(int i = 0; i < 8; i++) + // calculate all zone edges + for(int i = 1; i < 7; i++) { for(int j = 0; j < 3; j++) { - if(i > 0 && i < 7) - { - point[i][j] = point[((i >> (2 - j)) & 1) * 7][j]; - } + point[i][j] = point[((i >> (2 - j)) & 1) * 7][j]; + } + } - if(offset != 0.0 && j < 2) + // apply beam offset + if(offset != 0.0) + { + float center[2]; + center[0] = ((point[0][0] + point[7][0]) / 2); + center[1] = ((point[0][1] + point[7][1]) / 2); + + for(int i = 0; i < 8; i++) + { + for(int j = 0; j < 2; j++) { if(point[i][j] < center[j]) { point[i][j] += offset; } - else + else if(point[i][j] > center[j]) { point[i][j] -= offset; } From 009c849a6c2b2680a4fc22cb1cad65f7e5a0fc70 Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 22 Jan 2018 18:50:31 +0200 Subject: [PATCH 16/38] Fixed !b and !bend for built in zones. (#582) --- addons/sourcemod/scripting/shavit-core.sp | 110 ++++++--------------- addons/sourcemod/scripting/shavit-zones.sp | 41 ++++---- 2 files changed, 54 insertions(+), 97 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index 69ef1e32..ad13bedd 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -251,13 +251,14 @@ public void OnPluginStart() RegConsoleCmd("sm_r", Command_StartTimer, "Start your timer."); RegConsoleCmd("sm_restart", Command_StartTimer, "Start your timer."); - RegConsoleCmd("sm_b", Command_StartTimer_Bonus, "Start your timer on the bonus track."); - RegConsoleCmd("sm_bonus", Command_StartTimer_Bonus, "Start your timer on the bonus track."); + RegConsoleCmd("sm_b", Command_StartTimer, "Start your timer on the bonus track."); + RegConsoleCmd("sm_bonus", Command_StartTimer, "Start your timer on the bonus track."); // teleport to end RegConsoleCmd("sm_end", Command_TeleportEnd, "Teleport to endzone."); - RegConsoleCmd("sm_bend", Command_TeleportEnd_Bonus, "Teleport to endzone of the bonus track."); - RegConsoleCmd("sm_bonusend", Command_TeleportEnd_Bonus, "Teleport to endzone of the bonus track."); + + RegConsoleCmd("sm_bend", Command_TeleportEnd, "Teleport to endzone of the bonus track."); + RegConsoleCmd("sm_bonusend", Command_TeleportEnd, "Teleport to endzone of the bonus track."); // timer stop RegConsoleCmd("sm_stop", Command_StopTimer, "Stop your timer."); @@ -438,70 +439,36 @@ public Action Command_StartTimer(int client, int args) return Plugin_Handled; } + char[] sCommand = new char[16]; + GetCmdArg(0, sCommand, 16); + if(!gB_Restart) { if(args != -1) { - char[] sCommand = new char[16]; - GetCmdArg(0, sCommand, 16); - Shavit_PrintToChat(client, "%T", "CommandDisabled", client, gS_ChatStrings[sMessageVariable], sCommand, gS_ChatStrings[sMessageText]); } return Plugin_Handled; } - if(gB_AllowTimerWithoutZone || (gB_Zones && (Shavit_ZoneExists(Zone_Start, Track_Main) || gB_KZMap))) + int track = Track_Main; + + if(StrContains(sCommand, "sm_b", false) == 0) + { + track = Track_Bonus; + } + + if(gB_AllowTimerWithoutZone || (gB_Zones && (Shavit_ZoneExists(Zone_Start, track) || gB_KZMap))) { Call_StartForward(gH_Forwards_OnRestart); Call_PushCell(client); - Call_PushCell(Track_Main); + Call_PushCell(track); Call_Finish(); if(gB_AllowTimerWithoutZone) { - StartTimer(client, Track_Main); - } - } - - else - { - Shavit_PrintToChat(client, "%T", "StartZoneUndefined", client, gS_ChatStrings[sMessageWarning], gS_ChatStrings[sMessageText]); - } - - return Plugin_Handled; -} - -public Action Command_StartTimer_Bonus(int client, int args) -{ - if(!IsValidClient(client)) - { - return Plugin_Handled; - } - - if(!gB_Restart) - { - if(args != -1) - { - char[] sCommand = new char[16]; - GetCmdArg(0, sCommand, 16); - - Shavit_PrintToChat(client, "%T", "CommandDisabled", client, gS_ChatStrings[sMessageVariable], sCommand, gS_ChatStrings[sMessageText]); - } - - return Plugin_Handled; - } - - if(gB_AllowTimerWithoutZone || (gB_Zones && (Shavit_ZoneExists(Zone_Start, Track_Bonus) || gB_KZMap))) - { - Call_StartForward(gH_Forwards_OnRestart); - Call_PushCell(client); - Call_PushCell(Track_Bonus); - Call_Finish(); - - if(gB_AllowTimerWithoutZone) - { - StartTimer(client, Track_Bonus); + StartTimer(client, track); } } @@ -520,38 +487,23 @@ public Action Command_TeleportEnd(int client, int args) return Plugin_Handled; } - if(gB_Zones && Shavit_ZoneExists(Zone_End, Track_Main)) + char[] sCommand = new char[16]; + GetCmdArg(0, sCommand, 16); + + int track = Track_Main; + + if(StrContains(sCommand, "sm_b", false) == 0) + { + track = Track_Bonus; + } + + if(gB_Zones && (Shavit_ZoneExists(Zone_End, track) || gB_KZMap)) { Shavit_StopTimer(client); Call_StartForward(gH_Forwards_OnEnd); Call_PushCell(client); - Call_PushCell(Track_Main); // sm_bend will be bonus end - Call_Finish(); - } - - else - { - Shavit_PrintToChat(client, "%T", "EndZoneUndefined", client, gS_ChatStrings[sMessageWarning], gS_ChatStrings[sMessageText]); - } - - return Plugin_Handled; -} - -public Action Command_TeleportEnd_Bonus(int client, int args) -{ - if(!IsValidClient(client)) - { - return Plugin_Handled; - } - - if(gB_Zones && Shavit_ZoneExists(Zone_End, Track_Bonus)) - { - Shavit_StopTimer(client); - - Call_StartForward(gH_Forwards_OnEnd); - Call_PushCell(client); - Call_PushCell(Track_Bonus); + Call_PushCell(track); Call_Finish(); } @@ -1005,7 +957,7 @@ public int Native_FinishMap(Handle handler, int numParams) { int client = GetNativeCell(1); - any snapshot[TIMERSNAPSHOT_SIZE]; + any[] snapshot = new any[TIMERSNAPSHOT_SIZE]; snapshot[bTimerEnabled] = gB_TimerEnabled[client]; snapshot[fStartTime] = gF_StartTime[client]; snapshot[fPauseStartTime] = gF_PauseStartTime[client]; diff --git a/addons/sourcemod/scripting/shavit-zones.sp b/addons/sourcemod/scripting/shavit-zones.sp index 0a42c5e5..9b0d53e5 100644 --- a/addons/sourcemod/scripting/shavit-zones.sp +++ b/addons/sourcemod/scripting/shavit-zones.sp @@ -88,7 +88,7 @@ float gV_WallSnap[MAXPLAYERS+1][3]; bool gB_Button[MAXPLAYERS+1]; bool gB_InsideZone[MAXPLAYERS+1][ZONETYPES_SIZE][TRACKS_SIZE]; bool gB_InsideZoneID[MAXPLAYERS+1][MAX_ZONES]; -float gF_CustomSpawn[TRACKS_SIZE][3]; +float gF_CustomSpawns[TRACKS_SIZE][2][3]; int gI_ZoneTrack[MAXPLAYERS+1]; int gI_ZoneDatabaseID[MAXPLAYERS+1]; @@ -667,18 +667,15 @@ public void Frame_HookTrigger(any data) gI_KZButtons[track][zone] = entity; Shavit_MarkKZMap(); - if(zone == Zone_Start) - { - float maxs[3]; - GetEntPropVector(entity, Prop_Send, "m_vecMaxs", maxs); + float maxs[3]; + GetEntPropVector(entity, Prop_Send, "m_vecMaxs", maxs); - float origin[3]; - GetEntPropVector(entity, Prop_Send, "m_vecOrigin", origin); + float origin[3]; + GetEntPropVector(entity, Prop_Send, "m_vecOrigin", origin); - origin[2] -= (maxs[2] - 2.0); // so you don't get stuck in the ground - - gF_CustomSpawn[track] = origin; - } + origin[2] -= (maxs[2] - 2.0); // so you don't get stuck in the ground + + gF_CustomSpawns[track][zone] = origin; for(int i = 1; i <= MaxClients; i++) { @@ -821,9 +818,9 @@ public void SQL_RefreshZones_Callback(Database db, DBResultSet results, const ch { int track = results.FetchInt(10); - gF_CustomSpawn[track][0] = results.FetchFloat(7); - gF_CustomSpawn[track][1] = results.FetchFloat(8); - gF_CustomSpawn[track][2] = results.FetchFloat(9); + gF_CustomSpawns[track][Zone_Start][0] = results.FetchFloat(7); + gF_CustomSpawns[track][Zone_Start][1] = results.FetchFloat(8); + gF_CustomSpawns[track][Zone_Start][2] = results.FetchFloat(9); } else @@ -933,7 +930,7 @@ public Action Command_AddSpawn(int client, int args) return Plugin_Handled; } - if(!EmptyVector(gF_CustomSpawn[Track_Main])) + if(!EmptyVector(gF_CustomSpawns[Track_Main][Zone_Start])) { Shavit_PrintToChat(client, "%T", "ZoneCustomSpawnExists", client); @@ -990,7 +987,8 @@ void ClearCustomSpawn() { for(int j = 0; j < 3; j++) { - gF_CustomSpawn[i][j] = 0.0; + gF_CustomSpawns[i][Zone_Start][j] = 0.0; + gF_CustomSpawns[i][Zone_End][j] = 0.0; } } } @@ -2345,9 +2343,9 @@ public void Shavit_OnRestart(int client, int track) { if(gB_TeleportToStart) { - if(!EmptyVector(gF_CustomSpawn[track])) + if(!EmptyVector(gF_CustomSpawns[track][Zone_Start])) { - TeleportEntity(client, gF_CustomSpawn[track], NULL_VECTOR, view_as({0.0, 0.0, 0.0})); + TeleportEntity(client, gF_CustomSpawns[track][Zone_Start], NULL_VECTOR, view_as({0.0, 0.0, 0.0})); } else if(Shavit_IsKZMap() && !EmptyVector(gF_ClimbButtonCache[client][track][0]) && !EmptyVector(gF_ClimbButtonCache[client][track][1])) @@ -2382,6 +2380,13 @@ public void Shavit_OnEnd(int client, int track) { if(gB_TeleportToEnd) { + if(!EmptyVector(gF_CustomSpawns[track][Zone_End])) + { + TeleportEntity(client, gF_CustomSpawns[track][Zone_End], NULL_VECTOR, view_as({0.0, 0.0, 0.0})); + + return; + } + int index = GetZoneIndex(Zone_End, track); if(index == -1) From 917fe7e68398bf1b40e41de10a03b568b29168f4 Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 22 Jan 2018 18:58:11 +0200 Subject: [PATCH 17/38] Fixed style changes not restarting with built in zones. (#582) --- addons/sourcemod/scripting/shavit-core.sp | 2 +- addons/sourcemod/scripting/shavit-misc.sp | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index ad13bedd..5168a5cf 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -760,7 +760,7 @@ void ChangeClientStyle(int client, int style, bool manual) StopTimer(client); - if(gB_AllowTimerWithoutZone || (gB_Zones && Shavit_ZoneExists(Zone_Start, Track_Main))) + if(gB_AllowTimerWithoutZone || (gB_Zones && (Shavit_ZoneExists(Zone_Start, gI_Track[client]) || gB_KZMap))) { Call_StartForward(gH_Forwards_OnRestart); Call_PushCell(client); diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index 8e6d9c02..c2f8c5b3 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -172,6 +172,7 @@ Handle gH_GetPlayerMaxSpeed = null; // modules bool gB_Rankings = false; bool gB_Replay = false; +bool gB_Zones = false; // timer settings char gS_StyleStrings[STYLE_LIMIT][STYLESTRINGS_SIZE][128]; @@ -391,6 +392,7 @@ public void OnPluginStart() // modules gB_Rankings = LibraryExists("shavit-rankings"); gB_Replay = LibraryExists("shavit-replay"); + gB_Zones = LibraryExists("shavit-zones"); } public void OnClientCookiesCached(int client) @@ -605,6 +607,11 @@ public void OnLibraryAdded(const char[] name) { gB_Replay = true; } + + else if(StrEqual(name, "shavit-zones")) + { + gB_Zones = true; + } } public void OnLibraryRemoved(const char[] name) @@ -618,6 +625,11 @@ public void OnLibraryRemoved(const char[] name) { gB_Replay = false; } + + else if(StrEqual(name, "shavit-zones")) + { + gB_Zones = false; + } } public Action Command_Jointeam(int client, const char[] command, int args) @@ -2071,7 +2083,7 @@ public Action Respawn(Handle Timer, DataPack pack) void RestartTimer(int client, int track) { - if(Shavit_ZoneExists(Zone_Start, track)) + if((gB_Zones && Shavit_ZoneExists(Zone_Start, track)) || Shavit_IsKZMap()) { Shavit_RestartTimer(client, track); } From adda10c3d4c4473963018edede87e31dbcda6b4e Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 22 Jan 2018 19:05:50 +0200 Subject: [PATCH 18/38] Fixed replay HUD not showing track properly. --- addons/sourcemod/scripting/shavit-hud.sp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-hud.sp b/addons/sourcemod/scripting/shavit-hud.sp index af7bae13..5ba33bea 100644 --- a/addons/sourcemod/scripting/shavit-hud.sp +++ b/addons/sourcemod/scripting/shavit-hud.sp @@ -679,7 +679,6 @@ void UpdateHUD(int client) { int track = Shavit_GetClientTrack(target); char[] sTrack = new char[32]; - GetTrackName(client, track, sTrack, 32); if(!IsFakeClient(target)) { @@ -731,6 +730,7 @@ void UpdateHUD(int client) if(track != Track_Main) { + GetTrackName(client, track, sTrack, 32); Format(sHintText, 512, "%s[%s] ", sHintText, sTrack); } @@ -834,12 +834,13 @@ void UpdateHUD(int client) if(track != Track_Main) { + GetTrackName(client, track, sTrack, 32); Format(sTrack, 32, "(%s) ", sTrack); } if(gEV_Type == Engine_CSGO) { - FormatEx(sHintText, 512, ""); + FormatEx(sHintText, 512, ""); Format(sHintText, 512, "%s\t%s %T", sHintText, gS_StyleStrings[style][sHTMLColor], gS_StyleStrings[style][sStyleName], "ReplayText", client); Format(sHintText, 512, "%s\n\t%T: %s / %s", sHintText, "HudTimeText", client, sReplayTime, sReplayLength); Format(sHintText, 512, "%s\n\t%T: %d", sHintText, "HudSpeedText", client, iSpeed); From ee8b85621c457060c261f3295d96d5ff7530654a Mon Sep 17 00:00:00 2001 From: shavit Date: Tue, 23 Jan 2018 05:22:32 +0200 Subject: [PATCH 19/38] Changed playertimes' structure for the billionth time.. See: https://github.com/shavitush/bhoptimer/wiki/4.2.-Extra:-Updating-(Database)/_compare/74d468c639a39518dcc9523e6e4aa4b3b5f14b04...40f21523f46029b270c92caf930bf441b270c83b Also, changed `style` and `track` to TINYINT. --- addons/sourcemod/scripting/shavit-wr.sp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-wr.sp b/addons/sourcemod/scripting/shavit-wr.sp index 9a93fb6d..dcfb7d81 100644 --- a/addons/sourcemod/scripting/shavit-wr.sp +++ b/addons/sourcemod/scripting/shavit-wr.sp @@ -1880,12 +1880,12 @@ void SQL_DBConnect() 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` INT, `date` CHAR(16), `strafes` INT, `sync` FLOAT, `points` FLOAT NOT NULL DEFAULT 0, `track` INT NOT NULL DEFAULT 0, PRIMARY KEY (`id`), INDEX `auth` (`auth`, `map`, `time`, `style`, `date`, `points`, `track`)) 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, PRIMARY KEY (`id`), INDEX `map` (`map`, `style`, `track`), INDEX `auth` (`auth`, `date`, `points`), INDEX `time` (`time`)) ENGINE=INNODB;", gS_MySQLPrefix); } 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` INT, `date` CHAR(16), `strafes` INT, `sync` FLOAT, `points` FLOAT NOT NULL DEFAULT 0, `track` INT 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);", gS_MySQLPrefix); } gH_SQL.Query(SQL_CreateTable_Callback, sQuery, 0, DBPrio_High); From 3a0f133da22e399d8692727a5d7612b3efb7d914 Mon Sep 17 00:00:00 2001 From: shavit Date: Tue, 23 Jan 2018 05:25:09 +0200 Subject: [PATCH 20/38] Tweaked points calculation format with a stored function. (#586) Big thanks to Deathknife~ * There's no bonus points for a bigger amount of records, due to necessary optimizations. * Added `GetRecordPoints`. * `sm_recalcall` should run *very* quickly now. --- addons/sourcemod/scripting/shavit-rankings.sp | 205 ++++++++---------- 1 file changed, 94 insertions(+), 111 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-rankings.sp b/addons/sourcemod/scripting/shavit-rankings.sp index 19f1e744..618d1134 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -19,8 +19,8 @@ */ // Design idea: -// Rank 1 per map/style/track gets ((points per tier * tier) * 1.5) + ((amount of records * (tier / 10.0) * 0.25)) + (rank 1 time in seconds / 15.0) points. -// Records below rank 1 get points% relative to their time in comparison to rank 1 and a final multiplier of 0.85% to promote rank 1 hunting. +// Rank 1 per map/style/track gets ((points per tier * tier) * 1.5) + (rank 1 time in seconds / 15.0) points. +// Records below rank 1 get points% relative to their time in comparison to rank 1 and a final multiplier of 85% to promote rank 1 hunting. // // Bonus track gets a 0.25* final mutliplier for points and is treated as tier 1. // @@ -68,7 +68,6 @@ float gF_PointsPerTier = 50.0; int gI_Rank[MAXPLAYERS+1]; float gF_Points[MAXPLAYERS+1]; -int gI_Progress[MAXPLAYERS+1]; int gI_RankedPlayers = 0; Menu gH_Top100Menu = null; @@ -82,7 +81,6 @@ char gS_TrackNames[TRACKS_SIZE][32]; any gA_StyleSettings[STYLE_LIMIT][STYLESETTINGS_SIZE]; int gI_Styles = 0; -int gI_RankedStyles = 0; public Plugin myinfo = { @@ -179,17 +177,10 @@ public void Shavit_OnStyleConfigLoaded(int styles) gI_Styles = Shavit_GetStyleCount(); } - gI_RankedStyles = 0; - for(int i = 0; i < gI_Styles; i++) { Shavit_GetStyleSettings(i, gA_StyleSettings[i]); Shavit_GetStyleStrings(i, sStyleName, gS_StyleNames[i], 64); - - if(!gA_StyleSettings[i][bUnranked]) - { - gI_RankedStyles++; - } } } @@ -305,9 +296,11 @@ public void SQL_CreateTable_Callback(Database db, DBResultSet results, const cha SQL_FastQuery(gH_SQL, "DELIMITER ;;"); SQL_FastQuery(gH_SQL, "DROP PROCEDURE IF EXISTS UpdateAllPoints;;"); // old (and very slow) deprecated method SQL_FastQuery(gH_SQL, "DROP FUNCTION IF EXISTS GetWeightedPoints;;"); // this is here, just in case we ever choose to modify or optimize the calculation + SQL_FastQuery(gH_SQL, "DROP FUNCTION IF EXISTS GetRecordPoints;;"); - char[] sQuery = new char[1024]; - FormatEx(sQuery, 1024, + bool bSuccess = true; + + RunLongFastQuery(bSuccess, "CREATE GetWeightedPoints", "CREATE FUNCTION GetWeightedPoints(authid CHAR(32)) " ... "RETURNS FLOAT " ... "BEGIN " ... @@ -330,20 +323,21 @@ public void SQL_CreateTable_Callback(Database db, DBResultSet results, const cha "RETURN total; " ... "END;;", gS_MySQLPrefix); - #if defined DEBUG - LogError("%s", sQuery); - #endif - - bool bSuccess = true; - - if(!SQL_FastQuery(gH_SQL, sQuery)) - { - char[] sError = new char[255]; - SQL_GetError(gH_SQL, sError, 255); - LogError("Timer (rankings, create GetWeightedPoints function) error! Reason: %s", sError); - - bSuccess = false; - } + RunLongFastQuery(bSuccess, "CREATE GetRecordPoints", + "CREATE FUNCTION GetRecordPoints(rstyle INT, rtrack INT, rtime FLOAT, rmap CHAR(128), pointspertier FLOAT, stylemultiplier FLOAT) " ... + "RETURNS FLOAT " ... + "BEGIN " ... + "DECLARE pwr, ppoints FLOAT DEFAULT 0.0; " ... + "DECLARE ptier INT DEFAULT 1; " ... + "SELECT tier FROM %smaptiers WHERE map = rmap INTO ptier; " ... + "SELECT MIN(time) FROM %splayertimes WHERE map = rmap AND style = rstyle AND track = rtrack INTO pwr; " ... + "IF rtrack > 0 THEN SET ptier = 1; END IF; " ... + "SET ppoints = ((pointspertier * ptier) * 1.5) + (pwr / 15.0); " ... + "IF rtime > pwr THEN SET ppoints = ppoints * (pwr / rtime); END IF; " ... + "SET ppoints = ppoints * stylemultiplier; " ... + "IF rtrack > 0 THEN SET ppoints = ppoints * 0.25; END IF; " ... + "RETURN ppoints; " ... + "END;;", gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix); SQL_FastQuery(gH_SQL, "DELIMITER ;"); SQL_UnlockDatabase(gH_SQL); @@ -364,6 +358,21 @@ public void SQL_CreateTable_Callback(Database db, DBResultSet results, const cha } } +void RunLongFastQuery(bool &success, const char[] func, const char[] query, any ...) +{ + char[] sQuery = new char[2048]; + VFormat(sQuery, 2048, query, 4); + + if(!SQL_FastQuery(gH_SQL, sQuery)) + { + char[] sError = new char[255]; + SQL_GetError(gH_SQL, sError, 255); + LogError("Timer (rankings, %s) error! Reason: %s", func, sError); + + success = false; + } +} + public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue) { gF_PointsPerTier = gCV_PointsPerTier.FloatValue; @@ -437,7 +446,7 @@ public void SQL_GetMapTier_Callback(Database db, DBResultSet results, const char PrintToServer("DEBUG: 3 (tier: %d) (SQL_GetMapTier_Callback)", gI_Tier); #endif - RecalculateAll(gS_Map, gI_Tier); + RecalculateAll(gS_Map); UpdateAllPoints(); #if defined DEBUG @@ -515,7 +524,7 @@ void GuessBestMapName(const char[] input, char[] output, int size) public void OnMapEnd() { - RecalculateAll(gS_Map, gI_Tier); + RecalculateAll(gS_Map); } public Action Command_Tier(int client, int args) @@ -624,7 +633,7 @@ public Action Command_SetTier(int client, int args) char[] sQuery = new char[256]; FormatEx(sQuery, 256, "REPLACE INTO %smaptiers (map, tier) VALUES ('%s', %d);", gS_MySQLPrefix, gS_Map, tier); - gH_SQL.Query(SQL_SetMapTier_Callback, sQuery, tier, DBPrio_Low); + gH_SQL.Query(SQL_SetMapTier_Callback, sQuery); return Plugin_Handled; } @@ -638,12 +647,12 @@ public void SQL_SetMapTier_Callback(Database db, DBResultSet results, const char return; } - RecalculateAll(gS_Map, data); + RecalculateAll(gS_Map); } public Action Command_RecalcMap(int client, int args) { - RecalculateAll(gS_Map, gI_Tier); + RecalculateAll(gS_Map); UpdateAllPoints(); ReplyToCommand(client, "Done."); @@ -653,33 +662,63 @@ public Action Command_RecalcMap(int client, int args) public Action Command_RecalcAll(int client, int args) { - ReplyToCommand(client, "Check your console for information.\nDatabase related queries might not work until this is done."); - ReplyToCommand(client, "- [0.0%%] Started recalculating points for all maps."); + ReplyToCommand(client, "- Started recalculating points for all maps. Check console for output."); - gI_Progress[client] = 0; + Transaction trans = new Transaction(); - int serial = (client == 0)? 0:GetClientSerial(client); - int size = gA_ValidMaps.Length; - - for(int i = 0; i < size; i++) + for(int i = 0; i < gI_Styles; i++) { - char[] sMap = new char[160]; - gA_ValidMaps.GetString(i, sMap, 160); + char[] sQuery = new char[192]; - int tier = 1; - gA_MapTiers.GetValue(sMap, tier); + if(gA_StyleSettings[i][bUnranked] || view_as(gA_StyleSettings[i][fRankingMultiplier]) == 0.0) + { + FormatEx(sQuery, 192, "UPDATE %splayertimes SET points = 0 WHERE style = %d;", gS_MySQLPrefix, i); + } - RecalculateAll(sMap, tier, serial, true); + else + { + FormatEx(sQuery, 192, "UPDATE %splayertimes SET points = GetRecordPoints(%d, track, time, map, %.1f, %.3f) WHERE style = %d;", gS_MySQLPrefix, i, gF_PointsPerTier, view_as(gA_StyleSettings[i][fRankingMultiplier]), i); + } - #if defined DEBUG - PrintToConsole(client, "size: %d | %d | %s", size, i, sMap); - #endif + trans.AddQuery(sQuery); } + gH_SQL.Execute(trans, Trans_OnRecalcSuccess, Trans_OnRecalcFail, (client == 0)? 0:GetClientSerial(client)); + return Plugin_Handled; } -void RecalculateAll(const char[] map, const int tier, int serial = 0, bool print = false) +public void Trans_OnRecalcSuccess(Database db, any data, int numQueries, DBResultSet[] results, any[] queryData) +{ + int client = (data == 0)? 0:GetClientFromSerial(data); + + if(client != 0) + { + SetCmdReplySource(SM_REPLY_TO_CONSOLE); + } + + ReplyToCommand(client, "- Finished recalculating all points. Recalculating user points, top 100 and user cache."); + + UpdateAllPoints(); + UpdateTop100(); + + for(int i = 1; i <= MaxClients; i++) + { + if(IsClientInGame(i) && IsClientAuthorized(i)) + { + UpdatePlayerRank(i); + } + } + + ReplyToCommand(client, "- Done."); +} + +public void Trans_OnRecalcFail(Database db, any data, int numQueries, const char[] error, int failIndex, any[] queryData) +{ + LogError("Timer (rankings) error! Recalculation failed. Reason: %s", error); +} + +void RecalculateAll(const char[] map) { #if defined DEBUG LogError("DEBUG: 5 (RecalculateAll)"); @@ -694,55 +733,26 @@ void RecalculateAll(const char[] map, const int tier, int serial = 0, bool print continue; } - RecalculateMap(map, i, j, tier, serial, print); + RecalculateMap(map, i, j); } } } public void Shavit_OnFinish_Post(int client, int style, float time, int jumps, int strafes, float sync, int rank, int overwrite, int track) { - RecalculateMap(gS_Map, track, style, gI_Tier); + RecalculateMap(gS_Map, track, style); } -void RecalculateMap(const char[] map, const int track, const int style, const int tier, int serial = -1, bool print = false) +void RecalculateMap(const char[] map, const int track, const int style) { #if defined DEBUG - PrintToServer("Recalculating points. (%s, %d, %d, %d)", map, track, style, tier); + PrintToServer("Recalculating points. (%s, %d, %d)", map, track, style); #endif - char[] sQuery = new char[2048]; - FormatEx(sQuery, 2048, "UPDATE %splayertimes t LEFT JOIN " ... - "(SELECT MIN(time) mintime, MAP, track, style FROM %splayertimes GROUP BY MAP, track, style) minjoin " ... - "ON t.time = minjoin.mintime AND t.MAP = minjoin.MAP AND t.track = minjoin.track AND t.style = minjoin.style " ... - "JOIN (SELECT ((%.01f * %d) * 1.5) points) best " ... - "JOIN (SELECT (COUNT(*) * (%d / 10.0)) points, MAP, track, style FROM %splayertimes GROUP BY MAP, track, style) additive " ... - "ON t.MAP = additive.MAP AND t.track = additive.track AND t.style = additive.style " ... - "JOIN (SELECT MIN(time) lowest, (MIN(time) / 15.0) points, MAP, track, style FROM %splayertimes GROUP BY MAP, track, style) FINAL " ... - "ON t.MAP = FINAL.MAP AND t.track = FINAL.track AND t.style = FINAL.style JOIN (SELECT (%.03f) style, (%.03f) track) multipliers " ... + char[] sQuery = new char[192]; + FormatEx(sQuery, 192, "UPDATE %splayertimes SET points = GetRecordPoints(%d, %d, time, '%s', %.1f, %.3f) WHERE style = %d AND track = %d AND map = '%s';", gS_MySQLPrefix, style, track, map, gF_PointsPerTier, gA_StyleSettings[style][fRankingMultiplier], style, track, map); - "SET t.points = (CASE " ... - "WHEN minjoin.mintime IS NOT NULL THEN (((best.points + additive.points + FINAL.points) * multipliers.style) * multipliers.track) " ... - "ELSE (((((best.points + additive.points + FINAL.points) * multipliers.style) * multipliers.track) * (FINAL.lowest / t.time)) * 0.85) " ... - "END) " ... - - "WHERE t.MAP = '%s' " ... - "AND t.track = %d " ... - "AND t.style = %d;", - gS_MySQLPrefix, gS_MySQLPrefix, - gF_PointsPerTier, (track == Track_Main)? tier:1, (track == Track_Main)? tier:1, - gS_MySQLPrefix, gS_MySQLPrefix, - gA_StyleSettings[style][fRankingMultiplier], (track == Track_Main)? 1.0:0.25, - map, track, style); - - DataPack pack = new DataPack(); - pack.WriteCell(serial); - pack.WriteCell(strlen(map)); - pack.WriteString(map); - pack.WriteCell(track); - pack.WriteCell(style); - pack.WriteCell(print); - - gH_SQL.Query(SQL_Recalculate_Callback, sQuery, pack, DBPrio_High); + gH_SQL.Query(SQL_Recalculate_Callback, sQuery, 0, DBPrio_High); #if defined DEBUG PrintToServer("Sent query."); @@ -751,18 +761,6 @@ void RecalculateMap(const char[] map, const int track, const int style, const in public void SQL_Recalculate_Callback(Database db, DBResultSet results, const char[] error, DataPack data) { - data.Reset(); - int serial = data.ReadCell(); - int size = data.ReadCell(); - - char[] sMap = new char[size+1]; - data.ReadString(sMap, size+1); - - int track = data.ReadCell(); - int style = data.ReadCell(); - bool print = view_as(data.ReadCell()); - delete data; - if(results == null) { LogError("Timer (rankings, recalculate map points) error! Reason: %s", error); @@ -770,21 +768,6 @@ public void SQL_Recalculate_Callback(Database db, DBResultSet results, const cha return; } - if(print && serial != -1) - { - int client = (serial == 0)? 0:GetClientFromSerial(serial); - - if(serial != 0 && client == 0) - { - return; - } - - int max = ((gA_ValidMaps.Length * TRACKS_SIZE) * gI_RankedStyles); - float current = ((float(++gI_Progress[client]) / max) * 100.0); - - PrintToConsole(client, "- [%.01f%%] Recalculated \"%s\" (%s | %s).", current, sMap, gS_TrackNames[track], gS_StyleNames[style]); - } - #if defined DEBUG PrintToServer("Recalculated."); #endif From 132d3d80e29db03fb479bb2ebd7fc24e67df6792 Mon Sep 17 00:00:00 2001 From: shavit Date: Thu, 25 Jan 2018 01:18:13 +0200 Subject: [PATCH 21/38] Hacky fix for autorespawn. L 01/24/2018 - 08:49:06: Info (map "bhop_forest") (file "errors_20180124.log") L 01/24/2018 - 08:49:06: [SM] Exception reported: Invalid data pack handle 11503 (error 4) L 01/24/2018 - 08:49:06: [SM] Blaming: shavit-misc.smx L 01/24/2018 - 08:49:06: [SM] Call stack trace: L 01/24/2018 - 08:49:06: [SM] [0] DataPack.Reset L 01/24/2018 - 08:49:06: [SM] [1] Line 2059, E:\git\bhoptimer\addons\sourcemod\scripting\shavit-misc.sp::Respawn --- addons/sourcemod/scripting/shavit-misc.sp | 28 +++++++++++++++---- addons/sourcemod/scripting/shavit-rankings.sp | 2 +- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index c2f8c5b3..d601a0fd 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -2047,18 +2047,34 @@ public void Shavit_OnRestart(int client, int track) } } - DataPack pack = null; - CreateDataTimer(0.1, Respawn, pack, TIMER_FLAG_NO_MAPCHANGE); + DataPack pack = new DataPack(); pack.WriteCell(GetClientSerial(client)); pack.WriteCell(track); + view_as(pack) |= (1 << 24); + + CreateTimer(0.1, Respawn, pack, TIMER_FLAG_NO_MAPCHANGE); } } -public Action Respawn(Handle Timer, DataPack pack) +public Action Respawn(Handle Timer, any data) { - pack.Reset(); - int client = GetClientFromSerial(pack.ReadCell()); - int track = pack.ReadCell(); + int track = Track_Main; + int client = 0; + + if(data & (1 << 24) > 0) + { + data &= ~(1 << 24); + DataPack pack = data; + pack.Reset(); + client = GetClientFromSerial(pack.ReadCell()); + track = pack.ReadCell(); + delete pack; + } + + else + { + client = GetClientFromSerial(data); + } if(IsValidClient(client) && !IsPlayerAlive(client) && GetClientTeam(client) >= 2) { diff --git a/addons/sourcemod/scripting/shavit-rankings.sp b/addons/sourcemod/scripting/shavit-rankings.sp index 618d1134..d7fed7d3 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -20,7 +20,7 @@ // Design idea: // Rank 1 per map/style/track gets ((points per tier * tier) * 1.5) + (rank 1 time in seconds / 15.0) points. -// Records below rank 1 get points% relative to their time in comparison to rank 1 and a final multiplier of 85% to promote rank 1 hunting. +// Records below rank 1 get points% relative to their time in comparison to rank 1. // // Bonus track gets a 0.25* final mutliplier for points and is treated as tier 1. // From 1eda6a2616cc20d346d3381ac9749283ed2a76c0 Mon Sep 17 00:00:00 2001 From: shavit Date: Thu, 25 Jan 2018 01:45:02 +0200 Subject: [PATCH 22/38] just pretend that the previous commit never existed --- addons/sourcemod/scripting/shavit-misc.sp | 48 +++++++++-------------- 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index d601a0fd..813af94f 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -515,7 +515,7 @@ public void OnMapStart() GetCurrentMap(gS_CurrentMap, 192); GetMapDisplayName(gS_CurrentMap, gS_CurrentMap, 192); - if(gI_CreateSpawnPoints > 0) + if(gI_CreateSpawnPoints > 0 && gEV_Type != Engine_TF2) { int iEntity = -1; float fOrigin[3]; @@ -1008,11 +1008,7 @@ public void OnClientPutInServer(int client) gB_SaveStates[client] = false; - if(gA_SaveFrames[client] != null) - { - delete gA_SaveFrames[client]; - gA_SaveFrames[client] = null; - } + delete gA_SaveFrames[client]; } public void OnClientDisconnect(int client) @@ -1914,7 +1910,7 @@ public Action Command_Specs(int client, int args) iObserverTarget = iNewTarget; } - int iCount; + int iCount = 0; char[] sSpecs = new char[192]; for(int i = 1; i <= MaxClients; i++) @@ -2047,34 +2043,26 @@ public void Shavit_OnRestart(int client, int track) } } - DataPack pack = new DataPack(); - pack.WriteCell(GetClientSerial(client)); - pack.WriteCell(track); - view_as(pack) |= (1 << 24); + if(gEV_Type == Engine_TF2) + { + TF2_RespawnPlayer(client); + } - CreateTimer(0.1, Respawn, pack, TIMER_FLAG_NO_MAPCHANGE); + else + { + CS_RespawnPlayer(client); + } + + if(gB_RespawnOnRestart) + { + RestartTimer(client, track); + } } } public Action Respawn(Handle Timer, any data) { - int track = Track_Main; - int client = 0; - - if(data & (1 << 24) > 0) - { - data &= ~(1 << 24); - DataPack pack = data; - pack.Reset(); - client = GetClientFromSerial(pack.ReadCell()); - track = pack.ReadCell(); - delete pack; - } - - else - { - client = GetClientFromSerial(data); - } + int client = GetClientFromSerial(data); if(IsValidClient(client) && !IsPlayerAlive(client) && GetClientTeam(client) >= 2) { @@ -2090,7 +2078,7 @@ public Action Respawn(Handle Timer, any data) if(gB_RespawnOnRestart) { - RestartTimer(client, track); + RestartTimer(client, Track_Main); } } From 008f60f248e6c99d019db6e0d44a082bc5218e5d Mon Sep 17 00:00:00 2001 From: shavit Date: Fri, 26 Jan 2018 04:59:07 +0200 Subject: [PATCH 23/38] Updated Travis to use SM 1.9. --- .travis.yml | 6 +----- README.md | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8332bdb4..e3de1b47 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,3 @@ -# i have no idea AT ALL on how to use travis, -# stolen from splewis: https://raw.githubusercontent.com/splewis/csgo-pug-setup/master/.travis.yml -# i'll fail anyways, right? :( sudo: false addons: @@ -8,7 +5,7 @@ addons: - lib32stdc++6 # needed for spcomp env: - - SMVERSION=1.8 + - SMVERSION=1.9 before_script: # install smbuilder @@ -26,7 +23,6 @@ before_script: - chmod +x spcomp - PATH+=":$PWD" - # - cp ../../../scripting/include/* include/ # i don't think this is necessary anymore - cd ../../.. script: diff --git a/README.md b/README.md index e80f9762..2ab498f5 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,10 @@ Including a records system, map zones (start/end marks etc), bonuses, HUD with u # Requirements: * Steam version of Counter-Strike: Source or Counter-Strike: Global Offensive. -* [SourceMod 1.8 or above](http://www.sourcemod.net/downloads.php) +* [SourceMod 1.9 or above](http://www.sourcemod.net/downloads.php) # Optional requirements: -* [DHooks](http://users.alliedmods.net/~drifter/builds/dhooks/2.0/) - required for 250/260 runspeed for all weapons. +* [DHooks](http://users.alliedmods.net/~drifter/builds/dhooks/2.1/) - required for 250/260 runspeed for all weapons. * [Bunnyhop Statistics](https://forums.alliedmods.net/showthread.php?t=286135) - to show amount of scrolls for non-auto styles in the key display. Required for TF2 servers. * [SteamWorks](https://forums.alliedmods.net/showthread.php?t=229556) - for the `{serverip}` advertisement variable. * [Chat-Processor](https://github.com/Drixevel/Chat-Processor) - if you're enabling the `shavit-chat` module. From d7f9ed3186de1f68a714925999fc0fb24bbbb753 Mon Sep 17 00:00:00 2001 From: shavit Date: Fri, 26 Jan 2018 05:56:24 +0200 Subject: [PATCH 24/38] Remove custom `IsNullVector` function. --- addons/sourcemod/scripting/shavit-misc.sp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index 813af94f..91040fd5 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -2522,10 +2522,3 @@ void CopyArray(const any[] from, any[] to, int size) to[i] = from[i]; } } - -#if SOURCEMOD_V_MAJOR == 1 && SOURCEMOD_V_MINOR < 9 -bool IsNullVector(float vec[3]) -{ - return (vec[0] == NULL_VECTOR[0] && vec[1] == NULL_VECTOR[1] && vec[2] == NULL_VECTOR[2]); -} -#endif \ No newline at end of file From a4bcaa6fcf9a3581d0f72ff4a58cbd2d32fd2ae9 Mon Sep 17 00:00:00 2001 From: shavit Date: Fri, 26 Jan 2018 05:56:57 +0200 Subject: [PATCH 25/38] Show time in CS:S while paused. --- addons/sourcemod/scripting/shavit-hud.sp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-hud.sp b/addons/sourcemod/scripting/shavit-hud.sp index 5ba33bea..2b85124c 100644 --- a/addons/sourcemod/scripting/shavit-hud.sp +++ b/addons/sourcemod/scripting/shavit-hud.sp @@ -772,22 +772,19 @@ void UpdateHUD(int client) { if(status != Timer_Stopped) { - if(Shavit_GetTimerStatus(target) == Timer_Running) + char[] sFirstLine = new char[64]; + strcopy(sFirstLine, 64, gS_StyleStrings[style][sStyleName]); + + if(Shavit_IsPracticeMode(target)) { - char[] sFirstLine = new char[64]; - strcopy(sFirstLine, 64, gS_StyleStrings[style][sStyleName]); - - if(Shavit_IsPracticeMode(target)) - { - Format(sFirstLine, 64, "%s %T", sFirstLine, "HudPracticeMode", client); - } - - FormatEx(sHintText, 512, "%s\n%T: %s (%d)\n%T: %d\n%T: %d\n%T: %d%s", sFirstLine, "HudTimeText", client, sTime, rank, "HudJumpsText", client, jumps, "HudStrafeText", client, strafes, "HudSpeedText", client, iSpeed, (gA_StyleSettings[style][fVelocityLimit] > 0.0 && Shavit_InsideZone(target, Zone_NoVelLimit, -1))? "\nNo Speed Limit":""); + Format(sFirstLine, 64, "%s %T", sFirstLine, "HudPracticeMode", client); } - else + FormatEx(sHintText, 512, "%s\n%T: %s (%d)\n%T: %d\n%T: %d\n%T: %d%s", sFirstLine, "HudTimeText", client, sTime, rank, "HudJumpsText", client, jumps, "HudStrafeText", client, strafes, "HudSpeedText", client, iSpeed, (gA_StyleSettings[style][fVelocityLimit] > 0.0 && Shavit_InsideZone(target, Zone_NoVelLimit, -1))? "\nNo Speed Limit":""); + + if(Shavit_GetTimerStatus(target) == Timer_Paused) { - FormatEx(sHintText, 16, "%T", "HudPaused", client); + Format(sHintText, 512, "%s\n%T", sHintText, "HudPaused", client); } if(track != Track_Main) From dda1afa0e71dd2dcd677cdca521312191ddbda76 Mon Sep 17 00:00:00 2001 From: shavit Date: Fri, 26 Jan 2018 05:57:09 +0200 Subject: [PATCH 26/38] Fix RTL chat messages being colored randomly. --- addons/sourcemod/scripting/shavit-chat.sp | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/sourcemod/scripting/shavit-chat.sp b/addons/sourcemod/scripting/shavit-chat.sp index be6e4523..5affd318 100644 --- a/addons/sourcemod/scripting/shavit-chat.sp +++ b/addons/sourcemod/scripting/shavit-chat.sp @@ -363,6 +363,7 @@ public Action CP_OnChatMessage(int &author, ArrayList recipients, char[] flagstr // proper colors with rtler if(gB_RTLer && RTLify(sTemp, MAXLENGTH_MESSAGE, message) > 0) { + TrimString(message); Format(message, MAXLENGTH_MESSAGE, "%s%s", message, gS_CustomMessage[author]); } From 53456ffe38b21c47a0aee8287dc9dfbdc07073cd Mon Sep 17 00:00:00 2001 From: shavit Date: Fri, 26 Jan 2018 05:58:53 +0200 Subject: [PATCH 27/38] Implemented `GetGameFrameTime` usage. (#440) * Made pausing better. * Added `Shavit_OnTimeIncrement` and `Shavit_OnTimeIncrementPost`. Use this for proper timescaling/save state usage. --- addons/sourcemod/scripting/include/shavit.inc | 29 +++- addons/sourcemod/scripting/shavit-core.sp | 139 +++++++++++------- 2 files changed, 108 insertions(+), 60 deletions(-) diff --git a/addons/sourcemod/scripting/include/shavit.inc b/addons/sourcemod/scripting/include/shavit.inc index 12153ac2..bd60f76c 100644 --- a/addons/sourcemod/scripting/include/shavit.inc +++ b/addons/sourcemod/scripting/include/shavit.inc @@ -134,10 +134,7 @@ enum enum { bTimerEnabled, - fStartTime, fCurrentTime, - fPauseStartTime, - fPauseTotalTime, bClientPaused, iJumps, bsStyle, @@ -304,6 +301,32 @@ stock void FormatSeconds(float time, char[] newtime, int newtimesize, bool preci */ forward Action Shavit_OnUserCmdPre(int client, int &buttons, int &impulse, float vel[3], float angles[3], TimerStatus status, int track, int style, any stylesettings[STYLESETTINGS_SIZE]); +/** + * Called just before shavit-core adds time to a player's timer. + * This is the forward you should use to modify the player's timer smoothly. + * A good example use case is timescaling. + * + * @param client Client index. + * @param snapshot A snapshot with the player's current timer. You cannot manipulate it here. + * @param time The time to be added to the player's timer. + * @param stylesettings An array that contains the player's bhop style's settings. + * @noreturn + */ +forward void Shavit_OnTimeIncrement(int client, any snapshot[TIMERSNAPSHOT_SIZE], float &time, any stylesettings[STYLESETTINGS_SIZE]); + +/** + * Called just before shavit-core adds time to a player's timer. + * This is the forward you should use to modify the player's timer smoothly. + * A good example use case is timescaling. + * + * @param client Client index. + * @param snapshot A snapshot with the player's current timer. Read above in shavit.inc for more information. + * @param time The time to be added to the player's timer. + * @param stylesettings An array that contains the player's bhop style's settings. + * @noreturn + */ +forward void Shavit_OnTimeIncrementPost(int client, float time, any stylesettings[STYLESETTINGS_SIZE]); + /** * Called when a player's timer starts. * (WARNING: Will be called every tick when the player stands at the start zone!) diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index 5168a5cf..194d9b2d 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -58,12 +58,13 @@ Handle gH_Forwards_OnStyleConfigLoaded = null; Handle gH_Forwards_OnDatabaseLoaded = null; Handle gH_Forwards_OnChatConfigLoaded = null; Handle gH_Forwards_OnUserCmdPre = null; +Handle gH_Forwards_OnTimerIncrement = null; +Handle gH_Forwards_OnTimerIncrementPost = null; // timer variables bool gB_TimerEnabled[MAXPLAYERS+1]; -float gF_StartTime[MAXPLAYERS+1]; -float gF_PauseStartTime[MAXPLAYERS+1]; -float gF_PauseTotalTime[MAXPLAYERS+1]; +float gF_PlayerTimer[MAXPLAYERS+1]; +float gF_PausePosition[MAXPLAYERS+1][3][3]; bool gB_ClientPaused[MAXPLAYERS+1]; int gI_Jumps[MAXPLAYERS+1]; int gBS_Style[MAXPLAYERS+1]; @@ -203,6 +204,8 @@ public void OnPluginStart() gH_Forwards_OnDatabaseLoaded = CreateGlobalForward("Shavit_OnDatabaseLoaded", ET_Event); gH_Forwards_OnChatConfigLoaded = CreateGlobalForward("Shavit_OnChatConfigLoaded", ET_Event); gH_Forwards_OnUserCmdPre = CreateGlobalForward("Shavit_OnUserCmdPre", ET_Event, Param_Cell, Param_CellByRef, Param_CellByRef, Param_Array, Param_Array, Param_Cell, Param_Cell, Param_Cell, Param_Array); + gH_Forwards_OnTimerIncrement = CreateGlobalForward("Shavit_OnTimeIncrement", ET_Event, Param_Cell, Param_Array, Param_CellByRef, Param_Array); + gH_Forwards_OnTimerIncrementPost = CreateGlobalForward("Shavit_OnTimeIncrementPost", ET_Event, Param_Cell, Param_Cell, Param_Array); LoadTranslations("shavit-core.phrases"); @@ -567,13 +570,20 @@ public Action Command_TogglePause(int client, int args) if(gB_ClientPaused[client]) { + TeleportEntity(client, gF_PausePosition[client][0], gF_PausePosition[client][1], gF_PausePosition[client][2]); ResumeTimer(client); + Shavit_PrintToChat(client, "%T", "MessageUnpause", client, gS_ChatStrings[sMessageText], gS_ChatStrings[sMessageWarning], gS_ChatStrings[sMessageText]); } else { + GetClientAbsOrigin(client, gF_PausePosition[client][0]); + GetClientEyeAngles(client, gF_PausePosition[client][1]); + GetEntPropVector(client, Prop_Data, "m_vecAbsVelocity", gF_PausePosition[client][2]); + PauseTimer(client); + Shavit_PrintToChat(client, "%T", "MessagePause", client, gS_ChatStrings[sMessageText], gS_ChatStrings[sMessageWarning], gS_ChatStrings[sMessageText]); } @@ -899,8 +909,7 @@ public int Native_GetTimer(Handle handler, int numParams) int client = GetNativeCell(1); // 2 - time - float time = CalculateTime(client); - SetNativeCellRef(2, time); + SetNativeCellRef(2, gF_PlayerTimer[client]); SetNativeCellRef(3, gI_Jumps[client]); SetNativeCellRef(4, gBS_Style[client]); SetNativeCellRef(5, gB_TimerEnabled[client]); @@ -908,7 +917,7 @@ public int Native_GetTimer(Handle handler, int numParams) public int Native_GetClientTime(Handle handler, int numParams) { - return view_as(CalculateTime(GetNativeCell(1))); + return view_as(gF_PlayerTimer[GetNativeCell(1)]); } public int Native_GetClientTrack(Handle handler, int numParams) @@ -959,9 +968,6 @@ public int Native_FinishMap(Handle handler, int numParams) any[] snapshot = new any[TIMERSNAPSHOT_SIZE]; snapshot[bTimerEnabled] = gB_TimerEnabled[client]; - snapshot[fStartTime] = gF_StartTime[client]; - snapshot[fPauseStartTime] = gF_PauseStartTime[client]; - snapshot[fPauseTotalTime] = gF_PauseTotalTime[client]; snapshot[bClientPaused] = gB_ClientPaused[client]; snapshot[iJumps] = gI_Jumps[client]; snapshot[bsStyle] = gBS_Style[client]; @@ -969,7 +975,7 @@ public int Native_FinishMap(Handle handler, int numParams) snapshot[iTotalMeasures] = gI_TotalMeasures[client]; snapshot[iGoodGains] = gI_GoodGains[client]; snapshot[fServerTime] = GetEngineTime(); - snapshot[fCurrentTime] = CalculateTime(client); + snapshot[fCurrentTime] = gF_PlayerTimer[client]; snapshot[iSHSWCombination] = gI_SHSW_FirstCombination[client]; snapshot[iTimerTrack] = gI_Track[client]; @@ -993,7 +999,7 @@ public int Native_FinishMap(Handle handler, int numParams) if(result == Plugin_Continue) { Call_PushCell(style = gBS_Style[client]); - Call_PushCell(CalculateTime(client)); + Call_PushCell(gF_PlayerTimer[client]); Call_PushCell(gI_Jumps[client]); Call_PushCell(gI_Strafes[client]); Call_PushCell((gA_StyleSettings[gBS_Style[client]][bSync])? (gI_GoodGains[client] == 0)? 0.0:(gI_GoodGains[client] / float(gI_TotalMeasures[client]) * 100.0):-1.0); @@ -1139,9 +1145,6 @@ public int Native_SaveSnapshot(Handle handler, int numParams) any[] snapshot = new any[TIMERSNAPSHOT_SIZE]; snapshot[bTimerEnabled] = gB_TimerEnabled[client]; - snapshot[fStartTime] = gF_StartTime[client]; - snapshot[fPauseStartTime] = gF_PauseStartTime[client]; - snapshot[fPauseTotalTime] = gF_PauseTotalTime[client]; snapshot[bClientPaused] = gB_ClientPaused[client]; snapshot[iJumps] = gI_Jumps[client]; snapshot[bsStyle] = gBS_Style[client]; @@ -1149,7 +1152,7 @@ public int Native_SaveSnapshot(Handle handler, int numParams) snapshot[iTotalMeasures] = gI_TotalMeasures[client]; snapshot[iGoodGains] = gI_GoodGains[client]; snapshot[fServerTime] = GetEngineTime(); - snapshot[fCurrentTime] = CalculateTime(client); + snapshot[fCurrentTime] = gF_PlayerTimer[client]; snapshot[iSHSWCombination] = gI_SHSW_FirstCombination[client]; snapshot[iTimerTrack] = gI_Track[client]; @@ -1171,16 +1174,13 @@ public int Native_LoadSnapshot(Handle handler, int numParams) } gB_TimerEnabled[client] = view_as(snapshot[bTimerEnabled]); - gF_PauseStartTime[client] = view_as(snapshot[fPauseStartTime]); - gF_PauseTotalTime[client] = view_as(snapshot[fPauseTotalTime]); - gB_ClientPaused[client] = false; // Pausing is disabled in practice mode. + gB_ClientPaused[client] = view_as(snapshot[bClientPaused]); gI_Jumps[client] = view_as(snapshot[iJumps]); gBS_Style[client] = snapshot[bsStyle]; gI_Strafes[client] = view_as(snapshot[iStrafes]); gI_TotalMeasures[client] = view_as(snapshot[iTotalMeasures]); gI_GoodGains[client] = view_as(snapshot[iGoodGains]); - gF_StartTime[client] = GetEngineTime() - view_as(snapshot[fCurrentTime]); - gI_SHSW_FirstCombination[client] = view_as(snapshot[iSHSWCombination]);\ + gI_SHSW_FirstCombination[client] = view_as(snapshot[iSHSWCombination]); } public int Native_MarkKZMap(Handle handler, int numParams) @@ -1215,13 +1215,6 @@ void StartTimer(int client, int track) if(!gB_NoZAxisSpeed || gA_StyleSettings[gBS_Style[client]][bPrespeed] || (fSpeed[2] == 0.0 && SquareRoot(Pow(fSpeed[0], 2.0) + Pow(fSpeed[1], 2.0)) <= 290.0)) { - gI_Strafes[client] = 0; - gI_Jumps[client] = 0; - gI_TotalMeasures[client] = 0; - gI_GoodGains[client] = 0; - gF_StartTime[client] = GetEngineTime(); - gI_Track[client] = track; - Action result = Plugin_Continue; Call_StartForward(gH_Forwards_Start); Call_PushCell(client); @@ -1230,12 +1223,15 @@ void StartTimer(int client, int track) if(result == Plugin_Continue) { + gI_Strafes[client] = 0; + gI_Jumps[client] = 0; + gI_TotalMeasures[client] = 0; + gI_GoodGains[client] = 0; + gF_PlayerTimer[client] = 0.0; + gI_Track[client] = track; gB_TimerEnabled[client] = true; gI_SHSW_FirstCombination[client] = -1; - - gF_PauseTotalTime[client] = 0.0; - gB_ClientPaused[client] = false; - gB_PracticeMode[client] = false; + gF_PlayerTimer[client] = 0.0; SetEntityGravity(client, view_as(gA_StyleSettings[gBS_Style[client]][fGravityMultiplier])); SetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue", view_as(gA_StyleSettings[gBS_Style[client]][fSpeedMultiplier])); @@ -1257,8 +1253,7 @@ void StopTimer(int client) gB_TimerEnabled[client] = false; gI_Jumps[client] = 0; - gF_StartTime[client] = 0.0; - gF_PauseTotalTime[client] = 0.0; + gF_PlayerTimer[client] = 0.0; gB_ClientPaused[client] = false; gI_Strafes[client] = 0; gI_TotalMeasures[client] = 0; @@ -1277,7 +1272,6 @@ void PauseTimer(int client) Call_PushCell(gI_Track[client]); Call_Finish(); - gF_PauseStartTime[client] = GetEngineTime(); gB_ClientPaused[client] = true; } @@ -1293,32 +1287,9 @@ void ResumeTimer(int client) Call_PushCell(gI_Track[client]); Call_Finish(); - gF_PauseTotalTime[client] += (GetEngineTime() - gF_PauseStartTime[client]); gB_ClientPaused[client] = false; } -float CalculateTime(int client) -{ - float time = 0.0; - - if(!gB_ClientPaused[client]) - { - time = (GetEngineTime() - gF_StartTime[client] - gF_PauseTotalTime[client]); - } - - else - { - time = (gF_PauseStartTime[client] - gF_StartTime[client] - gF_PauseTotalTime[client]); - } - - if(gA_StyleSettings[gBS_Style[client]][bHalftime]) - { - time /= 2.0; - } - - return time; -} - public void OnClientDisconnect(int client) { StopTimer(client); @@ -1800,6 +1771,54 @@ public void PreThinkPost(int client) } } +public void OnGameFrame() +{ + float frametime = GetGameFrameTime(); + + for(int i = 1; i <= MaxClients; i++) + { + if(gB_ClientPaused[i] || !gB_TimerEnabled[i]) + { + continue; + } + + float time = frametime; + + if(gA_StyleSettings[gBS_Style[i]][bHalftime]) + { + time /= 2.0; + } + + any[] snapshot = new any[TIMERSNAPSHOT_SIZE]; + snapshot[bTimerEnabled] = gB_TimerEnabled[i]; + snapshot[bClientPaused] = gB_ClientPaused[i]; + snapshot[iJumps] = gI_Jumps[i]; + snapshot[bsStyle] = gBS_Style[i]; + snapshot[iStrafes] = gI_Strafes[i]; + snapshot[iTotalMeasures] = gI_TotalMeasures[i]; + snapshot[iGoodGains] = gI_GoodGains[i]; + snapshot[fServerTime] = GetEngineTime(); + snapshot[fCurrentTime] = gF_PlayerTimer[i]; + snapshot[iSHSWCombination] = gI_SHSW_FirstCombination[i]; + snapshot[iTimerTrack] = gI_Track[i]; + + Call_StartForward(gH_Forwards_OnTimerIncrement); + Call_PushCell(i); + Call_PushArray(snapshot, TIMERSNAPSHOT_SIZE); + Call_PushCellRef(time); + Call_PushArray(gA_StyleSettings[gBS_Style[i]], STYLESETTINGS_SIZE); + Call_Finish(); + + gF_PlayerTimer[i] += time; + + Call_StartForward(gH_Forwards_OnTimerIncrementPost); + Call_PushCell(i); + Call_PushCell(time); + Call_PushArray(gA_StyleSettings[gBS_Style[i]], STYLESETTINGS_SIZE); + Call_Finish(); + } +} + public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3]) { if(!IsPlayerAlive(client) || IsFakeClient(client)) @@ -1807,14 +1826,20 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3 return Plugin_Continue; } + int flags = GetEntityFlags(client); + if(gB_ClientPaused[client]) { buttons = 0; vel = view_as({0.0, 0.0, 0.0}); + SetEntityFlags(client, (flags | FL_ATCONTROLS)); + return Plugin_Changed; } + SetEntityFlags(client, (flags & ~FL_ATCONTROLS)); + Action result = Plugin_Continue; Call_StartForward(gH_Forwards_OnUserCmdPre); Call_PushCell(client); From 9a49977e108253ac1d3e45dccb13628d39fa27d8 Mon Sep 17 00:00:00 2001 From: shavit Date: Fri, 26 Jan 2018 08:05:53 +0200 Subject: [PATCH 28/38] Fixed a few leftover issues from the frametime change. * Fixed time not being loaded via snapshots. * Fixed practice mode not being set to false upon restart. --- addons/sourcemod/scripting/shavit-core.sp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index 194d9b2d..882cba9d 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -1180,6 +1180,7 @@ public int Native_LoadSnapshot(Handle handler, int numParams) gI_Strafes[client] = view_as(snapshot[iStrafes]); gI_TotalMeasures[client] = view_as(snapshot[iTotalMeasures]); gI_GoodGains[client] = view_as(snapshot[iGoodGains]); + gF_PlayerTimer[client] = snapshot[fCurrentTime]; gI_SHSW_FirstCombination[client] = view_as(snapshot[iSHSWCombination]); } @@ -1232,6 +1233,7 @@ void StartTimer(int client, int track) gB_TimerEnabled[client] = true; gI_SHSW_FirstCombination[client] = -1; gF_PlayerTimer[client] = 0.0; + gB_PracticeMode[client] = false; SetEntityGravity(client, view_as(gA_StyleSettings[gBS_Style[client]][fGravityMultiplier])); SetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue", view_as(gA_StyleSettings[gBS_Style[client]][fSpeedMultiplier])); From 5ba897e274429b7951610c00945d5946cefe9994 Mon Sep 17 00:00:00 2001 From: shavit Date: Fri, 26 Jan 2018 19:50:16 +0200 Subject: [PATCH 29/38] Fixed 'shavit_hud_ticksperupdate'. --- addons/sourcemod/scripting/shavit-hud.sp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-hud.sp b/addons/sourcemod/scripting/shavit-hud.sp index 2b85124c..5e19713e 100644 --- a/addons/sourcemod/scripting/shavit-hud.sp +++ b/addons/sourcemod/scripting/shavit-hud.sp @@ -46,7 +46,6 @@ int gI_Cycle = 0; int gI_GradientColors[3]; int gI_GradientDirection = -1; int gI_Styles = 0; -int gI_Tickrate = 0; Handle gH_HUDCookie = null; int gI_HUDSettings[MAXPLAYERS+1]; @@ -104,7 +103,6 @@ public void OnPluginStart() // game-specific gEV_Type = GetEngineVersion(); - gI_Tickrate = RoundToZero(1.0 / GetTickInterval()); if(IsSource2013(gEV_Type)) { @@ -134,7 +132,7 @@ public void OnPluginStart() // plugin convars gCV_GradientStepSize = CreateConVar("shavit_hud_gradientstepsize", "15", "How fast should the start/end HUD gradient be?\nThe number is the amount of color change per 0.1 seconds.\nThe higher the number the faster the gradient.", 0, true, 1.0, true, 255.0); - gCV_TicksPerUpdate = CreateConVar("shavit_hud_ticksperupdate", "20", "How often (in ticks) should the HUD update?\nPlay around with this value until you find the best for your server.\nThe maximum value is your tickrate.", 0, true, 1.0, true, float(gI_Tickrate)); + gCV_TicksPerUpdate = CreateConVar("shavit_hud_ticksperupdate", "20", "How often (in ticks) should the HUD update?\nPlay around with this value until you find the best for your server.\nThe maximum value is your tickrate.", 0, true, 1.0, true, (1.0 / GetTickInterval())); gCV_GradientStepSize.AddChangeHook(OnConVarChanged); gCV_TicksPerUpdate.AddChangeHook(OnConVarChanged); @@ -483,7 +481,7 @@ public int MenuHandler_HUD(Menu menu, MenuAction action, int param1, int param2) public void OnGameFrame() { - if(GetGameTickCount() % (gI_Tickrate / gI_TicksPerUpdate) == 0) + if(GetGameTickCount() % gI_TicksPerUpdate == 0) { Cron(); } From 52b9c1e81f410cdc55ed4edf20dba6dacb72215d Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 28 Jan 2018 20:54:15 +0200 Subject: [PATCH 30/38] Allowed pausing in practice mode. It was disabled before due to the mess with time calculation. Shouldn't be problematic now. --- addons/sourcemod/scripting/shavit-core.sp | 7 ------- addons/sourcemod/translations/shavit-core.phrases.txt | 5 ----- 2 files changed, 12 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index 882cba9d..a3f19c51 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -561,13 +561,6 @@ public Action Command_TogglePause(int client, int args) return Plugin_Handled; } - if(gB_PracticeMode[client]) - { - Shavit_PrintToChat(client, "%T", "PausePractice", client, gS_ChatStrings[sMessageWarning], gS_ChatStrings[sMessageText]); - - return Plugin_Handled; - } - if(gB_ClientPaused[client]) { TeleportEntity(client, gF_PausePosition[client][0], gF_PausePosition[client][1], gF_PausePosition[client][2]); diff --git a/addons/sourcemod/translations/shavit-core.phrases.txt b/addons/sourcemod/translations/shavit-core.phrases.txt index 88f7c732..432bdaa4 100644 --- a/addons/sourcemod/translations/shavit-core.phrases.txt +++ b/addons/sourcemod/translations/shavit-core.phrases.txt @@ -105,11 +105,6 @@ "#format" "{1:s},{2:s}" "en" "Timer has been {1}paused{2}." } - "PausePractice" - { - "#format" "{1:s},{2:s}" - "en" "You {1}are not{2} allowed to pause while in practice mode." - } // ---------- Zones ---------- // "StartZoneUndefined" { From 14a23b210a796bc03c9d1be3d1cec642957dda89 Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 28 Jan 2018 20:54:45 +0200 Subject: [PATCH 31/38] Changed default HUD updates to 5 ticks per. Previous default was 20 ticks per update. --- addons/sourcemod/scripting/shavit-hud.sp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-hud.sp b/addons/sourcemod/scripting/shavit-hud.sp index 5e19713e..d1d9f7b7 100644 --- a/addons/sourcemod/scripting/shavit-hud.sp +++ b/addons/sourcemod/scripting/shavit-hud.sp @@ -67,7 +67,7 @@ ConVar gCV_TicksPerUpdate = null; // cached cvars int gI_GradientStepSize = 5; -int gI_TicksPerUpdate = 20; +int gI_TicksPerUpdate = 5; // timer settings char gS_StyleStrings[STYLE_LIMIT][STYLESTRINGS_SIZE][128]; @@ -132,7 +132,7 @@ public void OnPluginStart() // plugin convars gCV_GradientStepSize = CreateConVar("shavit_hud_gradientstepsize", "15", "How fast should the start/end HUD gradient be?\nThe number is the amount of color change per 0.1 seconds.\nThe higher the number the faster the gradient.", 0, true, 1.0, true, 255.0); - gCV_TicksPerUpdate = CreateConVar("shavit_hud_ticksperupdate", "20", "How often (in ticks) should the HUD update?\nPlay around with this value until you find the best for your server.\nThe maximum value is your tickrate.", 0, true, 1.0, true, (1.0 / GetTickInterval())); + gCV_TicksPerUpdate = CreateConVar("shavit_hud_ticksperupdate", "5", "How often (in ticks) should the HUD update?\nPlay around with this value until you find the best for your server.\nThe maximum value is your tickrate.", 0, true, 1.0, true, (1.0 / GetTickInterval())); gCV_GradientStepSize.AddChangeHook(OnConVarChanged); gCV_TicksPerUpdate.AddChangeHook(OnConVarChanged); From cb7bbce676374839623f92092420fe20843ae6cb Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 28 Jan 2018 20:57:22 +0200 Subject: [PATCH 32/38] Changed `block_pstrafe`'s behavior. * Changed default (1) to block button inconsistencies. * Made the duration of inconsistencies less annoying. * Changed the first option to 2, which stops the timer on inconsistencies. --- addons/sourcemod/configs/shavit-styles.cfg | 2 +- addons/sourcemod/scripting/include/shavit.inc | 2 +- addons/sourcemod/scripting/shavit-core.sp | 22 ++++++++++++------- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/addons/sourcemod/configs/shavit-styles.cfg b/addons/sourcemod/configs/shavit-styles.cfg index ec461de9..bbe29d6c 100644 --- a/addons/sourcemod/configs/shavit-styles.cfg +++ b/addons/sourcemod/configs/shavit-styles.cfg @@ -40,7 +40,7 @@ "force_hsw" "0" // Force half-sideways gameplay. 1 for regular HSW and 2 for surf-HSW. "block_pleft" "0" // Block +left (requires shavit_core_blockleftright 1). "block_pright" "0" // Block +right (requires shavit_core_blockleftright 1). - "block_pstrafe" "0" // Stops timer on +strafe usage. May have false positives when players lag. Will prvent some strafe hacks too. + "block_pstrafe" "0" // Prevent button inconsistencies (including +pstrafe). May have false positives when players lag. Will prevent some strafe hacks too. Set this to 2 to also stop the timer. // Feature excluding "unranked" "0" // Unranked style. No ranking points and no records. diff --git a/addons/sourcemod/scripting/include/shavit.inc b/addons/sourcemod/scripting/include/shavit.inc index bd60f76c..116232a5 100644 --- a/addons/sourcemod/scripting/include/shavit.inc +++ b/addons/sourcemod/scripting/include/shavit.inc @@ -107,7 +107,7 @@ enum iForceHSW, bBlockPLeft, bBlockPRight, - bBlockPStrafe, + iBlockPStrafe, bUnranked, bNoReplay, bSync, diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index a3f19c51..7a8cad5f 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -1460,7 +1460,7 @@ bool LoadStyles() gA_StyleSettings[i][iForceHSW] = kv.GetNum("force_hsw", 0); gA_StyleSettings[i][bBlockPLeft] = view_as(kv.GetNum("block_pleft", 0)); gA_StyleSettings[i][bBlockPRight] = view_as(kv.GetNum("block_pright", 0)); - gA_StyleSettings[i][bBlockPStrafe] = view_as(kv.GetNum("block_pstrafe", 0)); + gA_StyleSettings[i][iBlockPStrafe] = kv.GetNum("block_pstrafe", 0); gA_StyleSettings[i][bUnranked] = view_as(kv.GetNum("unranked", 0)); gA_StyleSettings[i][bNoReplay] = view_as(kv.GetNum("noreplay", 0)); gA_StyleSettings[i][bSync] = view_as(kv.GetNum("sync", 1)); @@ -1869,19 +1869,25 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3 } // +strafe block - if(gA_StyleSettings[gBS_Style[client]][bBlockPStrafe] && + if(gA_StyleSettings[gBS_Style[client]][iBlockPStrafe] > 0 && ((vel[0] > 0.0 && (buttons & IN_FORWARD) == 0) || (vel[0] < 0.0 && (buttons & IN_BACK) == 0) || (vel[1] > 0.0 && (buttons & IN_MOVERIGHT) == 0) || (vel[1] < 0.0 && (buttons & IN_MOVELEFT) == 0))) { - float fTime = GetEngineTime(); - - if(gF_StrafeWarning[client] < fTime) + if(gF_StrafeWarning[client] < gF_PlayerTimer[client]) { - FormatEx(sCheatDetected, 64, "%T", "Inconsistencies", client); - StopTimer_Cheat(client, sCheatDetected); + if(gA_StyleSettings[gBS_Style[client]][iBlockPStrafe] >= 2) + { + FormatEx(sCheatDetected, 64, "%T", "Inconsistencies", client); + StopTimer_Cheat(client, sCheatDetected); + } + + vel[0] = 0.0; + vel[1] = 0.0; + + return Plugin_Changed; } - gF_StrafeWarning[client] = fTime + 0.20; + gF_StrafeWarning[client] = gF_PlayerTimer[client] + 0.3; } } From 1d34b310d1a61021ba7dc69065f8816f9687f850 Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 28 Jan 2018 20:57:55 +0200 Subject: [PATCH 33/38] Fixed top-left HUD flickering. Text might look uglier in CS:GO, but this works. --- addons/sourcemod/scripting/shavit-hud.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/shavit-hud.sp b/addons/sourcemod/scripting/shavit-hud.sp index d1d9f7b7..78fe518f 100644 --- a/addons/sourcemod/scripting/shavit-hud.sp +++ b/addons/sourcemod/scripting/shavit-hud.sp @@ -1046,7 +1046,7 @@ void UpdateTopLeftHUD(int client, bool wait) FormatEx(sTopLeft, 128, "WR: %s (%s)", sWRTime, sWRName); } - SetHudTextParams(0.01, 0.01, 2.5, 255, 255, 255, 255); + SetHudTextParams(0.01, 0.01, 2.5, 255, 255, 255, 255, 0, 0.0, 0.0, 0.0); ShowSyncHudText(client, gH_HUD, "%s", sTopLeft); } } From 8f51d4c964bed8d6875f40ebd1036b3d642f4128 Mon Sep 17 00:00:00 2001 From: shavit Date: Wed, 31 Jan 2018 05:48:59 +0200 Subject: [PATCH 34/38] Added `mouse[2]` to OnUserCmdPre. --- addons/sourcemod/scripting/include/shavit.inc | 3 ++- addons/sourcemod/scripting/shavit-core.sp | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/addons/sourcemod/scripting/include/shavit.inc b/addons/sourcemod/scripting/include/shavit.inc index 116232a5..4a257b1c 100644 --- a/addons/sourcemod/scripting/include/shavit.inc +++ b/addons/sourcemod/scripting/include/shavit.inc @@ -297,9 +297,10 @@ stock void FormatSeconds(float time, char[] newtime, int newtimesize, bool preci * @param track The player's timer track. * @param style The player's bhop style. * @param stylesettings An array that contains the player's bhop style's settings. + * @param mouse Mouse direction (x, y). * @return Plugin_Continue to let shavit-core keep doing what it does, Plugin_Changed to pass different values. */ -forward Action Shavit_OnUserCmdPre(int client, int &buttons, int &impulse, float vel[3], float angles[3], TimerStatus status, int track, int style, any stylesettings[STYLESETTINGS_SIZE]); +forward Action Shavit_OnUserCmdPre(int client, int &buttons, int &impulse, float vel[3], float angles[3], TimerStatus status, int track, int style, any stylesettings[STYLESETTINGS_SIZE], int mouse[2]); /** * Called just before shavit-core adds time to a player's timer. diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index 7a8cad5f..f8f592fe 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -203,7 +203,7 @@ public void OnPluginStart() gH_Forwards_OnStyleConfigLoaded = CreateGlobalForward("Shavit_OnStyleConfigLoaded", ET_Event, Param_Cell); gH_Forwards_OnDatabaseLoaded = CreateGlobalForward("Shavit_OnDatabaseLoaded", ET_Event); gH_Forwards_OnChatConfigLoaded = CreateGlobalForward("Shavit_OnChatConfigLoaded", ET_Event); - gH_Forwards_OnUserCmdPre = CreateGlobalForward("Shavit_OnUserCmdPre", ET_Event, Param_Cell, Param_CellByRef, Param_CellByRef, Param_Array, Param_Array, Param_Cell, Param_Cell, Param_Cell, Param_Array); + gH_Forwards_OnUserCmdPre = CreateGlobalForward("Shavit_OnUserCmdPre", ET_Event, Param_Cell, Param_CellByRef, Param_CellByRef, Param_Array, Param_Array, Param_Cell, Param_Cell, Param_Cell, Param_Array, Param_Array); gH_Forwards_OnTimerIncrement = CreateGlobalForward("Shavit_OnTimeIncrement", ET_Event, Param_Cell, Param_Array, Param_CellByRef, Param_Array); gH_Forwards_OnTimerIncrementPost = CreateGlobalForward("Shavit_OnTimeIncrementPost", ET_Event, Param_Cell, Param_Cell, Param_Array); @@ -1814,7 +1814,7 @@ public void OnGameFrame() } } -public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3]) +public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2]) { if(!IsPlayerAlive(client) || IsFakeClient(client)) { @@ -1846,6 +1846,7 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3 Call_PushCell(gI_Track[client]); Call_PushCell(gBS_Style[client]); Call_PushArray(gA_StyleSettings[gBS_Style[client]], STYLESETTINGS_SIZE); + Call_PushArrayEx(mouse, 2, SM_PARAM_COPYBACK); Call_Finish(result); if(result != Plugin_Continue && result != Plugin_Changed) From d99548abd7fe64f1dc13363973ea76c238b06c52 Mon Sep 17 00:00:00 2001 From: shavit Date: Fri, 2 Feb 2018 10:27:40 +0200 Subject: [PATCH 35/38] Fix wrong entities being removed. --- addons/sourcemod/scripting/shavit-zones.sp | 26 +++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-zones.sp b/addons/sourcemod/scripting/shavit-zones.sp index 9b0d53e5..99743d09 100644 --- a/addons/sourcemod/scripting/shavit-zones.sp +++ b/addons/sourcemod/scripting/shavit-zones.sp @@ -736,6 +736,14 @@ void KillZoneEntity(int index) gB_InsideZoneID[i][index] = false; } + char[] sTargetname = new char[32]; + GetEntPropString(entity, Prop_Data, "m_iName", sTargetname, 32); + + if(StrContains(sTargetname, "shavit_zones_") == -1) + { + return; + } + UnhookEntity(entity); AcceptEntityInput(entity, "Kill"); } @@ -769,21 +777,17 @@ void UnloadZones(int zone) { gB_ZonesCreated = false; - int iMaxEntities = GetMaxEntities(); - - char[] sClassname = new char[32]; char[] sTargetname = new char[32]; + int iEntity = INVALID_ENT_REFERENCE; - for(int i = (MaxClients + 1); i < iMaxEntities; i++) + while((iEntity = FindEntityByClassname(iEntity, "trigger_multiple")) != INVALID_ENT_REFERENCE) { - if(!IsValidEntity(i) - || !GetEntityClassname(i, sClassname, 32) || !StrEqual(sClassname, "trigger_multiple") - || GetEntPropString(i, Prop_Data, "m_iName", sTargetname, 32) == 0 || StrContains(sTargetname, "shavit_zones_") == -1) - { - continue; - } + GetEntPropString(iEntity, Prop_Data, "m_iName", sTargetname, 32); - AcceptEntityInput(i, "Kill"); + if(StrContains(sTargetname, "shavit_zones_") != -1) + { + AcceptEntityInput(iEntity, "Kill"); + } } } From 26fc6e0b380df99c0e626f734defe5142c90606b Mon Sep 17 00:00:00 2001 From: shavit Date: Fri, 2 Feb 2018 10:59:56 +0200 Subject: [PATCH 36/38] Tweaked movetype/flag adjustments on bots. --- addons/sourcemod/scripting/shavit-replay.sp | 38 ++++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-replay.sp b/addons/sourcemod/scripting/shavit-replay.sp index 80a51cea..9defc382 100644 --- a/addons/sourcemod/scripting/shavit-replay.sp +++ b/addons/sourcemod/scripting/shavit-replay.sp @@ -1359,6 +1359,19 @@ public void Shavit_OnResume(int client) gB_Record[client] = true; } +void ModifyFlags(int &flags, int flag, bool add) +{ + if(add) + { + flags |= flag; + } + + else + { + flags &= flag; + } +} + // OnPlayerRunCmd instead of Shavit_OnUserCmdPre because bots are also used here. public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3]) { @@ -1465,23 +1478,30 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3 buttons = gA_Frames[style][track].Get(gI_ReplayTick[style], 5); + MoveType mt = MOVETYPE_NOCLIP; + if(gA_FrameCache[style][track][3] >= 0x02) { - SetEntityFlags(client, gA_Frames[style][track].Get(gI_ReplayTick[style], 6)); + int iReplayFlags = gA_Frames[style][track].Get(gI_ReplayTick[style], 6); + int iEntityFlags = GetEntityFlags(client); + + ModifyFlags(iEntityFlags, FL_ONGROUND, (iReplayFlags & FL_ONGROUND) > 0); + ModifyFlags(iEntityFlags, FL_PARTIALGROUND, (iReplayFlags & FL_PARTIALGROUND) > 0); + ModifyFlags(iEntityFlags, FL_INWATER, (iReplayFlags & FL_INWATER) > 0); + ModifyFlags(iEntityFlags, FL_SWIM, (iReplayFlags & FL_SWIM) > 0); + + SetEntityFlags(client, iEntityFlags); - MoveType mt = gA_Frames[style][track].Get(gI_ReplayTick[style], 7); + MoveType movetype = gA_Frames[style][track].Get(gI_ReplayTick[style], 7); - if(mt == MOVETYPE_WALK || mt == MOVETYPE_LADDER) + if(movetype == MOVETYPE_WALK || movetype == MOVETYPE_LADDER) { - SetEntityMoveType(client, mt); - } - - else - { - SetEntityMoveType(client, MOVETYPE_NOCLIP); + mt = movetype; } } + SetEntityMoveType(client, mt); + float vecVelocity[3]; MakeVectorFromPoints(vecCurrentPosition, vecPosition, vecVelocity); ScaleVector(vecVelocity, gF_Tickrate); From bb2571cd0845ed2f94c2342345b23b2527443de4 Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 4 Feb 2018 10:25:27 +0200 Subject: [PATCH 37/38] Add TF2 spawn point generation. --- addons/sourcemod/scripting/shavit-misc.sp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index 91040fd5..96a20f70 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -515,17 +515,15 @@ public void OnMapStart() GetCurrentMap(gS_CurrentMap, 192); GetMapDisplayName(gS_CurrentMap, gS_CurrentMap, 192); - if(gI_CreateSpawnPoints > 0 && gEV_Type != Engine_TF2) + if(gI_CreateSpawnPoints > 0) { int iEntity = -1; float fOrigin[3]; - if((iEntity = FindEntityByClassname(iEntity, "info_player_terrorist")) != INVALID_ENT_REFERENCE) - { - GetEntPropVector(iEntity, Prop_Send, "m_vecOrigin", fOrigin); - } - - else if((iEntity = FindEntityByClassname(iEntity, "info_player_counterterrorist")) != INVALID_ENT_REFERENCE) + if((iEntity = FindEntityByClassname(iEntity, "info_player_terrorist")) != INVALID_ENT_REFERENCE || // CS:S/CS:GO T + (iEntity = FindEntityByClassname(iEntity, "info_player_counterterrorist")) != INVALID_ENT_REFERENCE || // CS:S/CS:GO CT + (iEntity = FindEntityByClassname(iEntity, "info_player_teamspawn")) != INVALID_ENT_REFERENCE || // TF2 spawn point + (iEntity = FindEntityByClassname(iEntity, "info_player_start")) != INVALID_ENT_REFERENCE) { GetEntPropVector(iEntity, Prop_Send, "m_vecOrigin", fOrigin); } From 7cd9fbef9ba091daf4aad6cf49fa9e6a8c840865 Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 4 Feb 2018 10:26:10 +0200 Subject: [PATCH 38/38] Fixed states not applying correctly on style/track changes. (#588) --- addons/sourcemod/scripting/shavit-misc.sp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index 96a20f70..bc30b79f 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -2172,6 +2172,14 @@ void RestoreState(any data) return; } + if(gA_SaveStates[client][bsStyle] != Shavit_GetBhopStyle(client) || + gA_SaveStates[client][iTimerTrack] != Shavit_GetClientTrack(client)) + { + gB_SaveStates[client] = false; + + return; + } + LoadState(client); } @@ -2451,17 +2459,12 @@ void LoadState(int client) Shavit_LoadSnapshot(client, gA_SaveStates[client]); - if(gA_SaveFrames[client] != null) + if(gB_Replay && gA_SaveFrames[client] != null) { - if(gB_Replay) - { - Shavit_SetReplayData(client, gA_SaveFrames[client]); - } - - delete gA_SaveFrames[client]; - gA_SaveFrames[client] = null; + Shavit_SetReplayData(client, gA_SaveFrames[client]); } + delete gA_SaveFrames[client]; gB_SaveStates[client] = false; }