mirror of
https://github.com/shavitush/bhoptimer.git
synced 2025-12-06 18:08:26 +00:00
Added segmented run support with replay integration.
Use `segments` in the `specialstring` property to enable segmented checkpoints.
This commit is contained in:
parent
41c2136b42
commit
afe0a261a7
@ -36,7 +36,7 @@ Some features are: Per-player settings (!hud), truevel and gradient-like display
|
|||||||
#### shavit-misc
|
#### shavit-misc
|
||||||
This plugin handles miscellaneous things used in bunnyhop servers.
|
This plugin handles miscellaneous things used in bunnyhop servers.
|
||||||
|
|
||||||
Such as: Team handling (respawning/spectating too), spectators list (!specs), smart player hiding that works for spectating too, teleportation to other players, weapon commands (!knife/!usp/!glock) and ammo management, segmented checkpoints, noclipping (can be set to work for VIPs/admins only), drop-all, godmode, prespeed blocking, prespeed limitation, chat tidying, radar hiding, weapon drop cleaning, player collision removal, auto-respawning, spawn points generator, radio removal, scoreboard manipulation, model opacity changes, fixed runspeed, automatic and configurable chat advertisements, player ragdoll removal and WR messages.
|
Such as: Segmented runs, team handling (respawning/spectating too), spectators list (!specs), smart player hiding that works for spectating too, teleportation to other players, weapon commands (!knife/!usp/!glock) and ammo management, segmented checkpoints, noclipping (can be set to work for VIPs/admins only), drop-all, godmode, prespeed blocking, prespeed limitation, chat tidying, radar hiding, weapon drop cleaning, player collision removal, auto-respawning, spawn points generator, radio removal, scoreboard manipulation, model opacity changes, fixed runspeed, automatic and configurable chat advertisements, player ragdoll removal and WR messages.
|
||||||
|
|
||||||
#### shavit-rankings
|
#### shavit-rankings
|
||||||
Enables !rank, !top and introduces map tiers (!settier).
|
Enables !rank, !top and introduces map tiers (!settier).
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
This is (nearly) an all-in-one server plugin for Counter-Strike: Source, Counter-Strike: Global Offensive and Team Fortress 2 that adds a timer system and many other utilities, so you can install it and have a proper bunnyhop server running.
|
This is (nearly) an all-in-one server plugin for Counter-Strike: Source, Counter-Strike: Global Offensive and Team Fortress 2 that adds a timer system and many other utilities, so you can install it and have a proper bunnyhop server running.
|
||||||
|
|
||||||
Including a records system, map zones (start/end marks etc), bonuses, HUD with useful information, chat processor, miscellaneous such as weapon commands/spawn point generator, bots that replay the best records of the map, sounds, statistics, a fair & competitive rankings system and more!
|
Including a records system, map zones (start/end marks etc), bonuses, HUD with useful information, chat processor, miscellaneous such as weapon commands/spawn point generator, bots that replay the best records of the map, sounds, statistics, segmented running, a fair & competitive rankings system and more!
|
||||||
|
|
||||||
[Mapzones' setup demonstration](https://youtu.be/OXFMGm40F6c)
|
[Mapzones' setup demonstration](https://youtu.be/OXFMGm40F6c)
|
||||||
|
|
||||||
|
|||||||
@ -50,19 +50,22 @@ enum CheckpointsCache
|
|||||||
iCPFlags,
|
iCPFlags,
|
||||||
any:aCPSnapshot[TIMERSNAPSHOT_SIZE],
|
any:aCPSnapshot[TIMERSNAPSHOT_SIZE],
|
||||||
String:sCPTargetname[32],
|
String:sCPTargetname[32],
|
||||||
|
ArrayList:aCPFrames,
|
||||||
|
bool:bCPSegmented,
|
||||||
PCPCACHE_SIZE
|
PCPCACHE_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma newdecls required
|
#pragma newdecls required
|
||||||
#pragma semicolon 1
|
#pragma semicolon 1
|
||||||
#pragma dynamic 131072
|
#pragma dynamic 524288
|
||||||
|
|
||||||
#define CP_ANGLES (1 << 0)
|
#define CP_ANGLES (1 << 0)
|
||||||
#define CP_VELOCITY (1 << 1)
|
#define CP_VELOCITY (1 << 1)
|
||||||
|
|
||||||
#define CP_DEFAULT (CP_ANGLES|CP_VELOCITY)
|
#define CP_DEFAULT (CP_ANGLES|CP_VELOCITY)
|
||||||
|
|
||||||
#define CP_MAX 1000 // segmented runs shouldn't even reach 1k jumps on any map anyways
|
#define CP_MAX 1000 // shouldn't even reach 1k jumps on any map when routing anyways
|
||||||
|
#define CP_MAX_SEGMENTED 25
|
||||||
|
|
||||||
// game specific
|
// game specific
|
||||||
EngineVersion gEV_Type = Engine_Unknown;
|
EngineVersion gEV_Type = Engine_Unknown;
|
||||||
@ -84,7 +87,7 @@ int gI_LastShot[MAXPLAYERS+1];
|
|||||||
ArrayList gA_Advertisements = null;
|
ArrayList gA_Advertisements = null;
|
||||||
int gI_AdvertisementsCycle = 0;
|
int gI_AdvertisementsCycle = 0;
|
||||||
char gS_CurrentMap[192];
|
char gS_CurrentMap[192];
|
||||||
int gBS_Style[MAXPLAYERS+1];
|
int gI_Style[MAXPLAYERS+1];
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -425,7 +428,7 @@ public void OnClientCookiesCached(int client)
|
|||||||
gI_CheckpointsSettings[client] = StringToInt(sSetting);
|
gI_CheckpointsSettings[client] = StringToInt(sSetting);
|
||||||
}
|
}
|
||||||
|
|
||||||
gBS_Style[client] = Shavit_GetBhopStyle(client);
|
gI_Style[client] = Shavit_GetBhopStyle(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Shavit_OnStyleConfigLoaded(int styles)
|
public void Shavit_OnStyleConfigLoaded(int styles)
|
||||||
@ -440,6 +443,7 @@ public void Shavit_OnStyleConfigLoaded(int styles)
|
|||||||
Shavit_GetStyleSettings(i, gA_StyleSettings[i]);
|
Shavit_GetStyleSettings(i, gA_StyleSettings[i]);
|
||||||
Shavit_GetStyleStrings(i, sStyleName, gS_StyleStrings[i][sStyleName], 128);
|
Shavit_GetStyleStrings(i, sStyleName, gS_StyleStrings[i][sStyleName], 128);
|
||||||
Shavit_GetStyleStrings(i, sClanTag, gS_StyleStrings[i][sClanTag], 128);
|
Shavit_GetStyleStrings(i, sClanTag, gS_StyleStrings[i][sClanTag], 128);
|
||||||
|
Shavit_GetStyleStrings(i, sSpecialString, gS_StyleStrings[i][sSpecialString], 128);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,7 +462,14 @@ public void Shavit_OnChatConfigLoaded()
|
|||||||
|
|
||||||
public void Shavit_OnStyleChanged(int client, int oldstyle, int newstyle, int track, bool manual)
|
public void Shavit_OnStyleChanged(int client, int oldstyle, int newstyle, int track, bool manual)
|
||||||
{
|
{
|
||||||
gBS_Style[client] = newstyle;
|
gI_Style[client] = newstyle;
|
||||||
|
|
||||||
|
if(StrContains(gS_StyleStrings[oldstyle][sSpecialString], "segments") == -1 &&
|
||||||
|
StrContains(gS_StyleStrings[newstyle][sSpecialString], "segments") != -1)
|
||||||
|
{
|
||||||
|
OpenCheckpointsMenu(client, 0);
|
||||||
|
Shavit_PrintToChat(client, "%T", "MiscSegmentedCommand", client, gS_ChatStrings[sMessageVariable], gS_ChatStrings[sMessageText]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
||||||
@ -503,6 +514,11 @@ public void OnConfigsExecuted()
|
|||||||
|
|
||||||
public void OnMapStart()
|
public void OnMapStart()
|
||||||
{
|
{
|
||||||
|
for(int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
ResetCheckpoints(i);
|
||||||
|
}
|
||||||
|
|
||||||
gSM_Checkpoints.Clear();
|
gSM_Checkpoints.Clear();
|
||||||
|
|
||||||
GetCurrentMap(gS_CurrentMap, 192);
|
GetCurrentMap(gS_CurrentMap, 192);
|
||||||
@ -547,6 +563,14 @@ public void OnMapStart()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnMapEnd()
|
||||||
|
{
|
||||||
|
for(int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
ResetCheckpoints(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool LoadAdvertisementsConfig()
|
bool LoadAdvertisementsConfig()
|
||||||
{
|
{
|
||||||
gA_Advertisements.Clear();
|
gA_Advertisements.Clear();
|
||||||
@ -727,7 +751,7 @@ public MRESReturn DHook_GetPlayerMaxSpeed(int pThis, Handle hReturn)
|
|||||||
return MRES_Ignored;
|
return MRES_Ignored;
|
||||||
}
|
}
|
||||||
|
|
||||||
DHookSetReturn(hReturn, view_as<float>(gA_StyleSettings[gBS_Style[pThis]][fRunspeed]));
|
DHookSetReturn(hReturn, view_as<float>(gA_StyleSettings[gI_Style[pThis]][fRunspeed]));
|
||||||
|
|
||||||
return MRES_Override;
|
return MRES_Override;
|
||||||
}
|
}
|
||||||
@ -888,8 +912,8 @@ void UpdateClanTag(int client)
|
|||||||
|
|
||||||
char[] sCustomTag = new char[32];
|
char[] sCustomTag = new char[32];
|
||||||
strcopy(sCustomTag, 32, gS_ClanTag);
|
strcopy(sCustomTag, 32, gS_ClanTag);
|
||||||
ReplaceString(sCustomTag, 32, "{style}", gS_StyleStrings[gBS_Style[client]][sStyleName]);
|
ReplaceString(sCustomTag, 32, "{style}", gS_StyleStrings[gI_Style[client]][sStyleName]);
|
||||||
ReplaceString(sCustomTag, 32, "{styletag}", gS_StyleStrings[gBS_Style[client]][sClanTag]);
|
ReplaceString(sCustomTag, 32, "{styletag}", gS_StyleStrings[gI_Style[client]][sClanTag]);
|
||||||
ReplaceString(sCustomTag, 32, "{time}", sTime);
|
ReplaceString(sCustomTag, 32, "{time}", sTime);
|
||||||
ReplaceString(sCustomTag, 32, "{tr}", sTrack);
|
ReplaceString(sCustomTag, 32, "{tr}", sTrack);
|
||||||
|
|
||||||
@ -919,7 +943,7 @@ public Action Shavit_OnUserCmdPre(int client, int &buttons, int &impulse, float
|
|||||||
int iGroundEntity = GetEntPropEnt(client, Prop_Send, "m_hGroundEntity");
|
int iGroundEntity = GetEntPropEnt(client, Prop_Send, "m_hGroundEntity");
|
||||||
|
|
||||||
// prespeed
|
// prespeed
|
||||||
if(!bNoclip && !gA_StyleSettings[gBS_Style[client]][bPrespeed] && Shavit_InsideZone(client, Zone_Start, track))
|
if(!bNoclip && !gA_StyleSettings[gI_Style[client]][bPrespeed] && Shavit_InsideZone(client, Zone_Start, track))
|
||||||
{
|
{
|
||||||
if((gI_PreSpeed == 2 || gI_PreSpeed == 3) && gI_GroundEntity[client] == -1 && iGroundEntity != -1 && (buttons & IN_JUMP) > 0)
|
if((gI_PreSpeed == 2 || gI_PreSpeed == 3) && gI_GroundEntity[client] == -1 && iGroundEntity != -1 && (buttons & IN_JUMP) > 0)
|
||||||
{
|
{
|
||||||
@ -940,7 +964,7 @@ public Action Shavit_OnUserCmdPre(int client, int &buttons, int &impulse, float
|
|||||||
|
|
||||||
if(gI_PreSpeed < 4)
|
if(gI_PreSpeed < 4)
|
||||||
{
|
{
|
||||||
fLimit = view_as<float>(gA_StyleSettings[gBS_Style[client]][fRunspeed]) + gF_PrestrafeLimit;
|
fLimit = view_as<float>(gA_StyleSettings[gI_Style[client]][fRunspeed]) + gF_PrestrafeLimit;
|
||||||
|
|
||||||
// if trying to jump, add a very low limit to stop prespeeding in an elegant way
|
// if trying to jump, add a very low limit to stop prespeeding in an elegant way
|
||||||
// otherwise, make sure nothing weird is happening (such as sliding at ridiculous speeds, at zone enter)
|
// otherwise, make sure nothing weird is happening (such as sliding at ridiculous speeds, at zone enter)
|
||||||
@ -985,7 +1009,7 @@ public void OnClientPutInServer(int client)
|
|||||||
|
|
||||||
if(!AreClientCookiesCached(client))
|
if(!AreClientCookiesCached(client))
|
||||||
{
|
{
|
||||||
gBS_Style[client] = Shavit_GetBhopStyle(client);
|
gI_Style[client] = Shavit_GetBhopStyle(client);
|
||||||
gB_Hide[client] = false;
|
gB_Hide[client] = false;
|
||||||
gI_CheckpointsSettings[client] = CP_DEFAULT;
|
gI_CheckpointsSettings[client] = CP_DEFAULT;
|
||||||
}
|
}
|
||||||
@ -1015,6 +1039,14 @@ void ResetCheckpoints(int client)
|
|||||||
for(int i = 0; i < gI_CheckpointsCache[client][iCheckpoints]; i++)
|
for(int i = 0; i < gI_CheckpointsCache[client][iCheckpoints]; i++)
|
||||||
{
|
{
|
||||||
FormatEx(key, 32, "%d_%d", serial, i);
|
FormatEx(key, 32, "%d_%d", serial, i);
|
||||||
|
|
||||||
|
CheckpointsCache cpcache[PCPCACHE_SIZE];
|
||||||
|
|
||||||
|
if(gSM_Checkpoints.GetArray(key, cpcache[0], view_as<int>(PCPCACHE_SIZE)))
|
||||||
|
{
|
||||||
|
delete cpcache[aCPFrames]; // free up replay frames if there are any
|
||||||
|
}
|
||||||
|
|
||||||
gSM_Checkpoints.Remove(key);
|
gSM_Checkpoints.Remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1099,7 +1131,7 @@ public void OnPreThink(int client)
|
|||||||
if(IsPlayerAlive(client))
|
if(IsPlayerAlive(client))
|
||||||
{
|
{
|
||||||
// not the best method, but only one i found for tf2
|
// not the best method, but only one i found for tf2
|
||||||
SetEntPropFloat(client, Prop_Send, "m_flMaxspeed", view_as<float>(gA_StyleSettings[gBS_Style[client]][fRunspeed]));
|
SetEntPropFloat(client, Prop_Send, "m_flMaxspeed", view_as<float>(gA_StyleSettings[gI_Style[client]][fRunspeed]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1501,7 +1533,9 @@ public Action Command_Tele(int client, int args)
|
|||||||
|
|
||||||
public Action OpenCheckpointsMenu(int client, int item)
|
public Action OpenCheckpointsMenu(int client, int item)
|
||||||
{
|
{
|
||||||
if(!gB_Checkpoints)
|
bool bSegmented = CanSegment(client);
|
||||||
|
|
||||||
|
if(!gB_Checkpoints && !bSegmented)
|
||||||
{
|
{
|
||||||
Shavit_PrintToChat(client, "%T", "FeatureDisabled", client, gS_ChatStrings[sMessageWarning], gS_ChatStrings[sMessageText]);
|
Shavit_PrintToChat(client, "%T", "FeatureDisabled", client, gS_ChatStrings[sMessageWarning], gS_ChatStrings[sMessageText]);
|
||||||
|
|
||||||
@ -1509,7 +1543,16 @@ public Action OpenCheckpointsMenu(int client, int item)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Menu menu = new Menu(MenuHandler_Checkpoints, MENU_ACTIONS_DEFAULT|MenuAction_DisplayItem);
|
Menu menu = new Menu(MenuHandler_Checkpoints, MENU_ACTIONS_DEFAULT|MenuAction_DisplayItem);
|
||||||
menu.SetTitle("%T\n%T\n ", "MiscCheckpointMenu", client, "MiscCheckpointWarning", client);
|
|
||||||
|
if(!bSegmented)
|
||||||
|
{
|
||||||
|
menu.SetTitle("%T\n%T\n ", "MiscCheckpointMenu", client, "MiscCheckpointWarning", client);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
menu.SetTitle("%T\n ", "MiscCheckpointMenuSegmented", client);
|
||||||
|
}
|
||||||
|
|
||||||
char[] sDisplay = new char[64];
|
char[] sDisplay = new char[64];
|
||||||
FormatEx(sDisplay, 64, "%T", "MiscCheckpointSave", client, (gI_CheckpointsCache[client][iCheckpoints] + 1));
|
FormatEx(sDisplay, 64, "%T", "MiscCheckpointSave", client, (gI_CheckpointsCache[client][iCheckpoints] + 1));
|
||||||
@ -1556,30 +1599,42 @@ public int MenuHandler_Checkpoints(Menu menu, MenuAction action, int param1, int
|
|||||||
{
|
{
|
||||||
if(action == MenuAction_Select)
|
if(action == MenuAction_Select)
|
||||||
{
|
{
|
||||||
int current = gI_CheckpointsCache[param1][iCurrentCheckpoint];
|
bool bSegmenting = CanSegment(param1);
|
||||||
|
int iMaxCPs = GetMaxCPs(param1);
|
||||||
|
int iCurrent = gI_CheckpointsCache[param1][iCurrentCheckpoint];
|
||||||
|
|
||||||
switch(param2)
|
switch(param2)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
// fight an exploit
|
if(!bSegmenting)
|
||||||
if(gI_CheckpointsCache[param1][iCheckpoints] >= CP_MAX)
|
|
||||||
{
|
{
|
||||||
return 0;
|
// fight an exploit
|
||||||
|
if(gI_CheckpointsCache[param1][iCheckpoints] >= iMaxCPs)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveCheckpoint(param1, gI_CheckpointsCache[param1][iCheckpoints]);
|
||||||
|
gI_CheckpointsCache[param1][iCurrentCheckpoint] = ++gI_CheckpointsCache[param1][iCheckpoints];
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveCheckpoint(param1, gI_CheckpointsCache[param1][iCheckpoints]);
|
else
|
||||||
gI_CheckpointsCache[param1][iCurrentCheckpoint] = ++gI_CheckpointsCache[param1][iCheckpoints];
|
{
|
||||||
|
bool bOverflow = gI_CheckpointsCache[param1][iCheckpoints] >= iMaxCPs;
|
||||||
|
SaveCheckpoint(param1, gI_CheckpointsCache[param1][iCheckpoints], bOverflow);
|
||||||
|
gI_CheckpointsCache[param1][iCurrentCheckpoint] = (bOverflow)? iMaxCPs:++gI_CheckpointsCache[param1][iCheckpoints];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
TeleportToCheckpoint(param1, current - 1, true);
|
TeleportToCheckpoint(param1, iCurrent - 1, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
if(current > 1)
|
if(iCurrent > 1)
|
||||||
{
|
{
|
||||||
gI_CheckpointsCache[param1][iCurrentCheckpoint]--;
|
gI_CheckpointsCache[param1][iCurrentCheckpoint]--;
|
||||||
}
|
}
|
||||||
@ -1589,7 +1644,7 @@ public int MenuHandler_Checkpoints(Menu menu, MenuAction action, int param1, int
|
|||||||
{
|
{
|
||||||
CheckpointsCache cpcache[PCPCACHE_SIZE];
|
CheckpointsCache cpcache[PCPCACHE_SIZE];
|
||||||
|
|
||||||
if(current < CP_MAX && GetCheckpoint(param1, current, cpcache))
|
if(iCurrent < iMaxCPs && GetCheckpoint(param1, iCurrent, cpcache))
|
||||||
{
|
{
|
||||||
gI_CheckpointsCache[param1][iCurrentCheckpoint]++;
|
gI_CheckpointsCache[param1][iCurrentCheckpoint]++;
|
||||||
}
|
}
|
||||||
@ -1636,7 +1691,7 @@ public int MenuHandler_Checkpoints(Menu menu, MenuAction action, int param1, int
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SaveCheckpoint(int client, int index)
|
bool SaveCheckpoint(int client, int index, bool overflow = false)
|
||||||
{
|
{
|
||||||
int target = client;
|
int target = client;
|
||||||
|
|
||||||
@ -1726,6 +1781,56 @@ bool SaveCheckpoint(int client, int index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CopyArray(snapshot, cpcache[aCPSnapshot], TIMERSNAPSHOT_SIZE);
|
CopyArray(snapshot, cpcache[aCPSnapshot], TIMERSNAPSHOT_SIZE);
|
||||||
|
|
||||||
|
if(CanSegment(client))
|
||||||
|
{
|
||||||
|
if(gB_Replay)
|
||||||
|
{
|
||||||
|
cpcache[aCPFrames] = Shavit_GetReplayData(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
cpcache[bCPSegmented] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cpcache[aCPFrames] = null;
|
||||||
|
cpcache[bCPSegmented] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(overflow)
|
||||||
|
{
|
||||||
|
int iSerial = GetClientSerial(client);
|
||||||
|
int iMaxCPs = GetMaxCPs(client);
|
||||||
|
|
||||||
|
char[] sKey = new char[32];
|
||||||
|
|
||||||
|
for(int i = 0; i < iMaxCPs; i++)
|
||||||
|
{
|
||||||
|
CheckpointsCache cpcacheold[PCPCACHE_SIZE];
|
||||||
|
FormatEx(sKey, 32, "%d_%d", iSerial, i);
|
||||||
|
|
||||||
|
if(!gSM_Checkpoints.GetArray(sKey, cpcacheold[0], view_as<int>(PCPCACHE_SIZE)))
|
||||||
|
{
|
||||||
|
continue; // ???
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i == 0)
|
||||||
|
{
|
||||||
|
delete cpcacheold[aCPFrames];
|
||||||
|
gSM_Checkpoints.Remove(sKey);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
gSM_Checkpoints.Remove(sKey);
|
||||||
|
FormatEx(sKey, 32, "%d_%d", iSerial, (i - 1)); // set cp index to one less
|
||||||
|
gSM_Checkpoints.SetArray(sKey, cpcacheold[0], view_as<int>(PCPCACHE_SIZE));
|
||||||
|
}
|
||||||
|
|
||||||
|
index = (iMaxCPs - 1);
|
||||||
|
}
|
||||||
|
|
||||||
SetCheckpoint(client, index, cpcache);
|
SetCheckpoint(client, index, cpcache);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -1733,7 +1838,7 @@ bool SaveCheckpoint(int client, int index)
|
|||||||
|
|
||||||
void TeleportToCheckpoint(int client, int index, bool suppressMessage)
|
void TeleportToCheckpoint(int client, int index, bool suppressMessage)
|
||||||
{
|
{
|
||||||
if(index < 0 || index >= CP_MAX)
|
if(index < 0 || index >= CP_MAX || (!gB_Checkpoints && !CanSegment(client)))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1769,7 +1874,10 @@ void TeleportToCheckpoint(int client, int index, bool suppressMessage)
|
|||||||
Shavit_StopTimer(client);
|
Shavit_StopTimer(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
Shavit_SetPracticeMode(client, true, !bInStart);
|
if(!cpcache[bCPSegmented])
|
||||||
|
{
|
||||||
|
Shavit_SetPracticeMode(client, true, !bInStart);
|
||||||
|
}
|
||||||
|
|
||||||
any snapshot[TIMERSNAPSHOT_SIZE];
|
any snapshot[TIMERSNAPSHOT_SIZE];
|
||||||
CopyArray(cpcache[aCPSnapshot], snapshot, TIMERSNAPSHOT_SIZE);
|
CopyArray(cpcache[aCPSnapshot], snapshot, TIMERSNAPSHOT_SIZE);
|
||||||
@ -1816,6 +1924,16 @@ void TeleportToCheckpoint(int client, int index, bool suppressMessage)
|
|||||||
SetEntPropFloat(client, Prop_Send, "m_flDuckSpeed", cpcache[fCPDuckSpeed]);
|
SetEntPropFloat(client, Prop_Send, "m_flDuckSpeed", cpcache[fCPDuckSpeed]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(cpcache[bCPSegmented] && gB_Replay)
|
||||||
|
{
|
||||||
|
Shavit_SetReplayData(client, cpcache[aCPFrames]);
|
||||||
|
|
||||||
|
if((gI_CheckpointsSettings[client] & CP_ANGLES) > 0)
|
||||||
|
{
|
||||||
|
Shavit_HijackAngles(client, ang[0], ang[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!suppressMessage)
|
if(!suppressMessage)
|
||||||
{
|
{
|
||||||
Shavit_PrintToChat(client, "%T", "MiscCheckpointsTeleported", client, (index + 1), gS_ChatStrings[sMessageVariable], gS_ChatStrings[sMessageText]);
|
Shavit_PrintToChat(client, "%T", "MiscCheckpointsTeleported", client, (index + 1), gS_ChatStrings[sMessageVariable], gS_ChatStrings[sMessageText]);
|
||||||
@ -1977,7 +2095,7 @@ public Action Command_Specs(int client, int args)
|
|||||||
|
|
||||||
public Action Shavit_OnStart(int client)
|
public Action Shavit_OnStart(int client)
|
||||||
{
|
{
|
||||||
if(!gA_StyleSettings[gBS_Style[client]][bPrespeed] && GetEntityMoveType(client) == MOVETYPE_NOCLIP)
|
if(!gA_StyleSettings[gI_Style[client]][bPrespeed] && GetEntityMoveType(client) == MOVETYPE_NOCLIP)
|
||||||
{
|
{
|
||||||
return Plugin_Stop;
|
return Plugin_Stop;
|
||||||
}
|
}
|
||||||
@ -2499,6 +2617,7 @@ void LoadState(int client)
|
|||||||
if(gB_Replay && gA_SaveFrames[client] != null)
|
if(gB_Replay && gA_SaveFrames[client] != null)
|
||||||
{
|
{
|
||||||
Shavit_SetReplayData(client, gA_SaveFrames[client]);
|
Shavit_SetReplayData(client, gA_SaveFrames[client]);
|
||||||
|
Shavit_HijackAngles(client, gF_SaveStateData[client][1][0], gF_SaveStateData[client][1][1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete gA_SaveFrames[client];
|
delete gA_SaveFrames[client];
|
||||||
@ -2550,3 +2669,13 @@ void CopyArray(const any[] from, any[] to, int size)
|
|||||||
to[i] = from[i];
|
to[i] = from[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CanSegment(int client)
|
||||||
|
{
|
||||||
|
return StrContains(gS_StyleStrings[gI_Style[client]][sSpecialString], "segments") != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetMaxCPs(int client)
|
||||||
|
{
|
||||||
|
return CanSegment(client)? CP_MAX_SEGMENTED:CP_MAX;
|
||||||
|
}
|
||||||
|
|||||||
@ -83,6 +83,11 @@
|
|||||||
"#format" "{1:d},{2:s},{3:s}"
|
"#format" "{1:d},{2:s},{3:s}"
|
||||||
"en" "Checkpoint {1} is {2}empty{3}."
|
"en" "Checkpoint {1} is {2}empty{3}."
|
||||||
}
|
}
|
||||||
|
"MiscSegmentedCommand"
|
||||||
|
{
|
||||||
|
"#format" "{1:s},{2:s}"
|
||||||
|
"en" "Use {1}!cp{2} to re-open the segmented checkpoints menu."
|
||||||
|
}
|
||||||
// ---------- Menus ---------- //
|
// ---------- Menus ---------- //
|
||||||
"TeleportMenuTitle"
|
"TeleportMenuTitle"
|
||||||
{
|
{
|
||||||
@ -97,6 +102,10 @@
|
|||||||
{
|
{
|
||||||
"en" "Checkpoints"
|
"en" "Checkpoints"
|
||||||
}
|
}
|
||||||
|
"MiscCheckpointMenuSegmented"
|
||||||
|
{
|
||||||
|
"en" "Segmented Checkpoints"
|
||||||
|
}
|
||||||
"MiscCheckpointWarning"
|
"MiscCheckpointWarning"
|
||||||
{
|
{
|
||||||
"en" "WARNING: Teleporting will stop your timer!"
|
"en" "WARNING: Teleporting will stop your timer!"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user