View Single Post
PC Gamer
Veteran Member
Join Date: Mar 2014
Old 11-18-2019 , 18:35   Re: [TF2] Client game crash when the client get a weapon
Reply With Quote #6

Thanks again nosoop! With your help I managed to eliminate tag mismatch error.

Good News: It now runs without any crashes.
Bad News: I had to add an include for tf2items_giveweapon exclusively for wearable items in weapon slots (razorback, tide turner, etc.).

I'd like to remove the dependency on tf2items if at all possible. However, after trying for several hours and many server crashes I still couldn't figure out how to use the forked version of tf2wearables and Econ Data to do this:
1. remove whatever weapon is in slot 1, and
2. replace it with a wearable weapon such as the razorback.

On the plus side, after reading your notes above I was able to come up with a better (but not perfect) way to solve the slot problems with removeslot.

If you have a way to remove the dependency on tf2items_giveweapon please share. I'm eager to learn.

This code relies on forked version of tf2wearables mentioned above, tf2items_giveweapon, and tf2attributes. It's functional but could be improved.

PHP Code:
#include <tf2attributes>
#include <tf_econ_data>
#include <tf2wearables>
#include <tf2items_giveweapon>

#pragma semicolon 1

#define DEBUG 0
#define PLUGIN_VERSION "1.1"

Handle g_hWeaponEquip;
Handle g_hWWeaponEquip;
Handle g_hGameConfig;

public 
Plugin myinfo 
{
    
name "Give Stuff",
    
author "Whai and PC Gamer",
    
description "Give Weapon and Cosmetic items to players",
    
version PLUGIN_VERSION,
    
url "https://forums.alliedmods.net"
}

public 
void OnPluginStart() 
{
    
g_hGameConfig LoadGameConfigFile("give.stuff");
    
    if (!
g_hGameConfig)
    {
        
SetFailState("Failed to find give.stuff.txt gamedata! Can't continue.");
    }    
    
    
StartPrepSDKCall(SDKCall_Player);
    
PrepSDKCall_SetFromConf(g_hGameConfigSDKConf_Virtual"WeaponEquip");
    
PrepSDKCall_AddParameter(SDKType_CBaseEntitySDKPass_Pointer);
    
g_hWeaponEquip EndPrepSDKCall();
    
    if (!
g_hWeaponEquip)
    {
        
SetFailState("Failed to prepare the SDKCall for giving weapons. Try updating gamedata or restarting your server.");
    }
    
    
StartPrepSDKCall(SDKCall_Player);
    
PrepSDKCall_SetFromConf(g_hGameConfigSDKConf_Virtual"EquipWearable");
    
PrepSDKCall_AddParameter(SDKType_CBaseEntitySDKPass_Pointer);
    
g_hWWeaponEquip EndPrepSDKCall();
    
    if (!
g_hWWeaponEquip)
    {
        
SetFailState("Failed to prepare the SDKCall for giving wearable weapons. Try updating gamedata or restarting your server.");
    }
    
    
RegAdminCmd("sm_give"Command_GiveADMFLAG_SLAY"Have a Great Day!");    
}

public 
Action:Command_Give(clientargs)
{
    if (
args != 2)
    {
        
ReplyToCommand(client"[SM] Usage: sm_give <client> <index>");
        return 
Plugin_Handled;
    }
    
    new 
String:arg1[32];
    
GetCmdArg(1arg1sizeof(arg1));
    
    new 
String:arg2[32];
    
GetCmdArg(2arg2sizeof(arg2));

    
decl String:target_name[MAX_TARGET_LENGTH];
    
decl target_list[MAXPLAYERS], target_countbool:tn_is_ml;
    
    if ((
target_count ProcessTargetString(
                    
arg1,
                    
client,
                    
target_list,
                    
MAXPLAYERS,
                    
COMMAND_FILTER_CONNECTED,
                    
target_name,
                    
sizeof(target_name),
                    
tn_is_ml)) <= 0)
    {
        
ReplyToTargetError(clienttarget_count);
        return 
Plugin_Handled;
    }
    
    new 
itemID StringToInt(arg2);

    for (new 
0target_counti++)
    {
        
TF2_GivePlayerItem(clienttarget_list[i], itemID);        
    }
    
    return 
Plugin_Handled;
}

public 
Action:TF2_GivePlayerItem(int iClientint iTargetint iItemID)
{
    if (!(
IsValidClient(iTarget) || IsPlayerAlive(iTarget)))
    {
        
PrintToChat(iClient"Target is Not Alive");
        return 
Plugin_Handled;
    }
    
    if(!
TF2Econ_IsValidItemDefinition(iItemID))
    {
        
PrintToChat(iClient"[SM] Invalid item definition index");
        return 
Plugin_Handled;
    }
    if (
iItemID == 405 || iItemID == 608 || iItemID == 1101 || iItemID == 133 || iItemID == 444 || iItemID == 57 || iItemID == 231 || iItemID == 642 || iItemID == 131 || iItemID == 406 || iItemID == 1099 || iItemID == 1144)
    {
        
TF2_RemoveWeaponSlot(iTarget1);
        
TF2Items_GiveWeapon(iTargetiItemID);
        
PrintToChat(iClient"Gave Item %i to %N"iItemIDiTarget);
        
PrintToChat(iTarget"%N Gave You Item %i"iClientiItemID);
        return 
Plugin_Handled;
    }

    
int iLevel GetRandomInt(1,99);
    
int iQuality GetRandomInt(0,14);

    
char strClassname[64];
    
TF2Econ_GetItemClassName(iItemIDstrClassnamesizeof(strClassname));
    
#if DEBUG
    
PrintToChat(iClient"Old Item Name: %s"strClassname);    
    
#endif    
    
TF2Econ_TranslateWeaponEntForClass(strClassnamesizeof(strClassname), TF2_GetPlayerClass(iTarget));
    
#if DEBUG
    
PrintToChat(iClient"New Item Translated Name: %s"strClassname);
    
#endif
    
int weaponprimary CreateEntityByName(strClassname);

    if (!
IsValidEntity(weaponprimary))
    {
        
PrintToChat(iClient,"Invalid Entity: Item Classname : %s"strClassname);    
        return 
Plugin_Handled;
    }

    
char entclass[64];
    
GetEntityNetClass(weaponprimaryentclasssizeof(entclass));
    
SetEntData(weaponprimaryFindSendPropInfo(entclass"m_iItemDefinitionIndex"), iItemID);
    
SetEntData(weaponprimaryFindSendPropInfo(entclass"m_bInitialized"), 1);
    
SetEntData(weaponprimaryFindSendPropInfo(entclass"m_iEntityLevel"), iLevel);
    
SetEntData(weaponprimaryFindSendPropInfo(entclass"m_iEntityQuality"), iQuality);
    
TF2Attrib_SetByDefIndex(weaponprimary7250.2);

    new 
iSlot TF2Econ_GetItemSlot(iItemIDTF2_GetPlayerClass(iTarget)); 

    
TF2Econ_TranslateWeaponEntForClass(strClassnamesizeof(strClassname), TF2_GetPlayerClass(iTarget));
    if (
StrEqual(strClassname"tf_weapon_revolver"false))
    {
        
iSlot 0;
    }
    if (
StrEqual(strClassname"tf_weapon_knife"false))
    {
        
iSlot 2;
    }
    if (
StrEqual(strClassname"tf_weapon_pda_spy"false))
    {
        
iSlot 3;
    }
    if (
StrEqual(strClassname"tf_weapon_invis"false))
    {
        
iSlot 4;
    }    
    
    switch (
iItemID)
    {
    case 
81083193310801102:
        {
            
SetEntData(weaponprimaryFindSendPropInfo(entclass"m_iObjectType"), 3);
            
iSlot 0;
        }
    case 
25737:
        {
            
iSlot 3;
        }
    case 
998:
        {
            
SetEntData(weaponprimaryFindSendPropInfo(entclass"m_nChargeResistType"), GetRandomInt(0,2));
        }
    case 
1071:
        {
            
TF2Attrib_SetByName(weaponprimary"item style override"0.0);
            
TF2Attrib_SetByName(weaponprimary"loot rarity"1.0);        
            
TF2Attrib_SetByName(weaponprimary"turn to gold"1.0);
        }        
    }
    
    if (
iSlot <0)
    {
        
PrintToChat(iClient"Item Index %i is invalid for target class"iItemID);
        return 
Plugin_Handled;
    }

    if (
iSlot >6)
    {
        
DispatchSpawn(weaponprimary);
        
SDKCall(g_hWWeaponEquipiTargetweaponprimary);
    }
    else
    {
        
TF2_RemoveWeaponSlot(iTargetiSlot);
        
DispatchSpawn(weaponprimary);
        
SDKCall(g_hWeaponEquipiTargetweaponprimary);
    }
    
    
char strItemName[64];
    
TF2Econ_GetItemName(iItemIDstrItemNamesizeof(strItemName));
    
PrintToChat(iClient"Gave %s to %N"strItemNameiTarget);    
    
PrintToChat(iTarget"%N gave you a %s"iClientstrItemName);
    
    
#if DEBUG
    
char strQualityName[32];
    
TF2Econ_GetQualityName(iQualitystrQualityNamesizeof(strQualityName));

    
char strItemSlotName[32];
    
TF2Econ_TranslateLoadoutSlotIndexToName(iSlotstrItemSlotNamesizeof(strItemSlotName));

    
PrintToChat(iClient"[Give Debug]: Target Name : %N"iTarget);
    
PrintToChat(iClient"[Give Debug]: Target Class : %i"TF2_GetPlayerClass(iTarget));
    
PrintToChat(iClient"[Give Debug]: Item Name : %s"strItemName);
    
PrintToChat(iClient"[Give Debug]: Item Classname : %s"strClassname);
    
PrintToChat(iClient"[Give Debug]: iSlot : %i"iSlot);
    
PrintToChat(iClient"[Give Debug]: iSlotName : %s"strItemSlotName);    
    
PrintToChat(iClient"[Give Debug]: iQuality : %i"iQuality);
    
PrintToChat(iClient"[Give Debug]: iQualityName : %s"strQualityName);    
    
PrintToChat(iClient"[Give Debug]: iLevel : %i"iLevel);

    
#endif

    
return Plugin_Handled;
}

stock bool:IsValidClient(client)
{
    if (
client <= 0) return false;
    if (
client MaxClients) return false;
    return 
IsClientInGame(client);


Last edited by PC Gamer; 11-18-2019 at 18:36.
PC Gamer is offline