Raised This Month: $ Target: $400
 0% 

Any way to hook function of another plugin?


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
midnight9
Senior Member
Join Date: Nov 2012
Old 04-05-2015 , 19:23   Any way to hook function of another plugin?
Reply With Quote #1

Hello, is it possible to hook function of another plugin? Im using tank HUD panel plugin that its being triggered by tank spawn event. I also use plugin to allow players to swap unwanted tank to another player, and after that swap the tank HUD panel doesnt work any more, it does work when tank client leaves the game or he switches to spectator and the control of the tank is being taken by another player, but it doesnt when tank is swaped to another player via tank swap plugin the tank HUD basically disappers. So im wondering if there's any way to somehow hook this swap tank function and when its used, trigger the tank hud panel again? Im not sure if this even make sense, but im not sure how i to explain it.

Regards
midnight9 is offline
Miu
Veteran Member
Join Date: Nov 2013
Old 04-06-2015 , 08:44   Re: Any way to hook function of another plugin?
Reply With Quote #2

If you have the source you could just change it...?
Miu is offline
midnight9
Senior Member
Join Date: Nov 2012
Old 04-06-2015 , 12:08   Re: Any way to hook function of another plugin?
Reply With Quote #3

Change it how?
PHP Code:
#pragma semicolon 1
#include <sourcemod>
#include <sdktools>
#include <left4downtown>
#define PLUGIN_VERSION "1.0.7"
#define TEST_DEBUG 0
#define TEST_DEBUG_LOG 1

static const String:SURRENDER_BUTTON_STRING[]      = "RELOAD"// what is shown in the Notification as Button to press
static const SURRENDER_BUTTON                       IN_RELOAD// Sourcemod Button definition. Alternatives: IN_DUCK, IN_USE
static const String:GAMEDATA_FILENAME[]             = "l4d2addresses";
static const 
String:GHOST_ENTPROP[]                 = "m_isGhost";
static const 
String:CLASS_ENTPROP[]                 = "m_zombieClass";
static const 
Float:CONTROL_DELAY_SAFETY             0.3;
static const 
Float:CONTROL_RETRY_DELAY              2.0;
static const 
TEAM_INFECTED                          3;
static const 
ZOMBIECLASS_TANK                       8;

static 
Handle:cvar_SurrenderTimeLimit               INVALID_HANDLE;
static 
Handle:cvar_SurrenderChoiceType              INVALID_HANDLE;
static 
Handle:surrenderMenu                         INVALID_HANDLE;
static 
bool:withinTimeLimit                         false;
static 
bool:isFinale                                false;
static 
primaryTankPlayer                            = -1;
static 
tankAttemptsFailed                         0;
static 
Handle:sdkTakeOverZombieBot INVALID_HANDLE;
static 
Handle:sdkReplaceWithBot INVALID_HANDLE;
static 
Handle:sdkCullZombie INVALID_HANDLE;
static 
Handle:sdkReplaceTank INVALID_HANDLE;
static 
Address:g_pZombieManager;
public 
Plugin:myinfo 
{
    
name "L4D2 Tank Swap",
    
author "AtomicStryker",
    
description " Allows a primary Tank Player to surrender control to one of his teammates, or admins to take it anytime ",
    
version PLUGIN_VERSION,
    
url "http://forums.alliedmods.net/showthread.php?t=120807"
}
public 
OnPluginStart()
{
    
Require_L4D2();
    
    
PrepSDKCalls();
    
CreateConVar("l4d2_tankswap_version"PLUGIN_VERSION" Version of L4D2 Tank Swap on this server "FCVAR_PLUGIN|FCVAR_NOTIFY|FCVAR_SPONLY|FCVAR_DONTRECORD);
    
cvar_SurrenderTimeLimit CreateConVar("l4d2_tankswap_timelimit""10"" How many seconds can a primary Tank Player surrender control "FCVAR_PLUGIN|FCVAR_NOTIFY);
    
cvar_SurrenderChoiceType CreateConVar("l4d2_tankswap_choicetype""1"" 0 - Disabled; 1 - press Button to call Menu; 2 - Menu appears for every Tank "FCVAR_PLUGIN|FCVAR_NOTIFY);
    
    
RegAdminCmd("sm_taketank"TS_CMD_TakeTankADMFLAG_CHEATS" Take over the current Tank ");
    
    
LoadTranslations("common.phrases");
    
    
HookEvent("finale_start"_FinaleStart_EventEventHookMode_PostNoCopy);
    
HookEvent("round_end"_RoundEnd_EventEventHookMode_PostNoCopy);
}
public 
Action:_RoundEnd_Event(Handle:event, const String:name[], bool:dontBroadcast)
{
    
isFinale false;
}
public 
Action:_FinaleStart_Event(Handle:event, const String:name[], bool:dontBroadcast)
{
    
isFinale true;
}
stock Require_L4D2()
{
    
decl String:game[32];
    
GetGameFolderName(gamesizeof(game));
    if (!
StrEqual(game"left4dead2"false))
    {
        
SetFailState("Plugin supports Left 4 Dead 2 only.");
    }
}
public 
Action:TS_CMD_TakeTank(clientargs)
{
    if (!
client) return Plugin_Handled;
    
    new 
target FindHumanTankPlayer();
    
    if (!
target)
    {
        
ReplyToCommand(client"There is no human Tank in Play");
        return 
Plugin_Handled;
    }
    else if (
target == client)
    {
        
ReplyToCommand(client"Dont try to use dangerous SDKCalls with experimental inputs.");
        return 
Plugin_Handled;
    }
    
    if (
CancelClientMenu(target))
    {
        
DebugPrintToAll("TakeTank Command used while client menu was active, shutting down client menu");
        
withinTimeLimit false;
        
surrenderMenu INVALID_HANDLE;
    }
    
    if (
GetClientHealth(client) > && !IsPlayerGhost(client))
    {
        
L4D2_ReplaceWithBot(clienttrue);
    }
    
L4D2_ReplaceTank(targetclient);
    return 
Plugin_Handled;
}
public 
Action:L4D_OnSpawnTank(const Float:vector[3], const Float:qangle[3])
{
    
DebugPrintToAll("L4D_OnSpawnTank fired, creating Timer");
    
    new 
Float:PlayerControlDelay GetConVarFloat(FindConVar("director_tank_lottery_selection_time"));
    
    if (!
isFinale)
    {
        
tankAttemptsFailed 0;
        switch (
GetConVarInt(cvar_SurrenderChoiceType))
        {
            case 
0:     return Plugin_Continue;
            case 
1:     CreateTimer(PlayerControlDelay CONTROL_DELAY_SAFETYTS_DisplayNotificationToTank);
            case 
2:     CreateTimer(PlayerControlDelay CONTROL_DELAY_SAFETYTS_Display_Auto_MenuToTank);
        }
    }
    
    return 
Plugin_Continue;
}
public 
Action:TS_DisplayNotificationToTank(Handle:timer)
{
    
primaryTankPlayer FindHumanTankPlayer();
    if (!
primaryTankPlayer)
    {
        
tankAttemptsFailed++;
        if (
tankAttemptsFailed 5)
        {
            
DebugPrintToAll("FindHumanTankPlayer didnt find a human tank, retrying in 2 seconds");
            
CreateTimer(CONTROL_RETRY_DELAYTS_DisplayNotificationToTank);
        }
        return 
Plugin_Stop;
    }
    
    
withinTimeLimit true;
    new 
Float:SurrenderTimeLimit GetConVarFloat(cvar_SurrenderTimeLimit);
    
CreateTimer(SurrenderTimeLimitTS_TimeLimitIsOver);
    
PrintToChat(primaryTankPlayer"\x04[Tank Swap]\x01 You can \x03surrender Tank Control\x01 during the next \x04%i seconds\x01 to one of your teammates by pressing \x04%s\x01"RoundFloat(SurrenderTimeLimit), SURRENDER_BUTTON_STRING);
    return 
Plugin_Stop;
}
public 
Action:TS_TimeLimitIsOver(Handle:timer)
{
    
withinTimeLimit false;
    if (
surrenderMenu != INVALID_HANDLE)
    {
        
surrenderMenu INVALID_HANDLE;
    }
    
    return 
Plugin_Stop;
}
static 
FindHumanTankPlayer()
{
    for (new 
1<= MaxClientsi++)
    {
        if (!
IsClientInGame(i)) continue;
        if (
GetClientTeam(i) != TEAM_INFECTED) continue;
        if (!
IsPlayerTank(i)) continue;
        if (
GetClientHealth(i) < || !IsPlayerAlive(i)) continue;
        
        return 
i;
    }
    
    return 
0;
}
static 
bool:IsPlayerTank (client)
{
    return (
GetEntProp(clientProp_SendCLASS_ENTPROP) == ZOMBIECLASS_TANK);
}
public 
Action:OnPlayerRunCmd(client, &buttons, &impulseFloat:vel[3], Float:angles[3], &weapon)
{
    if (!
withinTimeLimit) return Plugin_Continue;
    if (
client != primaryTankPlayer) return Plugin_Continue;
    
    if (
buttons SURRENDER_BUTTON)
    {
        
withinTimeLimit false;
        
CallSurrenderMenu();
        return 
Plugin_Handled;
    }
    
    return 
Plugin_Continue;
}
static 
CallSurrenderMenu()
{
    
surrenderMenu CreateMenu(TS_MenuCallBackMenuAction:MENU_ACTIONS_ALL);
    
SetMenuTitle(surrenderMenu" Who shall be Tank instead ");
    
    
DebugPrintToAll("Initializing Tank Swap Menu");
    
    
decl String:name[MAX_NAME_LENGTH], String:number[10];
    new 
electables;
    
    
AddMenuItem(surrenderMenu"0""Anyone but me!");
    
    for (new 
1<= MaxClientsi++)
    {
        if (
== primaryTankPlayer) continue;
        if (!
IsClientInGame(i)) continue;
        if (
GetClientTeam(i) != TEAM_INFECTED) continue;
        if (
IsFakeClient(i)) continue;
        
        
DebugPrintToAll("Found valid Tank Swap Choice: %N"i);
        
        
Format(namesizeof(name), "%N"i);
        
Format(numbersizeof(number), "%i"i);
        
AddMenuItem(surrenderMenunumbername);
        
        
electables++;
    }
    
    
DebugPrintToAll("Valid Tank Choices Amount: %i"electables);
    
    if (
electables 0//only do all that if there is someone to swap to
    
{
        
SetMenuExitButton(surrenderMenufalse);
        
DisplayMenu(surrenderMenuprimaryTankPlayerGetConVarInt(cvar_SurrenderTimeLimit));
    }
}
public 
TS_MenuCallBack(Handle:menuMenuAction:actionparam1param2)
{
    if (
action == MenuAction_EndCloseHandle(menu);
    if (
action != MenuAction_Select) return; // only allow a valid choice to pass
    
    
decl String:number[4];
    
GetMenuItem(menuparam2numbersizeof(number));
    
DebugPrintToAll("Manual MenuCallBack, param1/client: %s: %N, choice: %s"param1param1number);
    new 
choice StringToInt(number);
    if (!
choice)
    {
        
choice GetRandomEligibleTank();
        if (
GetClientHealth(choice) > && !IsPlayerGhost(choice))
        {
            
L4D2_ReplaceWithBot(choicetrue);
        }
        
L4D2_ReplaceTank(primaryTankPlayerchoice);
        
        
PrintToChatAll("\x04[Tank Swap]\x01 Tank Control was surrendered randomly to: \x03%N\x01"choice);
        
DebugPrintToAll("Tank Control was surrendered randomly to: %N"choice);
    }
    else
    {
        if (
GetClientHealth(choice) > && !IsPlayerGhost(choice))
        {
            
L4D2_ReplaceWithBot(choicetrue);
        }
        
L4D2_ReplaceTank(primaryTankPlayerchoice);
        
        
PrintToChatAll("\x04[Tank Swap]\x01 Tank Control was surrendered to: \x03%N\x01"choice);
        
DebugPrintToAll("Tank Control was surrendered to: %N"choice);
    }
}
public 
Action:TS_Display_Auto_MenuToTank(Handle:timer)
{
    
primaryTankPlayer FindHumanTankPlayer();
    if (!
primaryTankPlayer)
    {
        if (
HasTeamHumanPlayers(3))
        {
            
DebugPrintToAll("FindHumanTankPlayer didnt find a human tank, retrying auto menu in 2 seconds");
            
CreateTimer(CONTROL_RETRY_DELAYTS_Display_Auto_MenuToTank);
            return 
Plugin_Stop;
        }
        else
        {
            
DebugPrintToAll("No Humans on Infected team, aborting");
            return 
Plugin_Stop;
        }
    }
    
surrenderMenu CreateMenu(TS_Auto_MenuCallBackMenuAction:MENU_ACTIONS_ALL);
    
SetMenuTitle(surrenderMenu" Tank Control Menu ");
    
    
DebugPrintToAll("Initializing Tank Swap Menu, auto triggered");
    
    
decl String:name[MAX_NAME_LENGTH], String:number[10];
    new 
electables;
    
    
AddMenuItem(surrenderMenu"0""I want to stay Tank!");
    
AddMenuItem(surrenderMenu"99""Anyone but me!");
    
    for (new 
1<= MaxClientsi++)
    {
        if (
== primaryTankPlayer) continue;
        if (!
IsClientInGame(i)) continue;
        if (
GetClientTeam(i) != TEAM_INFECTED) continue;
        if (
IsFakeClient(i)) continue;
        
        
DebugPrintToAll("Found valid Tank Swap Choice: %N"i);
        
        
Format(namesizeof(name), "%N"i);
        
Format(numbersizeof(number), "%i"i);
        
AddMenuItem(surrenderMenunumbername);
        
        
electables++;
    }
    
    
DebugPrintToAll("Valid Tank Choices Amount: %i"electables);
    
    if (
electables 0//only do all that if there is someone to swap to
    
{
        
SetMenuExitButton(surrenderMenufalse);
        
DisplayMenu(surrenderMenuprimaryTankPlayerGetConVarInt(cvar_SurrenderTimeLimit));
    }
    
    return 
Plugin_Stop;
}
bool:HasTeamHumanPlayers(team)
{
    for (new 
1<= MaxClientsi++)
    {
        if (
IsClientInGame(i)
        && 
GetClientTeam(i) == team
        
&& !IsFakeClient(i))
        {
            return 
true;
        }
    }
    return 
false;
}
public 
TS_Auto_MenuCallBack(Handle:menuMenuAction:actionparam1param2)
{
    if (
action == MenuAction_EndCloseHandle(menu);
    
    if (
action != MenuAction_Select) return; // only allow a valid choice to pass
    
    
decl String:number[4];
    
GetMenuItem(menuparam2numbersizeof(number));
    
DebugPrintToAll("Auto MenuCallBack, param1/client: %s: %N, choice: %s"param1param1number);
    new 
choice StringToInt(number);
    if (!
choice) return; // "I want to stay Tank"
    
else if (choice == 99)  // "Anyone but me"
    
{
        
choice GetRandomEligibleTank();
        if (
GetClientHealth(choice) > && !IsPlayerGhost(choice))
        {
            
L4D2_ReplaceWithBot(choicetrue);
        }
        
L4D2_ReplaceTank(primaryTankPlayerchoice);
        
        
PrintToChatAll("\x04[Tank Swap]\x01 Tank Control was surrendered randomly to: \x03%N\x01"choice);
        
DebugPrintToAll("Tank Control was surrendered randomly to: %N"choice);
    }
    else    
// choice is a specific player id
    
{
        if (
GetClientHealth(choice) > && !IsPlayerGhost(choice))
        {
            
L4D2_ReplaceWithBot(choicetrue);
        }
        
L4D2_ReplaceTank(primaryTankPlayerchoice);
        
        
PrintToChatAll("\x04[Tank Swap]\x01 Tank Control was surrendered to: \x03%N\x01"choice);
        
DebugPrintToAll("Tank Control was surrendered to: %N"choice);
    }
}
static 
bool:IsPlayerGhost(client)
{
    return (
GetEntProp(clientProp_SendGHOST_ENTPROP1) == 1);
}
static 
GetRandomEligibleTank()
{
    new 
electablespool[MaxClients/2];
    
    for (new 
1<= MaxClientsi++)
    {
        if (
== primaryTankPlayer) continue;
        if (!
IsClientInGame(i)) continue;
        if (
GetClientTeam(i) != TEAM_INFECTED) continue;
        if (
IsFakeClient(i)) continue;
        
        
DebugPrintToAll("Found valid random Tank: %N"i);
        
        
electables++;
        
pool[electables] = i;
    }
    
    return 
poolGetRandomInt(1electables) ];
}
PrepSDKCalls()
{
    new 
Handle:ConfigFile LoadGameConfigFile(GAMEDATA_FILENAME);
    new 
Handle:MySDKCall INVALID_HANDLE;
    
    
StartPrepSDKCall(SDKCall_Player);
    
PrepSDKCall_SetFromConf(ConfigFileSDKConf_Signature"TakeOverZombieBot");
    
PrepSDKCall_AddParameter(SDKType_CBasePlayerSDKPass_Pointer);
    
MySDKCall EndPrepSDKCall();
    
    if (
MySDKCall == INVALID_HANDLE)
    {
        
SetFailState("Cant initialize TakeOverZombieBot SDKCall");
    }
    
    
sdkTakeOverZombieBot CloneHandle(MySDKCallsdkTakeOverZombieBot);
    
    
StartPrepSDKCall(SDKCall_Player);
    
PrepSDKCall_SetFromConf(ConfigFileSDKConf_Signature"ReplaceWithBot");
    
PrepSDKCall_AddParameter(SDKType_BoolSDKPass_Plain);
    
MySDKCall EndPrepSDKCall();
    
    if (
MySDKCall == INVALID_HANDLE)
    {
        
SetFailState("Cant initialize ReplaceWithBot SDKCall");
    }
    
    
sdkReplaceWithBot CloneHandle(MySDKCallsdkReplaceWithBot);
    
    
StartPrepSDKCall(SDKCall_Player);
    
PrepSDKCall_SetFromConf(ConfigFileSDKConf_Signature"CullZombie");
    
MySDKCall EndPrepSDKCall();
    
    if (
MySDKCall == INVALID_HANDLE)
    {
        
SetFailState("Cant initialize CullZombie SDKCall");
    }
    
    
sdkCullZombie CloneHandle(MySDKCallsdkCullZombie);
    
    
g_pZombieManager GameConfGetAddress(ConfigFile"CZombieManager");
    if(
g_pZombieManager == Address_Null)
    {
        
SetFailState("Could not load the ZombieManager pointer");
    }
    
    
StartPrepSDKCall(SDKCall_Raw);
    
PrepSDKCall_SetFromConf(ConfigFileSDKConf_Signature"ReplaceTank");
    
PrepSDKCall_AddParameter(SDKType_CBasePlayerSDKPass_Pointer);
    
PrepSDKCall_AddParameter(SDKType_CBasePlayerSDKPass_Pointer);
    
MySDKCall EndPrepSDKCall();
    
    if (
MySDKCall == INVALID_HANDLE)
    {
        
SetFailState("Cant initialize ReplaceTank SDKCall");
    }
    
    
sdkReplaceTank CloneHandle(MySDKCallsdkReplaceTank);
    
    
CloseHandle(ConfigFile);
    
CloseHandle(MySDKCall);
}
// CTerrorPlayer::TakeOverZombieBot(CTerrorPlayer*)
// Client takes control of an Infected Bot - Tank included. Causes odd shit to happen if an alive client's current SI class doesnt match the taken over one, exception tank
// i suggest CullZombie or State Transitioning until classes match before calling this
stock L4D2_TakeOverZombieBot(clienttarget)
{
    
DebugPrintToAll("TakeOverZombieBot being called, client %N target %N"clienttarget);
    
SDKCall(sdkTakeOverZombieBotclienttarget);
}
// CTerrorPlayer::ReplaceWithBot(bool)
// causes a perfect 'clone' of you as bot to appear at your location. you do not(!) disappear or die by this function alone
// boolean has no obvious effect
// intended for use directly before CullZombie or ReplaceTank
stock L4D2_ReplaceWithBot(clientboolean)
{
    
DebugPrintToAll("ReplaceWithBot being called, client %N boolean %b"clientboolean);
    
SDKCall(sdkReplaceWithBotclientboolean);
}
// CTerrorPlayer::CullZombie(void)
// causes instant respawn as spawnready ghost, new class - but only when you were alive in the first place (ghost included)
stock L4D2_CullZombie(target)
{
    
DebugPrintToAll("CullZombie being called, target %N"target);
    
SDKCall(sdkCullZombietarget);
}

// ZombieManager::ReplaceTank(CTerrorPlayer *, CTerrorPlayer *)
// causes Tank control to instantly shift from target 1 to target 2. Frustration is reset, target 1 may become tank again if target 2 gets frustrated.
// if target 2 was alive and/or spawned at calling this, it disappears.
// do not use with bots. Use L4D2_TakeOverZombieBot instead.
stock L4D2_ReplaceTank(clienttarget)
{
    
DebugPrintToAll("ReplaceTank being called, client %N target %N"clienttarget);
    
DebugPrintToAll("ZombieManager pointer: 0x%x"g_pZombieManager);
    if (
GetClientHealth(client) < 1)
    {
        
DebugPrintToAll("ReplaceTank invalid, origin tank %N health is below 1"client);
    }
    
    
SDKCall(sdkReplaceTankg_pZombieManagerclienttarget);
}
stock DebugPrintToAll(const String:format[], any:...)
{
    
#if (TEST_DEBUG || TEST_DEBUG_LOG)
    
decl String:buffer[256];
    
    
VFormat(buffersizeof(buffer), format2);
    
    
#if TEST_DEBUG
    
PrintToChatAll("[TANKVOTE] %s"buffer);
    
PrintToConsole(0"[TANKVOTE] %s"buffer);
    
#endif
    
    
LogMessage("%s"buffer);
    
#else
    //suppress "format" never used warning
    
if(format[0])
        return;
    else
        return;
    
#endif
}
stock CheatCommand(client, const String:command[], const String:arguments[]="")
{
    if (!
client || !IsClientInGame(client))
    {
        for (new 
target 1target <= MaxClientstarget++)
        {
            if (
IsClientInGame(target)) client target;
        }
    }
    if (!
client || !IsClientInGame(client)) return;
    
    new 
admindata GetUserFlagBits(client);
    
SetUserFlagBits(clientADMFLAG_ROOT);
    new 
flags GetCommandFlags(command);
    
SetCommandFlags(commandflags & ~FCVAR_CHEAT);
    
FakeClientCommand(client"%s %s"commandarguments);
    
SetCommandFlags(commandflags);
    
SetUserFlagBits(clientadmindata);

PHP Code:
#pragma semicolon 1
#include <sourcemod>
#include <l4d2_direct>
#define L4D2UTIL_STOCKS_ONLY
#include <l4d2util>
new bool:isTankActive;
new 
tankClient = -1;
new 
Handle:burnDurationCvar;
new 
bool:hiddenTankPanel[MAXPLAYERS 1];
public 
OnPluginStart()
{
 
HookEvent("round_start"Round_EventEventHookMode_PostNoCopy);
 
HookEvent("round_end"Round_EventEventHookMode_PostNoCopy);
 
HookEvent("tank_spawn"TankSpawn_Event);
 
HookEvent("player_death"PlayerDeath_Event);
 
burnDurationCvar FindConVar("tank_burn_duration");
 
 
RegConsoleCmd("sm_tankhud"ToggleTankPanel_Cmd"Toggles the tank panel visibility so other menus can be seen");
}
public 
Round_Event(Handle:event, const String:name[], bool:dontBroadcast)
{
 
isTankActive false;
 
tankClient = -1;
}
public 
TankSpawn_Event(Handle:event, const String:name[], bool:dontBroadcast)
{
 
tankClient GetClientOfUserId(GetEventInt(event"userid"));
 if (!
isTankActive)
 {
  
isTankActive true;
  
CreateTimer(0.5MenuRefresh_Timer_TIMER_REPEAT);
 }
}
stock UpdateTank(client) {
 new 
newTank = -1;
 for (new 
1<= MaxClientsi++)
 {
  if (
client != && IsClientInGame(i) && GetClientTeam(i) == 3
    
&& GetZombieClass(i) == 8)
  {
   
newTank i;
   break;
  }
 }
 if (
newTank <= 0)
 {
  
isTankActive false;
 }
}
public 
PlayerDeath_Event(Handle:event, const String:name[], bool:dontBroadcast)
{
 new 
client GetClientOfUserId(GetEventInt(event"userid"));
 if (
client && client <= MaxClients && GetClientTeam(client) == && GetZombieClass(client) == 8)
 {
  
UpdateTank(client);
 }
}
public 
Action:MenuRefresh_Timer(Handle:timer)
{
 static 
Handle:menuPanel INVALID_HANDLE;
 if (
isTankActive)
 {
  static 
String:buffer[64], String:rageBuffer[64];
  if (
menuPanel != INVALID_HANDLE)
  {
   
CloseHandle(menuPanel);
  }
  
menuPanel CreatePanel();
  
// Header
  
SetPanelTitle(menuPanel"Error Tank HUD"); 
  
// Name
  
if (!IsFakeClient(tankClient))
  {
   
GetClientName(tankClientbuffersizeof(buffer));
   
   if (
strlen(buffer) > 25)
   {
    
buffer[23] = '.';
    
buffer[24] = '.';
    
buffer[25] = '.';
    
buffer[26] = 0;
   }
   
   
Format(buffersizeof(buffer), "Control: %s"buffer);
   
DrawPanelText(menuPanelbuffer);
  }
  else
  {
   
DrawPanelText(menuPanel"Control: AI");
  }
  
// Health
  
static maxHealth = -1;
  if (
maxHealth 0) {
   
maxHealth RoundToNearest(GetConVarFloat(FindConVar("z_tank_health"))*1.5);
  }
  new 
health GetClientHealth(tankClient);
  
Format(buffersizeof(buffer), "Health : %i / %.1f%%"health100.0*health/maxHealth);
  
DrawPanelText(menuPanelbuffer);
  
// Rage
  
if (!IsFakeClient(tankClient)) {
   
FormatEx(rageBuffersizeof(rageBuffer), "Rage   : %d%% (Pass #%i)"GetTankFrustration(tankClient), L4D2Direct_GetTankPassedCount());
   
DrawPanelText(menuPanelrageBuffer);
  }
  
// Fire
  
if (GetEntityFlags(tankClient) & FL_ONFIRE)
  {
   
FormatEx(buffersizeof(buffer), "Burning: %.1f sec"health/GetConVarInt(burnDurationCvar));
   
DrawPanelText(menuPanelbuffer);
  }
  for (new 
1<= MaxClientsi++)
  {
   if (
IsClientInGame(i) && !IsFakeClient(i) && GetClientTeam(i) != && != tankClient && !hiddenTankPanel[tankClient])
   {
    
SendPanelToClient(menuPaneliDummyHandler3);
   }
  }

  
// tank-only hud
  
static Handle:tankPanel INVALID_HANDLE;
  if (!
IsFakeClient(tankClient) && !hiddenTankPanel[tankClient]) {
   if (
tankPanel != INVALID_HANDLE)
   {
    
CloseHandle(tankPanel);
   }
   
tankPanel CreatePanel();
   
SetPanelTitle(tankPanel"Tank HUD");
   
DrawPanelText(tankPanelrageBuffer);
   
SendPanelToClient(tankPaneltankClientDummyHandler3);
  }
  return 
Plugin_Continue;
 }
 return 
Plugin_Stop;
}
stock GetZombieClass(client) return GetEntProp(clientProp_Send"m_zombieClass");
public 
DummyHandler(Handle:menuMenuAction:actionparam1param2) { }
public 
Action:ToggleTankPanel_Cmd(client,args)
{
 
hiddenTankPanel[tankClient] = !hiddenTankPanel[tankClient];
 if(
hiddenTankPanel[tankClient])
 {
  
ReplyToCommand(client,"Tank HUD is now disabled.");
 }
 else
 {
  
ReplyToCommand(client,"Tank HUD is now enabled.");
 }
}
public 
OnClientDisconnect(client)
{
 if (
client == tankClient) {
  
UpdateTank(client);
 }
 
hiddenTankPanel[client] = false;

Attached Files
File Type: sp Get Plugin or Get Source (l4d2_tankswap.sp - 165 views - 18.4 KB)
File Type: sp Get Plugin or Get Source (tank_hud.sp - 156 views - 4.3 KB)
midnight9 is offline
Miu
Veteran Member
Join Date: Nov 2013
Old 04-06-2015 , 13:14   Re: Any way to hook function of another plugin?
Reply With Quote #4

I'm not sure what you're trying to accomplish, but if the function you were trying to "hook" looked like this

PHP Code:
SomeFunction(any:SomeData)
{
    
PrintToServer("Hi!");

you could change it to

PHP Code:
native Action:SomeFunctionHook(any:SomeData);

SomeFunction(any:SomeData)
{
    if(
SomeFunctionHook(SomeData) != Plugin_Continue)
    {
        return;
    }
    
    
PrintToServer("Hi!");

and add this in the other plugin you want to hook it from

PHP Code:
public OnPluginStart()
{
    
CreateNative("SomeFunctionHook"SomeFunctionHook);
}

public 
SomeFunctionHook(Handle:hPluginnParams)
{
    new 
SomeData GetNativeCell(1);
    return 
_:Plugin_Continue;

You can pass any parameter to the hook and do whatever with it, and return _:Plugin_Handled if you want it to stop from executing or _:Plugin_Continue if you want it to continue normally
Miu is offline
midnight9
Senior Member
Join Date: Nov 2012
Old 04-06-2015 , 14:50   Re: Any way to hook function of another plugin?
Reply With Quote #5

I belive i need to hook
PHP Code:
L4D2_ReplaceTank 
from this part or either the whole part?
PHP Code:
public TS_MenuCallBack(Handle:menuMenuAction:actionparam1param2)
{
    if (
action == MenuAction_EndCloseHandle(menu);
    if (
action != MenuAction_Select) return; // only allow a valid choice to pass
    
    
decl String:number[4];
    
GetMenuItem(menuparam2numbersizeof(number));
    
DebugPrintToAll("Manual MenuCallBack, param1/client: %s: %N, choice: %s"param1param1number);
    new 
choice StringToInt(number);
    if (!
choice)
    {
        
choice GetRandomEligibleTank();
        if (
GetClientHealth(choice) > && !IsPlayerGhost(choice))
        {
            
L4D2_ReplaceWithBot(choicetrue);
        }
        
L4D2_ReplaceTank(primaryTankPlayerchoice);
        
        
PrintToChatAll("\x04[Tank Swap]\x01 Tank Control was surrendered randomly to: \x03%N\x01"choice);
        
DebugPrintToAll("Tank Control was surrendered randomly to: %N"choice);
    }
    else
    {
        if (
GetClientHealth(choice) > && !IsPlayerGhost(choice))
        {
            
L4D2_ReplaceWithBot(choicetrue);
        }
        
L4D2_ReplaceTank(primaryTankPlayerchoice);
        
        
PrintToChatAll("\x04[Tank Swap]\x01 Tank Control was surrendered to: \x03%N\x01"choice);
        
DebugPrintToAll("Tank Control was surrendered to: %N"choice);
    }

midnight9 is offline
Miu
Veteran Member
Join Date: Nov 2013
Old 04-06-2015 , 15:10   Re: Any way to hook function of another plugin?
Reply With Quote #6

in the first plugin, change the L4D2_ReplaceTank function to

PHP Code:
native OnReplaceTank(client);

stock L4D2_ReplaceTank(clienttarget)
{
    
OnReplaceTank(target);
    
    
DebugPrintToAll("ReplaceTank being called, client %N target %N"clienttarget);
    
DebugPrintToAll("ZombieManager pointer: 0x%x"g_pZombieManager);
    if (
GetClientHealth(client) < 1)
    {
        
DebugPrintToAll("ReplaceTank invalid, origin tank %N health is below 1"client);
    }
    
    
SDKCall(sdkReplaceTankg_pZombieManagerclienttarget);

in the second plugin, change the OnPluginStart function to

PHP Code:
public OnPluginStart()
{
    
CreateNative("OnReplaceTank"OnReplaceTank);
    
    
HookEvent("round_start"Round_EventEventHookMode_PostNoCopy);
    
HookEvent("round_end"Round_EventEventHookMode_PostNoCopy);
    
HookEvent("tank_spawn"TankSpawn_Event);
    
HookEvent("player_death"PlayerDeath_Event);
    
burnDurationCvar FindConVar("tank_burn_duration");
    
    
RegConsoleCmd("sm_tankhud"ToggleTankPanel_Cmd"Toggles the tank panel visibility so other menus can be seen");
}

public 
OnReplaceTank(Handle:hPluginnumParams)
{
    
tankClient GetNativeCell(1);

Miu is offline
midnight9
Senior Member
Join Date: Nov 2012
Old 04-06-2015 , 15:52   Re: Any way to hook function of another plugin?
Reply With Quote #7

Quote:
Originally Posted by Miu View Post
in the first plugin, change the L4D2_ReplaceTank function to

PHP Code:
native OnReplaceTank(client);

stock L4D2_ReplaceTank(clienttarget)
{
    
OnReplaceTank(target);
    
    
DebugPrintToAll("ReplaceTank being called, client %N target %N"clienttarget);
    
DebugPrintToAll("ZombieManager pointer: 0x%x"g_pZombieManager);
    if (
GetClientHealth(client) < 1)
    {
        
DebugPrintToAll("ReplaceTank invalid, origin tank %N health is below 1"client);
    }
    
    
SDKCall(sdkReplaceTankg_pZombieManagerclienttarget);

in the second plugin, change the OnPluginStart function to

PHP Code:
public OnPluginStart()
{
    
CreateNative("OnReplaceTank"OnReplaceTank);
    
    
HookEvent("round_start"Round_EventEventHookMode_PostNoCopy);
    
HookEvent("round_end"Round_EventEventHookMode_PostNoCopy);
    
HookEvent("tank_spawn"TankSpawn_Event);
    
HookEvent("player_death"PlayerDeath_Event);
    
burnDurationCvar FindConVar("tank_burn_duration");
    
    
RegConsoleCmd("sm_tankhud"ToggleTankPanel_Cmd"Toggles the tank panel visibility so other menus can be seen");
}

public 
OnReplaceTank(Handle:hPluginnumParams)
{
    
tankClient GetNativeCell(1);

As for the first plugin only this line
PHP Code:
native OnReplaceTank(client); 
is meant to be added? Since everything else seems exactly the same, both plugins compiled without error, allthough it doesnt work. When i swap tank to another player tank hud goes away.
midnight9 is offline
Miu
Veteran Member
Join Date: Nov 2013
Old 04-06-2015 , 16:09   Re: Any way to hook function of another plugin?
Reply With Quote #8

no, there's a call to it inside L4D2_ReplaceTank as well. just copy/paste the section.
Miu is offline
midnight9
Senior Member
Join Date: Nov 2012
Old 04-06-2015 , 16:16   Re: Any way to hook function of another plugin?
Reply With Quote #9

Oh yea, i missed that sorry, but it still doesnt work
midnight9 is offline
Miu
Veteran Member
Join Date: Nov 2013
Old 04-06-2015 , 16:17   Re: Any way to hook function of another plugin?
Reply With Quote #10

anyway, seems like you could just do

PHP Code:
for (new 1<= MaxClientsi++)
 {
  if (
IsClientInGame(i) && GetClientTeam(i) == 3
    
&& GetZombieClass(i) == 8)
  {
   
tankClient i;
   break;
  }
 } 
at the start of MenuRefresh_Timer to get the tank even if it changes, without needing any kind of hook
Miu is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 19:08.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode