diff --git a/extensions/tf2/natives.cpp b/extensions/tf2/natives.cpp index 4a1fabee8b..2a557107bc 100644 --- a/extensions/tf2/natives.cpp +++ b/extensions/tf2/natives.cpp @@ -648,6 +648,49 @@ cell_t TF2_RemoveWearable(IPluginContext *pContext, const cell_t *params) return 1; } +cell_t TF2_IsWearable(IPluginContext *pContext, const cell_t *params) +{ + static ICallWrapper *pWrapper = NULL; + + //CBasePlayer::IsWearable(CEconWearable *) + + if (!pWrapper) + { + int offset; + + if (!g_pGameConf->GetOffset("IsWearable", &offset)) + { + return pContext->ThrowNativeError("Failed to locate function"); + } + + PassInfo pass[1]; + pass[0].flags = PASSFLAG_BYVAL; + pass[0].size = sizeof(CBaseEntity *); + pass[0].type = PassType_Basic; + + pWrapper = g_pBinTools->CreateVCall(offset, 0, 0, NULL, pass, 1); + + g_RegNatives.Register(pWrapper); + } + + CBaseEntity *pEntity; + if (!(pEntity = UTIL_GetCBaseEntity(params[1], false))) + { + return pContext->ThrowNativeError("Entity index %d is not valid", params[1]); + } + + unsigned char vstk[sizeof(void *) + sizeof(CBaseEntity *)]; + unsigned char *vptr = vstk; + + *(void **)vptr = (void *)pEntity; + + cell_t ret = 0; + + pWrapper->Execute(vstk, (void*)&ret); + + return ret; +} + sp_nativeinfo_t g_TFNatives[] = { {"TF2_IgnitePlayer", TF2_Burn}, diff --git a/gamedata/sm-tf2.games.txt b/gamedata/sm-tf2.games.txt index d944d639ab..a706ef48af 100644 --- a/gamedata/sm-tf2.games.txt +++ b/gamedata/sm-tf2.games.txt @@ -111,6 +111,12 @@ } "Offsets" { + "IsWearable" + { + "windows" "87" + "linux" "88" + "mac" "88" + } "ForceRespawn" { "windows" "324" diff --git a/plugins/include/tf2.inc b/plugins/include/tf2.inc index 743675ee67..052737bf56 100644 --- a/plugins/include/tf2.inc +++ b/plugins/include/tf2.inc @@ -370,6 +370,14 @@ native bool:TF2_IsPlayerInDuel(client); */ native TF2_RemoveWearable(client, wearable); +/** + * Returns whether or not an entity is a valid econ wearable (hat, misc, etc). + * @param entity Entity to check if it's a wearable. + * @return True if entity is a wearable, false otherwise. + * @error Invalid entity index or no mod support. +*/ +native TF2_IsWearable(entity); + /** * Called after a condition is added to a player * diff --git a/plugins/include/tf2_stocks.inc b/plugins/include/tf2_stocks.inc index f1bbf295bf..6b45694c65 100644 --- a/plugins/include/tf2_stocks.inc +++ b/plugins/include/tf2_stocks.inc @@ -430,6 +430,7 @@ stock bool:TF2_SetPlayerResourceData(client, TFResourceType:type, any:value) * @noreturn * @error Invalid client, invalid slot or lack of mod support */ +#pragma deprecated Use TF2_RemoveWeaponSlot2 stock TF2_RemoveWeaponSlot(client, slot) { new weaponIndex; @@ -446,6 +447,7 @@ stock TF2_RemoveWeaponSlot(client, slot) * @param client Player's index. * @noreturn */ +#pragma deprecated Use TF2_RemoveAllWeapons2 stock TF2_RemoveAllWeapons(client) { for (new i = 0; i <= 5; i++) @@ -454,6 +456,37 @@ stock TF2_RemoveAllWeapons(client) } } +//Credit to friagram for the stocks. + +stock TF2_RemoveWeaponSlot2(client, slot) +{ + decl ew; + new weaponIndex; + while ((weaponIndex = GetPlayerWeaponSlot(client, slot)) != -1) + { + ew = GetEntPropEnt(weaponIndex, Prop_Send, "m_hExtraWearable"); + if(IsValidEntity(ew)) + { + TF2_RemoveWearable(client, ew); + } + ew = GetEntPropEnt(weaponIndex, Prop_Send, "m_hExtraWearableViewModel"); + if(IsValidEntity(ew)) + { + TF2_RemoveWearable(client, ew); + } + RemovePlayerItem(client, weaponIndex); + AcceptEntityInput(weaponIndex, "Kill"); + } +} + +stock TF2_RemoveAllWeapons2(client) +{ + for(new slot = 0; slot <= 5; slot++) + { + TF2_RemoveWeaponSlot2(client, slot); + } +} + /** * Gets a player's condition bits *