AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting (https://forums.alliedmods.net/forumdisplay.php?f=107)
-   -   Solved How to set SDKHook on round_start correctly? (https://forums.alliedmods.net/showthread.php?t=311558)

Dragokas 10-23-2018 12:31

How to set SDKHook on round_start correctly?
 
Hi,

Let's say I'm using SDKHook_OnTakeDamage to block some damage on all SURVIVORS (2) team (L4D).

It require to set hook on each individual client:

Code:

SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage);
No problem. But, on round_end, game engine automatically remove that hook.
So I need to set it again once player is fully-ingame (I guess) on next round_start.

For this reason, I'm using "player_team" event and check if "team == 2" (don't need extra unnecessary hooks).

Everything work ok. I just curious are there a simpler way than my monstro-code?

Code:

#include <sourcemod>
#include <sdktools>
#include <sdkhooks>

bool g_bHooked[MAXPLAYERS+1];

public void OnPluginStart()
{
        HookEvent("round_end",                                Event_RoundEnd,                EventHookMode_PostNoCopy);
        HookEvent("finale_win",                        Event_RoundEnd,                EventHookMode_PostNoCopy);
        HookEvent("mission_lost",                        Event_RoundEnd,                EventHookMode_PostNoCopy);
        HookEvent("map_transition",                Event_RoundEnd,                EventHookMode_PostNoCopy);
        HookEvent("player_team", Event_Player_Team);

}

public Action Event_RoundEnd(Event event, char[] name, bool dontBroadcast)
{
        ResetHookFlag();
}

public void OnMapEnd()
{
        ResetHookFlag();
}

void ResetHookFlag()
{
        for (int i = 1; i <= MaxClients; i++)
        {
                g_bHooked[i] = false;
        }
}

void Set_SDKHook(int client)
{
        if (!g_bHooked[client])
        {
                SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage);
                g_bHooked[client] = true;
        }
}

void Remove_SDKHook(int client)
{
        if (g_bHooked[client])
        {
                SDKUnhook(client, SDKHook_OnTakeDamage, OnTakeDamage);
                g_bHooked[client] = false;
        }
}

public Action Event_Player_Team(Event event, char[] name, bool dontBroadcast)
{
        int UserId = event.GetInt("userid");
        if (UserId != 0)
        {
                int client = GetClientOfUserId(UserId);

                if (client != 0)
                {
                        int team = event.GetInt("team");

                        if (team == 2) // joined to survivor
                        {
                                Set_SDKHook(client);
                        }
                        else {
                                int oldteam = event.GetInt("oldteam");
                                if (oldteam == 2 || oldteam == 1) // desconnected from survivors or spectators
                                {
                                        bool bDisconnect = event.GetBool("disconnect");
                                        if (bDisconnect)
                                        {
                                                Remove_SDKHook(client);
                                        }
                                }
                        }
                }
        }
}

public Action OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, float damageForce[3], float damagePosition[3])
{
...
//return Plugin_Handled;
//return Plugin_Continue;
}

(and yea, I know about "player_hurt" / "player_hurt_concise" non-SDK hooks)

P.S. I saw some people use OnClientPutInServer() to set hook, but it's extra hooks (e.g. here also clients with team == 3).

8guawong 10-23-2018 13:13

Re: How to set SDKHook on round_start correctly?
 
how do you know the game engine unhooks after round end?

Powerlord 10-23-2018 14:20

Re: How to set SDKHook on round_start correctly?
 
Quote:

Originally Posted by 8guawong (Post 2620959)
how do you know the game engine unhooks after round end?

Given that this is L4D, I bet round end also means map change.

8guawong 10-23-2018 14:42

Re: How to set SDKHook on round_start correctly?
 
Quote:

Originally Posted by Powerlord (Post 2620978)
Given that this is L4D, I bet round end also means map change.

Ahhh didn't know that

MasterMind420 10-23-2018 15:27

Re: How to set SDKHook on round_start correctly?
 
In l4d2 i use onclientputinserver....it either rehooks it on everymap load or never unhooks it to begin with...not really sure but it always works between map changes or round end. .i havent tried a client loop in on round start but the problem with that is not all clients may be available to hook at that time...not sure though...could use player spawn event...set a bool in round end and check...but i think onclientputinserver is what u want.

Psyk0tik 10-23-2018 16:39

Re: How to set SDKHook on round_start correctly?
 
Quote:

Originally Posted by MasterMind420 (Post 2620990)
In l4d2 i use onclientputinserver....it either rehooks it on everymap load or never unhooks it to begin with...not really sure but it always works between map changes or round end. .i havent tried a client loop in on round start but the problem with that is not all clients may be available to hook at that time...not sure though...could use player spawn event...set a bool in round end and check...but i think onclientputinserver is what u want.

Seconded.

OnClientPutInServer() is the way to go.

For late loads, you can use a for () loop on OnPluginStart() or OnMapStart().

Dragokas 10-23-2018 16:47

Re: How to set SDKHook on round_start correctly?
 
8guawong, thanks. You are right. I made a problem myself by Unhooking on "disconnect" reason.
I thought player_team set that reason when player is really disconnect from the server.

Looks like my main question is over. After hooking it once, engine never unhook it again itself.

So, how to recognize is it disconnection because client quit the game or because map ends?
OnClientDisconnect() forward is also called for all clients just right before map ends.

EDIT.
Ohh, MasterMind, Crasher, thanks too.

Psyk0tik 10-23-2018 17:20

Re: How to set SDKHook on round_start correctly?
 
Quote:

Originally Posted by Dragokas (Post 2620997)
8guawong, thanks. You are right. I made a problem myself by Unhooking on "disconnect" reason.
I thought player_team set that reason when player is really disconnect from the server.

Looks like my main question is over. After hooking it once, engine never unhook it again itself.

So, how to recognize is it disconnection because client quit the game or because map ends?
OnClientDisconnect() forward is also called for all clients just right before map ends.

EDIT.
Ohh, MasterMind, Crasher, thanks too.

You could try using the player_disconnect event. It's only called when a player disconnects from the server, so it shouldn't be called across map change. Same with the player_connect event.

eyal282 10-23-2018 17:24

Re: How to set SDKHook on round_start correctly?
 
Just hook in onclientputinserver and check there if team == 3

Dragokas 10-24-2018 06:36

Re: How to set SDKHook on round_start correctly?
 
Quote:

Originally Posted by eyal282 (Post 2621003)
Just hook in onclientputinserver and check there if team == 3

Impossible. GetClientTeam == 0 at that point of time.

Looks like the only opportunity is player_team or round_start + timer.

Quote:

You could try using the player_disconnect event. It's only called when a player disconnects from the server, so it shouldn't be called across map change. Same with the player_connect event.
Right.

... All right. It's enough info for me. Thanks @all.


All times are GMT -4. The time now is 07:45.

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