merge CP menus & shavit-kz.sp, etc. (#1137)

* fix normal CP menu spams on changing the style from non-kz to kz styles

* fix normal CP menu spams on changing from non-kz to kz styles, again

* merge OpenKZCPMenu() into OpenNormalCPMenu() and rename it to OpenCPMenu()

* fix handle error on server restart in KZCP styles

* 1. Added "kzcheckpoints_ontele" and "kzcheckpoints_ontele" style settings(merged in `shavit-kz.sp`).
2. Added "force"(ignore style access) parameter for "Shavit_LoadSnapshot()" and "Shavit_LoadCheckpointCache()".
3. Made "segments" as a style setting instead of special strings.
   (use "segments" as specialstrings is still feasible)

note: maybe better to change TAS's default ranking multiplier to "0.0" since segmented style is also "0.0".

* 😵‍💫

* updated shavit-checkpoints.sp

* updated style-settings.sp
This commit is contained in:
Shahrazad 2022-04-11 21:58:18 +08:00 committed by GitHub
parent c6ced66503
commit 6d208a8595
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 154 additions and 191 deletions

View File

@ -58,8 +58,6 @@
"block_pleft" "0" // Block +left. 2 to stop timer.
"block_pright" "0" // Block +right. 2 to stop timer.
"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.
"kzcheckpoints" "0" // KZ styled checkpoints. They reset upon timer start and you don't get reverted to a save state, and you cannot save when airborne or someone else's checkpoints.
"kzcheckpoints_ladders" "0" // KZ styled checkpoints allowed to checkpoint onto ladders (like GOKZ)
// Feature excluding
"unranked" "0" // Unranked style. No ranking points and no records.
@ -85,7 +83,14 @@
"permission" "" // Permission required. Syntax: "flag;override". For example "p;style_tas" to require the 'p' flag or the "style_tas" override.
"ordering" "0" // Ordering in menus where styles appear. If this value is not present, style ID will be used instead.
// TAS Settings
// KZ settings
"kzcheckpoints" "0" // KZ styled checkpoints. They reset upon timer start and you don't get reverted to a save state, and you cannot save when airborne or someone else's checkpoints.
"kzcheckpoints_ladders" "0" // KZ styled checkpoints allowed to checkpoint onto ladders (like GOKZ)
"kzcheckpoints_ontele" "-1" // The style to be changed to on client teleporting to a checkpoint in KZ styles. The destination style will be inaccessible if enabled. -1 or set "kzcheckpoints" to 0 for disabled.
"kzcheckpoints_onstart" "-1" // The style to be changed to on client getting inside the start zone in KZ styles. This style will be inaccessible if enabled. -1 or set "kzcheckpoints" to 0 for disabled.
// TAS settings
"segments" "0" // Segments styled checkpoints. 0 for disabled.
"tas" "0" // 0 = Do nothing. 1 = Currently sets the following keys unless they are explicity disabled: `tas_timescale -1`, `autostrafe 1`, `autoprestrafe 1`, `edgejump 1`, and `autojumponstart 1`
"tas_timescale" "0" // TAS-like timescaling. 0 = Disabled. -1 = User can edit the timescale (TAS menu, sm_ts, sm_tsplus, sm_tsminus). >0 = Fixed tas-timescale value for the style (e.g. 0.5 for a fixed timescale). Total time-increase-rate for the player = timescale * tas_timescale
"autostrafe" "0" // 0 = Disabled. 1 = 1tick autostrafer. 2 = velocity/autogain. 3 = velocity/autogain (no speed loss). -1 = Lets players toggle between 1tick and velocity/autogain.
@ -226,8 +231,9 @@
"command" "sr; seg; segment; segmented"
"clantag" "SEG"
"rankingmultiplier" "0.0"
"specialstring" "segments"
"segments" "1"
"rankingmultiplier" "0.0"
}
"8"

View File

@ -23,6 +23,13 @@
#endif
#define _shavit_checkpoints_included
enum TimerAction
{
TimerAction_None,
TimerAction_OnStart,
TimerAction_OnTeleport
}
enum struct cp_cache_t
{
float fPosition[3];
@ -261,10 +268,11 @@ native bool Shavit_HasSavestate(int client);
* @param cache Input cp_cache_t
* @param index -1 if you want the cp_cache_t to be loaded as "persistent data". 0 if not. greater-than-zero if you know what you're doing and intentionally want to spoof the cp_cache_t as a checkpoint index for some reason... I recommend looking at shavit-checkpoints.sp to see how "index" and "isPersistentData" are used to see what kind of difference there is.
* @param size sizeof(cp_cache_t) to mostly ensure the calling plugin has a matching cp_cache_t.
* @param force Forcibly load the cp_cache_t without checking the style access for a player.
*
* @return Returns whether the checkpoint cache was able to be loaded.
*/
native bool Shavit_LoadCheckpointCache(int client, any[] cache, int index, int size = sizeof(cp_cache_t));
native bool Shavit_LoadCheckpointCache(int client, any[] cache, int index, int size = sizeof(cp_cache_t), bool force = false);
/**
* Saves a cp_cache_t from a player.

View File

@ -1197,9 +1197,10 @@ native void Shavit_SaveSnapshot(int client, any[] snapshot, int size = sizeof(ti
* @param client Client index.
* @param snapshot Full snapshot of the client's timer.
* @param size Size of the snapshot buffer, e.g sizeof(timer_snapshot_t)
* @param force Forcibly load the snapshot without checking the style access for a player.
* @return Success boolean
*/
native bool Shavit_LoadSnapshot(int client, any[] snapshot, int size = sizeof(timer_snapshot_t));
native bool Shavit_LoadSnapshot(int client, any[] snapshot, int size = sizeof(timer_snapshot_t), bool force = false);
/**
* Use this native to stop the click sound that plays upon chat messages.

View File

@ -209,8 +209,14 @@ public SMCResult OnStyleEnterSection(SMCParser smc, const char[] name, bool opt_
SetStyleSettingInt(gI_CurrentParserIndex, "inaccessible", 0);
SetStyleSettingInt(gI_CurrentParserIndex, "enabled", 1);
SetStyleSettingInt(gI_CurrentParserIndex, "kzcheckpoints", 0);
SetStyleSettingInt(gI_CurrentParserIndex, "kzcheckpoints_ladders", 0);
SetStyleSettingInt(gI_CurrentParserIndex, "kzcheckpoints_ontele", -1);
SetStyleSettingInt(gI_CurrentParserIndex, "kzcheckpoints_onstart", -1);
SetStyleSettingInt(gI_CurrentParserIndex, "segments", 0);
SetStyleSettingInt(gI_CurrentParserIndex, "force_groundkeys", 0);
gI_OrderedStyles[gI_CurrentParserIndex] = gI_CurrentParserIndex;
@ -236,6 +242,11 @@ public SMCResult OnStyleLeaveSection(SMCParser smc)
SetStyleSettingInt (gI_CurrentParserIndex, "inaccessible", 1);
}
if (GetStyleSettingInt(gI_CurrentParserIndex, "kzcheckpoints_onstart") != -1)
{
SetStyleSettingInt (gI_CurrentParserIndex, "inaccessible", 1);
}
if (GetStyleSettingBool(gI_CurrentParserIndex, "halftime"))
{
SetStyleSettingFloat(gI_CurrentParserIndex, "timescale", 0.5);

View File

@ -79,7 +79,6 @@ Handle gH_Forwards_OnCheckpointCacheLoaded = null;
chatstrings_t gS_ChatStrings;
int gI_Style[MAXPLAYERS+1];
bool gB_ClosedKZCP[MAXPLAYERS+1];
ArrayList gA_Checkpoints[MAXPLAYERS+1];
int gI_CurrentCheckpoint[MAXPLAYERS+1];
@ -195,7 +194,7 @@ public void OnPluginStart()
Convar.AutoExecConfig();
CreateTimer(10.0, Timer_Cron, 0, TIMER_REPEAT);
CreateTimer(0.5, Timer_PersistKZCPMenu, 0, TIMER_REPEAT);
CreateTimer(0.5, Timer_PersistCPMenu, 0, TIMER_REPEAT);
LoadDHooks();
@ -397,7 +396,7 @@ public Action Timer_Cron(Handle timer)
return Plugin_Continue;
}
public Action Timer_PersistKZCPMenu(Handle timer)
public Action Timer_PersistCPMenu(Handle timer)
{
if (!gCV_Checkpoints.BoolValue)
{
@ -405,18 +404,10 @@ public Action Timer_PersistKZCPMenu(Handle timer)
}
for(int i = 1; i <= MaxClients; i++)
{
if(!gB_ClosedKZCP[i] &&
Shavit_GetStyleSettingInt(gI_Style[i], "kzcheckpoints")
&& GetClientMenu(i) == MenuSource_None &&
IsClientInGame(i) && IsPlayerAlive(i) && !IsFakeClient(i))
{
if(IsClientInGame(i) && IsPlayerAlive(i) && !IsFakeClient(i) && ShouldReopenCheckpointMenu(i))
{
OpenKZCPMenu(i);
}
// reopen repeatedly in case someone has bad internet and the menu disappears
else if (gB_InCheckpointMenu[i])
{
OpenNormalCPMenu(i);
OpenCPMenu(i);
}
}
@ -478,7 +469,6 @@ public void OnClientPutInServer(int client)
}
gB_SaveStates[client] = false;
gB_ClosedKZCP[client] = false;
}
public void OnClientDisconnect(int client)
@ -512,12 +502,15 @@ public void Shavit_OnStyleChanged(int client, int oldstyle, int newstyle, int tr
{
gI_Style[client] = newstyle;
bool bSegmented = Shavit_GetStyleSettingBool(newstyle, "segments");
bool bKzcheckpoints = Shavit_GetStyleSettingBool(newstyle, "kzcheckpoints");
if (gB_SaveStates[client] && manual)
{
DeletePersistentDataFromClient(client);
}
if (Shavit_GetStyleSettingBool(newstyle, "segments"))
if (bSegmented || bKzcheckpoints)
{
// Gammacase somehow had this callback fire before OnClientPutInServer.
// OnClientPutInServer will still fire but we need a valid arraylist in the mean time.
@ -535,9 +528,11 @@ public Action Shavit_OnStart(int client)
{
gI_TimesTeleported[client] = 0;
if (Shavit_GetStyleSettingInt(gI_Style[client], "kzcheckpoints"))
// shavit-kz
if(Shavit_GetStyleSettingBool(gI_Style[client], "kzcheckpoints"))
{
ResetCheckpoints(client);
UpdateKZStyle(client, TimerAction_OnStart);
}
return Plugin_Continue;
@ -545,12 +540,12 @@ public Action Shavit_OnStart(int client)
public void Shavit_OnRestart(int client, int track)
{
if(!gB_ClosedKZCP[client] &&
if(gB_InCheckpointMenu[client] &&
Shavit_GetStyleSettingInt(gI_Style[client], "kzcheckpoints") &&
GetClientMenu(client, null) == MenuSource_None &&
IsPlayerAlive(client) && GetClientTeam(client) >= 2)
{
OpenKZCPMenu(client);
OpenCPMenu(client);
}
}
@ -587,12 +582,12 @@ public void Player_Spawn(Event event, const char[] name, bool dontBroadcast)
}
// refreshes kz cp menu if there is nothing open
if (!gB_ClosedKZCP[client] &&
if (gB_InCheckpointMenu[client] &&
Shavit_GetStyleSettingInt(gI_Style[client], "kzcheckpoints") &&
GetClientMenu(client, null) == MenuSource_None &&
IsPlayerAlive(client) && GetClientTeam(client) >= 2)
{
OpenKZCPMenu(client);
OpenCPMenu(client);
}
}
@ -723,7 +718,9 @@ void LoadPersistentData(int serial)
gB_SaveStates[client] = false;
if (LoadCheckpointCache(client, aData.cpcache, -1))
bool bKzcheckpoints = Shavit_GetStyleSettingBool(aData.cpcache.aSnapshot.bsStyle, "kzcheckpoints");
if (LoadCheckpointCache(client, aData.cpcache, -1, bKzcheckpoints))
{
gI_TimesTeleported[client] = aData.iTimesTeleported;
@ -776,17 +773,7 @@ void ResetCheckpoints(int client)
bool ShouldReopenCheckpointMenu(int client)
{
if (gB_InCheckpointMenu[client])
{
return true;
}
if (!gB_ClosedKZCP[client] && Shavit_GetStyleSettingInt(gI_Style[client], "kzcheckpoints"))
{
return true;
}
return false;
return gB_InCheckpointMenu[client];
}
public Action Command_Checkpoints(int client, int args)
@ -803,11 +790,6 @@ public Action Command_Checkpoints(int client, int args)
return Plugin_Handled;
}
if(Shavit_GetStyleSettingInt(gI_Style[client], "kzcheckpoints"))
{
gB_ClosedKZCP[client] = false;
}
return OpenCheckpointsMenu(client);
}
@ -964,133 +946,17 @@ public Action Command_DeleteCheckpoint(int client, int args)
public Action OpenCheckpointsMenu(int client)
{
if(Shavit_GetStyleSettingInt(gI_Style[client], "kzcheckpoints"))
{
OpenKZCPMenu(client);
}
else
{
OpenNormalCPMenu(client);
}
OpenCPMenu(client);
return Plugin_Handled;
}
void OpenKZCPMenu(int client)
{
// if we're segmenting, resort to the normal checkpoints instead
if(CanSegment(client))
{
OpenNormalCPMenu(client);
return;
}
Menu menu = new Menu(MenuHandler_KZCheckpoints, MENU_ACTIONS_DEFAULT|MenuAction_DisplayItem);
menu.SetTitle("%T\n", "MiscCheckpointMenu", client);
char sDisplay[64];
FormatEx(sDisplay, 64, "%T", "MiscCheckpointSave", client, (gA_Checkpoints[client].Length + 1), gCV_MaxCP.IntValue);
menu.AddItem("save", sDisplay, (gA_Checkpoints[client].Length < gCV_MaxCP.IntValue)? ITEMDRAW_DEFAULT:ITEMDRAW_DISABLED);
if(gA_Checkpoints[client].Length > 0)
{
FormatEx(sDisplay, 64, "%T", "MiscCheckpointTeleport", client, gI_CurrentCheckpoint[client]);
menu.AddItem("tele", sDisplay, ITEMDRAW_DEFAULT);
}
else
{
FormatEx(sDisplay, 64, "%T", "MiscCheckpointTeleport", client, 1);
menu.AddItem("tele", sDisplay, ITEMDRAW_DISABLED);
}
FormatEx(sDisplay, 64, "%T", "MiscCheckpointPrevious", client);
menu.AddItem("prev", sDisplay);
FormatEx(sDisplay, 64, "%T", "MiscCheckpointNext", client);
menu.AddItem("next", sDisplay);
if((Shavit_CanPause(client) & CPR_ByConVar) == 0)
{
FormatEx(sDisplay, 64, "%T", "MiscCheckpointPause", client);
menu.AddItem("pause", sDisplay);
}
menu.ExitButton = true;
menu.Display(client, MENU_TIME_FOREVER);
}
public int MenuHandler_KZCheckpoints(Menu menu, MenuAction action, int param1, int param2)
{
if(action == MenuAction_Select)
{
if(CanSegment(param1) || !Shavit_GetStyleSettingInt(gI_Style[param1], "kzcheckpoints"))
{
return 0;
}
char sInfo[8];
menu.GetItem(param2, sInfo, 8);
if(StrEqual(sInfo, "save"))
{
if(gA_Checkpoints[param1].Length < gCV_MaxCP.IntValue)
{
SaveCheckpoint(param1);
}
}
else if(StrEqual(sInfo, "tele"))
{
TeleportToCheckpoint(param1, gI_CurrentCheckpoint[param1], true);
}
else if(StrEqual(sInfo, "prev"))
{
if(gI_CurrentCheckpoint[param1] > 1)
{
gI_CurrentCheckpoint[param1]--;
}
}
else if(StrEqual(sInfo, "next"))
{
if(gI_CurrentCheckpoint[param1] < gA_Checkpoints[param1].Length)
gI_CurrentCheckpoint[param1]++;
}
else if(StrEqual(sInfo, "pause"))
{
if(Shavit_CanPause(param1) == 0)
{
if(Shavit_IsPaused(param1))
{
Shavit_ResumeTimer(param1, true);
}
else
{
Shavit_PauseTimer(param1);
}
}
}
OpenCheckpointsMenu(param1);
}
else if(action == MenuAction_Cancel)
{
if(param2 == MenuCancel_Exit)
{
gB_ClosedKZCP[param1] = true;
}
}
else if(action == MenuAction_End)
{
delete menu;
}
return 0;
}
void OpenNormalCPMenu(int client)
void OpenCPMenu(int client)
{
bool bSegmented = CanSegment(client);
bool bKzcheckpoints = Shavit_GetStyleSettingBool(gI_Style[client], "kzcheckpoints");
if(!gCV_Checkpoints.BoolValue && !bSegmented)
if(!gCV_Checkpoints.BoolValue && !bSegmented && !bKzcheckpoints)
{
Shavit_PrintToChat(client, "%T", "FeatureDisabled", client, gS_ChatStrings.sWarning, gS_ChatStrings.sText);
@ -1101,7 +967,18 @@ void OpenNormalCPMenu(int client)
if(!bSegmented)
{
menu.SetTitle("%T\n%T\n ", "MiscCheckpointMenu", client, "MiscCheckpointWarning", client);
char sInfo[64];
if(!bKzcheckpoints)
{
FormatEx(sInfo, 64, "%T\n%T\n ", "MiscCheckpointMenu", client, "MiscCheckpointWarning", client);
}
else
{
FormatEx(sInfo, 64, "%T\n ", "MiscCheckpointMenu", client);
}
menu.SetTitle(sInfo);
}
else
{
@ -1128,9 +1005,16 @@ void OpenNormalCPMenu(int client)
FormatEx(sDisplay, 64, "%T", "MiscCheckpointPrevious", client);
menu.AddItem("prev", sDisplay, (gI_CurrentCheckpoint[client] > 1)? ITEMDRAW_DEFAULT:ITEMDRAW_DISABLED);
FormatEx(sDisplay, 64, "%T\n ", "MiscCheckpointNext", client);
FormatEx(sDisplay, 64, "%T%s", "MiscCheckpointNext", client, (bKzcheckpoints)? "":"\n ");
menu.AddItem("next", sDisplay, (gI_CurrentCheckpoint[client] < gA_Checkpoints[client].Length)? ITEMDRAW_DEFAULT:ITEMDRAW_DISABLED);
if((Shavit_CanPause(client) & CPR_ByConVar) == 0 && bKzcheckpoints)
{
FormatEx(sDisplay, 64, "%T", "MiscCheckpointPause", client);
menu.AddItem("pause", sDisplay);
}
// apparently this is the fix
// menu.AddItem("spacer", "", ITEMDRAW_RAWLINE);
@ -1147,24 +1031,29 @@ void OpenNormalCPMenu(int client)
menu.AddItem("tsplus", sDisplay, (ts != 1.0) ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED);
}
FormatEx(sDisplay, 64, "%T", "MiscCheckpointDeleteCurrent", client);
menu.AddItem("del", sDisplay, (gA_Checkpoints[client].Length > 0) ? ITEMDRAW_DEFAULT:ITEMDRAW_DISABLED);
FormatEx(sDisplay, 64, "%T", "MiscCheckpointReset", client);
menu.AddItem("reset", sDisplay);
if(!bSegmented)
if(!bKzcheckpoints)
{
char sInfo[16];
IntToString(CP_ANGLES, sInfo, 16);
FormatEx(sDisplay, 64, "%T", "MiscCheckpointUseAngles", client);
menu.AddItem(sInfo, sDisplay);
FormatEx(sDisplay, 64, "%T", "MiscCheckpointDeleteCurrent", client);
menu.AddItem("del", sDisplay, (gA_Checkpoints[client].Length > 0) ? ITEMDRAW_DEFAULT:ITEMDRAW_DISABLED);
IntToString(CP_VELOCITY, sInfo, 16);
FormatEx(sDisplay, 64, "%T", "MiscCheckpointUseVelocity", client);
menu.AddItem(sInfo, sDisplay);
FormatEx(sDisplay, 64, "%T", "MiscCheckpointReset", client);
menu.AddItem("reset", sDisplay);
if(!bSegmented)
{
char sInfo[16];
IntToString(CP_ANGLES, sInfo, 16);
FormatEx(sDisplay, 64, "%T", "MiscCheckpointUseAngles", client);
menu.AddItem(sInfo, sDisplay);
IntToString(CP_VELOCITY, sInfo, 16);
FormatEx(sDisplay, 64, "%T", "MiscCheckpointUseVelocity", client);
menu.AddItem(sInfo, sDisplay);
}
}
menu.Pagination = MENU_NO_PAGINATION;
menu.ExitButton = true;
@ -1237,6 +1126,20 @@ public int MenuHandler_Checkpoints(Menu menu, MenuAction action, int param1, int
gI_CurrentCheckpoint[param1]++;
}
}
else if(StrEqual(sInfo, "pause"))
{
if(Shavit_CanPause(param1) == 0)
{
if(Shavit_IsPaused(param1))
{
Shavit_ResumeTimer(param1, true);
}
else
{
Shavit_PauseTimer(param1);
}
}
}
else if(StrEqual(sInfo, "del"))
{
if(DeleteCheckpoint(param1, gI_CurrentCheckpoint[param1]))
@ -1680,7 +1583,9 @@ void TeleportToCheckpoint(int client, int index, bool suppressMessage)
Shavit_StopTimer(client);
}
if (!LoadCheckpointCache(client, cpcache, index))
bool bKzcheckpoints = Shavit_GetStyleSettingBool(gI_Style[client], "kzcheckpoints");
if (!LoadCheckpointCache(client, cpcache, index, bKzcheckpoints))
{
return;
}
@ -1692,6 +1597,12 @@ void TeleportToCheckpoint(int client, int index, bool suppressMessage)
Call_PushCell(index);
Call_Finish();
// shavit-kz
if(bKzcheckpoints)
{
UpdateKZStyle(client, TimerAction_OnTeleport);
}
if(!suppressMessage)
{
Shavit_PrintToChat(client, "%T", "MiscCheckpointsTeleported", client, index, gS_ChatStrings.sVariable, gS_ChatStrings.sText);
@ -1699,10 +1610,10 @@ void TeleportToCheckpoint(int client, int index, bool suppressMessage)
}
// index = -1 when persistent data. index = 0 when Shavit_LoadCheckpointCache() usually. index > 0 when "actually a checkpoint"
bool LoadCheckpointCache(int client, cp_cache_t cpcache, int index)
bool LoadCheckpointCache(int client, cp_cache_t cpcache, int index, bool force = false)
{
// ripped this out and put it here since Shavit_LoadSnapshot() checks this and we want to bail early if LoadSnapShot would fail
if (!Shavit_HasStyleAccess(client, cpcache.aSnapshot.bsStyle))
if (!Shavit_HasStyleAccess(client, cpcache.aSnapshot.bsStyle) && !force)
{
return false;
}
@ -1755,7 +1666,7 @@ bool LoadCheckpointCache(int client, cp_cache_t cpcache, int index)
Shavit_SetPracticeMode(client, true, true);
}
Shavit_LoadSnapshot(client, cpcache.aSnapshot);
Shavit_LoadSnapshot(client, cpcache.aSnapshot, sizeof(timer_snapshot_t), force);
Shavit_UpdateLaggedMovement(client, true);
SetEntPropString(client, Prop_Data, "m_iName", cpcache.sTargetname);
@ -1843,6 +1754,29 @@ bool DeleteCheckpoint(int client, int index, bool force=false)
return true;
}
bool UpdateKZStyle(int client, TimerAction timerAction)
{
int iTargetStyle = -1;
if(timerAction == TimerAction_OnStart)
{
iTargetStyle = Shavit_GetStyleSettingInt(gI_Style[client], "kzcheckpoints_onstart");
}
else if(timerAction == TimerAction_OnTeleport)
{
iTargetStyle = Shavit_GetStyleSettingInt(gI_Style[client], "kzcheckpoints_ontele");
}
if(iTargetStyle != -1)
{
Shavit_ChangeClientStyle(client, iTargetStyle, true, false, false);
return true;
}
return false;
}
public any Native_GetCheckpoint(Handle plugin, int numParams)
{
if(GetNativeCell(4) != sizeof(cp_cache_t))
@ -2026,8 +1960,9 @@ public any Native_LoadCheckpointCache(Handle plugin, int numParams)
cp_cache_t cache;
GetNativeArray(2, cache, sizeof(cp_cache_t));
int index = GetNativeCell(3);
bool force = GetNativeCell(5);
return LoadCheckpointCache(client, cache, index);
return LoadCheckpointCache(client, cache, index, force);
}
public any Native_SaveCheckpointCache(Handle plugin, int numParams)

View File

@ -2172,7 +2172,9 @@ public int Native_LoadSnapshot(Handle handler, int numParams)
GetNativeArray(2, snapshot, sizeof(timer_snapshot_t));
snapshot.fTimescale = (snapshot.fTimescale > 0.0) ? snapshot.fTimescale : 1.0;
if (!Shavit_HasStyleAccess(client, snapshot.bsStyle))
bool force = GetNativeCell(4);
if (!Shavit_HasStyleAccess(client, snapshot.bsStyle) && !force)
{
return 0;
}

View File

@ -1808,7 +1808,7 @@ public Action Command_Weapon(int client, int args)
bool CanSegment(int client)
{
return StrContains(gS_StyleStrings[gI_Style[client]].sSpecialString, "segments") != -1;
return Shavit_GetStyleSettingBool(gI_Style[client], "segments");
}
bool ShouldDisplayStopWarning(int client)

View File

@ -4406,10 +4406,10 @@ public void StartTouchPost(int entity, int other)
case Zone_Stage:
{
int num = gA_ZoneCache[gI_EntityZone[entity]].iZoneData;
char special[sizeof(stylestrings_t::sSpecialString)];
Shavit_GetStyleStrings(Shavit_GetBhopStyle(other), sSpecialString, special, sizeof(special));
int iStyle = Shavit_GetBhopStyle(other);
bool bTASSegments = Shavit_GetStyleSettingBool(iStyle, "tas") || Shavit_GetStyleSettingBool(iStyle, "segments");
if (status == Timer_Running && Shavit_GetClientTrack(other) == gA_ZoneCache[gI_EntityZone[entity]].iZoneTrack && (num > gI_LastStage[other] || StrContains(special, "segments") != -1 || StrContains(special, "TAS") != -1 || Shavit_IsPracticeMode(other)))
if (status == Timer_Running && Shavit_GetClientTrack(other) == gA_ZoneCache[gI_EntityZone[entity]].iZoneTrack && (num > gI_LastStage[other] || bTASSegments || Shavit_IsPracticeMode(other)))
{
gI_LastStage[other] = num;
char sTime[32];