Veteran Member
|
11-20-2019
, 02:41
Re: [TF2] Client game crash when the client get a weapon
|
#8
|
Thanks again nosoop! With your sage advice I was able to get much farther.
Good News: Removed dependency of tf2items_giveweapon
Bad News: I'm still having a problem determining the correct slot to remove an existing wearable item.
I think maybe there is a problem with TF2_GetPlayerLoadoutSlot incorrectly because it always returns slot 8 for any wearable. I tested this with the tf2wearables_test plugin and found similar result. In other words, when I have three wearable items equipped the 'checkmyitems' command will only show one wearable in slot 8.
The impact is that it when I try to remove an item it will usually remove the wrong item.
Any idea on what I can do to fix the problem?
Output from tf2wearables_test plugin:
Quote:
Processed items for PC Gamer
PC Gamer Item Slot 0: ent 570, class "tf_weapon_handgun_scout_primary", index 220
PC Gamer Item Slot 1: ent 571, class "tf_weapon_pistol_scout", index 30666
PC Gamer Item Slot 2: ent 320, class "tf_weapon_bat", index 452
PC Gamer Item Slot 8: ent 490, class "tf_wearable", index 30253
PC Gamer Item Slot 9: ent 600, class "tf_weapon_spellbook", index 1132
|
Code with the changes you recommended:
PHP Code:
#include <tf2attributes>
#include <tf_econ_data>
#include <tf2wearables>
#pragma semicolon 1
#define DEBUG 1
#define PLUGIN_VERSION "1.3"
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()
{
RegAdminCmd("sm_give", Command_Give, ADMFLAG_SLAY, "Give Others an Item");
RegConsoleCmd("sm_get", Command_Get, "Give Self an Item");
}
public Action:Command_Give(client, args)
{
if (args != 2)
{
ReplyToCommand(client, "[SM] Usage: sm_give <client> <index>");
return Plugin_Handled;
}
new String:arg1[32];
GetCmdArg(1, arg1, sizeof(arg1));
new String:arg2[32];
GetCmdArg(2, arg2, sizeof(arg2));
decl String:target_name[MAX_TARGET_LENGTH];
decl target_list[MAXPLAYERS], target_count, bool: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(client, target_count);
return Plugin_Handled;
}
new itemID = StringToInt(arg2);
for (new i = 0; i < target_count; i++)
{
TF2_GivePlayerItem(client, target_list[i], itemID);
}
return Plugin_Handled;
}
public Action:Command_Get(client, args)
{
if (args != 1)
{
ReplyToCommand(client, "[SM] Usage: sm_get <itemindex>");
return Plugin_Handled;
}
new String:arg1[32];
GetCmdArg(1, arg1, sizeof(arg1));
new itemID = StringToInt(arg1);
TF2_GivePlayerItem(client, client, itemID);
return Plugin_Handled;
}
public Action:TF2_GivePlayerItem(int iClient, int iTarget, int 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;
}
new iSlot = TF2Econ_GetItemSlot(iItemID, TF2_GetPlayerClass(iTarget));
if (iSlot <0)
{
PrintToChat(iClient, "Item Index %i is invalid for target class", iItemID);
return Plugin_Handled;
}
//Information on Existing Item
new iOldSlotItem = TF2_GetPlayerLoadoutSlot(iTarget, TF2LoadoutSlot:iSlot);
decl String:oldclassname[64];
GetEntityClassname(iOldSlotItem, oldclassname, sizeof(oldclassname));
new olditemDefinitionIndex = GetEntProp(iOldSlotItem, Prop_Send, "m_iItemDefinitionIndex");
decl String:olditemname[64];
TF2Econ_GetItemName(olditemDefinitionIndex, olditemname, sizeof(olditemname));
new iOldEnt = iOldSlotItem;
PrintToChat(iClient, "[Give Debug Old Item] %N Item Slot %d: ent %d, class \"%s\", index %d, itemname %s", iTarget, iSlot, iOldSlotItem, oldclassname, olditemDefinitionIndex, olditemname);
//Begin Creation of New Item
char strClassname[64];
TF2Econ_GetItemClassName(iItemID, strClassname, sizeof(strClassname));
TF2Econ_TranslateWeaponEntForClass(strClassname, sizeof(strClassname), TF2_GetPlayerClass(iTarget));
int weaponprimary = CreateEntityByName(strClassname);
if (!IsValidEntity(weaponprimary))
{
PrintToChat(iClient,"Invalid Entity: Item Classname : %s", strClassname);
return Plugin_Handled;
}
char entclass[64];
GetEntityNetClass(weaponprimary, entclass, sizeof(entclass));
SetEntData(weaponprimary, FindSendPropInfo(entclass, "m_iItemDefinitionIndex"), iItemID);
SetEntData(weaponprimary, FindSendPropInfo(entclass, "m_bInitialized"), 1);
int iLevel = GetRandomInt(1,99);
SetEntData(weaponprimary, FindSendPropInfo(entclass, "m_iEntityLevel"), iLevel);
int iQuality = GetRandomInt(0,14);
SetEntData(weaponprimary, FindSendPropInfo(entclass, "m_iEntityQuality"), iQuality);
TF2Attrib_SetByDefIndex(weaponprimary, 725, 0.2);
switch (iItemID)
{
case 810, 831, 933, 1080, 1102:
{
SetEntData(weaponprimary, FindSendPropInfo(entclass, "m_iObjectType"), 3);
SetEntProp(weaponprimary, Prop_Data, "m_iSubType", 3);
}
case 998:
{
SetEntData(weaponprimary, FindSendPropInfo(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 (TF2_IsWearable(weaponprimary))
{
TF2_RemovePlayerWearable(iTarget, iOldEnt);
DispatchSpawn(weaponprimary);
TF2_EquipPlayerWearable(iTarget, weaponprimary);
}
else
{
TF2_RemoveWeapon(iTarget, iOldEnt);
DispatchSpawn(weaponprimary);
EquipPlayerWeapon(iTarget, weaponprimary);
}
char strItemName[64];
TF2Econ_GetItemName(iItemID, strItemName, sizeof(strItemName));
PrintToChat(iClient, "Gave %s to %N", strItemName, iTarget);
PrintToChat(iTarget, "%N gave you a %s", iClient, strItemName);
#if DEBUG
PrintToChat(iClient, "[Give Debug Old Item] %N Item Slot %d: ent %d, class \"%s\", index %d, itemname %s", iTarget, iSlot, iOldSlotItem, oldclassname, olditemDefinitionIndex, olditemname);
//New Item Info
char strQualityName[32];
TF2Econ_GetQualityName(iQuality, strQualityName, sizeof(strQualityName));
char strItemSlotName[32];
TF2Econ_TranslateLoadoutSlotIndexToName(iSlot, strItemSlotName, sizeof(strItemSlotName));
PrintToChat(iClient, "[Give Debug]: Target Name : %N, Target Class : %i", iTarget, TF2_GetPlayerClass(iTarget));
PrintToChat(iClient, "[Give Debug]: Item Index : %i, Item Name : %s", iItemID, strItemName);
PrintToChat(iClient, "[Give Debug]: Item Classname : %s", strClassname);
PrintToChat(iClient, "[Give Debug]: iSlot : %i, iSlotName : %s", iSlot, strItemSlotName);
PrintToChat(iClient, "[Give Debug]: iQuality : %i, iQualityName : %s", iQuality, 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);
}
|
|