plugin for jump king

This commit is contained in:
jenz 2023-05-15 22:53:08 +02:00
parent e2e0a0829b
commit b18d551cf1

View File

@ -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);
}