Added new CS_GetWeaponPrice native to cstrike extension (bug 4985, r=psychonic).

This commit is contained in:
Drifter 2011-06-28 20:32:55 -04:00
parent 91368e5656
commit ee1bbd5994
5 changed files with 137 additions and 13 deletions

View File

@ -42,6 +42,8 @@
#include <IBinTools.h>
#include <ISDKTools.h>
int CallPriceForward(int client, const char *weapon_name, int price);
/**
* @brief Sample implementation of the SDK Extension.
* Note: Uncomment one of the pre-defined virtual functions in order to use it.
@ -146,5 +148,6 @@ extern bool g_pIgnoreTerminateDetour;
extern bool g_pIgnoreCSWeaponDropDetour;
extern bool g_pTerminateRoundDetoured;
extern bool g_pCSWeaponDropDetoured;
extern int weaponNameOffset;
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_

View File

@ -51,19 +51,7 @@ DETOUR_DECL_MEMBER0(DetourWeaponPrice, int)
const char *weapon_name = reinterpret_cast<char *>(this+weaponNameOffset);
int original = price;
cell_t result = Pl_Continue;
g_pPriceForward->PushCell(lastclient);
g_pPriceForward->PushString(weapon_name);
g_pPriceForward->PushCellByRef(&price);
g_pPriceForward->Execute(&result);
if (result == Pl_Continue)
return original;
return price;
return CallPriceForward(lastclient, weapon_name, price);
}
DETOUR_DECL_MEMBER2(DetourTerminateRound, void, float, delay, int, reason)
@ -232,3 +220,19 @@ void RemoveCSWeaponDropDetour()
}
g_pCSWeaponDropDetoured = false;
}
int CallPriceForward(int client, const char *weapon_name, int price)
{
int changedprice = price;
cell_t result = Pl_Continue;
g_pPriceForward->PushCell(client);
g_pPriceForward->PushString(weapon_name);
g_pPriceForward->PushCellByRef(&changedprice);
g_pPriceForward->Execute(&result);
if (result == Pl_Continue)
return price;
return changedprice;
}

View File

@ -325,6 +325,58 @@ static cell_t CS_GetTranslatedWeaponAlias(IPluginContext *pContext, const cell_t
return 1;
}
static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
{
static ICallWrapper *pWrapper = NULL;
static int priceOffset = -1;
if (!pWrapper)
{
REGISTER_NATIVE_ADDR("GetWeaponInfo",
PassInfo pass[1]; \
PassInfo retpass[1]; \
pass[0].flags = PASSFLAG_BYVAL; \
pass[0].type = PassType_Basic; \
pass[0].size = sizeof(int); \
retpass[0].flags = PASSFLAG_BYVAL; \
retpass[0].type = PassType_Basic; \
retpass[0].size = sizeof(void *); \
pWrapper = g_pBinTools->CreateCall(addr, CallConv_Cdecl, &retpass[0], pass, 1))
}
if (priceOffset == -1)
{
if (!g_pGameConf->GetOffset("WeaponPrice", &priceOffset))
{
return pContext->ThrowNativeError("Failed to get WeaponPrice offset");
}
}
CBaseEntity *pEntity;
if (!(pEntity = GetCBaseEntity(params[1], true)))
{
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
}
void *info;
unsigned char vstk[sizeof(int)];
unsigned char *vptr = vstk;
*(int *)vptr = params[2];
pWrapper->Execute(vstk, &info);
if (!info)
return pContext->ThrowNativeError("Failed to get weaponinfo");
int price = *(int *)((intptr_t)info + priceOffset);
if (params[3] || weaponNameOffset == -1)
return price;
const char *weapon_name = (const char *)((intptr_t)info + weaponNameOffset);
return CallPriceForward(params[1], weapon_name, price);
}
sp_nativeinfo_t g_CSNatives[] =
{
@ -333,6 +385,7 @@ sp_nativeinfo_t g_CSNatives[] =
{"CS_DropWeapon", CS_DropWeapon},
{"CS_TerminateRound", CS_TerminateRound},
{"CS_GetTranslatedWeaponAlias", CS_GetTranslatedWeaponAlias},
{"CS_GetWeaponPrice", CS_GetWeaponPrice},
{NULL, NULL}
};

View File

@ -22,6 +22,12 @@
"linux" "6"
"mac" "6"
}
"WeaponPrice"
{
"windows" "2224"
"linux" "2224"
"mac" "2224"
}
}
"Signatures"
{
@ -74,6 +80,13 @@
"linux" "@_Z24GetTranslatedWeaponAliasPKc"
"mac" "@_Z24GetTranslatedWeaponAliasPKc"
}
"GetWeaponInfo"
{
"library" "server"
"windows" "\x8B\x4C\x2A\x2A\x85\xC9\x75\x2A\x33\xC0\xC3"
"linux" "@_Z13GetWeaponInfo10CSWeaponID"
"mac" "@_Z13GetWeaponInfo10CSWeaponID"
}
}
}
}

View File

@ -65,6 +65,43 @@ enum CSRoundEndReason
CSRoundEnd_GameStart // Game Commencing!
};
enum CSWeaponID
{
CSWeapon_NONE,
CSWeapon_P228,
CSWeapon_GLOCK,
CSWeapon_SCOUT,
CSWeapon_HEGRENADE,
CSWeapon_XM1014,
CSWeapon_C4,
CSWeapon_MAC10,
CSWeapon_AUG,
CSWeapon_SMOKEGRENADE,
CSWeapon_ELITE,
CSWeapon_FIVESEVEN,
CSWeapon_UMP45,
CSWeapon_SG550,
CSWeapon_GALIL,
CSWeapon_FAMAS,
CSWeapon_USP,
CSWeapon_AWP,
CSWeapon_MP5NAVY,
CSWeapon_M249,
CSWeapon_M3,
CSWeapon_M4A1,
CSWeapon_TMP,
CSWeapon_G3SG1,
CSWeapon_FLASHBANG,
CSWeapon_DEAGLE,
CSWeapon_SG552,
CSWeapon_AK47,
CSWeapon_KNIFE,
CSWeapon_P90,
CSWeapon_SHIELD,
CSWeapon_KEVLAR,
CSWeapon_ASSAULTSUIT,
CSWeapon_NIGHTVISION
};
/**
* Called when a player attempts to purchase an item.
* Return Plugin_Continue to allow the purchase or return a
@ -166,6 +203,19 @@ native CS_DropWeapon(client, weaponIndex, bool:toss, bool:blockhook = false);
*/
native CS_GetTranslatedWeaponAlias(const String:alias[], String:weapon[], size);
/**
* Gets a weapon's price
*
* @param client Client to check weapon price for.
* @param id Weapon id for the weapon to check
* @param defaultprice Set to true to get defaultprice.
* @return Returns price of the weapon (even if modified)
*
* @error Invalid client, failing to get weapon info, or failing to get price offset.
* @note Not all "weapons" will return their default price. Example: c4, knife, vest, vest helmet, night vision.
*/
native CS_GetWeaponPrice(client, CSWeaponID:id, bool:defaultprice=false);
/**
* Do not edit below this line!
*/
@ -189,6 +239,7 @@ public __ext_cstrike_SetNTVOptional()
MarkNativeAsOptional("CS_DropWeapon");
MarkNativeAsOptional("CS_TerminateRound");
MarkNativeAsOptional("CS_GetTranslatedWeaponAlias");
MarkNativeAsOptional("CS_GetWeaponPrice");
}
#endif