diff --git a/Hitmarker/materials/overlays/nano/hitmarker.vmt b/Hitmarker/materials/overlays/nano/hitmarker.vmt new file mode 100644 index 00000000..38e6884f --- /dev/null +++ b/Hitmarker/materials/overlays/nano/hitmarker.vmt @@ -0,0 +1,5 @@ +"UnlitGeneric" +{ + "$basetexture" "overlays/nano/hitmarker" + "$translucent" 1 +} \ No newline at end of file diff --git a/Hitmarker/materials/overlays/nano/hitmarker.vtf b/Hitmarker/materials/overlays/nano/hitmarker.vtf new file mode 100644 index 00000000..3bd9dddf Binary files /dev/null and b/Hitmarker/materials/overlays/nano/hitmarker.vtf differ diff --git a/Hitmarker/scripting/Hitmarker.sp b/Hitmarker/scripting/Hitmarker.sp new file mode 100644 index 00000000..df15d869 --- /dev/null +++ b/Hitmarker/scripting/Hitmarker.sp @@ -0,0 +1,303 @@ +#include +#include +#include +#include +#include +#include + +#define SPECMODE_NONE 0 +#define SPECMODE_FIRSTPERSON 4 +#define SPECMODE_THIRDPERSON 5 +#define SPECMODE_FREELOOK 6 + +#pragma newdecls required +#pragma semicolon 1 + +bool g_bShowBossHitmarker[MAXPLAYERS+1]; +bool g_bShowZombieHitmarker[MAXPLAYERS+1]; + +Handle g_hTimer[MAXPLAYERS+1] = {null,...}; + +Handle g_hCookie_ShowBossHitmarker; +Handle g_hCookie_ShowZombieHitmarker; + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public Plugin myinfo = +{ + name = "Htimarker", + author = "Neon & Nano", + description = "Players can enable or disable their hitmarkers while shooting zombies or bosses", + version = "1.0.0", +}; + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public void OnPluginStart() +{ + g_hCookie_ShowBossHitmarker = RegClientCookie("hitmarker_boss", "", CookieAccess_Private); + g_hCookie_ShowZombieHitmarker = RegClientCookie("hitmarker_zombie", "", CookieAccess_Private); + + RegConsoleCmd("sm_bhm", OnToggleBossHitmarker); + RegConsoleCmd("sm_zhm", OnToggleZombieHitmarker); + + SetCookieMenuItem(MenuHandler_CookieMenu, 0, "Hitmarker"); + + HookEvent("player_hurt", OnClientHurt); +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public void OnMapStart() +{ + PrecacheGeneric("overlays/nano/hitmarker.vtf", true); + PrecacheGeneric("overlays/nano/hitmarker.vmt", true); + AddFileToDownloadsTable("materials/overlays/nano/hitmarker.vtf"); + AddFileToDownloadsTable("materials/overlays/nano/hitmarker.vmt"); +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public void OnClientCookiesCached(int client) +{ + char sBuffer[4]; + GetClientCookie(client, g_hCookie_ShowBossHitmarker, sBuffer, sizeof(sBuffer)); + + if (sBuffer[0]) + g_bShowBossHitmarker[client] = true; + else + g_bShowBossHitmarker[client] = false; + + GetClientCookie(client, g_hCookie_ShowZombieHitmarker, sBuffer, sizeof(sBuffer)); + + if (sBuffer[0]) + g_bShowZombieHitmarker[client] = true; + else + g_bShowZombieHitmarker[client] = false; +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public void OnClientDisconnect(int client) +{ + g_bShowBossHitmarker[client] = false; + g_bShowZombieHitmarker[client] = false; +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public Action OnToggleBossHitmarker(int client, int args) +{ + ToggleBossHitmarker(client); + return Plugin_Handled; +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public void ToggleBossHitmarker(int client) +{ + g_bShowBossHitmarker[client] = !g_bShowBossHitmarker[client]; + SetClientCookie(client, g_hCookie_ShowBossHitmarker, g_bShowBossHitmarker[client] ? "1" : ""); + + CPrintToChat(client, "{cyan}[Hitmarker] {white}%s", g_bShowBossHitmarker[client] ? "Boss Hitmarker Enabled" : "Boss Hitmarker Disabled"); +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public Action OnToggleZombieHitmarker(int client, int args) +{ + ToggleZombieHitmarker(client); + return Plugin_Handled; +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public void ToggleZombieHitmarker(int client) +{ + g_bShowZombieHitmarker[client] = !g_bShowZombieHitmarker[client]; + SetClientCookie(client, g_hCookie_ShowZombieHitmarker, g_bShowZombieHitmarker[client] ? "1" : ""); + + CPrintToChat(client, "{cyan}[Hitmarker] {white}%s", g_bShowZombieHitmarker[client] ? "Zombie Hitmarker Enabled" : "Zombie Hitmarker Disabled"); +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public void ShowSettingsMenu(int client) +{ + Menu menu = new Menu(MenuHandler_MainMenu); + + menu.SetTitle("Hitmarker Settings", client); + + char sBuffer[128]; + + Format(sBuffer, sizeof(sBuffer), "Boss Hitmarker: %s", g_bShowBossHitmarker[client] ? "Enabled" : "Disabled"); + menu.AddItem("0", sBuffer); + + Format(sBuffer, sizeof(sBuffer), "Zombie Hitmarker: %s", g_bShowZombieHitmarker[client] ? "Enabled" : "Disabled"); + menu.AddItem("1", 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, "Hitmarker", 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): ToggleBossHitmarker(client); + case(1): ToggleZombieHitmarker(client); + } + + ShowSettingsMenu(client); + } + case(MenuAction_Cancel): + { + ShowCookieMenu(client); + } + case(MenuAction_End): + { + delete menu; + } + } +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public void OnBossDamaged(any Boss, any Config, int client, float damage) +{ + if (!IsValidClient(client)) + return; + + if (g_bShowBossHitmarker[client]) + ShowOverlay(client); + + for (int spec = 1; spec <= MaxClients; spec++) + { + if (!IsClientInGame(spec) || !IsClientObserver(spec) || !g_bShowBossHitmarker[spec]) + continue; + + int specMode = GetClientSpectatorMode(spec); + int specTarget = GetClientSpectatorTarget(spec); + + if ((specMode == SPECMODE_FIRSTPERSON) && specTarget == client) + ShowOverlay(spec); + } +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public void OnClientHurt(Event hEvent, const char[] sEvent, bool bDontBroadcast) +{ + int client = GetClientOfUserId(hEvent.GetInt("attacker")); + int victim = GetClientOfUserId(hEvent.GetInt("userid")); + + if (client < 1 || client > MaxClients || victim < 1 || victim > MaxClients) + return; + + if (client == victim || (IsPlayerAlive(client) && ZR_IsClientZombie(client))) + return; + + if (g_bShowZombieHitmarker[client]) + ShowOverlay(client); + + for (int spec = 1; spec <= MaxClients; spec++) + { + if (!IsClientInGame(spec) || !IsClientObserver(spec) || !g_bShowZombieHitmarker[spec]) + continue; + + int specMode = GetClientSpectatorMode(spec); + int specTarget = GetClientSpectatorTarget(spec); + + if (specMode == SPECMODE_FIRSTPERSON && specTarget == client) + ShowOverlay(spec); + } + +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public void ShowOverlay(int client) +{ + if (g_hTimer[client] != null) + { + delete g_hTimer[client]; + g_hTimer[client] = null; + } + ClientCommand(client, "r_screenoverlay \"%s\"", "overlays/nano/hitmarker"); + g_hTimer[client] = CreateTimer(0.3, ClearOverlay, client, TIMER_FLAG_NO_MAPCHANGE); +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public Action ClearOverlay(Handle timer, int client) +{ + g_hTimer[client] = null; + ClientCommand(client, "r_screenoverlay \"\""); +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +stock int IsValidClient(int client, bool nobots = true) +{ + if (client <= 0 || client > MaxClients || !IsClientConnected(client) || (nobots && IsFakeClient(client))) + return false; + + return IsClientInGame(client); +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +int GetClientSpectatorMode(int client) +{ + return GetEntProp(client, Prop_Send, "m_iObserverMode"); +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +int GetClientSpectatorTarget(int client) +{ + return GetEntPropEnt(client, Prop_Send, "m_hObserverTarget"); +}