From c503b0d74b2ae5687ebff2b7c27dc187e7a31a58 Mon Sep 17 00:00:00 2001 From: New Name Date: Tue, 8 Sep 2026 20:41:43 +0100 Subject: [PATCH] Allow USE anywhere to activate entWatch items --- entWatch4/scripting/entWatch-core.sp | 139 +++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/entWatch4/scripting/entWatch-core.sp b/entWatch4/scripting/entWatch-core.sp index c3fdd89..2c87633 100644 --- a/entWatch4/scripting/entWatch-core.sp +++ b/entWatch4/scripting/entWatch-core.sp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -20,6 +21,7 @@ bool g_bLate; bool g_bLoaded; bool g_bLoadPending; bool g_bIntermission; +bool g_bUseAnywhereDisabled[MAXPLAYERS+1]; /* ARRAYS */ ArrayList g_hArray_Items; @@ -36,6 +38,14 @@ Handle g_hFwd_OnClientItemDisconnect; Handle g_hFwd_OnClientItemCanPickup; Handle g_hFwd_OnClientItemCanActivate; +/* COOKIES */ +Handle g_hCookie_UseAnywhereDisabled; + +/* INTEGERS */ +int g_iLastButtons[MAXPLAYERS+1]; +int g_iActivateTick[MAXPLAYERS+1]; +int g_iActivateButton[MAXPLAYERS+1]; + //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- @@ -79,8 +89,12 @@ public void OnPluginStart() g_hArray_Items = new ArrayList(); g_hArray_Configs = new ArrayList(); + g_hCookie_UseAnywhereDisabled = RegClientCookie("EW_UseAnywhereDisabled", "", CookieAccess_Private); + RegAdminCmd("sm_ereload", Command_ReloadConfig, ADMFLAG_BAN); + RegConsoleCmd("sm_euseanywhere", Command_ToggleUseAnywhere); + HookEvent("player_death", OnClientDeath); HookEvent("round_start", OnRoundStart); HookEvent("round_end", OnRoundEnd); @@ -95,6 +109,9 @@ public void OnPluginStart() SDKHook(client, SDKHook_WeaponEquipPost, OnWeaponPickup); SDKHook(client, SDKHook_WeaponDropPost, OnWeaponDrop); SDKHook(client, SDKHook_WeaponCanUse, OnWeaponTouch); + + if (AreClientCookiesCached(client)) + OnClientCookiesCached(client); } } } @@ -136,6 +153,32 @@ public Action Command_ReloadConfig(int client, int args) } } +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public Action Command_ToggleUseAnywhere(int client, int args) +{ + if (!Client_IsValid(client)) + return Plugin_Handled; + + g_bUseAnywhereDisabled[client] = !g_bUseAnywhereDisabled[client]; + + if (g_bUseAnywhereDisabled[client]) + { + SetClientCookieBool(client, g_hCookie_UseAnywhereDisabled, true); + + CReplyToCommand(client, "\x07%s[entWatch] \x07%sYou will now have to aim at the item's trigger to use it.", "E01B5D", "F16767"); + return Plugin_Handled; + } + else + { + SetClientCookieBool(client, g_hCookie_UseAnywhereDisabled, false); + + CReplyToCommand(client, "\x07%s[entWatch] \x07%sYou can now use your item by pressing your USE key anywhere.", "E01B5D", "F16767"); + return Plugin_Handled; + } +} + //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- @@ -456,6 +499,11 @@ public int SortItemsArray(int index1, int index2, Handle array, Handle hndl) //---------------------------------------------------------------------------------------------------- public void OnClientPutInServer(int client) { + g_bUseAnywhereDisabled[client] = false; + g_iLastButtons[client] = 0; + g_iActivateTick[client] = 0; + g_iActivateButton[client] = INVALID_ENT_REFERENCE; + if (!IsFakeClient(client)) { SDKHook(client, SDKHook_WeaponEquipPost, OnWeaponPickup); @@ -464,6 +512,14 @@ public void OnClientPutInServer(int client) } } +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public void OnClientCookiesCached(int client) +{ + g_bUseAnywhereDisabled[client] = GetClientCookieBool(client, g_hCookie_UseAnywhereDisabled); +} + //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- @@ -578,6 +634,63 @@ public Action OnWeaponDrop(int client, int weapon) return Plugin_Handled; } +//---------------------------------------------------------------------------------------------------- +// Purpose: Activate the clients item on +use, without having to aim at its button. +//---------------------------------------------------------------------------------------------------- +public Action OnPlayerRunCmd(int client, int &buttons) +{ + bool bPressed = view_as((buttons & IN_USE) && !(g_iLastButtons[client] & IN_USE)); + + g_iLastButtons[client] = buttons; + + if (!bPressed || g_bUseAnywhereDisabled[client] || !IsPlayerAlive(client)) + return Plugin_Continue; + + int button = FindClientItemButton(client); + + if (button == INVALID_ENT_REFERENCE) + return Plugin_Continue; + + AcceptEntityInput(button, "Use", client, client); + + // Set after the input, so the press above is not blocked by its own guard. + g_iActivateTick[client] = GetGameTickCount(); + g_iActivateButton[client] = button; + + return Plugin_Continue; +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: Get the button of the clients item, but only if they carry exactly one. +//---------------------------------------------------------------------------------------------------- +stock int FindClientItemButton(int client) +{ + int iFound = -1; + + for (int index; index < g_hArray_Items.Length; index++) + { + CItem item = g_hArray_Items.Get(index); + + if (!(item.bClient && item.iClient == client)) + continue; + + if (iFound != -1) + return INVALID_ENT_REFERENCE; + + iFound = index; + } + + if (iFound != -1) + { + CItem itemFound = g_hArray_Items.Get(iFound); + + if (itemFound.bButton && Entity_IsValid(itemFound.iButton)) + return itemFound.iButton; + } + + return INVALID_ENT_REFERENCE; +} + //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- @@ -585,6 +698,10 @@ public Action OnButtonPress(int button, int client) { if (Client_IsValid(client) && Entity_IsValid(button) && g_hArray_Items.Length) { + // Ignore the engines own +use if we already fired this button for the client this tick. + if (g_iActivateTick[client] == GetGameTickCount() && g_iActivateButton[client] == button) + return Plugin_Handled; + if (HasEntProp(button, Prop_Data, "m_bLocked") && GetEntProp(button, Prop_Data, "m_bLocked")) return Plugin_Handled; @@ -788,3 +905,25 @@ public int Native_ClientHasItem(Handle hPlugin, int numParams) } return 0; } + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +stock void SetClientCookieBool(int client, Handle hCookie, bool value) +{ + char sValue[32]; + IntToString(view_as(value), sValue, sizeof(sValue)); + + SetClientCookie(client, hCookie, sValue); +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +stock bool GetClientCookieBool(int client, Handle hCookie) +{ + char sValue[32]; + GetClientCookie(client, hCookie, sValue, sizeof(sValue)); + + return view_as(StringToInt(sValue)); +}