/*
* shavit's Timer - Core
* by: shavit
*
* This file is part of shavit's Timer.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see .
*
*/
#include
#include
#include
#include
#include
#undef REQUIRE_PLUGIN
#define USES_CHAT_COLORS
#include
#pragma newdecls required
#pragma semicolon 1
// #define DEBUG
enum struct playertimer_t
{
bool bEnabled;
float fTimer;
bool bPaused;
int iJumps;
int iStyle;
bool bAuto;
int iLastButtons;
int iStrafes;
float fLastAngle;
int iTotalMeasures;
int iGoodGains;
bool bDoubleSteps;
float fStrafeWarning;
bool bPracticeMode;
int iSHSWCombination;
int iTrack;
int iMeasuredJumps;
int iPerfectJumps;
int iGroundTicks;
MoveType iMoveType;
}
// game type (CS:S/CS:GO/TF2)
EngineVersion gEV_Type = Engine_Unknown;
// database handle
Database gH_SQL = null;
bool gB_MySQL = false;
// forwards
Handle gH_Forwards_Start = null;
Handle gH_Forwards_Stop = null;
Handle gH_Forwards_FinishPre = null;
Handle gH_Forwards_Finish = null;
Handle gH_Forwards_OnRestart = null;
Handle gH_Forwards_OnEnd = null;
Handle gH_Forwards_OnPause = null;
Handle gH_Forwards_OnResume = null;
Handle gH_Forwards_OnStyleChanged = null;
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;
StringMap gSM_StyleCommands = null;
// player timer variables
playertimer_t gA_Timers[MAXPLAYERS+1];
// these are here until the compiler bug is fixed
float gF_PauseOrigin[MAXPLAYERS+1][3];
float gF_PauseAngles[MAXPLAYERS+1][3];
float gF_PauseVelocity[MAXPLAYERS+1][3];
// cookies
Handle gH_StyleCookie = null;
Handle gH_AutoBhopCookie = null;
// late load
bool gB_Late = false;
// modules
bool gB_Zones = false;
bool gB_WR = false;
bool gB_Replay = false;
bool gB_Rankings = false;
bool gB_HUD = false;
// cvars
ConVar gCV_Restart = null;
ConVar gCV_Pause = null;
ConVar gCV_AllowTimerWithoutZone = null;
ConVar gCV_BlockPreJump = null;
ConVar gCV_NoZAxisSpeed = null;
ConVar gCV_VelocityTeleport = null;
ConVar gCV_DefaultStyle = null;
// cached cvars
bool gB_Restart = true;
bool gB_Pause = true;
bool gB_AllowTimerWithoutZone = false;
bool gB_BlockPreJump = false;
bool gB_NoZAxisSpeed = true;
bool gB_VelocityTeleport = false;
int gI_DefaultStyle = 0;
bool gB_StyleCookies = true;
// table prefix
char gS_MySQLPrefix[32];
// server side
ConVar sv_airaccelerate = null;
ConVar sv_autobunnyhopping = null;
ConVar sv_enablebunnyhopping = null;
// timer settings
bool gB_Registered = false;
int gI_Styles = 0;
stylestrings_t gS_StyleStrings[STYLE_LIMIT];
stylesettings_t gA_StyleSettings[STYLE_LIMIT];
// chat settings
chatstrings_t gS_ChatStrings;
// misc cache
bool gB_StopChatSound = false;
bool gB_HookedJump = false;
char gS_LogPath[PLATFORM_MAX_PATH];
char gS_DeleteMap[MAXPLAYERS+1][160];
// flags
int gI_StyleFlag[STYLE_LIMIT];
char gS_StyleOverride[STYLE_LIMIT][32];
// kz support
bool gB_KZMap = false;
public Plugin myinfo =
{
name = "[shavit] Core",
author = "shavit",
description = "The core for shavit's bhop timer.",
version = SHAVIT_VERSION,
url = "https://github.com/shavitush/bhoptimer"
}
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
{
CreateNative("Shavit_FinishMap", Native_FinishMap);
CreateNative("Shavit_GetBhopStyle", Native_GetBhopStyle);
CreateNative("Shavit_GetChatStrings", Native_GetChatStrings);
CreateNative("Shavit_GetClientJumps", Native_GetClientJumps);
CreateNative("Shavit_GetClientTime", Native_GetClientTime);
CreateNative("Shavit_GetClientTrack", Native_GetClientTrack);
CreateNative("Shavit_GetDatabase", Native_GetDatabase);
CreateNative("Shavit_GetDB", Native_GetDB);
CreateNative("Shavit_GetGameType", Native_GetGameType);
CreateNative("Shavit_GetPerfectJumps", Native_GetPerfectJumps);
CreateNative("Shavit_GetStrafeCount", Native_GetStrafeCount);
CreateNative("Shavit_GetStyleCount", Native_GetStyleCount);
CreateNative("Shavit_GetStyleSettings", Native_GetStyleSettings);
CreateNative("Shavit_GetStyleStrings", Native_GetStyleStrings);
CreateNative("Shavit_GetSync", Native_GetSync);
CreateNative("Shavit_GetTimer", Native_GetTimer);
CreateNative("Shavit_GetTimerStatus", Native_GetTimerStatus);
CreateNative("Shavit_HasStyleAccess", Native_HasStyleAccess);
CreateNative("Shavit_IsKZMap", Native_IsKZMap);
CreateNative("Shavit_IsPracticeMode", Native_IsPracticeMode);
CreateNative("Shavit_LoadSnapshot", Native_LoadSnapshot);
CreateNative("Shavit_LogMessage", Native_LogMessage);
CreateNative("Shavit_MarkKZMap", Native_MarkKZMap);
CreateNative("Shavit_PauseTimer", Native_PauseTimer);
CreateNative("Shavit_PrintToChat", Native_PrintToChat);
CreateNative("Shavit_RestartTimer", Native_RestartTimer);
CreateNative("Shavit_ResumeTimer", Native_ResumeTimer);
CreateNative("Shavit_SaveSnapshot", Native_SaveSnapshot);
CreateNative("Shavit_SetPracticeMode", Native_SetPracticeMode);
CreateNative("Shavit_StartTimer", Native_StartTimer);
CreateNative("Shavit_StopChatSound", Native_StopChatSound);
CreateNative("Shavit_StopTimer", Native_StopTimer);
// registers library, check "bool LibraryExists(const char[] name)" in order to use with other plugins
RegPluginLibrary("shavit");
gB_Late = late;
return APLRes_Success;
}
public void OnPluginStart()
{
// forwards
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, 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);
gH_Forwards_OnResume = CreateGlobalForward("Shavit_OnResume", ET_Event, Param_Cell, Param_Cell);
gH_Forwards_OnStyleChanged = CreateGlobalForward("Shavit_OnStyleChanged", ET_Event, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell);
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, 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");
// game types
gEV_Type = GetEngineVersion();
if(gEV_Type == Engine_CSGO)
{
sv_autobunnyhopping = FindConVar("sv_autobunnyhopping");
sv_autobunnyhopping.BoolValue = false;
}
else if(gEV_Type != Engine_CSS && gEV_Type != Engine_TF2)
{
SetFailState("This plugin was meant to be used in CS:S, CS:GO and TF2 *only*.");
}
// database connections
SQL_SetPrefix();
SQL_DBConnect();
// hooks
gB_HookedJump = HookEventEx("player_jump", Player_Jump);
HookEvent("player_death", Player_Death);
HookEvent("player_team", Player_Death);
HookEvent("player_spawn", Player_Death);
// commands START
// style
RegConsoleCmd("sm_style", Command_Style, "Choose your bhop style.");
RegConsoleCmd("sm_styles", Command_Style, "Choose your bhop style.");
RegConsoleCmd("sm_diff", Command_Style, "Choose your bhop style.");
RegConsoleCmd("sm_difficulty", Command_Style, "Choose your bhop style.");
gH_StyleCookie = RegClientCookie("shavit_style", "Style cookie", CookieAccess_Protected);
// timer start
RegConsoleCmd("sm_s", Command_StartTimer, "Start your timer.");
RegConsoleCmd("sm_start", Command_StartTimer, "Start your timer.");
RegConsoleCmd("sm_r", Command_StartTimer, "Start your timer.");
RegConsoleCmd("sm_restart", Command_StartTimer, "Start your timer.");
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, "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.");
// timer pause / resume
RegConsoleCmd("sm_pause", Command_TogglePause, "Toggle pause.");
RegConsoleCmd("sm_unpause", Command_TogglePause, "Toggle pause.");
RegConsoleCmd("sm_resume", Command_TogglePause, "Toggle pause");
// autobhop toggle
RegConsoleCmd("sm_auto", Command_AutoBhop, "Toggle autobhop.");
RegConsoleCmd("sm_autobhop", Command_AutoBhop, "Toggle autobhop.");
gH_AutoBhopCookie = RegClientCookie("shavit_autobhop", "Autobhop cookie", CookieAccess_Protected);
// doublestep fixer
AddCommandListener(Command_DoubleStep, "+ds");
AddCommandListener(Command_DoubleStep, "-ds");
// style commands
gSM_StyleCommands = new StringMap();
#if defined DEBUG
RegConsoleCmd("sm_finishtest", Command_FinishTest);
#endif
// admin
RegAdminCmd("sm_deletemap", Command_DeleteMap, ADMFLAG_ROOT, "Deletes all map data. Usage: sm_deletemap