diff --git a/addons/sourcemod/scripting/include/shavit/checkpoints.inc b/addons/sourcemod/scripting/include/shavit/checkpoints.inc index a1b1ba90..805968e4 100644 --- a/addons/sourcemod/scripting/include/shavit/checkpoints.inc +++ b/addons/sourcemod/scripting/include/shavit/checkpoints.inc @@ -186,6 +186,15 @@ native void Shavit_SetCurrentCheckpoint(int client, int index); */ native int Shavit_GetTimesTeleported(int client); +/** + * Checks whether the client has savestate data. + * + * @param client Client index + * + * @return Whether a savestate or rejoin-savestate data exists for the client. + */ +native bool Shavit_HasSavestate(int client); + public SharedPlugin __pl_shavit_checkpoints = { name = "shavit-checkpoints", @@ -201,12 +210,17 @@ public SharedPlugin __pl_shavit_checkpoints = public void __pl_shavit_checkpoints_SetNTVOptional() { MarkNativeAsOptional("Shavit_GetTotalCheckpoints"); + MarkNativeAsOptional("Shavit_GetCheckpoint"); MarkNativeAsOptional("Shavit_SetCheckpoint"); + MarkNativeAsOptional("Shavit_TeleportToCheckpoint"); MarkNativeAsOptional("Shavit_ClearCheckpoints"); MarkNativeAsOptional("Shavit_SaveCheckpoint"); + MarkNativeAsOptional("Shavit_GetCurrentCheckpoint"); MarkNativeAsOptional("Shavit_SetCurrentCheckpoint"); + + MarkNativeAsOptional("Shavit_HasSavestate"); } #endif diff --git a/addons/sourcemod/scripting/include/shavit/physicsuntouch.inc b/addons/sourcemod/scripting/include/shavit/physicsuntouch.inc index f77ce73d..525cf848 100644 --- a/addons/sourcemod/scripting/include/shavit/physicsuntouch.inc +++ b/addons/sourcemod/scripting/include/shavit/physicsuntouch.inc @@ -5,7 +5,7 @@ Handle gH_PhysicsCheckForEntityUntouch; -void LoadPhysicsUntouch(Handle gamedata) +stock void LoadPhysicsUntouch(Handle gamedata) { StartPrepSDKCall(SDKCall_Entity); @@ -17,13 +17,13 @@ void LoadPhysicsUntouch(Handle gamedata) gH_PhysicsCheckForEntityUntouch = EndPrepSDKCall(); } -bool GetCheckUntouch(int client) +stock bool GetCheckUntouch(int client) { int flags = GetEntProp(client, Prop_Data, "m_iEFlags"); return (flags & EFL_CHECK_UNTOUCH) != 0; } -void MaybeDoPhysicsUntouch(int client) +stock void MaybeDoPhysicsUntouch(int client) { if (GetCheckUntouch(client)) { diff --git a/addons/sourcemod/scripting/shavit-checkpoints.sp b/addons/sourcemod/scripting/shavit-checkpoints.sp index c638d5e9..83de6728 100644 --- a/addons/sourcemod/scripting/shavit-checkpoints.sp +++ b/addons/sourcemod/scripting/shavit-checkpoints.sp @@ -20,10 +20,12 @@ #include #include +#include #include #include #include +#include #undef REQUIRE_PLUGIN #include @@ -31,6 +33,8 @@ #pragma newdecls required #pragma semicolon 1 +#define DEBUG 0 + #define CP_ANGLES (1 << 0) #define CP_VELOCITY (1 << 1) @@ -69,6 +73,7 @@ Handle gH_Forwards_OnCheckpointMenuSelect = null; chatstrings_t gS_ChatStrings; stylestrings_t gS_StyleStrings[STYLE_LIMIT]; +int gI_Style[MAXPLAYERS+1]; bool gB_ClosedKZCP[MAXPLAYERS+1]; ArrayList gA_Checkpoints[MAXPLAYERS+1]; @@ -82,6 +87,9 @@ int gI_CheckpointsSettings[MAXPLAYERS+1]; bool gB_SaveStates[MAXPLAYERS+1]; // whether we have data for when player rejoins from spec ArrayList gA_PersistentData = null; +bool gB_Eventqueuefix = false; +bool gB_Replay = false; + public Plugin myinfo = { name = "[shavit] Checkpoints", @@ -102,6 +110,9 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max CreateNative("Shavit_GetCurrentCheckpoint", Native_GetCurrentCheckpoint); CreateNative("Shavit_SetCurrentCheckpoint", Native_SetCurrentCheckpoint); CreateNative("Shavit_GetTimesTeleported", Native_GetTimesTeleported); + CreateNative("Shavit_HasSavestate", Native_HasSavestate); + + RegPluginLibrary("shavit-checkpoints"); gB_Late = late; @@ -139,7 +150,6 @@ public void OnPluginStart() gCV_Checkpoints = new Convar("shavit_misc_checkpoints", "1", "Allow players to save and teleport to checkpoints.", 0, true, 0.0, true, 1.0); gCV_RestoreStates = new Convar("shavit_misc_restorestates", "1", "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); - gCV_JointeamHook = new Convar("shavit_misc_jointeamhook", "1", "Hook `jointeam`?\n0 - Disabled\n1 - Enabled, players can instantly change teams.", 0, true, 0.0, true, 1.0); gCV_MaxCP = new Convar("shavit_misc_maxcp", "1000", "Maximum amount of checkpoints.\nNote: Very high values will result in high memory usage!", 0, true, 1.0, true, 10000.0); gCV_MaxCP_Segmented = new Convar("shavit_misc_maxcp_seg", "10", "Maximum amount of segmented checkpoints. Make this less or equal to shavit_misc_maxcp.\nNote: Very high values will result in HUGE memory usage! Segmented checkpoints contain frame data!", 0, true, 1.0, true, 50.0); gCV_PersistData = new Convar("shavit_misc_persistdata", "600", "How long to persist timer data for disconnected users in seconds?\n-1 - Until map change\n0 - Disabled"); @@ -163,6 +173,20 @@ public void OnPluginStart() } } +void LoadDHooks() +{ + Handle hGameData = LoadGameConfigFile("shavit.games"); + + if (hGameData == null) + { + SetFailState("Failed to load shavit gamedata"); + } + + LoadPhysicsUntouch(hGameData); + + delete hGameData; +} + public void OnLibraryAdded(const char[] name) { if (StrEqual(name, "shavit-replay")) @@ -461,15 +485,12 @@ public void Player_Spawn(Event event, const char[] name, bool dontBroadcast) int serial = GetClientSerial(client); - bool bCanStartOnSpawn = true; - if (gB_SaveStates[client]) { if(gCV_RestoreStates.BoolValue) { // events&outputs won't work properly unless we do this next frame... RequestFrame(LoadPersistentData, serial); - bCanStartOnSpawn = false; } } else @@ -482,15 +503,9 @@ public void Player_Spawn(Event event, const char[] name, bool dontBroadcast) gB_SaveStates[client] = true; // events&outputs won't work properly unless we do this next frame... RequestFrame(LoadPersistentData, serial); - bCanStartOnSpawn = false; } } - if (gCV_StartOnSpawn.BoolValue && bCanStartOnSpawn) - { - RestartTimer(client, Track_Main); - } - // refreshes kz cp menu if there is nothing open if (!gB_ClosedKZCP[client] && Shavit_GetStyleSettingInt(gI_Style[client], "kzcheckpoints") && @@ -1568,6 +1583,26 @@ public any Native_TeleportToCheckpoint(Handle plugin, int numParams) return 0; } +public any Native_HasSavestate(Handle plugin, int numParams) +{ + int client = GetNativeCell(1); + + if (gB_SaveStates[client]) + { + return true; + } + + persistent_data_t aData; + int iIndex = FindPersistentData(client, aData); + + if (iIndex != -1) + { + gB_SaveStates[client] = true; + } + + return gB_SaveStates[client]; +} + public any Native_GetTimesTeleported(Handle plugin, int numParams) { return gI_TimesTeleported[GetNativeCell(1)]; diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index 1a3d37d6..1653d5b4 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -33,6 +33,7 @@ #undef REQUIRE_PLUGIN #include +#include #include #include @@ -122,6 +123,7 @@ DynamicHook gH_IsSpawnPointValid = null; DynamicDetour gH_CalcPlayerScore = null; // modules +bool gB_Checkpoints = false; bool gB_Eventqueuefix = false; bool gB_Rankings = false; bool gB_Replay = false; @@ -288,6 +290,7 @@ public void OnPluginStart() } // modules + gB_Checkpoints = LibraryExists("shavit-checkpoints"); gB_Eventqueuefix = LibraryExists("eventqueuefix"); gB_Rankings = LibraryExists("shavit-rankings"); gB_Replay = LibraryExists("shavit-replay"); @@ -623,22 +626,22 @@ public void OnLibraryAdded(const char[] name) { gB_Rankings = true; } - else if(StrEqual(name, "shavit-replay")) { gB_Replay = true; } - else if(StrEqual(name, "shavit-zones")) { gB_Zones = true; } - else if(StrEqual(name, "shavit-chat")) { gB_Chat = true; } - + else if (StrEqual(name, "shavit-checkpoints")) + { + gB_Checkpoints = true; + } else if(StrEqual(name, "eventqueuefix")) { gB_Eventqueuefix = true; @@ -651,22 +654,22 @@ public void OnLibraryRemoved(const char[] name) { gB_Rankings = false; } - else if(StrEqual(name, "shavit-replay")) { gB_Replay = false; } - else if(StrEqual(name, "shavit-zones")) { gB_Zones = false; } - else if(StrEqual(name, "shavit-chat")) { gB_Chat = false; } - + else if (StrEqual(name, "shavit-checkpoints")) + { + gB_Checkpoints = false; + } else if(StrEqual(name, "eventqueuefix")) { gB_Eventqueuefix = false; @@ -1718,6 +1721,11 @@ void SetWeaponAmmo(int client, int weapon, bool setClip1) } } +bool CanSegment(int client) +{ + return StrContains(gS_StyleStrings[gI_Style[client]].sSpecialString, "segments") != -1; +} + bool ShouldDisplayStopWarning(int client) { return (gCV_StopTimerWarning.BoolValue && Shavit_GetTimerStatus(client) != Timer_Stopped && Shavit_GetClientTime(client) > gCV_StopTimerWarning.FloatValue && !CanSegment(client)); @@ -2156,27 +2164,9 @@ public void Player_Spawn(Event event, const char[] name, bool dontBroadcast) // TODO: bool bCanStartOnSpawn = true; - if(gB_SaveStates[client]) + if (gB_Checkpoints) { - if(gCV_RestoreStates.BoolValue) - { - // events&outputs won't work properly unless we do this next frame... - RequestFrame(LoadPersistentData, serial); - bCanStartOnSpawn = false; - } - } - else - { - persistent_data_t aData; - int iIndex = FindPersistentData(client, aData); - - if (iIndex != -1) - { - gB_SaveStates[client] = true; - // events&outputs won't work properly unless we do this next frame... - RequestFrame(LoadPersistentData, serial); - bCanStartOnSpawn = false; - } + bCanStartOnSpawn = !Shavit_HasSavestate(client); } if(gCV_StartOnSpawn.BoolValue && bCanStartOnSpawn)