#pragma semicolon 1

#include <sourcemod>
#include <sdkhooks>
#include <multicolors>
#include <clientprefs>

#pragma newdecls required

Handle g_hNoShakeCookie;
ConVar g_Cvar_NoShakeGlobal;

bool g_bNoShake[MAXPLAYERS + 1] = {false, ...};
bool g_bNoShakeGlobal = false;

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public Plugin myinfo =
{
	name 			= "NoShake",
	author 			= "BotoX",
	description 	= "Disable env_shake",
	version 		= "1.0.1",
	url 			= ""
};

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnPluginStart()
{
	RegConsoleCmd("sm_shake", Command_Shake, "[NoShake] Disables or enables screen shakes.");
	RegConsoleCmd("sm_noshake", Command_Shake, "[NoShake] Disables or enables screen shakes.");

	g_hNoShakeCookie = RegClientCookie("noshake_cookie", "NoShake", CookieAccess_Protected);

	g_Cvar_NoShakeGlobal = CreateConVar("sm_noshake_global", "0", "Disable screenshake globally.", 0, true, 0.0, true, 1.0);
	g_bNoShakeGlobal = g_Cvar_NoShakeGlobal.BoolValue;
	g_Cvar_NoShakeGlobal.AddChangeHook(OnConVarChanged);

	HookUserMessage(GetUserMessageId("Shake"), MsgHook, true);

	SetCookieMenuItem(MenuHandler_CookieMenu, 0, "NoShake");
}

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnClientCookiesCached(int client)
{
	char sBuffer[4];
	GetClientCookie(client, g_hNoShakeCookie, sBuffer, sizeof(sBuffer));

	if (sBuffer[0])
		g_bNoShake[client] = true;
	else
		g_bNoShake[client] = false;
}

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
{
	g_bNoShakeGlobal = convar.BoolValue;

	if(g_bNoShakeGlobal)
		CPrintToChatAll("{cyan}[NoShake] {white}Screen Shaking has been disabled globally.");
	else
		CPrintToChatAll("{cyan}[NoShake] {white}Screen Shaking has been reenabled globally.");

}

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public Action MsgHook(UserMsg msg_id, BfRead msg, const int[] players, int playersNum, bool reliable, bool init)
{
	if(playersNum == 1 && (g_bNoShakeGlobal || g_bNoShake[players[0]]))
		return Plugin_Handled;
	else
		return Plugin_Continue;
}

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public Action Command_Shake(int client, int args)
{
	ToggleShake(client);
	return Plugin_Handled;
}

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void ToggleShake(int client)
{
	if(g_bNoShakeGlobal)
	{
		CPrintToChat(client, "{cyan}[NoShake] {white}Screen Shaking is currently disabled globally.");
		return;
	}

	g_bNoShake[client] = !g_bNoShake[client];
	SetClientCookie(client, g_hNoShakeCookie, g_bNoShake[client] ? "1" : "");
	CPrintToChat(client, "{cyan}[NoShake] {white}%s", g_bNoShake[client] ? "You turned off Screen Shaking." : "You turned on Screen Shaking.");
}

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void ShowSettingsMenu(int client)
{
	Menu menu = new Menu(MenuHandler_MainMenu);

	menu.SetTitle("NoShake Settings", client);

	char sBuffer[128];
	Format(sBuffer, sizeof(sBuffer), "NoShake: %s", (g_bNoShake[client] || g_bNoShakeGlobal) ? "Enabled" : "Disabled");

	menu.AddItem("0", sBuffer);

	menu.ExitBackButton = true;

	menu.Display(client, MENU_TIME_FOREVER);
}

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void MenuHandler_CookieMenu(int client, CookieMenuAction action, any info, char[] buffer, int maxlen)
{
	switch(action)
	{
		case(CookieMenuAction_DisplayOption):
		{
			Format(buffer, maxlen, "NoShake", client);
		}
		case(CookieMenuAction_SelectOption):
		{
			ShowSettingsMenu(client);
		}
	}
}

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public int MenuHandler_MainMenu(Menu menu, MenuAction action, int client, int selection)
{
	switch(action)
	{
		case(MenuAction_Select):
		{
			switch(selection)
			{
				case(0): ToggleShake(client);
			}

			ShowSettingsMenu(client);
		}
		case(MenuAction_Cancel):
		{
			ShowCookieMenu(client);
		}
		case(MenuAction_End):
		{
			delete menu;
		}
	}
}