Raised This Month: $12 Target: $400
 3% 

Solved [TF2] EquipPlayerWeapon crash


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
PC Gamer
Veteran Member
Join Date: Mar 2014
Old 12-23-2020 , 16:49   [TF2] EquipPlayerWeapon crash
Reply With Quote #1

Can someone tell me how to fix the code below? When I execute the command !chop it instantly crashes my dedicated server.

PHP Code:
#pragma semicolon 1
#include <sourcemod>
#include <tf2_stocks>

#define PLUGIN_VERSION "1.0"

public Plugin:myinfo 
{
    
name "[TF2] Chopper",
    
author "PC Gamer",
    
description "Test of giving weapon",
    
version PLUGIN_VERSION,
    
url "www.sourcemod.com"
}

public 
OnPluginStart()
{
    
RegAdminCmd("sm_chop"Command_ChopADMFLAG_SLAY"Give Player a Weapon");
}

public 
Action:Command_Chop(clientargs)
{
    
decl String:arg1[32];
    if (
args 1)
    {
        
arg1 "@me";
    }
    else 
GetCmdArg(1arg1sizeof(arg1));
    new 
String:target_name[MAX_TARGET_LENGTH];
    new 
target_list[MAXPLAYERS], target_count;
    new 
bool:tn_is_ml;

    if ((
target_count ProcessTargetString(
                    
arg1,
                    
client,
                    
target_list,
                    
MAXPLAYERS,
                    
COMMAND_FILTER_ALIVE|(args COMMAND_FILTER_NO_IMMUNITY 0),
                    
target_name,
                    
sizeof(target_name),
                    
tn_is_ml)) <= 0)
    {
        
ReplyToTargetError(clienttarget_count);
        return 
Plugin_Handled;
    }
    for (new 
0target_counti++)
    {
        
Give_Client_Weapon(target_list[i]);
        
PrintToChat(target_list[i], "You have a new Weapon!");
        
PrintToChat(target_list[i], "You will lose this weapon when you touch a locker or die.");            
    }
    return 
Plugin_Handled;
}

Give_Client_Weapon(client)
{
        
TF2_RemoveWeaponSlot(client2); 
        
EquipPlayerWeapon(client132);    //Eyelander    

I normally use other methods to give a weapon, either an SDK call with gamedata or TF2items_giveweapon. However, someone suggested it would be better to use EquipPlayerWeapon. I'm sure I'm doing it wrong since it crashes my server.

Last edited by PC Gamer; 12-24-2020 at 22:09.
PC Gamer is offline
StrikeR14
AlliedModders Donor
Join Date: Apr 2016
Location: Behind my PC
Old 12-24-2020 , 14:45   Re: [TF2] EquipPlayerWeapon crash
Reply With Quote #2

Quote:
Originally Posted by PC Gamer View Post
someone suggested it would be better to use EquipPlayerWeapon
I wonder who that could be

Anyways, EquipPlayerWeapon's 2nd argument is the weapon's entity index, not the weapon's definition index.
Take a look at my TTT plugin for an example.
__________________
Currently taking TF2/CSGO paid private requests!

My Plugins | My Discord Account

Last edited by StrikeR14; 12-24-2020 at 16:53.
StrikeR14 is offline
PC Gamer
Veteran Member
Join Date: Mar 2014
Old 12-24-2020 , 22:09   Re: [TF2] EquipPlayerWeapon crash
Reply With Quote #3

Quote:
Originally Posted by StrikeR14 View Post
... is the weapon's entity index, not the weapon's definition index.
Ah... that makes sense, but I was hoping for a method of creating a weapon that didn't require TF2Items.

Here's some good news I found after digging through the gamedata files. A regular SourceMod installation provides the WeaponEquip offset in game.tf.txt file located in the gamedata/sdktools.games directory. I wasn't aware of that. That means you can create a weapon without having to make your own gamedata file.

Here's a working example of creating a weapon without TF2Items or making your own gamedata file:
PHP Code:
#pragma semicolon 1
#include <sourcemod>
#include <tf2_stocks>

#pragma newdecls required

#define PLUGIN_VERSION "1.0"

public Plugin myinfo 
{
    
name "[TF2] Chopper",
    
author "PC Gamer",
    
description "Test of giving weapon",
    
version PLUGIN_VERSION,
    
url "www.sourcemod.com"
}
Handle g_hWeaponEquip;

public 
void OnPluginStart()
{
    
RegAdminCmd("sm_chop"Command_ChopADMFLAG_SLAY"Give Player a Weapon");

    
GameData hTF2sdk = new GameData("/sdktools.games/game.tf"); // sdktools tf2 gamdata

    
if (!hTF2sdk)
    
SetFailState("This plugin is designed for a TF2 dedicated server only.");

    
StartPrepSDKCall(SDKCall_Player);
    
PrepSDKCall_SetVirtual(hTF2sdk.GetOffset("WeaponEquip")); 
    
PrepSDKCall_AddParameter(SDKType_CBaseEntitySDKPass_Pointer);
    
g_hWeaponEquip EndPrepSDKCall();

    if (!
g_hWeaponEquip)
    
SetFailState("Failed to create call: WeaponEquip. SourceMod version may be outdated.");

    
delete hTF2sdk
}

Action Command_Chop(int clientint args)
{
    
char arg1[32];
    if (
args 1)
    {
        
arg1 "@me";
    }
    else 
GetCmdArg(1arg1sizeof(arg1));
    
char target_name[MAX_TARGET_LENGTH];
    
int target_list[MAXPLAYERS], target_count;
    
bool tn_is_ml;

    if ((
target_count ProcessTargetString(
                    
arg1,
                    
client,
                    
target_list,
                    
MAXPLAYERS,
                    
COMMAND_FILTER_ALIVE|(args COMMAND_FILTER_NO_IMMUNITY 0),
                    
target_name,
                    
sizeof(target_name),
                    
tn_is_ml)) <= 0)
    {
        
ReplyToTargetError(clienttarget_count);
        return 
Plugin_Handled;
    }
    for (
int i 0target_counti++)
    {
        
CreateWeapon(target_list[i], "tf_weapon_sword"13232); //Eyelander    
        
PrintToChat(target_list[i], "You have a new Weapon!");
        
PrintToChat(target_list[i], "You will lose this weapon when you touch a locker or die.");            
    }
    return 
Plugin_Handled;
}

bool CreateWeapon(int clientchar[] classnameint itemindexint qualityint slot)
{
    
int weapon CreateEntityByName(classname);

    if (!
IsValidEntity(weapon))
    {
        return 
false;
    }
    
    
char entclass[64];
    
GetEntityNetClass(weaponentclasssizeof(entclass));
    
SetEntProp(weaponProp_Send"m_iItemDefinitionIndex"itemindex);     
    
SetEntProp(weaponProp_Send"m_bInitialized"1);
    
SetEntData(weaponFindSendPropInfo(entclass"m_iEntityQuality"), quality);
    
SetEntProp(weaponProp_Send"m_iEntityLevel"GetRandomInt(1,99));

    
TF2_RemoveWeaponSlot(clientslot);         

    
DispatchSpawn(weapon);
    
SDKCall(g_hWeaponEquipclientweapon);
    
    return 
true;

PC Gamer is offline
StrikeR14
AlliedModders Donor
Join Date: Apr 2016
Location: Behind my PC
Old 12-25-2020 , 16:33   Re: [TF2] EquipPlayerWeapon crash
Reply With Quote #4

Instead of
PHP Code:
SDKCall(g_hWeaponEquipclientweapon); 
Could've just write
PHP Code:
EquipPlayerWeapon(clientweapon); 
Since 'weapon' is the entity.

That would save you the gamedata initialization at the beginning.
__________________
Currently taking TF2/CSGO paid private requests!

My Plugins | My Discord Account

Last edited by StrikeR14; 12-25-2020 at 16:33.
StrikeR14 is offline
asherkin
SourceMod Developer
Join Date: Aug 2009
Location: OnGameFrame()
Old 12-26-2020 , 08:51   Re: [TF2] EquipPlayerWeapon crash
Reply With Quote #5

It is forbidden for plugins to load SM's gamedata files, they're not a public API and are not part of the stability guarantees (you're also trying to load a child file of a gamedata file set instead of the root, which isn't supported at all).

As StrikeR14 says, you're after the EquipPlayerWeapon native.
__________________
asherkin is offline
PC Gamer
Veteran Member
Join Date: Mar 2014
Old 12-26-2020 , 13:11   Re: [TF2] EquipPlayerWeapon crash
Reply With Quote #6

Thanks for the info! I now understand it much better.

This is a much better solution:
PHP Code:
#pragma semicolon 1
#include <sourcemod>
#include <tf2_stocks>

#pragma newdecls required

#define PLUGIN_VERSION "1.0"

public Plugin myinfo 
{
    
name "[TF2] Chopper",
    
author "PC Gamer",
    
description "Test of giving weapon",
    
version PLUGIN_VERSION,
    
url "www.sourcemod.com"
}

public 
void OnPluginStart()
{
    
RegAdminCmd("sm_chop"Command_ChopADMFLAG_SLAY"Give Player a Weapon");
}

Action Command_Chop(int clientint args)
{
    
char arg1[32];
    if (
args 1)
    {
        
arg1 "@me";
    }
    else 
GetCmdArg(1arg1sizeof(arg1));
    
char target_name[MAX_TARGET_LENGTH];
    
int target_list[MAXPLAYERS], target_count;
    
bool tn_is_ml;

    if ((
target_count ProcessTargetString(
                    
arg1,
                    
client,
                    
target_list,
                    
MAXPLAYERS,
                    
COMMAND_FILTER_ALIVE|(args COMMAND_FILTER_NO_IMMUNITY 0),
                    
target_name,
                    
sizeof(target_name),
                    
tn_is_ml)) <= 0)
    {
        
ReplyToTargetError(clienttarget_count);
        return 
Plugin_Handled;
    }
    for (
int i 0target_counti++)
    {
        
CreateWeapon(target_list[i], "tf_weapon_sword"13232); //Eyelander    
        
PrintToChat(target_list[i], "You have a new Weapon!");
        
PrintToChat(target_list[i], "You will lose this weapon when you touch a locker or die.");            
    }
    return 
Plugin_Handled;
}

bool CreateWeapon(int clientchar[] classnameint itemindexint qualityint slot)
{
    
int weapon CreateEntityByName(classname);

    if (!
IsValidEntity(weapon))
    {
        return 
false;
    }
    
    
char entclass[64];
    
GetEntityNetClass(weaponentclasssizeof(entclass));
    
SetEntProp(weaponProp_Send"m_iItemDefinitionIndex"itemindex);     
    
SetEntProp(weaponProp_Send"m_bInitialized"1);
    
SetEntData(weaponFindSendPropInfo(entclass"m_iEntityQuality"), quality);
    
SetEntProp(weaponProp_Send"m_iEntityLevel"GetRandomInt(1,99));

    
TF2_RemoveWeaponSlot(clientslot);         

    
DispatchSpawn(weapon);
    
EquipPlayerWeapon(clientweapon);  
    
    return 
true;

PC Gamer is offline
Reply


Thread Tools
Display Modes

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 08:56.


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