From 2446ff49f270894517495a184a4f3a0202de88de Mon Sep 17 00:00:00 2001 From: Arkshine Date: Wed, 14 Jan 2015 09:28:40 +0100 Subject: [PATCH] Add cs_create_entity native --- dlls/cstrike/cstrike/CstrikeDatas.h | 14 ++++++++------ dlls/cstrike/cstrike/CstrikeNatives.cpp | 23 +++++++++++++++++++++++ dlls/cstrike/cstrike/amxx_api.cpp | 6 ++++++ plugins/include/cstrike.inc | 16 ++++++++++++++++ 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/dlls/cstrike/cstrike/CstrikeDatas.h b/dlls/cstrike/cstrike/CstrikeDatas.h index 59d955e1..4c2b3e89 100644 --- a/dlls/cstrike/cstrike/CstrikeDatas.h +++ b/dlls/cstrike/cstrike/CstrikeDatas.h @@ -140,23 +140,23 @@ #define CS_CLICMD_OFFS_BOTARGS 22 #endif -/** - * CS_OnBuy forward - */ #if defined(__linux__) - #define CS_IDENT_GIVENSHIELD "_ZN11CBasePlayer10GiveShieldEb" - #define CS_IDENT_GIVENAMEDITEM "_ZN11CBasePlayer13GiveNamedItemEPKc" - #define CS_IDENT_ADDACCOUNT "_ZN11CBasePlayer10AddAccountEib" + #define CS_IDENT_GIVENSHIELD "_ZN11CBasePlayer10GiveShieldEb" // CS_OnBuy forward + #define CS_IDENT_GIVENAMEDITEM "_ZN11CBasePlayer13GiveNamedItemEPKc" // CS_OnBuy forward + #define CS_IDENT_ADDACCOUNT "_ZN11CBasePlayer10AddAccountEib" // CS_OnBuy forward + #define CS_IDENT_CREATENAMEDENTITY "_Z19CREATE_NAMED_ENTITYj" // cs_create_entity #define CS_IDENT_HIDDEN_STATE false #elif defined(__APPLE__) #define CS_IDENT_GIVENSHIELD "_ZN11CBasePlayer10GiveShieldEb" #define CS_IDENT_GIVENAMEDITEM "_ZN11CBasePlayer13GiveNamedItemEPKc" #define CS_IDENT_ADDACCOUNT "_ZN11CBasePlayer10AddAccountEib" + #define CS_IDENT_CREATENAMEDENTITY "_Z19CREATE_NAMED_ENTITYj" #define CS_IDENT_HIDDEN_STATE true #elif defined(WIN32) #define CS_IDENT_GIVENSHIELD "\\x56\\x8B\\x2A\\x57\\x33\\x2A\\x8B\\x2A\\x2A\\x2A\\x2A\\x2A\\xB0" #define CS_IDENT_GIVENAMEDITEM "\\x8B\\x2A\\x2A\\x2A\\x56\\x57\\x8B\\x2A\\x8B\\x2A\\x2A\\x2A\\x2A\\x2A\\x2B" #define CS_IDENT_ADDACCOUNT "\\x8B\\x2A\\x2A\\x2A\\x56\\x8B\\x2A\\x8B\\x2A\\x2A\\x2A\\x2A\\x2A\\x03" + #define CS_IDENT_CREATENAMEDENTITY "\\x56\\x57\\x8B\\x2A\\x2A\\x2A\\x57\\xFF\\x2A\\x2A\\x2A\\x2A\\x2A\\x8B" #define CS_IDENT_HIDDEN_STATE false #endif @@ -349,4 +349,6 @@ typedef enum } Menu; +typedef edict_t* (*CreateNamedEntityFunc)(string_t); + #endif // CSTRIKE_DATA_H diff --git a/dlls/cstrike/cstrike/CstrikeNatives.cpp b/dlls/cstrike/cstrike/CstrikeNatives.cpp index e494bfb0..902019d5 100644 --- a/dlls/cstrike/cstrike/CstrikeNatives.cpp +++ b/dlls/cstrike/cstrike/CstrikeNatives.cpp @@ -1707,6 +1707,28 @@ static cell AMX_NATIVE_CALL cs_set_c4_defusing(AMX* amx, cell* params) return 1; } +extern CreateNamedEntityFunc CS_CreateNamedEntity; + +// cs_create_entity(const classname[]) +static cell AMX_NATIVE_CALL cs_create_entity(AMX* amx, cell* params) +{ + if (CS_CreateNamedEntity > 0) + { + int len; + int iszClass = ALLOC_STRING(MF_GetAmxString(amx, params[1], 0, &len)); + + edict_t *pEnt = CS_CreateNamedEntity(iszClass); + + if (!FNullEnt(pEnt)) + { + return ENTINDEX(pEnt); + } + } + + return 0; +} + + #else static cell AMX_NATIVE_CALL not_on_64(AMX* amx, cell* params) @@ -1791,6 +1813,7 @@ AMX_NATIVE_INFO CstrikeNatives[] = { {"cs_set_c4_explode_time", cs_set_c4_explode_time}, {"cs_get_c4_defusing", cs_get_c4_defusing}, {"cs_set_c4_defusing", cs_set_c4_defusing}, + {"cs_create_entity", cs_create_entity }, {NULL, NULL} }; diff --git a/dlls/cstrike/cstrike/amxx_api.cpp b/dlls/cstrike/cstrike/amxx_api.cpp index 17dfd227..e0499675 100644 --- a/dlls/cstrike/cstrike/amxx_api.cpp +++ b/dlls/cstrike/cstrike/amxx_api.cpp @@ -13,6 +13,7 @@ #include "amxxmodule.h" #include "CstrikeUtils.h" +#include "CstrikeDatas.h" extern AMX_NATIVE_INFO CstrikeNatives[]; @@ -25,6 +26,7 @@ void ShutdownHacks(); void ToggleDetour_ClientCommands(bool enable); void ToggleDetour_BuyCommands(bool enable); +CreateNamedEntityFunc CS_CreateNamedEntity = NULL; int AmxxCheckGame(const char *game) { @@ -39,7 +41,11 @@ int AmxxCheckGame(const char *game) void OnAmxxAttach() { MF_AddNatives(CstrikeNatives); + InitializeHacks(); + + // cs_create_entity(). + CS_CreateNamedEntity = reinterpret_cast(UTIL_FindAddressFromEntry(CS_IDENT_CREATENAMEDENTITY, CS_IDENT_HIDDEN_STATE)); } void OnPluginsLoaded() diff --git a/plugins/include/cstrike.inc b/plugins/include/cstrike.inc index 6c404eda..6d41267b 100755 --- a/plugins/include/cstrike.inc +++ b/plugins/include/cstrike.inc @@ -350,6 +350,22 @@ native bool:cs_get_c4_defusing(c4index); native cs_set_c4_defusing(c4index, bool:defusing); +/** + * Creates an entity. + * + * @note Similar as create_entity() native from engine module, with the difference that in Counter-Strike + * to improve lookup performance on entities, the classname is hashed and saved in a global list. + * This means for classname, game uses a custom function which checks that list instead of calling pfnFindEntityByString. + * You would want to use this native if you want having custom entities to be known by the game. + * E.g. By creating a "weaponbox" entity, this will be automatically deleted by game on map restart. + * With engine version, you would have to remove it manually. + * + * @param classname Entity class name + * + * @return Index of the created entity, 0 otherwise. + */ +native cs_create_entity(const classname[]); + /** * Called when CS internally fires a command to a player. It does this for a few * functions, most notably rebuy/autobuy functionality. This is also used to pass