diff --git a/ze_jump_king/jump_king_plus.sp b/ze_jump_king/jump_king_plus.sp
new file mode 100644
index 00000000..7629c5f3
--- /dev/null
+++ b/ze_jump_king/jump_king_plus.sp
@@ -0,0 +1,679 @@
+#pragma semicolon 1
+#pragma newdecls required
+
+#include <sdkhooks>
+#include <clientprefs>
+#include <multicolors>
+#include <sdktools>
+
+#define DATA_CONFIG_PATH "addons/sourcemod/configs/jump_king_records.cfg"
+#define SKIN_FOR_TOP "models/microrost/player_solaire1.mdl"
+#define CROWN "models/microrost/jumpking/star.mdl"
+
+#define Entity_GetTargetName(%1,%2,%3) GetEntPropString(%1, Prop_Data, "m_iName", %2, %3)
+
+#define RECORD_LIMIT 20
+#define MAX_TOP_PLAYERS 4
+#define MAX_DISPLAY 4
+
+public Plugin myinfo =
+{
+	name = "[MAP] Jump King Plus",
+	author = "Kotya",
+	version = "0.1.0"
+};
+
+char g_szString[256];
+
+float g_fRoundStart;
+
+enum struct class_record
+{
+	char szName[128];
+	char szSteam[32];
+
+	float fTime;
+}
+
+enum struct class_cookie
+{
+	Cookie PassMain;
+}
+
+enum struct class_player
+{
+	int iDisplayID;
+	bool bPassMain;
+	bool bTop;
+}
+
+class_cookie g_Cookie;
+class_player g_PlayerData[MAXPLAYERS+1];
+
+ArrayList g_alRecords;
+ArrayList g_alSteamAcces;
+
+class_record g_rLastRun;
+
+Handle g_hTimerSkin;
+
+float g_fRecord;
+
+bool g_bAddRecord;
+
+bool g_bDisplay;
+bool g_bRecord;
+bool g_bEnding;
+
+public void OnPluginStart()
+{
+	g_hTimerSkin = INVALID_HANDLE;
+	g_alSteamAcces = new ArrayList(ByteCountToCells(32));
+	g_alRecords = new ArrayList(sizeof(class_record));
+
+	// Cookie
+	g_Cookie.PassMain = RegClientCookie("jump_king_plus_passmain", "Jump King beat map", CookieAccess_Private);
+
+	// Commands
+	RegAdminCmd("sm_af_remove", Command_Remove, ADMFLAG_BAN);
+
+	// Hooks
+	HookEvent("round_freeze_end", Event_FreezeEnd);
+	HookEvent("round_end", Event_RoundEnd);
+	HookEvent("round_start", Event_RoundStart);
+
+	for (int iClient = 1; iClient <= MaxClients; iClient++)
+	{
+		if (AreClientCookiesCached(iClient))
+		{
+			OnClientCookiesCached(iClient);
+		}
+		else
+		{
+			OnClientDisconnect(iClient);
+		}
+	}
+}
+
+public void OnClientCookiesCached(int iClient)
+{
+	if (IsFakeClient(iClient))
+	{
+		return;
+	}
+
+	GetClientCookie(iClient, g_Cookie.PassMain, g_szString, sizeof(g_szString));
+	g_PlayerData[iClient].bPassMain = false;
+	if (g_szString[0] != '\0')
+	{
+		g_PlayerData[iClient].bPassMain = view_as<bool>(StringToInt(g_szString));
+	}
+
+	g_PlayerData[iClient].bTop = false;
+	if (g_alSteamAcces.Length > 0)
+	{
+		GetClientAuthId(iClient, AuthId_Steam2, g_szString, sizeof(g_szString));
+
+		int ID = g_alSteamAcces.FindString(g_szString);
+		if (ID != -1)
+		{
+			g_PlayerData[iClient].bTop = true;
+
+			g_alSteamAcces.Erase(ID);
+		}
+	}
+}
+
+public void OnClientDisconnect(int iClient)
+{
+	g_PlayerData[iClient].iDisplayID = 0;
+	g_PlayerData[iClient].bPassMain = false;
+	g_PlayerData[iClient].bTop = false;
+}
+
+public void Event_FreezeEnd(Event hEvent, const char[] sEvName, bool bDontBroadcast)
+{
+	if (g_alRecords.Length > 0)
+	{
+		class_record Record;
+		g_alRecords.GetArray(0, Record, sizeof(Record));
+		g_fRecord = Record.fTime;
+
+		int iM = RoundToFloor(g_fRecord / 60);
+		int iS = RoundToFloor(g_fRecord - (iM * 60));
+		char szD[4];
+
+		FormatEx(g_szString, sizeof(g_szString), "%.3f", (g_fRecord - RoundToFloor(g_fRecord)));
+		strcopy(szD, sizeof(szD), g_szString[2]);
+
+		CPrintToChatAll(" {default}[{red}MAP{default}] {green}%s{default} {{purple}%s{default}} map record: {orange}%i:%i:%s", Record.szName, Record.szSteam, iM, iS, szD);
+	}
+}
+
+public void Event_RoundEnd(Event hEvent, const char[] sEvName, bool bDontBroadcast)
+{
+	if (g_bEnding)
+	{
+		for (int iClient = 1; iClient <= MaxClients; iClient++)
+		{
+			if (!IsClientInGame(iClient) ||
+			IsFakeClient(iClient) ||
+			!IsPlayerAlive(iClient) ||
+			GetClientTeam(iClient) != 3)
+			{
+				continue;
+			}
+
+			g_PlayerData[iClient].bPassMain = true;
+			SetClientCookie(iClient, g_Cookie.PassMain, "1");
+		}
+	}
+
+	Reset();
+}
+
+public void Event_RoundStart(Event hEvent, const char[] sEvName, bool bDontBroadcast)
+{
+	if (g_bAddRecord)
+	{
+		TryInsert(g_rLastRun);
+		g_bAddRecord = false;
+	}
+
+	if (g_alRecords.Length > 0)
+	{
+		g_alSteamAcces.Clear();
+
+		class_record Record;
+		for (int i = 0; i < g_alRecords.Length; i++)
+		{
+			if (i >= MAX_TOP_PLAYERS)
+			{
+				break;
+			}
+			g_alRecords.GetArray(i, Record, sizeof(Record));
+			g_alSteamAcces.PushString(Record.szSteam);
+		}
+
+		for (int iClient = 1, ID; iClient <= MaxClients; iClient++)
+		{
+			if (!IsClientInGame(iClient) ||
+			IsFakeClient(iClient))
+			{
+				continue;
+			}
+			g_PlayerData[iClient].iDisplayID = 0;
+			g_PlayerData[iClient].bTop = false;
+
+			if (g_alSteamAcces.Length > 0)
+			{
+				GetClientAuthId(iClient, AuthId_Steam2, g_szString, sizeof(g_szString));
+
+				ID = g_alSteamAcces.FindString(g_szString);
+				if (ID != -1)
+				{
+					g_PlayerData[iClient].bTop = true;
+
+					g_alSteamAcces.Erase(ID);
+				}
+			}
+		}
+
+		if (g_hTimerSkin != INVALID_HANDLE)
+		{
+			KillTimer(g_hTimerSkin);
+		}
+		g_hTimerSkin = CreateTimer(34.0, Timer_SetSkin);
+	}
+
+	Reset();
+}
+
+public Action Timer_SetSkin(Handle hTimer)
+{
+	g_hTimerSkin = INVALID_HANDLE;
+
+	for (int iClient = 1; iClient <= MaxClients; iClient++)
+	{
+		if (!IsClientInGame(iClient) ||
+		IsFakeClient(iClient) ||
+		!IsPlayerAlive(iClient) ||
+		GetClientTeam(iClient) != 3)
+		{
+			continue;
+		}
+
+		if (g_PlayerData[iClient].bTop)
+		{
+			SetEntityModel(iClient, SKIN_FOR_TOP);
+		}
+
+		if (g_PlayerData[iClient].bPassMain)
+		{
+			SetCrown(iClient);
+		}
+	}
+
+	return Plugin_Handled;
+}
+
+public void SetCrown(int iClient)
+{
+	float vecPos[3];
+	int iEntity = CreateEntityByName("prop_dynamic");
+	if (iEntity)
+	{
+		DispatchKeyValue(iEntity, "model", CROWN);
+		// DispatchKeyValue(iEntity, "rendermode", "1");
+		// DispatchKeyValue(iEntity, "renderamt", "192");
+		DispatchKeyValue(iEntity, "disableshadows", "1");
+		DispatchKeyValue(iEntity, "disableflashlight", "1");
+		if (DispatchSpawn(iEntity))
+		{
+
+			GetClientAbsOrigin(iClient, vecPos);
+			vecPos[2] += 73.0;
+
+			TeleportEntity(iEntity, vecPos);
+
+
+			SetVariantString("!activator");
+			AcceptEntityInput(iEntity, "SetParent", iClient, iEntity, 0);
+		}
+	}
+	int iEntity1 = CreateEntityByName("env_spritetrail");
+	if (iEntity1)
+	{
+		DispatchKeyValue(iEntity1, "rendermode", "5");
+		DispatchKeyValue(iEntity1, "spritename", "sprites/physbeam.vmt");
+		DispatchKeyValue(iEntity1, "startwidth", "16");
+		DispatchKeyValue(iEntity1, "rendercolor", "255 223 0");
+		DispatchKeyValue(iEntity1, "lifetime", "40");
+		if (DispatchSpawn(iEntity1))
+		{
+			GetClientAbsOrigin(iClient, vecPos);
+			vecPos[2] += 24.0;
+
+			TeleportEntity(iEntity1, vecPos);
+
+			SetVariantString("!activator");
+			AcceptEntityInput(iEntity1, "SetParent", iClient, iEntity1, 0);
+
+			SetVariantString("OnUser1 !self,SetScale,1.0,2.0,1");
+			AcceptEntityInput(iEntity1, "AddOutPut");
+			AcceptEntityInput(iEntity1, "FireUser1");
+		}
+	}
+}
+
+public void Reset()
+{
+	g_bDisplay = false;
+	g_bEnding = false;
+}
+
+public void OnMapEnd()
+{
+	Save_Config();
+
+	if (g_hTimerSkin != INVALID_HANDLE)
+	{
+		KillTimer(g_hTimerSkin);
+	}
+	g_hTimerSkin = INVALID_HANDLE;
+}
+
+public void OnMapStart()
+{
+	GetCurrentMap(g_szString, sizeof(g_szString));
+	if (StrContains(g_szString, "ze_jump_king") == -1)
+	{
+		GetPluginFilename(INVALID_HANDLE, g_szString, sizeof(g_szString));
+		return;
+	}
+
+	g_alRecords.Clear();
+
+	KeyValues kv = new KeyValues("");
+
+	if (FileExists(DATA_CONFIG_PATH) &&
+	kv.ImportFromFile(DATA_CONFIG_PATH) &&
+	kv.GotoFirstSubKey()) // Has Config
+	{
+		int iCount = 0;
+		class_record Record;
+
+		do
+		{
+			kv.GetString("name", Record.szName, sizeof(Record.szName));
+			kv.GetString("steam", Record.szSteam, sizeof(Record.szSteam));
+			Record.fTime = kv.GetFloat("time", 5000.000);
+
+			g_alRecords.PushArray(Record, sizeof(Record));
+			iCount++;
+		}
+		while (kv.GotoNextKey() &&
+		RECORD_LIMIT > iCount);
+	}
+
+	delete kv;
+
+	PrecacheModel(SKIN_FOR_TOP);
+	PrecacheModel(CROWN);
+}
+
+
+public void TryInsert(class_record newRecord)
+{
+	bool bSave = false;
+	int Index = -1;
+	class_record Record;
+
+	for (int i = 0; i < g_alRecords.Length; i++)
+	{
+		g_alRecords.GetArray(i, Record, sizeof(Record));
+		if (!strcmp(newRecord.szSteam, Record.szSteam))
+		{
+			if (Record.fTime > newRecord.fTime)
+			{
+				g_alRecords.Erase(i);
+			}
+			else
+			{
+				return;
+			}
+			break;
+		}
+	}
+
+	for (int i = 0; i < g_alRecords.Length; i++)
+	{
+		g_alRecords.GetArray(i, Record, sizeof(Record));
+		if (Record.fTime > newRecord.fTime)
+		{
+			Index = i;
+			break;
+		}
+	}
+
+	if (g_alRecords.Length < RECORD_LIMIT)
+	{
+		bSave = true;
+		g_alRecords.PushArray(newRecord, sizeof(newRecord));
+	}
+
+	if (Index != -1)
+	{
+		for (int i = g_alRecords.Length - 2; i >= Index; i--)
+		{
+			g_alRecords.GetArray(i, Record, sizeof(Record));
+			g_alRecords.SetArray(i + 1, Record, sizeof(Record));
+		}
+		g_alRecords.SetArray(Index, newRecord, sizeof(newRecord));
+	}
+
+	if (bSave)
+	{
+		Save_Config();
+	}
+}
+
+public void Save_Config()
+{
+	KeyValues kv = new KeyValues("Data");
+	class_record Record;
+
+	for (int i = 0; i < g_alRecords.Length; i++)
+	{
+		FormatEx(g_szString, sizeof(g_szString), "%i", i);
+		kv.JumpToKey(g_szString, true);
+
+		g_alRecords.GetArray(i, Record, sizeof(Record));
+
+		kv.SetString("name", Record.szName);
+		kv.SetString("steam", Record.szSteam);
+
+		FormatEx(g_szString, sizeof(g_szString), "%.3f", Record.fTime);
+		kv.SetString("time", g_szString);
+
+		kv.GoBack();
+	}
+
+	kv.ExportToFile(DATA_CONFIG_PATH);
+	delete kv;
+}
+
+public void OnGameFrame()
+{
+	if (!g_bDisplay)
+	{
+		return;
+	}
+
+	float fTottal;
+
+	if (g_bEnding)
+	{
+		fTottal = g_rLastRun.fTime;
+	}
+	else
+	{
+		fTottal = GetGameTime() - g_fRoundStart;
+	}
+
+	g_bRecord = (fTottal < g_fRecord);
+
+	int iM = RoundToFloor(fTottal / 60);
+	int iS = RoundToFloor(fTottal - (iM * 60));
+
+	char szD[4];
+	FormatEx(g_szString, sizeof(g_szString), "%.3f", (fTottal - RoundToFloor(fTottal)));
+	strcopy(szD, sizeof(szD), g_szString[2]);
+
+
+	int iColor[3] = {255, 255, 255};
+
+	if (g_alRecords.Length > 0)
+	{
+		if (g_bRecord)
+		{
+			FormatEx(g_szString, sizeof(g_szString), "%i:%i:%s -%.3f", iM, iS, szD, (g_fRecord - fTottal));
+			iColor = {255, 215, 0};
+		}
+		else
+		{
+			FormatEx(g_szString, sizeof(g_szString), "%i:%i:%s +%.3f", iM, iS, szD, (fTottal - g_fRecord));
+
+			if (fTottal - g_fRecord < 20.0)
+			{
+				iColor = {0, 255, 0};
+			}
+			else
+			{
+				iColor = {255, 0, 0};
+			}
+		}
+	}
+	else
+	{
+		FormatEx(g_szString, sizeof(g_szString), "%i:%i:%s", iM, iS, szD);
+		iColor = {255, 215, 0};
+	}
+
+	SetHudTextParams(-1.0, 0.15, 1.5, iColor[0], iColor[1], iColor[2], 0, 0, 0.25, 0.0, 0.0);
+
+	for (int iClient = 1; iClient <= MaxClients; iClient++)
+	{
+		if (IsClientInGame(iClient))
+		{
+			ShowHudText(iClient, 1, g_szString);
+		}
+	}
+}
+
+public Action Command_Remove(int iClient, int iArgs)
+{
+	// Hook_EndTimer("123", 0, iClient, 0.00);
+
+	// return Plugin_Handled;
+	GetCmdArgString(g_szString, sizeof(g_szString));
+	class_record Record;
+
+	for (int i = 0; i < g_alRecords.Length; i++)
+	{
+		g_alRecords.GetArray(i, Record, sizeof(Record));
+		if (!strcmp(Record.szSteam, g_szString))
+		{
+			g_alRecords.Erase(i);
+			Save_Config();
+			break;
+		}
+	}
+
+	return Plugin_Handled;
+}
+
+public void OnEntityCreated(int iEntity, const char[] szClassName)
+{
+	if (!strcmp(szClassName, "trigger_once") ||
+	!strcmp(szClassName, "trigger_multiple") ||
+	!strcmp(szClassName, "logic_relay"))
+	{
+		SDKHook(iEntity, SDKHook_SpawnPost, Hook_SpawnPost);
+	}
+}
+public void Hook_SpawnPost(int iEntity)
+{
+	SDKUnhook(iEntity, SDKHook_SpawnPost, Hook_SpawnPost);
+
+	if (!IsValidEntity(iEntity))
+	{
+		return;
+	}
+
+	Entity_GetTargetName(iEntity, g_szString, sizeof(g_szString));
+
+	if (g_szString[0] == '\0')
+	{
+		return;
+	}
+
+	if (!strcmp(g_szString, "speedrun_timer_start"))
+	{
+		HookSingleEntityOutput(iEntity, "OnStartTouch", Hook_StartTimer, true);
+	}
+	else if (!strcmp(g_szString, "speedrun_stop_timer"))
+	{
+		HookSingleEntityOutput(iEntity, "OnTrigger", Hook_EndTimer, true);
+	}
+	else if (!strcmp(g_szString, "nigger"))
+	{
+		HookSingleEntityOutput(iEntity, "OnStartTouch", Hook_ShowTop);
+	}
+}
+
+public void Hook_ShowTop(const char[] szOutput, int iCaller, int iClient, float fDelay)
+{
+	SetHudTextParams(-1.0, 0.6, 4.0, 0, 255, 255, 0, 0, 0.25, 0.0, 0.0);
+	if (g_alRecords.Length < 1)
+	{
+		ShowHudText(iClient, 1, "No records");
+		return;
+	}
+
+	class_record Record;
+	char szString[512];
+
+	int iM;
+	int iS;
+	char szD[4];
+
+	int iStart = g_PlayerData[iClient].iDisplayID * MAX_DISPLAY;
+	int iEnd = iStart + MAX_DISPLAY;
+	if (iEnd > g_alRecords.Length)
+	{
+		iEnd = g_alRecords.Length;
+	}
+
+	bool bFind;
+
+	for (int i = iStart; i < iEnd; i++)
+	{
+		g_alRecords.GetArray(i, Record, sizeof(Record));
+
+		GetClientAuthId(iClient, AuthId_Steam2, g_szString, sizeof(g_szString));
+		bFind = (!strcmp(g_szString, Record.szSteam));
+
+		iM = RoundToFloor(Record.fTime / 60);
+		iS = RoundToFloor(Record.fTime - (iM * 60));
+		FormatEx(g_szString, sizeof(g_szString), "%.3f", (Record.fTime - RoundToFloor(Record.fTime)));
+		strcopy(szD, sizeof(szD), g_szString[2]);
+
+		if (bFind)
+		{
+			Format(szString, sizeof(szString), "%s>>> %i. %s {%s} - %im %is %sms <<<", szString, i+1, Record.szName, Record.szSteam[6], iM, iS, szD);
+		}
+		else
+		{
+			Format(szString, sizeof(szString), "%s%i. %s {%s} - %im %is %sms", szString, i+1, Record.szName, Record.szSteam[6], iM, iS, szD);
+		}
+
+		if (i + 1 < iEnd)
+		{
+			StrCat(szString, sizeof(szString), "\n");
+		}
+	}
+
+	ShowHudText(iClient, 1, szString);
+
+	g_PlayerData[iClient].iDisplayID++;
+	if (g_PlayerData[iClient].iDisplayID >= RoundToCeil(float(g_alRecords.Length) / MAX_TOP_PLAYERS))
+	{
+		g_PlayerData[iClient].iDisplayID = 0;
+	}
+}
+
+public void Hook_StartTimer(const char[] szOutput, int iCaller, int iActivator, float fDelay)
+{
+	g_fRoundStart = GetGameTime();
+	g_bDisplay = true;
+}
+
+public void Hook_EndTimer(const char[] szOutput, int iCaller, int iClient, float fDelay)
+{
+	g_bEnding = true;
+	g_bAddRecord = true;
+
+	char szSteam[32];
+	GetClientAuthId(iClient, AuthId_Steam2, szSteam, sizeof(szSteam));
+
+	FormatEx(g_rLastRun.szName, sizeof(g_rLastRun.szName), "%N", iClient);
+	FormatEx(g_rLastRun.szSteam, sizeof(g_rLastRun.szSteam), szSteam);
+	g_rLastRun.fTime = GetGameTime() - g_fRoundStart;
+
+	g_bRecord = (g_rLastRun.fTime < g_fRecord);
+
+	int iM = RoundToFloor(g_rLastRun.fTime / 60);
+	int iS = RoundToFloor(g_rLastRun.fTime - (iM * 60));
+	char szD[4];
+	FormatEx(g_szString, sizeof(g_szString), "%.3f", (g_rLastRun.fTime - RoundToFloor(g_rLastRun.fTime)));
+	strcopy(szD, sizeof(szD), g_szString[2]);
+
+	if (g_alRecords.Length > 0)
+	{
+		if (g_bRecord)
+		{
+			FormatEx(g_szString, sizeof(g_szString), " {default}[{red}MAP{default}] {green}%N{default} {{purple}%s{default}} new record map: {orange}%i:%i:%s {green}-%.3f", iClient, szSteam, iM, iS, szD, (g_fRecord - g_rLastRun.fTime));
+		}
+		else
+		{
+			FormatEx(g_szString, sizeof(g_szString), " {default}[{red}MAP{default}] {green}%N{default} {{purple}%s{default}} complete map: %i:%i:%s {red}+%.3f", iClient, szSteam, iM, iS, szD, (g_rLastRun.fTime - g_fRecord));
+		}
+	}
+	else
+	{
+		FormatEx(g_szString, sizeof(g_szString), " {default}[{red}MAP{default}] {green}%N{default} {{purple}%s{default}} new record map: {orange}%i:%i:%s", iClient, szSteam, iM, iS, szD);
+	}
+
+	CPrintToChatAll(g_szString);
+}