AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting (https://forums.alliedmods.net/forumdisplay.php?f=107)
-   -   Replacement wanted for Tf2Items_OnGiveNamed Item_Post (https://forums.alliedmods.net/showthread.php?t=336157)

PC Gamer 01-31-2022 08:32

Replacement wanted for Tf2Items_OnGiveNamed Item_Post
 
Has anyone come up with a method for replacing this:
PHP Code:

void TF2Items_OnGiveNamedItem_Post(int clientchar[] classnameint itemDefIndexint levelint qualityint entity); 

with this?
PHP Code:

void OnEntityCreated(int entity, const char[] classname

in a way that allows you to check the itemDefIndex and level?

Benoist3012 01-31-2022 17:30

Re: Replacement wanted for Tf2Items_OnGiveNamed Item_Post
 
OnEntityCreated is indeed too early to retrieve any information. However once the entity is spawned (same frame there's no delay), you can read that info up.

So assuming you know the weapon classname, you could SDKHook the Spawn function.
And then read m_iEntityLevel or m_iItemDefinitionIndex netprops, under the spawn callback.
PHP Code:

public void OnEntityCreated(int entity, const char[] classname)
{
    if (
strcmp(classname"tf_weapon_something") == 0)
    {
        
SDKHook(entitySDKHook_SpawnWeapon_Spawn);
    }
}

public 
Action Weapon_Spawn(int entity)
{
    
int defIndex GetEntProp(entityProp_Send"m_iItemDefinitionIndex");
    
int level GetEntProp(entityProp_Send"m_iEntityLevel");
    return 
Plugin_Continue;



PC Gamer 01-31-2022 20:36

Re: Replacement wanted for Tf2Items_OnGiveNamed Item_Post
 
Unfortunately the classname and owner aren't known at this point. Any way to find out that info?

My goal is to fully remove dependency of TF2Items from the server. I've been able to accomplish most of that with TF_Econ_Data. However, I'm at a roadblock with this function.

nosoop 02-01-2022 05:52

Re: Replacement wanted for Tf2Items_OnGiveNamed Item_Post
 
The item should be completely initialized during SDKHook_SpawnPost, not SDKHook_Spawn. That said, the owner probably isn't in place up until after the game calls GiveTo on it. But that happens after CTFPlayer::GiveNamedItem, so that shouldn't matter.

GiveNamedItem also calls the item's Touch method, so a TouchPost hook should tell you the player that spawned it in.

Benoist3012 02-01-2022 06:05

Re: Replacement wanted for Tf2Items_OnGiveNamed Item_Post
 
If you don't know the classname, you could use "HasEntProp" under the OnEntityCreated forward, to figure which entity is an item. But that's less than ideal.

However, since DHooks is part of Sourcemod, you could simply do exactly what tf2items does in your plugin.
PHP Code:

static DynamicHook g_dhookCTFPlayer_GiveNamedItem;

static 
void GameData_Init()
{
    
GameData data = new GameData("yourgamedata");
    if (
data == null)
    {
        
SetFailState("Missing gamedata");
    }

    
int offset data.GetOffset("CTFPlayer::GiveNamedItem");
    
g_dhookCTFPlayer_GiveNamedItem = new DynamicHook(offsetHookType_EntityReturnType_CBaseEntityThisPointer_CBaseEntity);
    
g_dhookCTFPlayer_GiveNamedItem.AddParam(HookParamType_CharPtr);
    
g_dhookCTFPlayer_GiveNamedItem.AddParam(HookParamType_Int);
    
g_dhookCTFPlayer_GiveNamedItem.AddParam(HookParamType_ObjectPtr);
    
g_dhookCTFPlayer_GiveNamedItem.AddParam(HookParamType_Bool);
}

public 
void OnClientPutInServer(int client)
{
    
g_dhookCTFPlayer_GiveNamedItem.HookEntity(Hook_PostclientCTFPlayer_GiveNamedItem_Post);
}

static 
MRESReturn CTFPlayer_GiveNamedItem_Post(int player /* The item's owner */DHookReturn hReturnDHookParam hParams)
{
    
int item hReturn.Value/* The item entity index */
    
char classname[32];
    
GetEntityClassname(itemclassnamesizeof(classname)); /* The item's classname */
    
int itemDefIndex GetEntProp(itemProp_Send"m_iItemDefinitionIndex"); /* The item's def index */
    
int level GetEntProp(itemProp_Send"m_iEntityLevel"); /* The item's level */
    
int quality GetEntProp(itemProp_Send"m_iEntityQuality"); /* The item's quality */
    
return MRES_Ignored;


The gamedata can be tf2item's or yours, doesn't matter. Just make sure to change the key CTFPlayer::GiveNamedItem accordingly.

Edit :

If you're still going for a no gamedata approach. Then consider HasEntProp
PHP Code:

public void OnEntityCreated(int entity, const char[] classname)
{
    if (
HasEntProp(entityProp_Send"m_Item"))
    {
        
SDKHook(entitySDKHook_TouchPostItem_TouchPost);
    }
}

static 
void Item_TouchPost(int item /* The item entity index */int player /* The item's owner */)
{
    
char classname[32];
    
GetEntityClassname(itemclassnamesizeof(classname)); /* The item's classname */
    
int itemDefIndex GetEntProp(itemProp_Send"m_iItemDefinitionIndex"); /* The item's def index */
    
int level GetEntProp(itemProp_Send"m_iEntityLevel"); /* The item's level */
    
int quality GetEntProp(itemProp_Send"m_iEntityQuality"); /* The item's quality */

    
SDKUnhook(itemSDKHook_TouchPostItem_TouchPost);



PC Gamer 02-01-2022 17:35

Re: Replacement wanted for Tf2Items_OnGiveNamed Item_Post
 
Any idea what I may be doing wrong? Getting this error while using sm version 1.11.0.6837:
PHP Code:

L 02/01/2022 14:30:21: [SMException reportedHook not setup for a virtual hook.
L 02/01/2022 14:30:21: [SMBlamingbob.smx
L 02
/01/2022 14:30:21: [SMCall stack trace:
L 02/01/2022 14:30:21: [SM]   [0DynamicHook.HookEntity
L 02
/01/2022 14:30:21: [SM]   [1Line 34bob.sp::OnClientPutInServer 

Test Code:
PHP Code:

#pragma semicolon 1

#include <dhooks>

static DynamicHook g_dhookCTFPlayer_GiveNamedItem

public 
Plugin myinfo 
{
    
name "Test of OnGiveNamedItem Replacement",
    
author "Benoist3012",
    
description "Test of OnGiveNamedItem function",
    
version "1.0",
    
url "www.sourcemod.com"    
}

public 
OnPluginStart()

    
GameData data = new GameData("tf2.items");
    if (
data == null)
    {
        
SetFailState("Missing gamedata");
    }

    
int offset data.GetOffset("CTFPlayer::GiveNamedItem");
    
g_dhookCTFPlayer_GiveNamedItem = new DynamicHook(offsetHookType_EntityReturnType_CBaseEntityThisPointer_CBaseEntity);
    
g_dhookCTFPlayer_GiveNamedItem.AddParam(HookParamType_CharPtr);
    
g_dhookCTFPlayer_GiveNamedItem.AddParam(HookParamType_Int);
    
g_dhookCTFPlayer_GiveNamedItem.AddParam(HookParamType_ObjectPtr);
    
g_dhookCTFPlayer_GiveNamedItem.AddParam(HookParamType_Bool); 
}

public 
void OnClientPutInServer(int client)
{
    
g_dhookCTFPlayer_GiveNamedItem.HookEntity(Hook_PostclientCTFPlayer_GiveNamedItem_Post);
}

static 
MRESReturn CTFPlayer_GiveNamedItem_Post(int playerDHookReturn hReturnDHookParam hParams)
{
    
int item hReturn.Value/* The item entity index */
    
char classname[32];
    
GetEntityClassname(itemclassnamesizeof(classname)); /* The item's classname */
    
int itemDefIndex GetEntProp(itemProp_Send"m_iItemDefinitionIndex"); /* The item's def index */
    
int level GetEntProp(itemProp_Send"m_iEntityLevel"); /* The item's level */
    
int quality GetEntProp(itemProp_Send"m_iEntityQuality"); /* The item's quality */

    
PrintToChat(player"Player %N given item: %i with classname: %s, level: %i, and quality: %i"playeritemDefIndexclassnamelevelquality);

    return 
MRES_Ignored;




All times are GMT -4. The time now is 22:48.

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