diff --git a/StopSound/scripting/StopSound.sp b/StopSound/scripting/StopSound.sp
index 633ca13a..36527b56 100644
--- a/StopSound/scripting/StopSound.sp
+++ b/StopSound/scripting/StopSound.sp
@@ -1,206 +1,393 @@
 #pragma semicolon 1
-#pragma newdecls required
 
 #include <sourcemod>
 #include <sdktools>
+#include <sdkhooks>
+#include <cstrike>
+#include <clientprefs>
+
 #include <multicolors>
 
-#define PLUGIN_VERSION 	"1.3.0"
+#pragma newdecls required
+
+#define MAX_MAPMUSIC_ENTITIES 2048
+
+#define PLUGIN_VERSION 	"2.0.4"
+
+int MAX_ENTITIES = 0;
+bool g_bLateLoad = false;
+
+bool g_bStopWeaponSounds[MAXPLAYERS+1] = { false, ... };
+bool g_bStopMapMusic[MAXPLAYERS+1] = { false, ... };
+
+bool g_bStopWeaponSoundsHooked = false;
+bool g_bStopMapMusicHooked = false;
+
+int g_iMapMusicEntities[MAX_MAPMUSIC_ENTITIES];
+int g_iNumSounds = 0;
 
-bool g_bStopSound[MAXPLAYERS+1];
-bool g_bHooked;
 static char g_sKVPATH[PLATFORM_MAX_PATH];
 KeyValues g_hWepSounds;
 
+Handle g_hCookieStopSound = null;
+Handle g_hCookieStopMapMusic = null;
+
 public Plugin myinfo =
 {
-	name = "Toggle Weapon Sounds",
-	author = "GoD-Tony, edit by Obus + BotoX",
-	description = "Allows clients to stop hearing weapon sounds",
+	name = "Toggle Game Sounds",
+	author = "GoD-Tony, edit by Obus + BotoX, Oleg Tsvetkov",
+	description = "Allows clients to stop hearing weapon sounds and map music",
 	version = PLUGIN_VERSION,
 	url = "http://www.sourcemod.net/"
 };
 
+public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
+{
+	if (GetEngineVersion() != Engine_CSGO && GetEngineVersion() != Engine_CSS)
+	{
+		strcopy(error, err_max, "This plugin supports only CS:GO and CS:S!");
+		return APLRes_Failure;
+	}
+
+	g_bLateLoad = late;
+
+	return APLRes_Success;
+}
+
 public void OnPluginStart()
 {
+	// Load translations
+	LoadTranslations("plugin.stopsound.phrases");
+	LoadTranslations("common.phrases"); // For On/Off buttons in Cookies Menu
+
 	// Detect game and hook appropriate tempent.
-	static char sGame[32];
-	GetGameFolderName(sGame, sizeof(sGame));
+	AddTempEntHook("Shotgun Shot", CSS_Hook_ShotgunShot);
 
-	if(StrEqual(sGame, "cstrike"))
-		AddTempEntHook("Shotgun Shot", CSS_Hook_ShotgunShot);
-	else if(StrEqual(sGame, "dod"))
-		AddTempEntHook("FireBullets", DODS_Hook_FireBullets);
+	// Ambient sounds
+	AddAmbientSoundHook(Hook_AmbientSound);
 
-	// TF2/HL2:DM and misc weapon sounds will be caught here.
-	AddNormalSoundHook(Hook_NormalSound);
+	// Map music will be caught here
+	HookEvent("round_end", Event_RoundEnd);
+	HookEvent("player_spawn", Event_PlayerSpawn);
 
 	CreateConVar("sm_stopsound_version", PLUGIN_VERSION, "Toggle Weapon Sounds", FCVAR_NOTIFY|FCVAR_DONTRECORD|FCVAR_REPLICATED);
 	RegConsoleCmd("sm_stopsound", Command_StopSound, "Toggle hearing weapon sounds");
+	RegConsoleCmd("sm_stopmusic", Command_StopMusic, "Toggle hearing map music");
+	RegConsoleCmd("sm_music", Command_StopMusic, "Toggle hearing map music");
 
+	// Create KeyValues
 	g_hWepSounds = new KeyValues("WeaponSounds");
 	BuildPath(Path_SM, g_sKVPATH, sizeof(g_sKVPATH), "data/playerprefs.WepSounds.txt");
 	g_hWepSounds.ImportFromFile(g_sKVPATH);
 
+	// Cookies
+	g_hCookieStopSound = RegClientCookie("weaponsound_blocked", "Are weapon sounds enabled", CookieAccess_Protected);
+	g_hCookieStopMapMusic = RegClientCookie("mapmusic_blocked", "Are map music enabled", CookieAccess_Protected);
+
+	SetCookieMenuItem(CookieMenuHandler_StopSounds, 0, "Stop sounds");
+
 	// Suppress reload sound effects
 	UserMsg ReloadEffect = GetUserMessageId("ReloadEffect");
-	if(ReloadEffect != INVALID_MESSAGE_ID)
-		HookUserMessage(ReloadEffect, Hook_ReloadEffect, true);
+
+	// Game-specific setup
+	if (GetEngineVersion() == Engine_CSGO)
+	{
+		MAX_ENTITIES = 4096;
+
+		// Weapon sounds will be caught here.
+		AddNormalSoundHook(Hook_NormalSound_CSGO);
+
+		if (ReloadEffect != INVALID_MESSAGE_ID)
+		{
+			HookUserMessage(ReloadEffect, Hook_ReloadEffect_CSGO, true);
+		}
+	}
+	else
+	{
+		// CS:S
+		MAX_ENTITIES = 2048;
+
+		// Weapon sounds will be caught here.
+		AddNormalSoundHook(Hook_NormalSound_CSS);
+
+		if (ReloadEffect != INVALID_MESSAGE_ID)
+		{
+			HookUserMessage(ReloadEffect, Hook_ReloadEffect_CSS, true);
+		}
+	}
 
 	// Late load
-	for(int client = 1; client <= MaxClients; client++)
+	if (g_bLateLoad)
 	{
-		if(IsClientInGame(client) && IsClientAuthorized(client))
+		int entity = -1;
+		while ((entity = FindEntityByClassname(entity, "ambient_generic*")) != -1)
 		{
-			static char sAuth[32];
-			GetClientAuthId(client, AuthId_Steam2, sAuth, sizeof(sAuth));
-			OnClientAuthorized(client, sAuth);
+			OnEntitySpawned(entity);
 		}
+
+		for (int client = 1; client <= MaxClients; client++)
+		{
+			if (IsClientInGame(client) && AreClientCookiesCached(client))
+			{
+				OnClientCookiesCached(client);
+			}
+		}
+
+		g_bLateLoad = false;
 	}
 }
 
 public void OnPluginEnd()
 {
-	for(int client = 1; client <= MaxClients; client++)
+	for (int client = 1; client <= MaxClients; client++)
 	{
-		if(IsClientInGame(client))
+		if (IsClientInGame(client))
+		{
 			OnClientDisconnect_Post(client);
+		}
 	}
 
-	// Detect game and unhook appropriate tempent.
-	static char sGame[32];
-	GetGameFolderName(sGame, sizeof(sGame));
+	// Remove tempent hook
+	RemoveTempEntHook("Shotgun Shot", CSS_Hook_ShotgunShot);
 
-	if(StrEqual(sGame, "cstrike"))
-		RemoveTempEntHook("Shotgun Shot", CSS_Hook_ShotgunShot);
-	else if(StrEqual(sGame, "dod"))
-		RemoveTempEntHook("FireBullets", DODS_Hook_FireBullets);
-
-	// TF2/HL2:DM and misc weapon sounds were caught here.
-	RemoveNormalSoundHook(Hook_NormalSound);
+	// Remove ambient sound hook
+	RemoveAmbientSoundHook(Hook_AmbientSound);
 
+	// Find ReloadEffect
 	UserMsg ReloadEffect = GetUserMessageId("ReloadEffect");
-	if(ReloadEffect != INVALID_MESSAGE_ID)
-		UnhookUserMessage(ReloadEffect, Hook_ReloadEffect, true);
+
+	// Remove game-specific staff
+	if (GetEngineVersion() == Engine_CSGO)
+	{
+		RemoveNormalSoundHook(Hook_NormalSound_CSGO);
+
+		if (ReloadEffect != INVALID_MESSAGE_ID)
+		{
+			UnhookUserMessage(ReloadEffect, Hook_ReloadEffect_CSGO, true);
+		}
+	}
+	else
+	{
+		RemoveNormalSoundHook(Hook_NormalSound_CSS);
+
+		if (ReloadEffect != INVALID_MESSAGE_ID)
+		{
+			UnhookUserMessage(ReloadEffect, Hook_ReloadEffect_CSS, true);
+		}
+	}
+
+	// Delete KeyValues
+	delete g_hWepSounds;
+}
+
+public void OnMapStart()
+{
+	g_iNumSounds = 0;
+}
+
+public void OnEntityCreated(int entity, const char[] classname)
+{
+	if (!StrEqual(classname, "ambient_generic", false))
+	{
+		return;
+	}
+
+	SDKHook(entity, SDKHook_Spawn, OnEntitySpawned);
+}
+
+public void OnEntitySpawned(int entity)
+{
+	if (entity < 0 || entity > MAX_ENTITIES || !IsValidEntity(entity))
+	{
+		return;
+	}
+
+	if (g_iNumSounds >= MAX_MAPMUSIC_ENTITIES)
+	{
+		// Something went wrong...
+		return;
+	}
+	char sSoundPath[PLATFORM_MAX_PATH];
+	GetEntPropString(entity, Prop_Data, "m_iszSound", sSoundPath, sizeof(sSoundPath));
+
+	int iLen = strlen(sSoundPath);
+
+	if (iLen > 4 && (StrEqual(sSoundPath[iLen - 4], ".mp3", false) || StrEqual(sSoundPath[iLen - 4], ".wav", false)))
+	{
+		g_iMapMusicEntities[g_iNumSounds++] = EntIndexToEntRef(entity);
+	}
+}
+
+public void Event_RoundEnd(Event event, const char[] name, bool dontBroadcast)
+{
+	g_iNumSounds = 0;
+}
+
+public void Event_PlayerSpawn(Event event, const char[] name, bool dontBroadcast)
+{
+	int client = GetClientOfUserId(event.GetInt("userid"));
+
+	if (!IsClientInGame(client) || GetClientTeam(client) <= CS_TEAM_SPECTATOR)
+	{
+		return;
+	}
+
+	if (g_bStopWeaponSounds[client])
+	{
+		CPrintToChat(client, "%t %t", "Chat Prefix", "Weapon sounds disabled");
+	}
+
+	if (g_bStopMapMusic[client])
+	{
+		CPrintToChat(client, "%t %t", "Chat Prefix", "Map music disabled");
+	}
+}
+
+public Action Timer_DelayedStopForEntity(Handle timer, any data)
+{
+	DataPack datapack = view_as<DataPack>(data);
+	datapack.Reset();
+
+	char sSample[PLATFORM_MAX_PATH];
+	datapack.ReadString(sSample, sizeof(sSample));
+	int entity = datapack.ReadCell();
+
+	StopSoundFromEntity(sSample, entity);
+
+	return Plugin_Stop;
 }
 
 public Action Command_StopSound(int client, int args)
 {
-	if(client == 0)
+	if (client == 0)
 	{
-		PrintToServer("[SM] Cannot use command from server console.");
+		ReplyToCommand(client, "[SM] Cannot use command from server console.");
 		return Plugin_Handled;
 	}
 
-	if(args > 0)
+	g_bStopWeaponSounds[client] = !g_bStopWeaponSounds[client];
+	CheckWeaponSoundsHooks();
+
+	if (g_bStopWeaponSounds[client])
 	{
-		static char Arguments[32];
-		GetCmdArg(1, Arguments, sizeof(Arguments));
-
-		static char SID[32];
-		GetClientAuthId(client, AuthId_Steam2, SID, sizeof(SID));
-
-		if(StrEqual(Arguments, "save"))
-		{
-			g_hWepSounds.Rewind();
-
-			if(g_hWepSounds.JumpToKey(SID, true))
-			{
-				int disabled = g_hWepSounds.GetNum("disabled", 0);
-				if(!disabled)
-				{
-					//CPrintToChat(client, "[StopSound] Saved entry for STEAMID({green}%s{default}) {green}successfully{default}.", SID);
-					g_hWepSounds.SetNum("disabled", 1);
-					g_hWepSounds.Rewind();
-					g_hWepSounds.ExportToFile(g_sKVPATH);
-
-					g_bStopSound[client] = true;
-					CReplyToCommand(client, "{green}[StopSound]{default} Weapon sounds {red}disabled{default} - {green}entry saved{default}.");
-					CheckHooks();
-
-					return Plugin_Handled;
-				}
-				else
-				{
-					//CPrintToChat(client, "[StopSound] Entry for STEAMID({green}%s{default}) {green}successfully deleted{default}.", SID);
-					g_hWepSounds.DeleteThis();
-					g_hWepSounds.Rewind();
-					g_hWepSounds.ExportToFile(g_sKVPATH);
-
-					g_bStopSound[client] = false;
-					CReplyToCommand(client, "{green}[StopSound]{default} Weapon sounds {green}enabled{default} - {red}entry deleted{default}.");
-					CheckHooks();
-
-					return Plugin_Handled;
-				}
-			}
-
-			g_hWepSounds.Rewind();
-		}
-		else if(StrEqual(Arguments, "delete"))
-		{
-			g_hWepSounds.Rewind();
-
-			if(g_hWepSounds.JumpToKey(SID, false))
-			{
-				g_bStopSound[client] = false;
-				CReplyToCommand(client, "{green}[StopSound]{default} Weapon sounds {green}enabled{default} - {red}entry deleted{default}.");
-				CheckHooks();
-
-				g_hWepSounds.DeleteThis();
-				g_hWepSounds.Rewind();
-				g_hWepSounds.ExportToFile(g_sKVPATH);
-
-				return Plugin_Handled;
-			}
-			else
-			{
-				CPrintToChat(client, "{green}[StopSound]{default} Entry {red}not found{default}.");
-				return Plugin_Handled;
-			}
-		}
-		else
-		{
-			PrintToChat(client, "[SM] Usage sm_stopsound <save|delete>");
-			return Plugin_Handled;
-		}
+		SetClientCookie(client, g_hCookieStopSound, "1");
+		CReplyToCommand(client, "%t %t", "Chat Prefix", "Weapon sounds disabled");
+	}
+	else
+	{
+		SetClientCookie(client, g_hCookieStopSound, "0");
+		CReplyToCommand(client, "%t %t", "Chat Prefix", "Weapon sounds enabled");
 	}
-
-	g_bStopSound[client] = !g_bStopSound[client];
-	CReplyToCommand(client, "{green}[StopSound]{default} Weapon sounds %s.", g_bStopSound[client] ? "{red}disabled{default}" : "{green}enabled{default}");
-	CheckHooks();
 
 	return Plugin_Handled;
 }
 
-public void OnClientAuthorized(int client, const char[] auth)
+public Action Command_StopMusic(int client, int args)
 {
-	g_hWepSounds.Rewind();
-
-	if(KvJumpToKey(g_hWepSounds, auth, false))
+	if (client == 0)
 	{
-		int disabled = g_hWepSounds.GetNum("disabled", 0);
-		if(disabled)
-			g_bStopSound[client] = true;
+		ReplyToCommand(client, "[SM] Cannot use command from server console.");
+		return Plugin_Handled;
 	}
 
-	CheckHooks();
+	g_bStopMapMusic[client] = !g_bStopMapMusic[client];
+	CheckMapMusicHooks();
+
+	if (g_bStopMapMusic[client])
+	{
+		SetClientCookie(client, g_hCookieStopMapMusic, "1");
+		CReplyToCommand(client, "%t %t", "Chat Prefix", "Map music disabled");
+		StopMapMusic();
+	}
+	else
+	{
+		SetClientCookie(client, g_hCookieStopMapMusic, "0");
+		CReplyToCommand(client, "%t %t", "Chat Prefix", "Map music enabled");
+	}
+
+	return Plugin_Handled;
+}
+
+public void OnClientCookiesCached(int client)
+{
+	char sBuffer[2];
+	int iValue = 0;
+
+	// Weapon Sounds cookie
+	GetClientCookie(client, g_hCookieStopSound, sBuffer, sizeof(sBuffer));
+
+	iValue = StringToInt(sBuffer);
+	if (iValue == 1)
+	{
+		g_bStopWeaponSounds[client] = true;
+		g_bStopWeaponSoundsHooked = true;
+	}
+	else
+	{
+		g_bStopWeaponSounds[client] = BackwardCapabilityCheck(client);
+
+		if (iValue != 0)
+		{
+			SetClientCookie(client, g_hCookieStopSound, "0");
+		}
+	}
+
+	// Map Music cookie
+	GetClientCookie(client, g_hCookieStopMapMusic, sBuffer, sizeof(sBuffer));
+
+	iValue = StringToInt(sBuffer);
+	if (iValue == 1)
+	{
+		g_bStopMapMusic[client] = true;
+		g_bStopMapMusicHooked = true;
+	}
+	else
+	{
+		g_bStopMapMusic[client] = false;
+
+		if (iValue != 0)
+		{
+			SetClientCookie(client, g_hCookieStopMapMusic, "0");
+		}
+	}
+}
+
+// Because we have some players, whose settings are saved to KV file. We want to save this data.
+bool BackwardCapabilityCheck(int client)
+{
+	char sSteamId[32];
+	GetClientAuthId(client, AuthId_Steam2, sSteamId, sizeof(sSteamId));
+
 	g_hWepSounds.Rewind();
+
+	if (!g_hWepSounds.JumpToKey(sSteamId, false))
+	{
+		return false;
+	}
+
+	int disabled = g_hWepSounds.GetNum("disabled", 0);
+	g_hWepSounds.DeleteThis();
+	g_hWepSounds.Rewind();
+
+	return (disabled == 1);
 }
 
 public void OnClientDisconnect_Post(int client)
 {
-	g_bStopSound[client] = false;
-	CheckHooks();
+	g_bStopWeaponSounds[client] = false;
+	g_bStopMapMusic[client] = false;
+
+	CheckWeaponSoundsHooks();
+	CheckMapMusicHooks();
 }
 
-void CheckHooks()
+void CheckWeaponSoundsHooks()
 {
 	bool bShouldHook = false;
 
-	for(int i = 1; i <= MaxClients; i++)
+	for (int i = 1; i <= MaxClients; i++)
 	{
-		if(g_bStopSound[i])
+		if (g_bStopWeaponSounds[i])
 		{
 			bShouldHook = true;
 			break;
@@ -208,25 +395,202 @@ void CheckHooks()
 	}
 
 	// Fake (un)hook because toggling actual hooks will cause server instability.
-	g_bHooked = bShouldHook;
+	g_bStopWeaponSoundsHooked = bShouldHook;
 }
 
-public Action Hook_NormalSound(int clients[MAXPLAYERS], int &numClients, char sample[PLATFORM_MAX_PATH],
+void CheckMapMusicHooks()
+{
+	bool bShouldHook = false;
+
+	for (int i = 1; i <= MaxClients; i++)
+	{
+		if (g_bStopMapMusic[i])
+		{
+			bShouldHook = true;
+			break;
+		}
+	}
+
+	// Fake (un)hook because toggling actual hooks will cause server instability.
+	g_bStopMapMusicHooked = bShouldHook;
+}
+
+void StopMapMusic()
+{
+	char sSound[PLATFORM_MAX_PATH];
+	int entity = INVALID_ENT_REFERENCE;
+
+	for (int i = 0; i < g_iNumSounds; i++)
+	{
+		entity = EntRefToEntIndex(g_iMapMusicEntities[i]);
+
+		if (entity != INVALID_ENT_REFERENCE)
+		{
+			GetEntPropString(entity, Prop_Data, "m_iszSound", sSound, sizeof(sSound));
+
+			StopSoundFromEntity(sSound, entity);
+		}
+	}
+}
+
+void StopSoundFromEntity(const char[] sSample, int entity)
+{
+	for (int i = 1; i <= MaxClients; i++)
+	{
+		if (g_bStopMapMusic[i] && IsClientInGame(i))
+		{
+			Client_StopSound(i, entity, SNDCHAN_STATIC, sSample);
+		}
+	}
+}
+
+bool IsEntityInMapMusicEntities(int entity)
+{
+	for (int i = 0; i < g_iNumSounds; i++)
+	{
+		if (entity == EntRefToEntIndex(g_iMapMusicEntities[i]))
+		{
+			return true;
+		}
+	}
+
+	return false;
+}
+
+// I guess this is from SMLib
+void Client_StopSound(int client, int entity, int channel, const char[] name)
+{
+	EmitSoundToClient(client, name, entity, channel, SNDLEVEL_NONE, SND_STOP, 0.0, SNDPITCH_NORMAL, _, _, _, true);
+}
+
+public void CookieMenuHandler_StopSounds(int client, CookieMenuAction action, any info, char[] buffer, int maxlen)
+{
+	if (action == CookieMenuAction_DisplayOption)
+	{
+		Format(buffer, maxlen, "%T", "Cookie Menu Stop Sounds", client);
+	}
+	else if (action == CookieMenuAction_SelectOption)
+	{
+		ShowStopSoundsSettingsMenu(client);
+	}
+}
+
+void ShowStopSoundsSettingsMenu(int client)
+{
+	Menu menu = new Menu(MenuHandler_StopSoundsSettings);
+
+	menu.SetTitle("%T", "Cookie Menu Stop Sounds Title", client);
+
+	char sBuffer[128];
+
+	Format(sBuffer, sizeof(sBuffer), "%T%T", "Weapon Sounds", client, g_bStopWeaponSounds[client] ? "Disabled" : "Enabled", client);
+	menu.AddItem("0", sBuffer);
+
+	Format(sBuffer, sizeof(sBuffer), "%T%T", "Map Sounds", client, g_bStopMapMusic[client] ? "Disabled" : "Enabled", client);
+	menu.AddItem("1", sBuffer);
+
+	menu.ExitBackButton = true;
+	menu.Display(client, MENU_TIME_FOREVER);
+}
+
+public int MenuHandler_StopSoundsSettings(Menu menu, MenuAction action, int client, int selection)
+{
+	if (action == MenuAction_Cancel)
+	{
+		ShowCookieMenu(client);
+	}
+	else if (action == MenuAction_Select)
+	{
+		if (selection == 0)
+		{
+			g_bStopWeaponSounds[client] = !g_bStopWeaponSounds[client];
+			CheckWeaponSoundsHooks();
+
+			if (g_bStopWeaponSounds[client])
+			{
+				SetClientCookie(client, g_hCookieStopSound, "1");
+				CPrintToChat(client, "%t %t", "Chat Prefix", "Weapon sounds disabled");
+			}
+			else
+			{
+				SetClientCookie(client, g_hCookieStopSound, "0");
+				CPrintToChat(client, "%t %t", "Chat Prefix", "Weapon sounds enabled");
+			}
+
+		}
+		else if (selection == 1)
+		{
+			g_bStopMapMusic[client] = !g_bStopMapMusic[client];
+			CheckMapMusicHooks();
+
+			if (g_bStopMapMusic[client])
+			{
+				SetClientCookie(client, g_hCookieStopMapMusic, "1");
+				CPrintToChat(client, "%t %t", "Chat Prefix", "Map music disabled");
+				StopMapMusic();
+			}
+			else
+			{
+				SetClientCookie(client, g_hCookieStopMapMusic, "0");
+				CPrintToChat(client, "%t %t", "Chat Prefix", "Map music enabled");
+			}
+		}
+
+		ShowStopSoundsSettingsMenu(client);
+	}
+	else if (action == MenuAction_End)
+	{
+		delete menu;
+	}
+}
+
+public Action Hook_NormalSound_CSS(int clients[MAXPLAYERS], int &numClients, char sample[PLATFORM_MAX_PATH],
 	  int &entity, int &channel, float &volume, int &level, int &pitch, int &flags,
 	  char soundEntry[PLATFORM_MAX_PATH], int &seed)
 {
 	// Ignore non-weapon sounds.
-	if(!g_bHooked || !(strncmp(sample, "weapons", 7) == 0 || strncmp(sample[1], "weapons", 7) == 0))
+	if (!g_bStopWeaponSoundsHooked || channel != SNDCHAN_WEAPON)
+	{
 		return Plugin_Continue;
+	}
 
-	for(int i = 0; i < numClients; i++)
+	for (int i = 0; i < numClients; i++)
 	{
 		int client = clients[i];
-		if(g_bStopSound[client])
+		if (g_bStopWeaponSounds[client])
 		{
 			// Remove the client from the array.
-			for(int j = i; j < numClients - 1; j++)
+			for (int j = i; j < numClients - 1; j++) {
 				clients[j] = clients[j + 1];
+			}
+
+			numClients--;
+			i--;
+		}
+	}
+
+	return (numClients > 0) ? Plugin_Changed : Plugin_Stop;
+}
+
+public Action Hook_NormalSound_CSGO(int clients[MAXPLAYERS], int &numClients, char sample[PLATFORM_MAX_PATH],
+	  int &entity, int &channel, float &volume, int &level, int &pitch, int &flags,
+	  char soundEntry[PLATFORM_MAX_PATH], int &seed)
+{
+	// Ignore non-weapon sounds.
+	if (!g_bStopWeaponSoundsHooked || (channel != SNDCHAN_WEAPON && !(channel == SNDCHAN_AUTO && strncmp(sample, "physics/flesh", 13) == 0) && !(channel == SNDCHAN_STATIC  && StrContains(sample, "player/headshot", true) != -1)))
+	{
+		return Plugin_Continue;
+	}
+
+	for (int i = 0; i < numClients; i++)
+	{
+		int client = clients[i];
+		if (g_bStopWeaponSounds[client] || !IsClientConnected(client))
+		{
+			// Remove the client from the array.
+			for (int j = i; j < numClients - 1; j++) {
+				clients[j] = clients[j + 1];
+			}
 
 			numClients--;
 			i--;
@@ -238,25 +602,33 @@ public Action Hook_NormalSound(int clients[MAXPLAYERS], int &numClients, char sa
 
 public Action CSS_Hook_ShotgunShot(const char[] te_name, const int[] Players, int numClients, float delay)
 {
-	if(!g_bHooked)
+	if (!g_bStopWeaponSoundsHooked)
+	{
 		return Plugin_Continue;
+	}
 
 	// Check which clients need to be excluded.
 	int[] newClients = new int[numClients];
 	int newTotal = 0;
 
-	for(int i = 0; i < numClients; i++)
+	for (int i = 0; i < numClients; i++)
 	{
-		int client = Players[i];
-		if(!g_bStopSound[client])
-			newClients[newTotal++] = client;
+		if (!g_bStopWeaponSounds[Players[i]])
+		{
+			newClients[newTotal++] = Players[i];
+		}
 	}
 
 	// No clients were excluded.
-	if(newTotal == numClients)
+	if (newTotal == numClients)
+	{
 		return Plugin_Continue;
-	else if(newTotal == 0) // All clients were excluded and there is no need to broadcast.
+	}
+	else if (newTotal == 0)
+	{
+		// All clients were excluded and there is no need to broadcast.
 		return Plugin_Stop;
+	}
 
 	// Re-broadcast to clients that still need it.
 	float vTemp[3];
@@ -276,75 +648,94 @@ public Action CSS_Hook_ShotgunShot(const char[] te_name, const int[] Players, in
 	return Plugin_Stop;
 }
 
-public Action DODS_Hook_FireBullets(const char[] te_name, const int[] Players, int numClients, float delay)
+public Action Hook_ReloadEffect_CSS(UserMsg msg_id, BfRead msg, const int[] players, int playersNum, bool reliable, bool init)
 {
-	if(!g_bHooked)
-		return Plugin_Continue;
-
-	// Check which clients need to be excluded.
-	int[] newClients = new int[numClients];
-	int newTotal = 0;
-
-	for(int i = 0; i < numClients; i++)
+	if (!g_bStopWeaponSoundsHooked)
 	{
-		int client = Players[i];
-		if(!g_bStopSound[client])
-			newClients[newTotal++] = client;
+		return Plugin_Continue;
 	}
 
-	// No clients were excluded.
-	if(newTotal == numClients)
-		return Plugin_Continue;
-	else if(newTotal == 0)// All clients were excluded and there is no need to broadcast.
-		return Plugin_Stop;
-
-	// Re-broadcast to clients that still need it.
-	float vTemp[3];
-	TE_Start("FireBullets");
-	TE_ReadVector("m_vecOrigin", vTemp);
-	TE_WriteVector("m_vecOrigin", vTemp);
-	TE_WriteFloat("m_vecAngles[0]", TE_ReadFloat("m_vecAngles[0]"));
-	TE_WriteFloat("m_vecAngles[1]", TE_ReadFloat("m_vecAngles[1]"));
-	TE_WriteNum("m_iWeaponID", TE_ReadNum("m_iWeaponID"));
-	TE_WriteNum("m_iMode", TE_ReadNum("m_iMode"));
-	TE_WriteNum("m_iSeed", TE_ReadNum("m_iSeed"));
-	TE_WriteNum("m_iPlayer", TE_ReadNum("m_iPlayer"));
-	TE_WriteFloat("m_flSpread", TE_ReadFloat("m_flSpread"));
-	TE_Send(newClients, newTotal, delay);
-
-	return Plugin_Stop;
-}
-
-public Action Hook_ReloadEffect(UserMsg msg_id, BfRead msg, const int[] players, int playersNum, bool reliable, bool init)
-{
-	if(!g_bHooked)
-		return Plugin_Continue;
-
 	int client = msg.ReadShort();
 
 	// Check which clients need to be excluded.
 	int[] newClients = new int[playersNum];
 	int newTotal = 0;
 
-	for(int i = 0; i < playersNum; i++)
+	for (int i = 0; i < playersNum; i++)
 	{
 		int client_ = players[i];
-		if(IsClientInGame(client_) && !g_bStopSound[client_])
+		if (IsClientInGame(client_) && !g_bStopWeaponSounds[client_])
+		{
 			newClients[newTotal++] = client_;
+		}
 	}
 
-	// No clients were excluded.
-	if(newTotal == playersNum)
+	if (newTotal == playersNum)
+	{
+		// No clients were excluded.
 		return Plugin_Continue;
-	else if(newTotal == 0) // All clients were excluded and there is no need to broadcast.
+	}
+	else if (newTotal == 0)
+	{
+		// All clients were excluded and there is no need to broadcast.
 		return Plugin_Handled;
+	}
 
 	DataPack pack = new DataPack();
 	pack.WriteCell(client);
 	pack.WriteCell(newTotal);
 
-	for(int i = 0; i < newTotal; i++)
+	for (int i = 0; i < newTotal; i++)
+	{
 		pack.WriteCell(newClients[i]);
+	}
+
+	RequestFrame(OnReloadEffect, pack);
+
+	return Plugin_Handled;
+}
+
+public Action Hook_ReloadEffect_CSGO(UserMsg msg_id, Protobuf msg, const int[] players, int playersNum, bool reliable, bool init)
+{
+	if (!g_bStopWeaponSoundsHooked)
+	{
+		return Plugin_Continue;
+	}
+
+	int client = PbReadInt(msg, "entidx");
+
+	// Check which clients need to be excluded.
+	int[] newClients = new int[playersNum];
+	int newTotal = 0;
+
+	for (int i = 0; i < playersNum; i++)
+	{
+		int client_ = players[i];
+		if (IsClientInGame(client_) && !g_bStopWeaponSounds[client_])
+		{
+			newClients[newTotal++] = client_;
+		}
+	}
+
+	if (newTotal == playersNum)
+	{
+		// No clients were excluded.
+		return Plugin_Continue;
+	}
+	else if (newTotal == 0)
+	{
+		// All clients were excluded and there is no need to broadcast.
+		return Plugin_Handled;
+	}
+
+	DataPack pack = new DataPack();
+	pack.WriteCell(client);
+	pack.WriteCell(newTotal);
+
+	for (int i = 0; i < newTotal; i++)
+	{
+		pack.WriteCell(newClients[i]);
+	}
 
 	RequestFrame(OnReloadEffect, pack);
 
@@ -360,18 +751,40 @@ public void OnReloadEffect(DataPack pack)
 	int[] players = new int[newTotal];
 	int playersNum = 0;
 
-	for(int i = 0; i < newTotal; i++)
+	for (int i = 0; i < newTotal; i++)
 	{
 		int client_ = pack.ReadCell();
-		if(IsClientInGame(client_))
+		if (IsClientInGame(client_))
+		{
 			players[playersNum++] = client_;
+		}
 	}
+
 	CloseHandle(pack);
 
 	Handle ReloadEffect = StartMessage("ReloadEffect", players, playersNum, USERMSG_RELIABLE | USERMSG_BLOCKHOOKS);
-	if(GetFeatureStatus(FeatureType_Native, "GetUserMessageType") == FeatureStatus_Available && GetUserMessageType() == UM_Protobuf)
+	if (GetFeatureStatus(FeatureType_Native, "GetUserMessageType") == FeatureStatus_Available && GetUserMessageType() == UM_Protobuf)
+	{
 		PbSetInt(ReloadEffect, "entidx", client);
+	}
 	else
+	{
 		BfWriteShort(ReloadEffect, client);
+	}
+
 	EndMessage();
 }
+
+public Action Hook_AmbientSound(char sample[PLATFORM_MAX_PATH], int &entity, float &volume, int &level, int &pitch, float pos[3], int &flags, float &delay)
+{
+	if (g_bStopMapMusicHooked && IsEntityInMapMusicEntities(entity))
+	{
+		DataPack datapack;
+		CreateDataTimer(0.0, Timer_DelayedStopForEntity, datapack, TIMER_FLAG_NO_MAPCHANGE);
+
+		datapack.WriteString(sample);
+		datapack.WriteCell(entity);
+	}
+
+	return Plugin_Continue;
+}
diff --git a/StopSound/scripting/include/morecolors.inc b/StopSound/scripting/include/morecolors.inc
deleted file mode 120000
index cd0d80e6..00000000
--- a/StopSound/scripting/include/morecolors.inc
+++ /dev/null
@@ -1 +0,0 @@
-../../../includes/morecolors.inc
\ No newline at end of file
diff --git a/StopSound/scripting/include/multicolors.inc b/StopSound/scripting/include/multicolors.inc
new file mode 100644
index 00000000..cb69a30d
--- /dev/null
+++ b/StopSound/scripting/include/multicolors.inc
@@ -0,0 +1 @@
+../../../includes/multicolors.inc
\ No newline at end of file
diff --git a/StopSound/translations/plugin.stopsound.phrases.txt b/StopSound/translations/plugin.stopsound.phrases.txt
new file mode 100644
index 00000000..5f28ef2e
--- /dev/null
+++ b/StopSound/translations/plugin.stopsound.phrases.txt
@@ -0,0 +1,68 @@
+"Phrases"
+{
+	"Chat Prefix"
+	{
+		"en"	"{green}[StopSound]{default}"
+		"ru"	"{green}[StopSound]{default}"
+	}
+
+	"Weapon sounds enabled"
+	{
+		"en"	"Weapon sounds {green}enabled{default}!"
+		"ru"	"Звуки стрельбы {green}включены{default}!"
+	}
+
+	"Weapon sounds disabled"
+	{
+		"en"	"Weapon sounds {darkred}disabled{default}!"
+		"ru"	"Звуки стрельбы {darkred}отключены{default}!"
+	}
+
+	"Map music enabled"
+	{
+		"en"	"Map music {green}enabled{default}!"
+		"ru"	"Музыка на картах {green}включена{default}!"
+	}
+
+	"Map music disabled"
+	{
+		"en"	"Map music {darkred}disabled{default}!"
+		"ru"	"Музыка на картах {darkred}отключена{default}!"
+	}
+
+	"Cookie Menu Stop Sounds"
+	{
+		"en"	"Stop Sounds"
+		"ru"	"Отключение звуков"
+	}
+
+	"Cookie Menu Stop Sounds Title"
+	{
+		"en"	"Stop Sounds Configuration"
+		"ru"	"Настройки Отключения Звуков"
+	}
+
+	"Weapon Sounds"
+	{
+		"en"	"Weapon sounds"
+		"ru"	"Звуки стрельбы"
+	}
+
+	"Map Sounds"
+	{
+		"en"	"Map music"
+		"ru"	"Музыка на картах"
+	}
+
+	"Disabled"
+	{
+		"en"	": Disabled"
+		"ru"	" [Выключено]"
+	}
+
+	"Enabled"
+	{
+		"en"	": Enabled"
+		"ru"	" [Включено]"
+	}
+}
\ No newline at end of file