mirror of
https://github.com/shavitush/bhoptimer.git
synced 2025-12-06 18:08:26 +00:00
Merge pull request #583 from shavitush/chat
Some updates after a while with none
This commit is contained in:
commit
d0eba8fd71
@ -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:
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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"
|
||||
}
|
||||
@ -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.
|
||||
|
||||
@ -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,
|
||||
@ -101,7 +107,7 @@ enum
|
||||
iForceHSW,
|
||||
bBlockPLeft,
|
||||
bBlockPRight,
|
||||
bBlockPStrafe,
|
||||
iBlockPStrafe,
|
||||
bUnranked,
|
||||
bNoReplay,
|
||||
bSync,
|
||||
@ -128,10 +134,7 @@ enum
|
||||
enum
|
||||
{
|
||||
bTimerEnabled,
|
||||
fStartTime,
|
||||
fCurrentTime,
|
||||
fPauseStartTime,
|
||||
fPauseTotalTime,
|
||||
bClientPaused,
|
||||
iJumps,
|
||||
bsStyle,
|
||||
@ -294,9 +297,36 @@ 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.
|
||||
* 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.
|
||||
@ -354,9 +384,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.
|
||||
@ -786,6 +817,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 +1163,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");
|
||||
|
||||
@ -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]);
|
||||
}
|
||||
|
||||
|
||||
@ -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];
|
||||
@ -193,7 +194,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);
|
||||
@ -202,7 +203,9 @@ 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);
|
||||
|
||||
LoadTranslations("shavit-core.phrases");
|
||||
|
||||
@ -251,13 +254,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 +442,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 +490,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();
|
||||
}
|
||||
|
||||
@ -606,22 +561,22 @@ 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]);
|
||||
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]);
|
||||
}
|
||||
|
||||
@ -808,7 +763,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);
|
||||
@ -947,8 +902,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]);
|
||||
@ -956,7 +910,7 @@ public int Native_GetTimer(Handle handler, int numParams)
|
||||
|
||||
public int Native_GetClientTime(Handle handler, int numParams)
|
||||
{
|
||||
return view_as<int>(CalculateTime(GetNativeCell(1)));
|
||||
return view_as<int>(gF_PlayerTimer[GetNativeCell(1)]);
|
||||
}
|
||||
|
||||
public int Native_GetClientTrack(Handle handler, int numParams)
|
||||
@ -1005,11 +959,8 @@ 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];
|
||||
snapshot[fPauseTotalTime] = gF_PauseTotalTime[client];
|
||||
snapshot[bClientPaused] = gB_ClientPaused[client];
|
||||
snapshot[iJumps] = gI_Jumps[client];
|
||||
snapshot[bsStyle] = gBS_Style[client];
|
||||
@ -1017,7 +968,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];
|
||||
|
||||
@ -1035,25 +986,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(CalculateTime(client));
|
||||
Call_PushCell(style = gBS_Style[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);
|
||||
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);
|
||||
@ -1175,9 +1138,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];
|
||||
@ -1185,7 +1145,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];
|
||||
|
||||
@ -1207,16 +1167,14 @@ public int Native_LoadSnapshot(Handle handler, int numParams)
|
||||
}
|
||||
|
||||
gB_TimerEnabled[client] = view_as<bool>(snapshot[bTimerEnabled]);
|
||||
gF_PauseStartTime[client] = view_as<float>(snapshot[fPauseStartTime]);
|
||||
gF_PauseTotalTime[client] = view_as<float>(snapshot[fPauseTotalTime]);
|
||||
gB_ClientPaused[client] = false; // Pausing is disabled in practice mode.
|
||||
gB_ClientPaused[client] = view_as<bool>(snapshot[bClientPaused]);
|
||||
gI_Jumps[client] = view_as<int>(snapshot[iJumps]);
|
||||
gBS_Style[client] = snapshot[bsStyle];
|
||||
gI_Strafes[client] = view_as<int>(snapshot[iStrafes]);
|
||||
gI_TotalMeasures[client] = view_as<int>(snapshot[iTotalMeasures]);
|
||||
gI_GoodGains[client] = view_as<int>(snapshot[iGoodGains]);
|
||||
gF_StartTime[client] = GetEngineTime() - view_as<float>(snapshot[fCurrentTime]);
|
||||
gI_SHSW_FirstCombination[client] = view_as<int>(snapshot[iSHSWCombination]);\
|
||||
gF_PlayerTimer[client] = snapshot[fCurrentTime];
|
||||
gI_SHSW_FirstCombination[client] = view_as<int>(snapshot[iSHSWCombination]);
|
||||
}
|
||||
|
||||
public int Native_MarkKZMap(Handle handler, int numParams)
|
||||
@ -1251,13 +1209,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);
|
||||
@ -1266,11 +1217,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;
|
||||
gF_PlayerTimer[client] = 0.0;
|
||||
gB_PracticeMode[client] = false;
|
||||
|
||||
SetEntityGravity(client, view_as<float>(gA_StyleSettings[gBS_Style[client]][fGravityMultiplier]));
|
||||
@ -1293,8 +1248,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;
|
||||
@ -1313,7 +1267,6 @@ void PauseTimer(int client)
|
||||
Call_PushCell(gI_Track[client]);
|
||||
Call_Finish();
|
||||
|
||||
gF_PauseStartTime[client] = GetEngineTime();
|
||||
gB_ClientPaused[client] = true;
|
||||
}
|
||||
|
||||
@ -1329,32 +1282,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);
|
||||
@ -1530,7 +1460,7 @@ bool LoadStyles()
|
||||
gA_StyleSettings[i][iForceHSW] = kv.GetNum("force_hsw", 0);
|
||||
gA_StyleSettings[i][bBlockPLeft] = view_as<bool>(kv.GetNum("block_pleft", 0));
|
||||
gA_StyleSettings[i][bBlockPRight] = view_as<bool>(kv.GetNum("block_pright", 0));
|
||||
gA_StyleSettings[i][bBlockPStrafe] = view_as<bool>(kv.GetNum("block_pstrafe", 0));
|
||||
gA_StyleSettings[i][iBlockPStrafe] = kv.GetNum("block_pstrafe", 0);
|
||||
gA_StyleSettings[i][bUnranked] = view_as<bool>(kv.GetNum("unranked", 0));
|
||||
gA_StyleSettings[i][bNoReplay] = view_as<bool>(kv.GetNum("noreplay", 0));
|
||||
gA_StyleSettings[i][bSync] = view_as<bool>(kv.GetNum("sync", 1));
|
||||
@ -1836,21 +1766,75 @@ public void PreThinkPost(int client)
|
||||
}
|
||||
}
|
||||
|
||||
public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3])
|
||||
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], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2])
|
||||
{
|
||||
if(!IsPlayerAlive(client) || IsFakeClient(client))
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
int flags = GetEntityFlags(client);
|
||||
|
||||
if(gB_ClientPaused[client])
|
||||
{
|
||||
buttons = 0;
|
||||
vel = view_as<float>({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);
|
||||
@ -1862,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)
|
||||
@ -1885,19 +1870,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -63,9 +63,11 @@ Handle gH_HUD = null;
|
||||
|
||||
// plugin cvars
|
||||
ConVar gCV_GradientStepSize = null;
|
||||
ConVar gCV_TicksPerUpdate = null;
|
||||
|
||||
// cached cvars
|
||||
int gI_GradientStepSize = 5;
|
||||
int gI_TicksPerUpdate = 5;
|
||||
|
||||
// timer settings
|
||||
char gS_StyleStrings[STYLE_LIMIT][STYLESTRINGS_SIZE][128];
|
||||
@ -130,13 +132,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", "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);
|
||||
|
||||
AutoExecConfig();
|
||||
|
||||
// cron
|
||||
CreateTimer(0.10, 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 +166,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 +479,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_TicksPerUpdate == 0)
|
||||
{
|
||||
Cron();
|
||||
}
|
||||
}
|
||||
|
||||
void Cron()
|
||||
{
|
||||
if(++gI_Cycle >= 65535)
|
||||
{
|
||||
@ -567,8 +578,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
|
||||
@ -635,7 +644,7 @@ void UpdateHUD(int client)
|
||||
{
|
||||
if(gEV_Type == Engine_CSGO)
|
||||
{
|
||||
FormatEx(sHintText, 64, "<font size=\"38\" color=\"#%06X\">%T</font>\n\t%T: %d", ((gI_GradientColors[0] << 16) + (gI_GradientColors[1] << 8) + (gI_GradientColors[2])), "HudStartZone", client, "HudSpeedText", client, iSpeed);
|
||||
FormatEx(sHintText, 128, " <font size='34' color='#%06X'>%T</font>\n\t %T: %d", ((gI_GradientColors[0] << 16) + (gI_GradientColors[1] << 8) + (gI_GradientColors[2])), "HudStartZone", client, "HudSpeedText", client, iSpeed);
|
||||
}
|
||||
|
||||
else
|
||||
@ -649,7 +658,7 @@ void UpdateHUD(int client)
|
||||
{
|
||||
if(gEV_Type == Engine_CSGO)
|
||||
{
|
||||
FormatEx(sHintText, 64, "<font size=\"38\" color=\"#%06X\">%T</font>\n\t%T: %d", ((gI_GradientColors[0] << 16) + (gI_GradientColors[1] << 8) + (gI_GradientColors[2])), "HudEndZone", client, "HudSpeedText", client, iSpeed);
|
||||
FormatEx(sHintText, 128, " <font size='34' color='#%06X'>%T</font>\n\t %T: %d", ((gI_GradientColors[0] << 16) + (gI_GradientColors[1] << 8) + (gI_GradientColors[2])), "HudEndZone", client, "HudSpeedText", client, iSpeed);
|
||||
}
|
||||
|
||||
else
|
||||
@ -667,6 +676,7 @@ void UpdateHUD(int client)
|
||||
else if((gI_HUDSettings[client] & HUD_CENTER) > 0)
|
||||
{
|
||||
int track = Shavit_GetClientTrack(target);
|
||||
char[] sTrack = new char[32];
|
||||
|
||||
if(!IsFakeClient(target))
|
||||
{
|
||||
@ -690,7 +700,7 @@ void UpdateHUD(int client)
|
||||
|
||||
if(gEV_Type == Engine_CSGO)
|
||||
{
|
||||
strcopy(sHintText, 512, "<font size=\"18\" face=\"Stratum2\">");
|
||||
strcopy(sHintText, 512, "<font size='18' face=''>");
|
||||
|
||||
if(status >= Timer_Running)
|
||||
{
|
||||
@ -698,7 +708,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 +726,16 @@ void UpdateHUD(int client)
|
||||
strcopy(sColor, 8, "FF0000");
|
||||
}
|
||||
|
||||
char[] sPauseItem = new char[64];
|
||||
FormatEx(sPauseItem, 64, "%T\t</font>", "HudPaused", client);
|
||||
if(track != Track_Main)
|
||||
{
|
||||
GetTrackName(client, track, sTrack, 32);
|
||||
Format(sHintText, 512, "%s[<font color='#FFFFFF'>%s</font>] ", sHintText, sTrack);
|
||||
}
|
||||
|
||||
char[] sUnpausedItem = new char[64];
|
||||
FormatEx(sUnpausedItem, 64, "%s</font> (%d)\t", sTime, rank);
|
||||
|
||||
Format(sHintText, 512, "%s%T: <font color='#%s'>%s", sHintText, "HudTimeText", client, sColor, (status == Timer_Paused)? sPauseItem:sUnpausedItem);
|
||||
Format(sHintText, 512, "%s<font color='#%s'>%s</font> (%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,37 +764,29 @@ void UpdateHUD(int client)
|
||||
Format(sHintText, 512, "%s%s\t%T: %d", sHintText, (iSpeed < 1000)? "\t":"", "HudStrafeText", client, strafes);
|
||||
}
|
||||
}
|
||||
|
||||
Format(sHintText, 512, "%s</font>", sHintText);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
char[] sTrack = new char[32];
|
||||
GetTrackName(client, track, sTrack, 32);
|
||||
|
||||
Format(sHintText, 512, "%s\n%s", sHintText, sTrack);
|
||||
}
|
||||
}
|
||||
@ -825,8 +827,6 @@ 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);
|
||||
@ -835,11 +835,10 @@ void UpdateHUD(int client)
|
||||
|
||||
if(gEV_Type == Engine_CSGO)
|
||||
{
|
||||
FormatEx(sHintText, 512, "<font face='Stratum2'>");
|
||||
FormatEx(sHintText, 512, "<font face=''>");
|
||||
Format(sHintText, 512, "%s\t<u><font color='#%s'>%s %T</font></u>", sHintText, gS_StyleStrings[style][sHTMLColor], gS_StyleStrings[style][sStyleName], "ReplayText", client);
|
||||
Format(sHintText, 512, "%s\n\t%T: <font color='#00FF00'>%s</font> / %s", sHintText, "HudTimeText", client, sReplayTime, sReplayLength);
|
||||
Format(sHintText, 512, "%s\n\t%T: %d", sHintText, "HudSpeedText", client, iSpeed);
|
||||
Format(sHintText, 512, "%s</font>", sHintText);
|
||||
}
|
||||
|
||||
else
|
||||
@ -876,7 +875,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":"ー");
|
||||
@ -1022,20 +1034,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);
|
||||
SetHudTextParams(0.01, 0.01, 2.5, 255, 255, 255, 255, 0, 0.0, 0.0, 0.0);
|
||||
ShowSyncHudText(client, gH_HUD, "%s", sTopLeft);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,15 +33,33 @@
|
||||
#undef REQUIRE_PLUGIN
|
||||
#include <shavit>
|
||||
|
||||
// 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];
|
||||
@ -156,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;
|
||||
@ -168,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];
|
||||
@ -232,6 +237,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");
|
||||
|
||||
@ -301,7 +307,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);
|
||||
@ -386,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)
|
||||
@ -503,6 +510,8 @@ public void OnConfigsExecuted()
|
||||
|
||||
public void OnMapStart()
|
||||
{
|
||||
gSM_Checkpoints.Clear();
|
||||
|
||||
GetCurrentMap(gS_CurrentMap, 192);
|
||||
GetMapDisplayName(gS_CurrentMap, gS_CurrentMap, 192);
|
||||
|
||||
@ -511,12 +520,10 @@ public void OnMapStart()
|
||||
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);
|
||||
}
|
||||
@ -598,6 +605,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)
|
||||
@ -611,6 +623,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)
|
||||
@ -871,11 +888,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);
|
||||
}
|
||||
@ -980,49 +1006,27 @@ 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)
|
||||
{
|
||||
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)
|
||||
@ -1178,19 +1182,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;
|
||||
@ -1434,11 +1448,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];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1446,13 +1460,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]);
|
||||
}
|
||||
}
|
||||
@ -1476,7 +1490,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)
|
||||
{
|
||||
@ -1491,7 +1505,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]);
|
||||
|
||||
@ -1516,12 +1536,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);
|
||||
}
|
||||
|
||||
@ -1560,20 +1580,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:
|
||||
@ -1585,15 +1605,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]++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1657,25 +1683,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;
|
||||
}
|
||||
@ -1689,7 +1740,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]);
|
||||
|
||||
@ -1704,17 +1755,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<MoveType>(gA_PlayerCheckPointsCache[client][index][iCPMoveType]));
|
||||
SetEntityGravity(client, view_as<float>(gA_PlayerCheckPointsCache[client][index][fCPGravity]));
|
||||
SetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue", view_as<float>(gA_PlayerCheckPointsCache[client][index][fCPSpeed]));
|
||||
SetEntPropFloat(client, Prop_Send, "m_flStamina", view_as<float>(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)
|
||||
{
|
||||
@ -1836,7 +1908,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++)
|
||||
@ -1969,21 +2041,6 @@ public void Shavit_OnRestart(int client, int track)
|
||||
}
|
||||
}
|
||||
|
||||
DataPack pack = null;
|
||||
CreateDataTimer(0.1, Respawn, pack, TIMER_FLAG_NO_MAPCHANGE);
|
||||
pack.WriteCell(GetClientSerial(client));
|
||||
pack.WriteCell(track);
|
||||
}
|
||||
}
|
||||
|
||||
public Action Respawn(Handle Timer, DataPack pack)
|
||||
{
|
||||
pack.Reset();
|
||||
int client = GetClientFromSerial(pack.ReadCell());
|
||||
int track = pack.ReadCell();
|
||||
|
||||
if(IsValidClient(client) && !IsPlayerAlive(client) && GetClientTeam(client) >= 2)
|
||||
{
|
||||
if(gEV_Type == Engine_TF2)
|
||||
{
|
||||
TF2_RespawnPlayer(client);
|
||||
@ -1999,13 +2056,36 @@ public Action Respawn(Handle Timer, DataPack pack)
|
||||
RestartTimer(client, track);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action Respawn(Handle Timer, any data)
|
||||
{
|
||||
int client = GetClientFromSerial(data);
|
||||
|
||||
if(IsValidClient(client) && !IsPlayerAlive(client) && GetClientTeam(client) >= 2)
|
||||
{
|
||||
if(gEV_Type == Engine_TF2)
|
||||
{
|
||||
TF2_RespawnPlayer(client);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
CS_RespawnPlayer(client);
|
||||
}
|
||||
|
||||
if(gB_RespawnOnRestart)
|
||||
{
|
||||
RestartTimer(client, Track_Main);
|
||||
}
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@ -2092,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);
|
||||
}
|
||||
|
||||
@ -2209,7 +2297,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"));
|
||||
}
|
||||
@ -2218,7 +2306,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));
|
||||
@ -2371,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;
|
||||
}
|
||||
|
||||
@ -2407,6 +2490,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<int>(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<int>(PCPCACHE_SIZE));
|
||||
}
|
||||
|
||||
void UpdateFootsteps(int client)
|
||||
{
|
||||
if(sv_footsteps != null)
|
||||
@ -2417,9 +2516,10 @@ void UpdateFootsteps(int client)
|
||||
}
|
||||
}
|
||||
|
||||
#if SOURCEMOD_V_MAJOR == 1 && SOURCEMOD_V_MINOR < 9
|
||||
bool IsNullVector(float vec[3])
|
||||
void CopyArray(const any[] from, any[] to, int size)
|
||||
{
|
||||
return (vec[0] == NULL_VECTOR[0] && vec[1] == NULL_VECTOR[1] && vec[2] == NULL_VECTOR[2]);
|
||||
for(int i = 0; i < size; i++)
|
||||
{
|
||||
to[i] = from[i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -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.
|
||||
//
|
||||
// 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<float>(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<float>(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];
|
||||
ReadPackString(data, sMap, size + 1);
|
||||
|
||||
int track = data.ReadCell();
|
||||
int style = data.ReadCell();
|
||||
bool print = view_as<bool>(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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -64,12 +64,14 @@ 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];
|
||||
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;
|
||||
|
||||
@ -138,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);
|
||||
@ -247,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)];
|
||||
}
|
||||
|
||||
@ -419,6 +427,11 @@ public int Native_GetReplayBotTrack(Handle handler, int numParams)
|
||||
return GetReplayTrack(GetNativeCell(1));
|
||||
}
|
||||
|
||||
public int Native_GetReplayBotType(Handle handler, int numParams)
|
||||
{
|
||||
return view_as<int>((gB_CentralBot)? Replay_Central:Replay_Legacy);
|
||||
}
|
||||
|
||||
public void Shavit_OnDatabaseLoaded()
|
||||
{
|
||||
gH_SQL = Shavit_GetDatabase();
|
||||
@ -557,8 +570,19 @@ bool LoadStyling()
|
||||
kv.GetString("centralstyletag", gS_ReplayStrings[sReplayCentralStyleTag], MAX_NAME_LENGTH, "<EMPTY CENTRALSTYLETAG>");
|
||||
kv.GetString("unloaded", gS_ReplayStrings[sReplayUnloaded], MAX_NAME_LENGTH, "<EMPTY UNLOADED>");
|
||||
|
||||
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 +702,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 +718,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 +794,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);
|
||||
}
|
||||
@ -796,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);
|
||||
@ -828,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<float>(aReplayData[0]), 0);
|
||||
gA_Frames[style][track].Set(i, view_as<float>(aReplayData[1]), 1);
|
||||
@ -840,6 +869,12 @@ bool LoadReplay(int style, int track, const char[] path)
|
||||
gA_Frames[style][track].Set(i, view_as<float>(aReplayData[3]), 3);
|
||||
gA_Frames[style][track].Set(i, view_as<float>(aReplayData[4]), 4);
|
||||
gA_Frames[style][track].Set(i, view_as<int>(aReplayData[5]), 5);
|
||||
|
||||
if(gA_FrameCache[style][track][3] >= 0x02)
|
||||
{
|
||||
gA_Frames[style][track].Set(i, view_as<int>(aReplayData[6]), 6);
|
||||
gA_Frames[style][track].Set(i, view_as<int>(aReplayData[7]), 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -911,7 +946,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 +988,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))
|
||||
{
|
||||
@ -1324,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])
|
||||
{
|
||||
@ -1430,6 +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)
|
||||
{
|
||||
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 movetype = gA_Frames[style][track].Get(gI_ReplayTick[style], 7);
|
||||
|
||||
if(movetype == MOVETYPE_WALK || movetype == MOVETYPE_LADDER)
|
||||
{
|
||||
mt = movetype;
|
||||
}
|
||||
}
|
||||
|
||||
SetEntityMoveType(client, mt);
|
||||
|
||||
float vecVelocity[3];
|
||||
MakeVectorFromPoints(vecCurrentPosition, vecPosition, vecVelocity);
|
||||
ScaleVector(vecVelocity, gF_Tickrate);
|
||||
@ -1473,6 +1545,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]++;
|
||||
}
|
||||
|
||||
@ -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)];
|
||||
}
|
||||
|
||||
@ -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];
|
||||
@ -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);
|
||||
|
||||
@ -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++)
|
||||
{
|
||||
@ -739,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");
|
||||
}
|
||||
@ -772,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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -821,9 +822,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 +934,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 +991,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2077,7 +2079,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 +2094,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);
|
||||
}
|
||||
}
|
||||
@ -2143,31 +2145,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;
|
||||
}
|
||||
@ -2340,9 +2347,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<float>({0.0, 0.0, 0.0}));
|
||||
TeleportEntity(client, gF_CustomSpawns[track][Zone_Start], NULL_VECTOR, view_as<float>({0.0, 0.0, 0.0}));
|
||||
}
|
||||
|
||||
else if(Shavit_IsKZMap() && !EmptyVector(gF_ClimbButtonCache[client][track][0]) && !EmptyVector(gF_ClimbButtonCache[client][track][1]))
|
||||
@ -2377,6 +2384,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<float>({0.0, 0.0, 0.0}));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int index = GetZoneIndex(Zone_End, track);
|
||||
|
||||
if(index == -1)
|
||||
|
||||
@ -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"
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user