diff --git a/publish.gradle b/publish.gradle index 0ca227e..504e7dd 100644 --- a/publish.gradle +++ b/publish.gradle @@ -24,12 +24,17 @@ task publishPrepareFiles << { //project.file('publish/publishRoot/reapi/addons/amxmodx/scripting/include').mkdirs() _copyFileToDir('publish/reapi_amxx.dll', 'publish/publishRoot/reapi/addons/amxmodx/modules/') + _copyFileToDir('publish/reapi_amxx.pdb', 'publish/publishRoot/reapi/addons/amxmodx/modules/') _copyFile('publish/libreapi_amxx_i386.so', 'publish/publishRoot/reapi/addons/amxmodx/modules/reapi_amxx_i386.so') copy { from 'reapi/extra' into 'publish/publishRoot/reapi/addons' } + copy { + from 'reapi/src/reapi_version.inc' + into 'publish/publishRoot/reapi/addons/amxmodx/scripting/include' + } } task publishPackage(type: Zip, dependsOn: 'publishPrepareFiles') { diff --git a/reapi/build.gradle b/reapi/build.gradle index 67852cc..c6598d9 100644 --- a/reapi/build.gradle +++ b/reapi/build.gradle @@ -61,7 +61,7 @@ void setupToolchain(NativeBinarySpec b) { '_snprintf': 'snprintf' ]) - cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp', '-msse2', '-fp-model fast=2', '-fomit-frame-pointer', '-inline-forceinline', '-fvisibility=default', '-fvisibility-inlines-hidden', '-fno-rtti', '-g0', '-s' + cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp', '-msse2', '-fomit-frame-pointer', '-inline-forceinline', '-fvisibility=default', '-fvisibility-inlines-hidden', '-fno-rtti', '-g0', '-s' } ToolchainConfigUtils.apply(project, cfg, b) diff --git a/reapi/extra/amxmodx/scripting/include/reapi.inc b/reapi/extra/amxmodx/scripting/include/reapi.inc index 2770ef3..3d7475b 100644 --- a/reapi/extra/amxmodx/scripting/include/reapi.inc +++ b/reapi/extra/amxmodx/scripting/include/reapi.inc @@ -13,10 +13,12 @@ #pragma library reapi #endif -#include +#define NULLENT -1 + #include // NOTE: only for ReHLDS #include // NOTE: only for gamedll Counter-Strike (ReGameDLL_CS) -#include // NOTE: Common set of natives and forwards. +#include // NOTE: 3-rd party addons +#include // hookchain return type enum @@ -42,56 +44,54 @@ enum HookChain }; /* - * Hook API function that are available into enum - * Look at the enum's for parameter lists. - * - * @param function The function to hook. - * @param callback The forward to call. - * @param post Whether or not to forward this in post. - * @return Returns a handle to the hook. Use EnableHookChain/DisableHookChain to toggle the forward on or off. - * - */ +* Hook API function that are available into enum +* Look at the enum's for parameter lists. +* +* @param function The function to hook. +* @param callback The forward to call. +* @param post Whether or not to forward this in post. +* @return Returns a handle to the hook. Use EnableHookChain/DisableHookChain to toggle the forward on or off. +* +*/ native HookChain:RegisterHookChain(any:function_id, const callback[], post = 0); /* - * Stops a hook from triggering. - * Use the return value from RegisterHookChain as the parameter here! - * - * @param hook The hook to stop. - * - */ +* Stops a hook from triggering. +* Use the return value from RegisterHookChain as the parameter here! +* +* @param hook The hook to stop. +* +*/ native bool:DisableHookChain(HookChain:hook); /* - * Starts a hook back up. - * Use the return value from RegisterHookChain as the parameter here! - * - * @param hook The hook to re-enable. - * @return Returns if the function is successful executed true otherwise false - * - */ +* Starts a hook back up. +* Use the return value from RegisterHookChain as the parameter here! +* +* @param hook The hook to re-enable. +* @return Returns if the function is successful executed true otherwise false +* +*/ native bool:EnableHookChain(HookChain:hook); /* - * Sets the return value of a hookchain. - * This needs to be used in conjunction with RH_OVERRIDE or RH_SUPERCEDE. - * - * @param type To specify the type RHV_*, look at the enum HookChainReturn - * @param value The value to set the return to. - * - * native SetHookChainReturn(AType:type, any:...); - */ +* Sets the return value of a hookchain. +* This needs to be used in conjunction with RH_OVERRIDE or RH_SUPERCEDE. +* +* @param type To specify the type RHV_*, look at the enum HookChainReturn +* @param value The value to set the return to. +* +*/ native SetHookChainReturn(AType:type, any:...); /* - * Gets the return value of a hookchain. - * This needs to be used in conjunction with RH_OVERRIDE or RH_SUPERCEDE. - * - * @param type To specify the type RHV_*, look at the enum HookChainReturn - * @param value The value to set the return to. - * - * native GetHookChainReturn(AType:type, any:...); - */ +* Gets the return value of a hookchain. +* This needs to be used in conjunction with RH_OVERRIDE or RH_SUPERCEDE. +* +* @param type To specify the type RHV_*, look at the enum HookChainReturn +* @param value The value to set the return to. +* +*/ native GetHookChainReturn(AType:type, any:...); /* @@ -103,7 +103,6 @@ native GetHookChainReturn(AType:type, any:...); * @param [maxlen] Max length of string (optional) * @return Returns if the function is successful executed true otherwise false * -* native SetHookChainArg(number, AType:type, any:...); */ native SetHookChainArg(number, AType:type, any:...); @@ -114,18 +113,18 @@ native SetHookChainArg(number, AType:type, any:...); */ public __reapi_version_check(const majorVersion, const minorVersion) { - if (majorVersion != REAPI_VERISON_MAJOR) + if (majorVersion != REAPI_VERSION_MAJOR) { new temp[512]; - formatex(temp, sizeof temp - 1, "[ReAPI]: Api major version mismatch; expected %d, real %d", REAPI_VERISON_MAJOR, majorVersion); + formatex(temp, sizeof temp - 1, "[ReAPI]: Api major version mismatch; expected %d, real %d", REAPI_VERSION_MAJOR, majorVersion); set_fail_state(temp); return; } - if (minorVersion < REAPI_VERISON_MINOR) + if (minorVersion < REAPI_VERSION_MINOR) { new temp[512]; - formatex(temp, sizeof temp - 1, "[ReAPI]: Api minor version mismatch; expected at least %d, real %d", REAPI_VERISON_MINOR, minorVersion); + formatex(temp, sizeof temp - 1, "[ReAPI]: Api minor version mismatch; expected at least %d, real %d", REAPI_VERSION_MINOR, minorVersion); set_fail_state(temp); return; } diff --git a/reapi/extra/amxmodx/scripting/include/reapi_addons.inc b/reapi/extra/amxmodx/scripting/include/reapi_addons.inc new file mode 100644 index 0000000..9c18f4b --- /dev/null +++ b/reapi/extra/amxmodx/scripting/include/reapi_addons.inc @@ -0,0 +1,77 @@ +#if defined _reapi_addons_included + #endinput +#endif +#define _reapi_addons_included + +enum client_auth_type +{ + CA_TYPE_NONE = 0, + CA_TYPE_DPROTO, + CA_TYPE_STEAM, + CA_TYPE_STEAMEMU, + CA_TYPE_REVEMU, + CA_TYPE_OLDREVEMU, + CA_TYPE_HLTV, + CA_TYPE_SC2009, + CA_TYPE_AVSMP, + CA_TYPE_SXEI, + CA_TYPE_REVEMU2013, + CA_TYPE_SSE3, +}; + +/* +* Checks whether the player is talking at this moment +* +* @param index Client index +* @return 1 if client is speaking, 0 otherwise +* +*/ +native VTC_IsClientSpeaking(const index); + +/* +* Mutes this player +* +* @param index Client index +* @noreturn +*/ +native VTC_MuteClient(const index); + +/* +* Unmutes this player +* +* @param index Client index +* @noreturn +*/ +native VTC_UnmuteClient(const index); + +/* +* Called when player started talking +* +* @param index Client index +* @noreturn +*/ +forward VTC_OnClientStartSpeak(const index); + +/* +* Called when player stopped talking +* +* @param index Client index +* @noreturn +*/ +forward VTC_OnClientStopSpeak(const index); + +/* +* Get client protocol +* +* @param index Client index +* @return client protocol +*/ +native REU_GetProtocol(const index); + +/* +* Get client auth type +* +* @param index Client index +* @return client auth type +*/ +native client_auth_type:REU_GetAuthtype(const index); diff --git a/reapi/extra/amxmodx/scripting/include/reapi_const.inc b/reapi/extra/amxmodx/scripting/include/reapi_const.inc deleted file mode 100644 index 16c7a3b..0000000 --- a/reapi/extra/amxmodx/scripting/include/reapi_const.inc +++ /dev/null @@ -1,8 +0,0 @@ -#if defined _reapi_const_included - #endinput -#endif -#define _reapi_const_included - -// reapi version -#define REAPI_VERISON_MAJOR 1 -#define REAPI_VERISON_MINOR 0 diff --git a/reapi/extra/amxmodx/scripting/include/reapi_engine.inc b/reapi/extra/amxmodx/scripting/include/reapi_engine.inc index 79c0e27..cf8391e 100644 --- a/reapi/extra/amxmodx/scripting/include/reapi_engine.inc +++ b/reapi/extra/amxmodx/scripting/include/reapi_engine.inc @@ -4,32 +4,4 @@ #define _reapi_engine_included -enum EngineFunc -{ - /** - * Description: - - * Params: (const recipients, const entity, const channel, const sample[], const volume, Float:attenuation, const fFlags, const pitch) - */ - RH_SV_StartSound = 0, - - /** - * Description: - - * Params: (const client, bool:crash, const fmt[]) - */ - RH_SV_DropClient, - - /** - * Description: - - * Params: (const runPhysics) - */ - RH_SV_ActivateServer, - - /** - * Description: - - * Params: (pcvar, const value[]) - */ - RH_Cvar_DirectSet, - - // [...] - RH_EngineFunc_End -}; +#include diff --git a/reapi/extra/amxmodx/scripting/include/reapi_engine_const.inc b/reapi/extra/amxmodx/scripting/include/reapi_engine_const.inc new file mode 100644 index 0000000..5dafd29 --- /dev/null +++ b/reapi/extra/amxmodx/scripting/include/reapi_engine_const.inc @@ -0,0 +1,35 @@ +#if defined _reapi_engine_const_included + #endinput +#endif + +#define _reapi_engine_const_included + +enum EngineFunc +{ + /* + * Description: - + * Params: (const recipients, const entity, const channel, const sample[], const volume, Float:attenuation, const fFlags, const pitch) + */ + RH_SV_StartSound = 0, + + /* + * Description: - + * Params: (const client, bool:crash, const fmt[]) + */ + RH_SV_DropClient, + + /* + * Description: - + * Params: (const runPhysics) + */ + RH_SV_ActivateServer, + + /* + * Description: - + * Params: (pcvar, const value[]) + */ + RH_Cvar_DirectSet, + + // [...] + RH_EngineFunc_End +}; diff --git a/reapi/extra/amxmodx/scripting/include/reapi_gamedll.inc b/reapi/extra/amxmodx/scripting/include/reapi_gamedll.inc index dd855c0..40944b6 100644 --- a/reapi/extra/amxmodx/scripting/include/reapi_gamedll.inc +++ b/reapi/extra/amxmodx/scripting/include/reapi_gamedll.inc @@ -188,7 +188,7 @@ native Float:[3] rg_fire_bullets3(const inflictor, const attacker, Float:vecSrc[ * * @noreturn */ -native rg_round_end(const Float:tmDelay, const WinStatus:st, const ScenarionEventEndRound:event = ROUND_NONE, const message[] = "default", const sentence[] = "default"); +native rg_round_end(const Float:tmDelay, const WinStatus:st, const ScenarioEventEndRound:event = ROUND_NONE, const message[] = "default", const sentence[] = "default"); /* * Update current scores @@ -200,3 +200,79 @@ native rg_round_end(const Float:tmDelay, const WinStatus:st, const ScenarionEven * @noreturn */ native rg_update_teamscores(const iCtsWins = 0, const iTsWins = 0, const bool:bAdd = true); + +/* +* Creates an entity using Counter-Strike's custom CreateNamedEntity wrapper. +* +* @param classname Entity class name +* +* @return Index of the created entity or 0 otherwise +* +*/ +native rg_create_entity(const classname[]); + +/* +* Finds an entity in the world using Counter-Strike's custom FindEntityByString wrapper. +* +* @param start_index Entity index to start searching from. -1 to start from the first entity +* @param classname Classname to search for +* +* @return Entity index > 0 if found, 0 otherwise +* +*/ +native rg_find_ent_by_class(start_index, const classname[]); + +/* +* Finds an entity in the world using Counter-Strike's custom FindEntityByString wrapper, matching by owner. +* +* @param start_index Entity index to start searching from. -1 to start from the first entity +* @param classname Classname to search for +* +* @return 1 if found, 0 otherwise +* +*/ +native rg_find_ent_by_owner(&start_index, const classname[], owner); + +/* +* Returns some information about a weapon. +* +* @param weapon name or id Weapon id, see WEAPON_* constants WeaponIdType or weapon_* name +* @param WpnInfo:type Info type, see WI_* constants +* +* @return Weapon information value +* @error If weapon_id and type are out of bound, an error will be thrown. +* +*/ +native rg_get_weapon_info(any:...); + +/* +* Sets specific values of weapons info. +* +* @param weapon_id Weapon id, see WEAPON_* constants +* @param type Info type, see WI_* constants +* +* @return 1 if successfully, 0 otherwise +* +*/ +native rg_set_weapon_info(const {WeaponIdType,_}:weapon_id, WpnInfo:type, any:...); + +/* +* Remove all the player's stuff +* +* @param index Client index +* +* @noreturn +* +*/ +native rg_remove_all_items(const index, bool:bRemoveSuit); + +/* +* Remove specifed the player's item by class name +* +* @param index Client index +* @param item_name Class name item +* +* @return 1 if found and remove, 0 otherwise +* +*/ +native rg_remove_item(const index, const item_name[]); diff --git a/reapi/extra/amxmodx/scripting/include/reapi_gamedll_const.inc b/reapi/extra/amxmodx/scripting/include/reapi_gamedll_const.inc index 86f140f..554a3ce 100644 --- a/reapi/extra/amxmodx/scripting/include/reapi_gamedll_const.inc +++ b/reapi/extra/amxmodx/scripting/include/reapi_gamedll_const.inc @@ -11,6 +11,66 @@ #define SIGNAL_ESCAPE (1<<3) #define SIGNAL_VIPSAFETY (1<<4) +// Returns 1, if round ended by expired time +// NOTE: Use this for hookchain RG_RoundEnd with the parameter ScenarioEventEndRound:event +#define HadRoundExpired(event) (1< IReGameHook_RoundEnd; typedef IHookChainRegistryClassEmpty IReGameHookRegistry_RoundEnd; +// CanBuyThis hook +typedef IHookChain IReGameHook_CanBuyThis; +typedef IHookChainRegistry IReGameHookRegistry_CanBuyThis; + +// InstallGameRules hook +typedef IHookChain IReGameHook_InstallGameRules; +typedef IHookChainRegistry IReGameHookRegistry_InstallGameRules; + class IReGameHookchains { public: virtual ~IReGameHookchains() {} @@ -216,6 +224,8 @@ public: virtual IReGameHookRegistry_PlayerBlind* PlayerBlind() = 0; virtual IReGameHookRegistry_RadiusFlash_TraceLine* RadiusFlash_TraceLine() = 0; virtual IReGameHookRegistry_RoundEnd* RoundEnd() = 0; + virtual IReGameHookRegistry_CanBuyThis* CanBuyThis() = 0; + virtual IReGameHookRegistry_InstallGameRules* InstallGameRules() = 0; }; @@ -235,7 +245,7 @@ struct ReGameFuncs_t { void (*AddMultiDamage)(entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType); void (*EndRoundMessage)(const char *sentence, int event); - + class CBaseEntity *(*UTIL_FindEntityByString)(class CBaseEntity *pStartEntity, const char *szKeyword, const char *szValue); }; class IReGameApi { diff --git a/reapi/include/cssdk/dlls/regamedll_interfaces.h b/reapi/include/cssdk/dlls/regamedll_interfaces.h index e2d3fd0..aced5e1 100644 --- a/reapi/include/cssdk/dlls/regamedll_interfaces.h +++ b/reapi/include/cssdk/dlls/regamedll_interfaces.h @@ -301,6 +301,7 @@ public: virtual void GiveNamedItem(const char *pszName) = 0; virtual void GiveDefaultItems() = 0; virtual void GiveShield(bool bDeploy = true) = 0; + virtual void RemoveAllItems(bool bRemoveSuit) = 0; }; class IAPI_Bot: public ICSPlayer { @@ -2075,5 +2076,6 @@ class IReGameData { public: virtual ~IReGameData() {} - virtual class CGameRules** GetGameRules() = 0; + virtual class CGameRules* GetGameRules() = 0; + virtual struct WeaponInfoStruct *GetWeaponInfo(int weaponID) = 0; }; diff --git a/reapi/include/cssdk/dlls/weapontype.h b/reapi/include/cssdk/dlls/weapontype.h index c185b3e..8b1bd82 100644 --- a/reapi/include/cssdk/dlls/weapontype.h +++ b/reapi/include/cssdk/dlls/weapontype.h @@ -399,4 +399,5 @@ struct WeaponInfoStruct int maxRounds; int ammoType; char *entityName; + const char *ammoName; }; diff --git a/reapi/include/reunion_api.h b/reapi/include/reunion_api.h new file mode 100644 index 0000000..0bd7b35 --- /dev/null +++ b/reapi/include/reunion_api.h @@ -0,0 +1,36 @@ +#ifndef REUNION_API_H +#define REUNION_API_H + +#define REUNION_API_VERSION_MAJOR 1 +#define REUNION_API_VERSION_MINOR 1 + +enum dp_authkind_e +{ + DP_AUTH_NONE = 0, + DP_AUTH_DPROTO = 1, + DP_AUTH_STEAM = 2, + DP_AUTH_STEAMEMU = 3, + DP_AUTH_REVEMU = 4, + DP_AUTH_OLDREVEMU = 5, + DP_AUTH_HLTV = 6, + DP_AUTH_SC2009 = 7, + DP_AUTH_AVSMP = 8, + DP_AUTH_SXEI = 9, + DP_AUTH_REVEMU2013 = 10, + DP_AUTH_SSE3 = 11, +}; + +class IReunionApi +{ +public: + int version_major; + int version_minor; + + virtual int GetClientProtocol(int index) = 0; // index: 0-31 + virtual dp_authkind_e GetClientAuthtype(int index) = 0; // index: 0-31 + + virtual size_t GetClientAuthdata(int index, void *data, int maxlen) = 0; // get auth data as binary. index: 0-31 + virtual const char *GetClientAuthdataString(int index, char *data, int maxlen) = 0; // get auth data as string. index: 0-31 +}; + +#endif // REUNION_API_H diff --git a/reapi/msvc/reapi.vcxproj b/reapi/msvc/reapi.vcxproj index b36141a..2ee6175 100644 --- a/reapi/msvc/reapi.vcxproj +++ b/reapi/msvc/reapi.vcxproj @@ -200,14 +200,17 @@ + + + - + @@ -241,11 +244,12 @@ + - + Create Create @@ -258,13 +262,13 @@ - + - + - + diff --git a/reapi/msvc/reapi.vcxproj.filters b/reapi/msvc/reapi.vcxproj.filters index a361ede..7ca71ec 100644 --- a/reapi/msvc/reapi.vcxproj.filters +++ b/reapi/msvc/reapi.vcxproj.filters @@ -636,12 +636,21 @@ src\natives - - src\natives - include + + src\natives + + + src + + + src\mods + + + src\natives + @@ -716,7 +725,10 @@ src\natives - + + src\mods + + src\natives @@ -727,25 +739,25 @@ amxmodx\scripting - - src - - - amxmodx\scripting\include - - - amxmodx\scripting\include - amxmodx\scripting\include amxmodx\scripting\include - + amxmodx\scripting\include + + amxmodx\scripting\include + + + amxmodx\scripting\include + + + src + diff --git a/reapi/src/amxxmodule.cpp b/reapi/src/amxxmodule.cpp index a5e15cf..a06c7aa 100644 --- a/reapi/src/amxxmodule.cpp +++ b/reapi/src/amxxmodule.cpp @@ -159,10 +159,12 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc) *(void **)((unsigned long)&g_amxxapi + g_funcrequests[i].offset) = fptr; } + OnAmxxAttach(); + RegisterNatives_HookChains(); RegisterNatives_Members(); RegisterNatives_Misc(); - RegisterNatives_Vtc(); + RegisterNatives_Addons(); return AMXX_OK; } @@ -175,7 +177,7 @@ C_DLLEXPORT int AMXX_Detach() C_DLLEXPORT int AMXX_PluginsLoaded() { int iFwd = g_amxxapi.RegisterForward("__reapi_version_check", ET_IGNORE, FP_CELL, FP_CELL, FP_DONE); - g_amxxapi.ExecuteForward(iFwd, REAPI_VERISON_MAJOR, REAPI_VERISON_MINOR); + g_amxxapi.ExecuteForward(iFwd, REAPI_VERSION_MAJOR, REAPI_VERSION_MINOR); if (api_cfg.hasVTC()) { diff --git a/reapi/src/api_config.cpp b/reapi/src/api_config.cpp index 38ae618..583257d 100644 --- a/reapi/src/api_config.cpp +++ b/reapi/src/api_config.cpp @@ -2,30 +2,26 @@ CAPI_Config api_cfg; -CAPI_Config::CAPI_Config() : m_api_rehlds(false), m_api_regame(false), m_api_vtc(false) +CAPI_Config::CAPI_Config() : m_api_rehlds(false), m_api_regame(false), m_api_vtc(false), m_api_reunion(false) { } -bool CAPI_Config::Init() +void CAPI_Config::Init() { - m_api_rehlds = RehldsApi_Init(); - m_api_regame = RegamedllApi_Init(); - m_api_vtc = VTC_Api_Init(); + m_api_rehlds = RehldsApi_Init(); + m_api_regame = RegamedllApi_Init(); + m_api_vtc = VTC_Api_Init(); + m_api_reunion = ReunionApi_Init(); - return true; -} - -void CAPI_Config::ServerActivate() const -{ if (m_api_regame) { - g_pCSGameRules = (CHalfLifeMultiplay **)g_ReGameApi->GetGameData()->GetGameRules(); + g_ReGameHookchains->InstallGameRules()->registerHook(&InstallGameRules); } } void CAPI_Config::ServerDeactivate() const { if (m_api_regame) { - g_pCSGameRules = nullptr; + g_pGameRules = nullptr; } } diff --git a/reapi/src/api_config.h b/reapi/src/api_config.h index 87cb35b..531bc9c 100644 --- a/reapi/src/api_config.h +++ b/reapi/src/api_config.h @@ -1,18 +1,18 @@ #pragma once // reapi version -#include "reapi_const.inc" +#include "reapi_version.inc" class CAPI_Config { public: CAPI_Config(); - bool Init(); + void Init(); bool hasReHLDS() const { return m_api_rehlds; } bool hasReGameDLL() const { return m_api_regame; } bool hasVTC() const { return m_api_vtc; } + bool hasReunion() const { return m_api_reunion; } - void ServerActivate() const; void ServerDeactivate() const; private: @@ -22,8 +22,9 @@ private: // future plans? bool m_api_vtc; // for gag + bool m_api_reunion; // for information about authorization client + //bool m_api_revoice; // for gag #2 - //bool m_api_reunion; // for information about authorization client //bool m_api_rechecker; // for detection when checking and adding few files }; diff --git a/reapi/src/dllapi.cpp b/reapi/src/dllapi.cpp index cbf822f..000190a 100644 --- a/reapi/src/dllapi.cpp +++ b/reapi/src/dllapi.cpp @@ -1,8 +1,5 @@ #include "precompiled.h" -extern void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax); -extern void ServerDeactivate_Post(); - DLL_FUNCTIONS gFunctionTable = { NULL, // pfnGameInit @@ -26,7 +23,7 @@ DLL_FUNCTIONS gFunctionTable = NULL, // pfnClientPutInServer NULL, // pfnClientCommand NULL, // pfnClientUserInfoChanged - &ServerActivate, // pfnServerActivate + NULL, // pfnServerActivate NULL, // pfnServerDeactivate NULL, // pfnPlayerPreThink NULL, // pfnPlayerPostThink @@ -80,7 +77,7 @@ DLL_FUNCTIONS gFunctionTable_Post = NULL, // pfnClientPutInServer NULL, // pfnClientCommand NULL, // pfnClientUserInfoChanged - NULL, // pfnServerActivate + &ServerActivate_Post, // pfnServerActivate &ServerDeactivate_Post, // pfnServerDeactivate NULL, // pfnPlayerPreThink NULL, // pfnPlayerPostThink diff --git a/reapi/src/engine_api.cpp b/reapi/src/engine_api.cpp index bcd5722..5194a40 100644 --- a/reapi/src/engine_api.cpp +++ b/reapi/src/engine_api.cpp @@ -1,6 +1,6 @@ #include "precompiled.h" -enginefuncs_t meta_engfuncs_post = +enginefuncs_t meta_engfuncs_post = { NULL, // pfnPrecacheModel() NULL, // pfnPrecacheSound() diff --git a/reapi/src/hook_callback.cpp b/reapi/src/hook_callback.cpp index 3193df1..dcf3c07 100644 --- a/reapi/src/hook_callback.cpp +++ b/reapi/src/hook_callback.cpp @@ -9,7 +9,7 @@ void SV_StartSound(IRehldsHook_SV_StartSound *chain, int recipients, edict_t *en { auto original = [chain](int _recipients, int _entity, int _channel, const char *_sample, int _volume, float _attenuation, int _fFlags, int _pitch) { - chain->callNext(_recipients, INDEXENT(_entity), _channel, _sample, _volume, _attenuation, _fFlags, _pitch); + chain->callNext(_recipients, edictByIndexAmx(_entity), _channel, _sample, _volume, _attenuation, _fFlags, _pitch); }; callVoidForward(RH_SV_StartSound, original, recipients, indexOfEdict(entity), channel, sample, volume, attenuation, fFlags, pitch); @@ -55,7 +55,7 @@ void CBasePlayer_Spawn(IReGameHook_CBasePlayer_Spawn *chain, CBasePlayer *pthis) chain->callNext(); }; - callVoidForward(RG_CBasePlayer_Spawn, original, pthis->entindex()); + callVoidForward(RG_CBasePlayer_Spawn, original, indexOfEdict(pthis->pev)); } void CBasePlayer_Precache(IReGameHook_CBasePlayer_Precache *chain, CBasePlayer *pthis) @@ -65,7 +65,7 @@ void CBasePlayer_Precache(IReGameHook_CBasePlayer_Precache *chain, CBasePlayer * chain->callNext(); }; - callVoidForward(RG_CBasePlayer_Precache, original, pthis->entindex()); + callVoidForward(RG_CBasePlayer_Precache, original, indexOfEdict(pthis->pev)); } int CBasePlayer_ObjectCaps(IReGameHook_CBasePlayer_ObjectCaps *chain, CBasePlayer *pthis) @@ -75,7 +75,7 @@ int CBasePlayer_ObjectCaps(IReGameHook_CBasePlayer_ObjectCaps *chain, CBasePlaye return chain->callNext(); }; - return callForward(RG_CBasePlayer_ObjectCaps, original, pthis->entindex()); + return callForward(RG_CBasePlayer_ObjectCaps, original, indexOfEdict(pthis->pev)); } int CBasePlayer_Classify(IReGameHook_CBasePlayer_Classify *chain, CBasePlayer *pthis) @@ -85,7 +85,7 @@ int CBasePlayer_Classify(IReGameHook_CBasePlayer_Classify *chain, CBasePlayer *p return chain->callNext(); }; - return callForward(RG_CBasePlayer_Classify, original, pthis->entindex()); + return callForward(RG_CBasePlayer_Classify, original, indexOfEdict(pthis->pev)); } void CBasePlayer_TraceAttack(IReGameHook_CBasePlayer_TraceAttack *chain, CBasePlayer *pthis, entvars_t *pevAttacker, float flDamage, Vector& vecDir, TraceResult *ptr, int bitsDamageType) @@ -97,7 +97,7 @@ void CBasePlayer_TraceAttack(IReGameHook_CBasePlayer_TraceAttack *chain, CBasePl chain->callNext(PEV(_pevAttacker), _flDamage, vecDirCopy, _ptr, _bitsDamageType); }; - callVoidForward(RG_CBasePlayer_TraceAttack, original, pthis->entindex(), indexOfEdict(pevAttacker), flDamage, g_amxxapi.PrepareCellArrayA(reinterpret_cast(&vecDirCopy), 3, true), ptr, bitsDamageType); + callVoidForward(RG_CBasePlayer_TraceAttack, original, indexOfEdict(pthis->pev), indexOfEdict(pevAttacker), flDamage, g_amxxapi.PrepareCellArrayA(reinterpret_cast(&vecDirCopy), 3, true), ptr, bitsDamageType); } int CBasePlayer_TakeDamage(IReGameHook_CBasePlayer_TakeDamage *chain, CBasePlayer *pthis, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType) @@ -107,7 +107,7 @@ int CBasePlayer_TakeDamage(IReGameHook_CBasePlayer_TakeDamage *chain, CBasePlaye return chain->callNext(PEV(_pevInflictor), PEV(_pevAttacker), _flDamage, _bitsDamageType); }; - return callForward(RG_CBasePlayer_TakeDamage, original, pthis->entindex(), indexOfEdict(pevInflictor), indexOfEdict(pevAttacker), flDamage, bitsDamageType); + return callForward(RG_CBasePlayer_TakeDamage, original, indexOfEdict(pthis->pev), indexOfEdict(pevInflictor), indexOfEdict(pevAttacker), flDamage, bitsDamageType); } int CBasePlayer_TakeHealth(IReGameHook_CBasePlayer_TakeHealth *chain, CBasePlayer *pthis, float flHealth, int bitsDamageType) @@ -117,7 +117,7 @@ int CBasePlayer_TakeHealth(IReGameHook_CBasePlayer_TakeHealth *chain, CBasePlaye return chain->callNext(_flHealth, _bitsDamageType); }; - return callForward(RG_CBasePlayer_TakeHealth, original, pthis->entindex(), flHealth, bitsDamageType); + return callForward(RG_CBasePlayer_TakeHealth, original, indexOfEdict(pthis->pev), flHealth, bitsDamageType); } void CBasePlayer_Killed(IReGameHook_CBasePlayer_Killed *chain, CBasePlayer *pthis, entvars_t *pevAttacker, int iGib) @@ -127,7 +127,7 @@ void CBasePlayer_Killed(IReGameHook_CBasePlayer_Killed *chain, CBasePlayer *pthi chain->callNext(PEV(_pevAttacker), _iGib); }; - callVoidForward(RG_CBasePlayer_Killed, original, pthis->entindex(), indexOfEdict(pevAttacker), iGib); + callVoidForward(RG_CBasePlayer_Killed, original, indexOfEdict(pthis->pev), indexOfEdict(pevAttacker), iGib); } void CBasePlayer_AddPoints(IReGameHook_CBasePlayer_AddPoints *chain, CBasePlayer *pthis, int score, BOOL bAllowNegativeScore) @@ -137,7 +137,7 @@ void CBasePlayer_AddPoints(IReGameHook_CBasePlayer_AddPoints *chain, CBasePlayer chain->callNext(_score, _bAllowNegativeScore); }; - callVoidForward(RG_CBasePlayer_AddPoints, original, pthis->entindex(), score, bAllowNegativeScore); + callVoidForward(RG_CBasePlayer_AddPoints, original, indexOfEdict(pthis->pev), score, bAllowNegativeScore); } void CBasePlayer_AddPointsToTeam(IReGameHook_CBasePlayer_AddPointsToTeam *chain, CBasePlayer *pthis, int score, BOOL bAllowNegativeScore) @@ -147,7 +147,7 @@ void CBasePlayer_AddPointsToTeam(IReGameHook_CBasePlayer_AddPointsToTeam *chain, chain->callNext(_score, _bAllowNegativeScore); }; - callVoidForward(RG_CBasePlayer_AddPointsToTeam, original, pthis->entindex(), score, bAllowNegativeScore); + callVoidForward(RG_CBasePlayer_AddPointsToTeam, original, indexOfEdict(pthis->pev), score, bAllowNegativeScore); } BOOL CBasePlayer_AddPlayerItem(IReGameHook_CBasePlayer_AddPlayerItem *chain, CBasePlayer *pthis, CBasePlayerItem *pItem) @@ -157,7 +157,7 @@ BOOL CBasePlayer_AddPlayerItem(IReGameHook_CBasePlayer_AddPlayerItem *chain, CBa return chain->callNext(getPrivate(_pItem)); }; - return callForward(RG_CBasePlayer_AddPlayerItem, original, pthis->entindex(), pItem->entindex()); + return callForward(RG_CBasePlayer_AddPlayerItem, original, indexOfEdict(pthis->pev), indexOfEdict(pItem->pev)); } BOOL CBasePlayer_RemovePlayerItem(IReGameHook_CBasePlayer_RemovePlayerItem *chain, CBasePlayer *pthis, CBasePlayerItem *pItem) @@ -167,7 +167,7 @@ BOOL CBasePlayer_RemovePlayerItem(IReGameHook_CBasePlayer_RemovePlayerItem *chai return chain->callNext(getPrivate(_pItem)); }; - return callForward(RG_CBasePlayer_RemovePlayerItem, original, pthis->entindex(), pItem->entindex()); + return callForward(RG_CBasePlayer_RemovePlayerItem, original, indexOfEdict(pthis->pev), indexOfEdict(pItem->pev)); } int CBasePlayer_GiveAmmo(IReGameHook_CBasePlayer_GiveAmmo *chain, CBasePlayer *pthis, int iAmount, char *szName, int iMax) @@ -177,7 +177,7 @@ int CBasePlayer_GiveAmmo(IReGameHook_CBasePlayer_GiveAmmo *chain, CBasePlayer *p return chain->callNext(_iAmount, _szName, _iMax); }; - return callForward(RG_CBasePlayer_GiveAmmo, original, pthis->entindex(), iAmount, szName, iMax); + return callForward(RG_CBasePlayer_GiveAmmo, original, indexOfEdict(pthis->pev), iAmount, szName, iMax); } void CBasePlayer_ResetMaxSpeed(IReGameHook_CBasePlayer_ResetMaxSpeed *chain, CBasePlayer *pthis) @@ -187,7 +187,7 @@ void CBasePlayer_ResetMaxSpeed(IReGameHook_CBasePlayer_ResetMaxSpeed *chain, CBa chain->callNext(); }; - callVoidForward(RG_CBasePlayer_ResetMaxSpeed, original, pthis->entindex()); + callVoidForward(RG_CBasePlayer_ResetMaxSpeed, original, indexOfEdict(pthis->pev)); } void CBasePlayer_Jump(IReGameHook_CBasePlayer_Jump *chain, CBasePlayer *pthis) @@ -197,7 +197,7 @@ void CBasePlayer_Jump(IReGameHook_CBasePlayer_Jump *chain, CBasePlayer *pthis) chain->callNext(); }; - callVoidForward(RG_CBasePlayer_Jump, original, pthis->entindex()); + callVoidForward(RG_CBasePlayer_Jump, original, indexOfEdict(pthis->pev)); } void CBasePlayer_Duck(IReGameHook_CBasePlayer_Duck *chain, CBasePlayer *pthis) @@ -207,7 +207,7 @@ void CBasePlayer_Duck(IReGameHook_CBasePlayer_Duck *chain, CBasePlayer *pthis) chain->callNext(); }; - callVoidForward(RG_CBasePlayer_Duck, original, pthis->entindex()); + callVoidForward(RG_CBasePlayer_Duck, original, indexOfEdict(pthis->pev)); } void CBasePlayer_PreThink(IReGameHook_CBasePlayer_PreThink *chain, CBasePlayer *pthis) @@ -217,7 +217,7 @@ void CBasePlayer_PreThink(IReGameHook_CBasePlayer_PreThink *chain, CBasePlayer * chain->callNext(); }; - callVoidForward(RG_CBasePlayer_PreThink, original, pthis->entindex()); + callVoidForward(RG_CBasePlayer_PreThink, original, indexOfEdict(pthis->pev)); } void CBasePlayer_PostThink(IReGameHook_CBasePlayer_PostThink *chain, CBasePlayer *pthis) @@ -227,7 +227,7 @@ void CBasePlayer_PostThink(IReGameHook_CBasePlayer_PostThink *chain, CBasePlayer chain->callNext(); }; - callVoidForward(RG_CBasePlayer_PostThink, original, pthis->entindex()); + callVoidForward(RG_CBasePlayer_PostThink, original, indexOfEdict(pthis->pev)); } void CBasePlayer_UpdateClientData(IReGameHook_CBasePlayer_UpdateClientData *chain, CBasePlayer *pthis) @@ -237,7 +237,7 @@ void CBasePlayer_UpdateClientData(IReGameHook_CBasePlayer_UpdateClientData *chai chain->callNext(); }; - callVoidForward(RG_CBasePlayer_UpdateClientData, original, pthis->entindex()); + callVoidForward(RG_CBasePlayer_UpdateClientData, original, indexOfEdict(pthis->pev)); } void CBasePlayer_ImpulseCommands(IReGameHook_CBasePlayer_ImpulseCommands *chain, CBasePlayer *pthis) @@ -247,7 +247,7 @@ void CBasePlayer_ImpulseCommands(IReGameHook_CBasePlayer_ImpulseCommands *chain, chain->callNext(); }; - callVoidForward(RG_CBasePlayer_ImpulseCommands, original, pthis->entindex()); + callVoidForward(RG_CBasePlayer_ImpulseCommands, original, indexOfEdict(pthis->pev)); } void CBasePlayer_RoundRespawn(IReGameHook_CBasePlayer_RoundRespawn *chain, CBasePlayer *pthis) @@ -257,7 +257,7 @@ void CBasePlayer_RoundRespawn(IReGameHook_CBasePlayer_RoundRespawn *chain, CBase chain->callNext(); }; - callVoidForward(RG_CBasePlayer_RoundRespawn, original, pthis->entindex()); + callVoidForward(RG_CBasePlayer_RoundRespawn, original, indexOfEdict(pthis->pev)); } void CBasePlayer_Blind(IReGameHook_CBasePlayer_Blind *chain, CBasePlayer *pthis, float flUntilTime, float flHoldTime, float flFadeTime, int iAlpha) @@ -267,7 +267,7 @@ void CBasePlayer_Blind(IReGameHook_CBasePlayer_Blind *chain, CBasePlayer *pthis, chain->callNext(_flUntilTime, _flHoldTime, _flFadeTime, _iAlpha); }; - callVoidForward(RG_CBasePlayer_Blind, original, pthis->entindex(), flUntilTime, flHoldTime, flFadeTime, iAlpha); + callVoidForward(RG_CBasePlayer_Blind, original, indexOfEdict(pthis->pev), flUntilTime, flHoldTime, flFadeTime, iAlpha); } CBaseEntity *CBasePlayer_Observer_IsValidTarget(IReGameHook_CBasePlayer_Observer_IsValidTarget *chain, CBasePlayer *pthis, int iPlayerIndex, bool bSameTeam) @@ -277,7 +277,7 @@ CBaseEntity *CBasePlayer_Observer_IsValidTarget(IReGameHook_CBasePlayer_Observer return chain->callNext(_iPlayerIndex, _bSameTeam); }; - return callForward(RG_CBasePlayer_Observer_IsValidTarget, original, pthis->entindex(), iPlayerIndex, bSameTeam); + return callForward(RG_CBasePlayer_Observer_IsValidTarget, original, indexOfEdict(pthis->pev), iPlayerIndex, bSameTeam); } void CBasePlayer_SetAnimation(IReGameHook_CBasePlayer_SetAnimation *chain, CBasePlayer *pthis, PLAYER_ANIM playerAnim) @@ -287,7 +287,7 @@ void CBasePlayer_SetAnimation(IReGameHook_CBasePlayer_SetAnimation *chain, CBase chain->callNext(_playerAnim); }; - callVoidForward(RG_CBasePlayer_SetAnimation, original, pthis->entindex(), playerAnim); + callVoidForward(RG_CBasePlayer_SetAnimation, original, indexOfEdict(pthis->pev), playerAnim); } void CBasePlayer_GiveDefaultItems(IReGameHook_CBasePlayer_GiveDefaultItems *chain, CBasePlayer *pthis) @@ -297,7 +297,7 @@ void CBasePlayer_GiveDefaultItems(IReGameHook_CBasePlayer_GiveDefaultItems *chai chain->callNext(); }; - callVoidForward(RG_CBasePlayer_GiveDefaultItems, original, pthis->entindex()); + callVoidForward(RG_CBasePlayer_GiveDefaultItems, original, indexOfEdict(pthis->pev)); } void CBasePlayer_GiveNamedItem(IReGameHook_CBasePlayer_GiveNamedItem *chain, CBasePlayer *pthis, const char *pszName) @@ -307,7 +307,7 @@ void CBasePlayer_GiveNamedItem(IReGameHook_CBasePlayer_GiveNamedItem *chain, CBa chain->callNext(_pszName); }; - callVoidForward(RG_CBasePlayer_GiveNamedItem, original, pthis->entindex(), pszName); + callVoidForward(RG_CBasePlayer_GiveNamedItem, original, indexOfEdict(pthis->pev), pszName); } void CBasePlayer_AddAccount(IReGameHook_CBasePlayer_AddAccount *chain, CBasePlayer *pthis, int amount, bool bTrackChange) @@ -317,7 +317,7 @@ void CBasePlayer_AddAccount(IReGameHook_CBasePlayer_AddAccount *chain, CBasePlay chain->callNext(_amount, _bTrackChange); }; - callVoidForward(RG_CBasePlayer_AddAccount, original, pthis->entindex(), amount, bTrackChange); + callVoidForward(RG_CBasePlayer_AddAccount, original, indexOfEdict(pthis->pev), amount, bTrackChange); } void CBasePlayer_GiveShield(IReGameHook_CBasePlayer_GiveShield *chain, CBasePlayer *pthis, bool bDeploy) @@ -327,7 +327,7 @@ void CBasePlayer_GiveShield(IReGameHook_CBasePlayer_GiveShield *chain, CBasePlay chain->callNext(_bDeploy); }; - callVoidForward(RG_CBasePlayer_GiveShield, original, pthis->entindex(), bDeploy); + callVoidForward(RG_CBasePlayer_GiveShield, original, indexOfEdict(pthis->pev), bDeploy); } void CBaseAnimating_ResetSequenceInfo(IReGameHook_CBaseAnimating_ResetSequenceInfo *chain, CBaseAnimating *pthis) @@ -337,7 +337,7 @@ void CBaseAnimating_ResetSequenceInfo(IReGameHook_CBaseAnimating_ResetSequenceIn chain->callNext(); }; - callVoidForward(RG_CBaseAnimating_ResetSequenceInfo, original, pthis->entindex()); + callVoidForward(RG_CBaseAnimating_ResetSequenceInfo, original, indexOfEdict(pthis->pev)); } int GetForceCamera(IReGameHook_GetForceCamera *chain, CBasePlayer *pObserver) @@ -347,7 +347,7 @@ int GetForceCamera(IReGameHook_GetForceCamera *chain, CBasePlayer *pObserver) return chain->callNext(getPrivate(_pObserver)); }; - return callForward(RG_GetForceCamera, original, pObserver->entindex()); + return callForward(RG_GetForceCamera, original, indexOfEdict(pObserver->pev)); } void PlayerBlind(IReGameHook_PlayerBlind *chain, CBasePlayer *pPlayer, entvars_t *pevInflictor, entvars_t *pevAttacker, float fadeTime, float fadeHold, int alpha, Vector& color) @@ -359,7 +359,7 @@ void PlayerBlind(IReGameHook_PlayerBlind *chain, CBasePlayer *pPlayer, entvars_t chain->callNext(getPrivate(_pPlayer), PEV(_pevInflictor), PEV(_pevAttacker), _fadeTime, _fadeHold, _alpha, colorCopy); }; - callVoidForward(RG_PlayerBlind, original, pPlayer->entindex(), indexOfEdict(pevInflictor), indexOfEdict(pevAttacker), fadeTime, fadeHold, alpha, g_amxxapi.PrepareCellArrayA(reinterpret_cast(&colorCopy), 3, true)); + callVoidForward(RG_PlayerBlind, original, indexOfEdict(pPlayer->pev), indexOfEdict(pevInflictor), indexOfEdict(pevAttacker), fadeTime, fadeHold, alpha, g_amxxapi.PrepareCellArrayA(reinterpret_cast(&colorCopy), 3, true)); } void RadiusFlash_TraceLine(IReGameHook_RadiusFlash_TraceLine *chain, CBasePlayer *pPlayer, entvars_t *pevInflictor, entvars_t *pevAttacker, Vector& vecSrc, Vector& vecSpot, TraceResult *ptr) @@ -371,7 +371,7 @@ void RadiusFlash_TraceLine(IReGameHook_RadiusFlash_TraceLine *chain, CBasePlayer chain->callNext(getPrivate(_pPlayer), PEV(_pevInflictor), PEV(_pevAttacker), vecSrcCopy, vecSpotCopy, _ptr); }; - callVoidForward(RG_RadiusFlash_TraceLine, original, pPlayer->entindex(), indexOfEdict(pevInflictor), indexOfEdict(pevAttacker), g_amxxapi.PrepareCellArrayA(reinterpret_cast(&vecSrcCopy), 3, true), g_amxxapi.PrepareCellArrayA(reinterpret_cast(&vecSpotCopy), 3, true), ptr); + callVoidForward(RG_RadiusFlash_TraceLine, original, indexOfEdict(pPlayer->pev), indexOfEdict(pevInflictor), indexOfEdict(pevAttacker), g_amxxapi.PrepareCellArrayA(reinterpret_cast(&vecSrcCopy), 3, true), g_amxxapi.PrepareCellArrayA(reinterpret_cast(&vecSpotCopy), 3, true), ptr); } bool RoundEnd(IReGameHook_RoundEnd *chain, int winStatus, ScenarioEventEndRound event, float tmDelay) @@ -384,6 +384,16 @@ bool RoundEnd(IReGameHook_RoundEnd *chain, int winStatus, ScenarioEventEndRound return callForward(RG_RoundEnd, original, winStatus, event, tmDelay); } +bool CanBuyThis(IReGameHook_CanBuyThis *chain, CBasePlayer *pPlayer, int iWeapon) +{ + auto original = [chain](int _pPlayer, int _iWeapon) + { + return chain->callNext(getPrivate(_pPlayer), _iWeapon); + }; + + return callForward(RG_CanBuyThis, original, indexOfEdict(pPlayer->pev), iWeapon); +} + int g_iClientStartSpeak, g_iClientStopSpeak; void ClientStartSpeak(size_t clientIndex) diff --git a/reapi/src/hook_callback.h b/reapi/src/hook_callback.h index b9d1605..8307552 100644 --- a/reapi/src/hook_callback.h +++ b/reapi/src/hook_callback.h @@ -203,6 +203,7 @@ int GetForceCamera(IReGameHook_GetForceCamera *chain, CBasePlayer *pObserver); void PlayerBlind(IReGameHook_PlayerBlind *chain, CBasePlayer *pPlayer, entvars_t *pevInflictor, entvars_t *pevAttacker, float fadeTime, float fadeHold, int alpha, Vector& color); void RadiusFlash_TraceLine(IReGameHook_RadiusFlash_TraceLine *chain, CBasePlayer *pPlayer, entvars_t *pevInflictor, entvars_t *pevAttacker, Vector& vecSrc, Vector& vecSpot, TraceResult *ptr); bool RoundEnd(IReGameHook_RoundEnd *chain, int winStatus, ScenarioEventEndRound event, float tmDelay); +bool CanBuyThis(IReGameHook_CanBuyThis *chain, CBasePlayer *pPlayer, int iWeapon); // regamedll functions - player void CBasePlayer_Spawn(IReGameHook_CBasePlayer_Spawn *chain, CBasePlayer *pthis); diff --git a/reapi/src/hook_list.cpp b/reapi/src/hook_list.cpp index 59d1c21..05bfac2 100644 --- a/reapi/src/hook_list.cpp +++ b/reapi/src/hook_list.cpp @@ -51,7 +51,7 @@ struct regfunc }; } - regfunc(const char *error) { UTIL_SysError(error); } // to cause a amxx module failure. + regfunc(const char *name) { UTIL_SysError("%s doesn't match hook definition", name); } // to cause a amxx module failure. operator regfunc_t() const { return func; } regfunc_t func; @@ -60,7 +60,7 @@ struct regfunc int regfunc::current_cell = 1; -#define ENG(h) { {}, {}, #h, "ReHLDS", [](){ return api_cfg.hasReHLDS(); }, ((!(RH_##h & (MAX_REGION_RANGE - 1)) ? regfunc::current_cell = 1, true : false) || (RH_##h & (MAX_REGION_RANGE - 1)) == regfunc::current_cell++) ? regfunc(h) : regfunc(#h " doesn't match hook definition"), [](){ g_RehldsHookchains->##h##()->registerHook(&##h); }, [](){ g_RehldsHookchains->##h##()->unregisterHook(&##h); }} +#define ENG(h) { {}, {}, #h, "ReHLDS", [](){ return api_cfg.hasReHLDS(); }, ((!(RH_##h & (MAX_REGION_RANGE - 1)) ? regfunc::current_cell = 1, true : false) || (RH_##h & (MAX_REGION_RANGE - 1)) == regfunc::current_cell++) ? regfunc(h) : regfunc(#h), [](){ g_RehldsHookchains->##h##()->registerHook(&##h); }, [](){ g_RehldsHookchains->##h##()->unregisterHook(&##h); }} hook_t hooklist_engine[] = { ENG(SV_StartSound), ENG(SV_DropClient), @@ -68,12 +68,13 @@ hook_t hooklist_engine[] = { ENG(Cvar_DirectSet) }; -#define DLL(h) { {}, {}, #h, "ReGameDLL", [](){ return api_cfg.hasReGameDLL(); }, ((!(RG_##h & (MAX_REGION_RANGE - 1)) ? regfunc::current_cell = 1, true : false) || (RG_##h & (MAX_REGION_RANGE - 1)) == regfunc::current_cell++) ? regfunc(h) : regfunc(#h " doesn't match hook definition"), [](){ g_ReGameHookchains->##h##()->registerHook(&##h); }, [](){ g_ReGameHookchains->##h##()->unregisterHook(&##h); }} +#define DLL(h) { {}, {}, #h, "ReGameDLL", [](){ return api_cfg.hasReGameDLL(); }, ((!(RG_##h & (MAX_REGION_RANGE - 1)) ? regfunc::current_cell = 1, true : false) || (RG_##h & (MAX_REGION_RANGE - 1)) == regfunc::current_cell++) ? regfunc(h) : regfunc(#h), [](){ g_ReGameHookchains->##h##()->registerHook(&##h); }, [](){ g_ReGameHookchains->##h##()->unregisterHook(&##h); }} hook_t hooklist_gamedll[] = { DLL(GetForceCamera), DLL(PlayerBlind), DLL(RadiusFlash_TraceLine), - DLL(RoundEnd) + DLL(RoundEnd), + DLL(CanBuyThis) }; hook_t hooklist_animating[] = { @@ -129,15 +130,27 @@ hook_t* hooklist_t::getHookSafe(size_t hook) return nullptr; } +void hooklist_t::clear() +{ + #define FOREACH_CLEAR(h) for (auto& h : hooklist_##h) h.clear(); + + FOREACH_CLEAR(engine); + FOREACH_CLEAR(gamedll); + FOREACH_CLEAR(animating); + FOREACH_CLEAR(player); +} + void hook_t::clear() { - for (auto h : pre) - delete h; - pre.clear(); + if (pre.size() || post.size()) { + for (auto h : pre) + delete h; + pre.clear(); - for (auto h : post) - delete h; - post.clear(); + for (auto h : post) + delete h; + post.clear(); - unregisterHookchain(); + unregisterHookchain(); + } } diff --git a/reapi/src/hook_list.h b/reapi/src/hook_list.h index 21e40c7..3f671e2 100644 --- a/reapi/src/hook_list.h +++ b/reapi/src/hook_list.h @@ -1,8 +1,9 @@ #pragma once -#define MAX_REGION_RANGE 1024 -#define BEGIN_FUNC_REGION(x) (MAX_REGION_RANGE * hooklist_t::hooks_tables_e::ht_##x) #define MAX_HOOK_FORWARDS 1024 +#define MAX_REGION_RANGE 1024 + +#define BEGIN_FUNC_REGION(x) (MAX_REGION_RANGE * hooklist_t::hooks_tables_e::ht_##x) typedef bool (*reqfunc_t)(); typedef int (*regfunc_t)(AMX *, const char *); @@ -49,6 +50,7 @@ struct hooklist_t } static hook_t *getHookSafe(size_t hook); + static void clear(); enum hooks_tables_e { @@ -78,6 +80,7 @@ enum GamedllFunc RG_PlayerBlind, RG_RadiusFlash_TraceLine, RG_RoundEnd, + RG_CanBuyThis, // [...] RG_End diff --git a/reapi/src/hook_manager.cpp b/reapi/src/hook_manager.cpp index f181add..922d11c 100644 --- a/reapi/src/hook_manager.cpp +++ b/reapi/src/hook_manager.cpp @@ -40,17 +40,7 @@ void CAmxxHook::SetState(fwdstate st) void CHookManager::clearHandlers() const { -#define CLEAR_HOOKLIST(__END__, __START__)\ - for (size_t i = BEGIN_FUNC_REGION(__START__); i < ##__END__; ++i) {\ - if (m_hooklist[i])\ - m_hooklist[i]->clear();\ - } - - CLEAR_HOOKLIST(RH_EngineFunc_End, engine); - - CLEAR_HOOKLIST(RG_End, gamedll); - CLEAR_HOOKLIST(RG_CBaseAnimating_End, animating); - CLEAR_HOOKLIST(RG_CBasePlayer_End, player); + m_hooklist.clear(); } hook_t* CHookManager::getHook(size_t func) const diff --git a/reapi/src/main.cpp b/reapi/src/main.cpp index d17552a..eea0c48 100644 --- a/reapi/src/main.cpp +++ b/reapi/src/main.cpp @@ -1,13 +1,17 @@ #include "precompiled.h" edict_t* g_pEdicts; +int gmsgSendAudio; +int gmsgTeamScore; + +void OnAmxxAttach() +{ + // initialize API + api_cfg.Init(); +} bool OnMetaAttach() { - // initialize API - if (!api_cfg.Init()) - return false; - return true; } @@ -20,20 +24,30 @@ void OnMetaDetach() g_pVoiceTranscoderApi->ClientStartSpeak()->unregisterCallback(&ClientStartSpeak); g_pVoiceTranscoderApi->ClientStopSpeak()->unregisterCallback(&ClientStopSpeak); } + + if (api_cfg.hasReGameDLL()) { + g_ReGameHookchains->InstallGameRules()->unregisterHook(&InstallGameRules); + } } -void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) +void ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax) { g_pEdicts = pEdictList; - api_cfg.ServerActivate(); + gmsgSendAudio = GET_USER_MSG_ID(PLID, "SendAudio", NULL); + gmsgTeamScore = GET_USER_MSG_ID(PLID, "TeamScore", NULL); SET_META_RESULT(MRES_IGNORED); } void ServerDeactivate_Post() { - api_cfg.ServerActivate(); + api_cfg.ServerDeactivate(); g_hookManager.clearHandlers(); SET_META_RESULT(MRES_IGNORED); } + +CGameRules *InstallGameRules(IReGameHook_InstallGameRules *chain) +{ + return g_pGameRules = chain->callNext(); +} diff --git a/reapi/src/main.h b/reapi/src/main.h new file mode 100644 index 0000000..3a7033c --- /dev/null +++ b/reapi/src/main.h @@ -0,0 +1,13 @@ +#pragma once + +extern edict_t* g_pEdicts; +extern int gmsgSendAudio; +extern int gmsgTeamScore; + +void OnAmxxAttach(); +bool OnMetaAttach(); +void OnMetaDetach(); + +void ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax); +void ServerDeactivate_Post(); +CGameRules *InstallGameRules(IReGameHook_InstallGameRules *chain); diff --git a/reapi/src/member_list.cpp b/reapi/src/member_list.cpp index 1af8f66..62b0471 100644 --- a/reapi/src/member_list.cpp +++ b/reapi/src/member_list.cpp @@ -1,6 +1,6 @@ #include "precompiled.h" -#define CLASS_MEMBERS(cx, mx) ((!(mx & (MAX_REGION_RANGE - 1)) ? regmember::current_cell = 1, true : false) || (mx & (MAX_REGION_RANGE - 1)) == regmember::current_cell++) ? regmember([](member_t* ptr){ decltype(##cx::##mx) f = {};ptr->size = getTypeSize(f);ptr->max_size = sizeof(f);ptr->offset = offsetof(##cx, ##mx);ptr->type = getMemberType(f);}) : regmember(#mx " doesn't match member definition") +#define CLASS_MEMBERS(cx, mx) ((!(mx & (MAX_REGION_RANGE - 1)) ? regmember::current_cell = 1, true : false) || (mx & (MAX_REGION_RANGE - 1)) == regmember::current_cell++) ? regmember([](member_t* ptr){ decltype(##cx::##mx) f = {};ptr->size = getTypeSize(f);ptr->max_size = sizeof(f);ptr->offset = offsetof(##cx, ##mx);ptr->type = getMemberType(f);}) : regmember(#mx) #define GM_MEMBERS(mx) CLASS_MEMBERS(CHalfLifeMultiplay, mx) #define GM_VOICE_MEMBERS(mx) CLASS_MEMBERS(CVoiceGameMgr, mx) @@ -59,7 +59,7 @@ struct regmember template regmember(T lambdaFunc) { lambdaFunc(&member); } - regmember(const char *error) { UTIL_SysError(error); } // to cause a amxx module failure. + regmember(const char *name) { UTIL_SysError("%s doesn't match member definition", name); } // to cause a amxx module failure. operator member_t() const { return member; } member_t member; diff --git a/reapi/src/member_list.h b/reapi/src/member_list.h index 42f1fca..c16594e 100644 --- a/reapi/src/member_list.h +++ b/reapi/src/member_list.h @@ -134,7 +134,7 @@ enum CSGameRules_Members m_bSkipSpawn }; -// CBasePlayer +// CBaseEntity enum CBaseEntity_Members { currentammo = BEGIN_MEMBER_REGION(base), diff --git a/reapi/src/meta_api.cpp b/reapi/src/meta_api.cpp index 4eaedb8..1dbb08d 100644 --- a/reapi/src/meta_api.cpp +++ b/reapi/src/meta_api.cpp @@ -19,9 +19,6 @@ plugin_info_t Plugin_info = PT_NEVER, // (when) unloadable }; -extern bool OnMetaAttach(); -extern void OnMetaDetach(); - C_DLLEXPORT int Meta_Query(char *interfaceVersion, plugin_info_t* *plinfo, mutil_funcs_t *pMetaUtilFuncs) { *plinfo = &Plugin_info; @@ -34,7 +31,7 @@ META_FUNCTIONS gMetaFunctionTable = { NULL, // pfnGetEntityAPI HL SDK; called before game DLL NULL, // pfnGetEntityAPI_Post META; called after game DLL - GetEntityAPI2, // pfnGetEntityAPI2 HL SDK2; called before game DLL + NULL, // pfnGetEntityAPI2 HL SDK2; called before game DLL GetEntityAPI2_Post, // pfnGetEntityAPI2_Post META; called after game DLL NULL, // pfnGetNewDLLFunctions HL SDK2; called before game DLL NULL, // pfnGetNewDLLFunctions_Post META; called after game DLL diff --git a/reapi/src/mods/mod_regamedll_api.cpp b/reapi/src/mods/mod_regamedll_api.cpp index f95d239..c36b939 100644 --- a/reapi/src/mods/mod_regamedll_api.cpp +++ b/reapi/src/mods/mod_regamedll_api.cpp @@ -3,7 +3,7 @@ IReGameApi *g_ReGameApi; const ReGameFuncs_t *g_ReGameFuncs; IReGameHookchains *g_ReGameHookchains; -CHalfLifeMultiplay **g_pCSGameRules = nullptr; +CGameRules *g_pGameRules = nullptr; bool RegamedllApi_Init() { diff --git a/reapi/src/mods/mod_regamedll_api.h b/reapi/src/mods/mod_regamedll_api.h index 3b8ef09..e0d1ab3 100644 --- a/reapi/src/mods/mod_regamedll_api.h +++ b/reapi/src/mods/mod_regamedll_api.h @@ -3,6 +3,6 @@ extern IReGameApi *g_ReGameApi; extern const ReGameFuncs_t *g_ReGameFuncs; extern IReGameHookchains *g_ReGameHookchains; -extern CHalfLifeMultiplay **g_pCSGameRules; +extern CGameRules *g_pGameRules; extern bool RegamedllApi_Init(); diff --git a/reapi/src/mods/mod_reunion_api.cpp b/reapi/src/mods/mod_reunion_api.cpp new file mode 100644 index 0000000..66451b4 --- /dev/null +++ b/reapi/src/mods/mod_reunion_api.cpp @@ -0,0 +1,27 @@ +#include "precompiled.h" + +IReunionApi* g_ReunionApi; + +bool ReunionApi_Init() +{ + if (g_RehldsApi == nullptr) + return false; + + g_ReunionApi = (IReunionApi *)g_RehldsApi->GetFuncs()->GetPluginApi("reunion"); + + if (g_ReunionApi == nullptr) { + return false; + } + + if (g_ReunionApi->version_major != REUNION_API_VERSION_MAJOR) { + UTIL_LogPrintf("[%s]: Reunion Api major version mismatch; expected %d, real %d\n", Plugin_info.logtag, REUNION_API_VERSION_MAJOR, g_ReunionApi->version_major); + return false; + } + + if (g_ReunionApi->version_minor < REUNION_API_VERSION_MINOR) { + UTIL_LogPrintf("[%s]: Reunion Api minor version mismatch; expected at least %d, real %d\n", Plugin_info.logtag, REUNION_API_VERSION_MINOR, g_ReunionApi->version_minor); + return false; + } + + return true; +} diff --git a/reapi/src/mods/mod_reunion_api.h b/reapi/src/mods/mod_reunion_api.h new file mode 100644 index 0000000..e1317f3 --- /dev/null +++ b/reapi/src/mods/mod_reunion_api.h @@ -0,0 +1,5 @@ +#pragma once + +extern IReunionApi* g_ReunionApi; + +extern bool ReunionApi_Init(); diff --git a/reapi/src/natives/natives_addons.cpp b/reapi/src/natives/natives_addons.cpp new file mode 100644 index 0000000..da5fba4 --- /dev/null +++ b/reapi/src/natives/natives_addons.cpp @@ -0,0 +1,116 @@ +#include "precompiled.h" + +/* +* Checks whether the player is talking at this moment +* +* @param index Client index +* @return 1 if client is speaking, 0 otherwise +* +* native VTC_IsClientSpeaking(const index); +*/ +cell AMX_NATIVE_CALL VTC_IsClientSpeaking(AMX *amx, cell *params) +{ + enum args_e { arg_count, arg_index }; + + CHECK_ISPLAYER(arg_index); + + return g_pVoiceTranscoderApi->IsClientSpeaking((size_t)params[arg_index]); +} + +/* +* Mutes this player +* +* @param index Client index +* @noreturn +* +* native VTC_MuteClient(const index); +*/ +cell AMX_NATIVE_CALL VTC_MuteClient(AMX *amx, cell *params) +{ + enum args_e { arg_count, arg_index }; + + CHECK_ISPLAYER(arg_index); + + g_pVoiceTranscoderApi->MuteClient((size_t)params[arg_index]); + + return FALSE; +} + +/* +* Unmutes this player +* +* @param index Client index +* @noreturn +* +* native VTC_UnmuteClient(const index); +*/ +cell AMX_NATIVE_CALL VTC_UnmuteClient(AMX *amx, cell *params) +{ + enum args_e { arg_count, arg_index }; + + CHECK_ISPLAYER(arg_index); + + g_pVoiceTranscoderApi->UnmuteClient((size_t)params[arg_index]); + + return FALSE; +} + +AMX_NATIVE_INFO Vtc_Natives[] = +{ + { "VTC_IsClientSpeaking", VTC_IsClientSpeaking }, + { "VTC_MuteClient", VTC_MuteClient }, + { "VTC_UnmuteClient", VTC_UnmuteClient }, + + { nullptr, nullptr } +}; + +/* +* Get client protocol +* +* @param index Client index +* @return client protocol +* +* native REU_GetProtocol(const index); +*/ +cell AMX_NATIVE_CALL REU_GetProtocol(AMX *amx, cell *params) +{ + enum args_e { arg_count, arg_index }; + + CHECK_ISPLAYER(arg_index); + + return g_ReunionApi->GetClientProtocol(params[arg_index] - 1); +} + +/* +* Get client auth type +* +* @param index Client index +* @return client auth type +* +* native REU_GetAuthtype(const index); +*/ +cell AMX_NATIVE_CALL REU_GetAuthtype(AMX *amx, cell *params) +{ + enum args_e { arg_count, arg_index }; + + CHECK_ISPLAYER(arg_index); + + return g_ReunionApi->GetClientAuthtype(params[arg_index] - 1); +} + +AMX_NATIVE_INFO Reunion_Natives[] = +{ + { "REU_GetProtocol", REU_GetProtocol }, + { "REU_GetAuthtype", REU_GetAuthtype }, + + { nullptr, nullptr } +}; + +void RegisterNatives_Addons() +{ + if (api_cfg.hasVTC()) + g_amxxapi.AddNatives(Vtc_Natives); + + if (api_cfg.hasReunion()) + g_amxxapi.AddNatives(Reunion_Natives); +} diff --git a/reapi/src/natives/natives_addons.h b/reapi/src/natives/natives_addons.h new file mode 100644 index 0000000..a4093f7 --- /dev/null +++ b/reapi/src/natives/natives_addons.h @@ -0,0 +1,3 @@ +#pragma once + +void RegisterNatives_Addons(); diff --git a/reapi/src/natives/natives_helper.h b/reapi/src/natives/natives_helper.h new file mode 100644 index 0000000..b3a432d --- /dev/null +++ b/reapi/src/natives/natives_helper.h @@ -0,0 +1,77 @@ +#pragma once + +#define CHECK_ISPLAYER(x) if (params[x] <= 0 || params[x] > gpGlobals->maxClients) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: invalid player index %i [%s]", __FUNCTION__, params[x], #x); return FALSE; } +#define CHECK_ISENTITY(x) if (params[x] > gpGlobals->maxEntities) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: invalid entity index %i [%s]", __FUNCTION__, params[x], #x); return FALSE; } + +class CAmxArg +{ +public: + CAmxArg(AMX* amx, cell value) : m_amx(amx), m_value(value) {} + operator float() const + { + return *(float *)m_value; + } + operator Vector&() const + { + return *(Vector *)getAmxAddr(m_amx, m_value); + } + operator entvars_s*() const + { + auto pev = PEV(m_value); // faster + return m_value < 0 ? nullptr : pev; + } + operator int() const + { + return m_value; + } + operator size_t() const + { + return size_t(m_value); + } + operator bool() const + { + return m_value != 0; + } + operator CBaseEntity*() const + { + if (m_value < 0) + return nullptr; + return getPrivate(m_value); + } + operator CBasePlayer*() const + { + if (m_value < 0) + return nullptr; + return static_cast(g_ReGameFuncs->UTIL_PlayerByIndex(m_value)); + } + operator PLAYER_ANIM() const + { + return static_cast(m_value); + } + operator ICSEntity*() const + { + return g_ReGameFuncs->INDEX_TO_CSENTITY(m_value); + } + Vector& vector() const + { + return operator Vector&(); + } + +private: + AMX* m_amx; + cell m_value; +}; + +class CAmxArgs +{ +public: + CAmxArgs(AMX* amx, cell* params) : m_amx(amx), m_params(params) {} + CAmxArg operator[](size_t index) const + { + return CAmxArg(m_amx, m_params[index]); + } + +private: + AMX* m_amx; + cell* m_params; +}; diff --git a/reapi/src/natives/natives_hookchains.cpp b/reapi/src/natives/natives_hookchains.cpp index 0012cee..7dad4cf 100644 --- a/reapi/src/natives/natives_hookchains.cpp +++ b/reapi/src/natives/natives_hookchains.cpp @@ -1,18 +1,17 @@ #include "precompiled.h" /* - * Hook API function that are available into enum - * Look at the enum's for parameter lists. - * - * @param function The function to hook. - * @param callback The forward to call. - * @param post Whether or not to forward this in post. - * @return Returns a handle to the hook. Use EnableHookChain/DisableHookChain to toggle the forward on or off. - * - * native RegisterHookChain(any:function_id, const callback[], post = 0); - */ - -static cell AMX_NATIVE_CALL RegisterHookChain(AMX *amx, cell *params) +* Hook API function that are available into enum +* Look at the enum's for parameter lists. +* +* @param function The function to hook. +* @param callback The forward to call. +* @param post Whether or not to forward this in post. +* @return Returns a handle to the hook. Use EnableHookChain/DisableHookChain to toggle the forward on or off. +* +* native RegisterHookChain(any:function_id, const callback[], post = 0); +*/ +cell AMX_NATIVE_CALL RegisterHookChain(AMX *amx, cell *params) { enum args_e { arg_count, arg_func, arg_handler, arg_post }; @@ -22,13 +21,13 @@ static cell AMX_NATIVE_CALL RegisterHookChain(AMX *amx, cell *params) if (hook == nullptr) { - MF_LogError(amx, AMX_ERR_NATIVE, "RegisterHookChain: function with id (%d) doesn't exist in current API version.", func); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: function with id (%d) doesn't exist in current API version.", __FUNCTION__, func); return 0; } if (!hook->checkRequirements()) { - MF_LogError(amx, AMX_ERR_NATIVE, "RegisterHookChain: function (%s) is not available, %s required", hook->func_name, hook->depend_name); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: function (%s) is not available, %s required", __FUNCTION__, hook->func_name, hook->depend_name); return 0; } @@ -36,14 +35,14 @@ static cell AMX_NATIVE_CALL RegisterHookChain(AMX *amx, cell *params) const char *funcname = getAmxString(amx, params[arg_handler]); if (g_amxxapi.amx_FindPublic(amx, funcname, &funcid) != AMX_ERR_NONE) { - MF_LogError(amx, AMX_ERR_NATIVE, "RegisterHookChain: public function \"%s\" not found.", funcname); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: public function \"%s\" not found.", __FUNCTION__, funcname); return 0; } int fwid = hook->registerForward(amx, funcname); if (fwid == -1) { - MF_LogError(amx, AMX_ERR_NATIVE, "RegisterHookChain: register forward failed."); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: register forward failed.", __FUNCTION__); return 0; } @@ -51,16 +50,15 @@ static cell AMX_NATIVE_CALL RegisterHookChain(AMX *amx, cell *params) } /* - * Enable hook by handle. - * Use the return value from RegisterHookChain as the parameter here! - * - * @param fwd The hook to re-enable. - * @return Returns if the function is successful executed true otherwise false - * - * native bool:EnableHookChain(any:fwd); - */ - -static cell AMX_NATIVE_CALL EnableHookChain(AMX *amx, cell *params) +* Enable hook by handle. +* Use the return value from RegisterHookChain as the parameter here! +* +* @param fwd The hook to re-enable. +* @return Returns if the function is successful executed true otherwise false +* +* native bool:EnableHookChain(any:fwd); +*/ +cell AMX_NATIVE_CALL EnableHookChain(AMX *amx, cell *params) { enum args_e { arg_count, arg_handle_hook }; @@ -68,7 +66,7 @@ static cell AMX_NATIVE_CALL EnableHookChain(AMX *amx, cell *params) if (hook == nullptr) { - MF_LogError(amx, AMX_ERR_NATIVE, "EnableHookChain: invalid HookChain handle."); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: invalid HookChain handle.", __FUNCTION__); return FALSE; } @@ -77,15 +75,14 @@ static cell AMX_NATIVE_CALL EnableHookChain(AMX *amx, cell *params) } /* - * Disable hook by handle. - * Use the return value from RegisterHookChain as the parameter here! - * - * @param fwd The hook to stop. - * - * native bool:DisableHookChain(any:fwd); - */ - -static cell AMX_NATIVE_CALL DisableHookChain(AMX *amx, cell *params) +* Disable hook by handle. +* Use the return value from RegisterHookChain as the parameter here! +* +* @param fwd The hook to stop. +* +* native bool:DisableHookChain(any:fwd); +*/ +cell AMX_NATIVE_CALL DisableHookChain(AMX *amx, cell *params) { enum args_e { arg_count, arg_handle_hook }; @@ -93,7 +90,7 @@ static cell AMX_NATIVE_CALL DisableHookChain(AMX *amx, cell *params) if (hook == nullptr) { - MF_LogError(amx, AMX_ERR_NATIVE, "DisableHookChain: invalid HookChain handle."); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: invalid HookChain handle.", __FUNCTION__); return FALSE; } @@ -102,20 +99,19 @@ static cell AMX_NATIVE_CALL DisableHookChain(AMX *amx, cell *params) } /* - * Sets the return value of a hookchain. - * This needs to be used in conjunction with RH_OVERRIDE or RH_SUPERCEDE. - * - * @param type To specify the type RHV_*, look at the enum AType - * @param value The value to set the return to. - * - * native SetHookChainReturn(AType:type, any:...); - */ - -static cell AMX_NATIVE_CALL SetHookChainReturn(AMX *amx, cell *params) +* Sets the return value of a hookchain. +* This needs to be used in conjunction with RH_OVERRIDE or RH_SUPERCEDE. +* +* @param type To specify the type RHV_*, look at the enum AType +* @param value The value to set the return to. +* +* native SetHookChainReturn(AType:type, any:...); +*/ +cell AMX_NATIVE_CALL SetHookChainReturn(AMX *amx, cell *params) { if (!g_hookCtx) { - MF_LogError(amx, AMX_ERR_NATIVE, "Trying to set return value without active hook."); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: trying to set return value without active hook.", __FUNCTION__); return FALSE; } @@ -124,7 +120,7 @@ static cell AMX_NATIVE_CALL SetHookChainReturn(AMX *amx, cell *params) if (params[arg_type] != retVal.type) { - MF_LogError(amx, AMX_ERR_NATIVE, "Trying to set incompatible return type."); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: trying to set return value with incompatible type.", __FUNCTION__); return FALSE; } @@ -148,7 +144,7 @@ static cell AMX_NATIVE_CALL SetHookChainReturn(AMX *amx, cell *params) break; } case ATYPE_CLASSPTR: - retVal._classptr = CBaseEntity::Instance(INDEXENT(*srcAddr)); + retVal._classptr = getPrivate(*srcAddr); break; default: return FALSE; @@ -168,12 +164,11 @@ static cell AMX_NATIVE_CALL SetHookChainReturn(AMX *amx, cell *params) * * native GetHookChainReturn(AType:type, any:...); */ - -static cell AMX_NATIVE_CALL GetHookChainReturn(AMX *amx, cell *params) +cell AMX_NATIVE_CALL GetHookChainReturn(AMX *amx, cell *params) { if (!g_hookCtx) { - MF_LogError(amx, AMX_ERR_NATIVE, "Trying to get return value without active hook."); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: trying to get return value without active hook.", __FUNCTION__); return FALSE; } @@ -197,7 +192,7 @@ static cell AMX_NATIVE_CALL GetHookChainReturn(AMX *amx, cell *params) break; } case ATYPE_CLASSPTR: - *dstAddr = retVal._classptr->entindex(); + *dstAddr = indexOfEdict(retVal._classptr->pev); break; default: return FALSE; @@ -217,12 +212,11 @@ static cell AMX_NATIVE_CALL GetHookChainReturn(AMX *amx, cell *params) * * native SetHookChainArg(number, AType:type, any:...); */ - -static cell AMX_NATIVE_CALL SetHookChainArg(AMX *amx, cell *params) +cell AMX_NATIVE_CALL SetHookChainArg(AMX *amx, cell *params) { if (!g_hookCtx) { - MF_LogError(amx, AMX_ERR_NATIVE, "Trying to get return value without active hook."); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: trying to get return value without active hook.", __FUNCTION__); return FALSE; } @@ -231,7 +225,7 @@ static cell AMX_NATIVE_CALL SetHookChainArg(AMX *amx, cell *params) if (number >= g_hookCtx->args_count) { - MF_LogError(amx, AMX_ERR_NATIVE, "SetHookChainArg: can't set argument %i of hookchain with %i args.", params[arg_number], g_hookCtx->args_count); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: can't set argument %i of hookchain with %i args.", __FUNCTION__, params[arg_number], g_hookCtx->args_count); return FALSE; } @@ -239,7 +233,7 @@ static cell AMX_NATIVE_CALL SetHookChainArg(AMX *amx, cell *params) if (params[arg_type] != type) { - MF_LogError(amx, AMX_ERR_NATIVE, "SetHookChainArg: invalid argument type provided."); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: invalid argument type provided.", __FUNCTION__); return FALSE; } @@ -258,7 +252,7 @@ static cell AMX_NATIVE_CALL SetHookChainArg(AMX *amx, cell *params) *(char **)destAddr = getAmxStringTemp(srcAddr, temp_strings[number], sizeof temp_strings[0] - 1); break; case ATYPE_CLASSPTR: - *(CBaseEntity **)destAddr = CBaseEntity::Instance(INDEXENT(*srcAddr)); + *(CBaseEntity **)destAddr = getPrivate(*srcAddr); break; } @@ -282,5 +276,6 @@ AMX_NATIVE_INFO HookChain_Natives[] = void RegisterNatives_HookChains() { - g_amxxapi.AddNatives(HookChain_Natives); + if (api_cfg.hasReHLDS() || api_cfg.hasReGameDLL()) + g_amxxapi.AddNatives(HookChain_Natives); } diff --git a/reapi/src/natives/natives_members.cpp b/reapi/src/natives/natives_members.cpp index 401b8d9..fa98f8e 100644 --- a/reapi/src/natives/natives_members.cpp +++ b/reapi/src/natives/natives_members.cpp @@ -1,22 +1,22 @@ #include "precompiled.h" // native set_member(_index, any:_member, any:...); -static cell AMX_NATIVE_CALL set_member(AMX *amx, cell *params) +cell AMX_NATIVE_CALL set_member(AMX *amx, cell *params) { enum args_e { arg_count, arg_index, arg_member, arg_value, arg_elem }; member_t *member = memberlist[params[arg_member]]; if (member == nullptr) { - MF_LogError(amx, AMX_ERR_NATIVE, "set_member: unknown member id %i", params[arg_member]); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: unknown member id %i", __FUNCTION__, params[arg_member]); return FALSE; } - edict_t *pEdict = INDEXENT(params[arg_index]); + edict_t *pEdict = edictByIndexAmx(params[arg_index]); if (pEdict == nullptr || pEdict->pvPrivateData == nullptr) { - MF_LogError(amx, AMX_ERR_NATIVE, "set_member: invalid or uninitialized entity"); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: invalid or uninitialized entity", __FUNCTION__); return FALSE; } - + cell* value = getAmxAddr(amx, params[arg_value]); size_t element = (PARAMS_COUNT == 4) ? *getAmxAddr(amx, params[arg_elem]) : 0; @@ -24,19 +24,19 @@ static cell AMX_NATIVE_CALL set_member(AMX *amx, cell *params) } // native any:get_member(_index, any:_member, any:...); -static cell AMX_NATIVE_CALL get_member(AMX *amx, cell *params) +cell AMX_NATIVE_CALL get_member(AMX *amx, cell *params) { enum args_e { arg_count, arg_index, arg_member, arg_3, arg_4 }; member_t *member = memberlist[params[arg_member]]; if (member == nullptr) { - MF_LogError(amx, AMX_ERR_NATIVE, "get_member: unknown member id %i", params[arg_member]); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: unknown member id %i", __FUNCTION__, params[arg_member]); return FALSE; } - edict_t *pEdict = INDEXENT(params[arg_index]); + edict_t *pEdict = edictByIndexAmx(params[arg_index]); if (pEdict == nullptr || pEdict->pvPrivateData == nullptr) { - MF_LogError(amx, AMX_ERR_NATIVE, "get_member: invalid or uninitialized entity"); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: invalid or uninitialized entity", __FUNCTION__); return FALSE; } @@ -68,46 +68,46 @@ static cell AMX_NATIVE_CALL get_member(AMX *amx, cell *params) } // native set_member_game(any:_member, any:...); -static cell AMX_NATIVE_CALL set_member_game(AMX *amx, cell *params) +cell AMX_NATIVE_CALL set_member_game(AMX *amx, cell *params) { enum args_e { arg_count, arg_member, arg_value, arg_elem }; member_t *member = memberlist[params[arg_member]]; if (member == nullptr) { - MF_LogError(amx, AMX_ERR_NATIVE, "set_member_game: unknown member id %i", params[arg_member]); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: unknown member id %i", __FUNCTION__, params[arg_member]); return FALSE; } - if (g_pCSGameRules == nullptr || *g_pCSGameRules == nullptr) { - MF_LogError(amx, AMX_ERR_NATIVE, "get_member_game: gamerules not initialized"); + if (g_pGameRules == nullptr) { + MF_LogError(amx, AMX_ERR_NATIVE, "%s: gamerules not initialized", __FUNCTION__); return FALSE; } cell* value = getAmxAddr(amx, params[arg_value]); size_t element = (PARAMS_COUNT == 4) ? *getAmxAddr(amx, params[arg_elem]) : 0; - return set_member(*g_pCSGameRules, member, element, value); + return set_member(g_pGameRules, member, element, value); } // native get_member_game(any:_member, any:...); -static cell AMX_NATIVE_CALL get_member_game(AMX *amx, cell *params) +cell AMX_NATIVE_CALL get_member_game(AMX *amx, cell *params) { enum args_e { arg_count, arg_member, arg_3, arg_4 }; member_t *member = memberlist[params[arg_member]]; if (member == nullptr) { - MF_LogError(amx, AMX_ERR_NATIVE, "get_member_game: unknown member id %i", params[arg_member]); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: unknown member id %i", __FUNCTION__, params[arg_member]); return FALSE; } - if (g_pCSGameRules == nullptr || *g_pCSGameRules == nullptr) { - MF_LogError(amx, AMX_ERR_NATIVE, "get_member_game: gamerules not initialized"); + if (g_pGameRules == nullptr) { + MF_LogError(amx, AMX_ERR_NATIVE, "%s: gamerules not initialized", __FUNCTION__); return FALSE; } cell* dest; size_t element; - + if (PARAMS_COUNT == 4) { dest = getAmxAddr(amx, params[arg_3]); element = *getAmxAddr(amx, params[arg_4]); @@ -129,14 +129,14 @@ static cell AMX_NATIVE_CALL get_member_game(AMX *amx, cell *params) element = 0; } - return get_member(*g_pCSGameRules, member, element, dest); + return get_member(g_pGameRules, member, element, dest); } AMX_NATIVE_INFO Member_Natives[] = { { "set_member", set_member }, { "get_member", get_member }, - + { "set_member_game", set_member_game }, { "get_member_game", get_member_game }, @@ -145,7 +145,8 @@ AMX_NATIVE_INFO Member_Natives[] = void RegisterNatives_Members() { - g_amxxapi.AddNatives(Member_Natives); + if (api_cfg.hasReGameDLL()) + g_amxxapi.AddNatives(Member_Natives); } BOOL set_member(void* pdata, const member_t *member, size_t element, cell* value) @@ -154,7 +155,7 @@ BOOL set_member(void* pdata, const member_t *member, size_t element, cell* value case MEMBER_CLASSPTR: { // native set_member(_index, any:_member, _value, _elem); - CBaseEntity *pEntity = CBaseEntity::Instance(INDEXENT(*value)); + CBaseEntity *pEntity = getPrivate(*value); set_member(pdata, member->offset, pEntity, element); return TRUE; } @@ -162,14 +163,14 @@ BOOL set_member(void* pdata, const member_t *member, size_t element, cell* value { // native set_member(_index, any:_member, _value, _elem); EHANDLE& ehandle = get_member(pdata, member->offset, element); - edict_t *pEdictValue = INDEXENT(*value); + edict_t *pEdictValue = edictByIndexAmx(*value); ehandle.Set(pEdictValue); return TRUE; } case MEMBER_EDICT: { // native set_member(_index, any:_member, _value, _elem); - edict_t *pEdictValue = INDEXENT(*value); + edict_t *pEdictValue = edictByIndexAmx(*value); set_member(pdata, member->offset, pEdictValue, element); return TRUE; } @@ -253,14 +254,14 @@ cell get_member(void* pdata, const member_t *member, size_t element, cell* dest) { case MEMBER_CLASSPTR: // native any:get_member(_index, any:_member, element); - return get_member(pdata, member->offset, element)->entindex(); + return indexOfEdict(get_member(pdata, member->offset, element)->pev); case MEMBER_EHANDLE: { // native any:get_member(_index, any:_member, element); EHANDLE ehandle = get_member(pdata, member->offset, element); edict_t *pEntity = ehandle.Get(); if (pEntity != nullptr) { - return ENTINDEX(pEntity); + return indexOfEdict(pEntity); } return -1; } @@ -269,7 +270,7 @@ cell get_member(void* pdata, const member_t *member, size_t element, cell* dest) // native any:get_member(_index, any:_member, element); edict_t *pEntity = get_member(pdata, member->offset, element); if (pEntity != nullptr) { - return ENTINDEX(pEntity); + return indexOfEdict(pEntity); } return -1; @@ -280,11 +281,7 @@ cell get_member(void* pdata, const member_t *member, size_t element, cell* dest) if (!dest) return 0; - cell* vecSrc = get_member_direct(pdata, member->offset, element); - - dest[0] = vecSrc[0]; - dest[1] = vecSrc[1]; - dest[2] = vecSrc[2]; + dest = get_member_direct(pdata, member->offset, element); return 1; } case MEMBER_STRING: @@ -300,14 +297,14 @@ cell get_member(void* pdata, const member_t *member, size_t element, cell* dest) } else { // char * const char *src = get_member(pdata, member->offset); - if (src != nullptr) { - setAmxString(dest, src, element); - return 1; + if (src == nullptr) { + setAmxString(dest, "", 1); + return 0; } - setAmxString(dest, "", 1); + setAmxString(dest, src, element); } - return 0; + return 1; } case MEMBER_FLOAT: case MEMBER_INTEGER: diff --git a/reapi/src/natives/natives_misc.cpp b/reapi/src/natives/natives_misc.cpp index 5fe3c63..51e181f 100644 --- a/reapi/src/natives/natives_misc.cpp +++ b/reapi/src/natives/natives_misc.cpp @@ -10,16 +10,19 @@ * * native rg_set_animation(index, PLAYER_ANIM:playerAnim); */ -static cell AMX_NATIVE_CALL rg_set_animation(AMX *amx, cell *params) +cell AMX_NATIVE_CALL rg_set_animation(AMX *amx, cell *params) { enum args_e { arg_count, arg_index, arg_anim }; + CHECK_ISPLAYER(arg_index); + ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]); if (pPlayer == nullptr || !pPlayer->IsConnected()) { + MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]); return FALSE; } - pPlayer->SetAnimation(static_cast(params[arg_anim])); + pPlayer->SetAnimation(CAmxArg(amx, params[arg_anim])); return TRUE; } @@ -34,12 +37,15 @@ static cell AMX_NATIVE_CALL rg_set_animation(AMX *amx, cell *params) * * native rg_add_account(index, amount, bool:bTrackChange = true); */ -static cell AMX_NATIVE_CALL rg_add_account(AMX *amx, cell *params) +cell AMX_NATIVE_CALL rg_add_account(AMX *amx, cell *params) { enum args_e { arg_count, arg_index, arg_amount, arg_track_change }; + CHECK_ISPLAYER(arg_index); + ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]); if (pPlayer == nullptr || !pPlayer->IsConnected()) { + MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]); return FALSE; } @@ -57,13 +63,15 @@ static cell AMX_NATIVE_CALL rg_add_account(AMX *amx, cell *params) * * native rg_give_item(index, const pszName[]); */ -static cell AMX_NATIVE_CALL rg_give_item(AMX *amx, cell *params) +cell AMX_NATIVE_CALL rg_give_item(AMX *amx, cell *params) { enum args_e { arg_count, arg_index, arg_item }; - ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]); + CHECK_ISPLAYER(arg_index); + ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]); if (pPlayer == nullptr || !pPlayer->IsConnected()) { + MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]); return FALSE; } @@ -81,12 +89,15 @@ static cell AMX_NATIVE_CALL rg_give_item(AMX *amx, cell *params) * * native rg_give_default_items(index); */ -static cell AMX_NATIVE_CALL rg_give_default_items(AMX *amx, cell *params) +cell AMX_NATIVE_CALL rg_give_default_items(AMX *amx, cell *params) { enum args_e { arg_count, arg_index }; + CHECK_ISPLAYER(arg_index); + ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]); if (pPlayer == nullptr || !pPlayer->IsConnected()) { + MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]); return FALSE; } @@ -104,12 +115,15 @@ static cell AMX_NATIVE_CALL rg_give_default_items(AMX *amx, cell *params) * * native rg_give_shield(index, bool:bDeploy = true); */ -static cell AMX_NATIVE_CALL rg_give_shield(AMX *amx, cell *params) +cell AMX_NATIVE_CALL rg_give_shield(AMX *amx, cell *params) { enum args_e { arg_count, arg_index, arg_deploy }; + CHECK_ISPLAYER(arg_index); + ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]); if (pPlayer == nullptr || !pPlayer->IsConnected()) { + MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]); return FALSE; } @@ -132,17 +146,16 @@ static cell AMX_NATIVE_CALL rg_give_shield(AMX *amx, cell *params) * * native rg_dmg_radius(Float:vecSrc[3], inflictor, attacker, Float:flDamage, Float:flRadius, iClassIgnore, bitsDamageType); */ -static cell AMX_NATIVE_CALL rg_dmg_radius(AMX *amx, cell *params) +cell AMX_NATIVE_CALL rg_dmg_radius(AMX *amx, cell *params) { enum args_e { arg_count, arg_vec, arg_inflictor, arg_attacker, arg_damage, arg_radius, arg_ignore_class, arg_dmg_type }; - cell *pSrc = getAmxAddr(amx, params[arg_vec]); + CHECK_ISENTITY(arg_inflictor); + CHECK_ISENTITY(arg_attacker); - entvars_t *pevInflictor = VARS(INDEXENT(params[arg_inflictor])); - entvars_t *pevAttacker = VARS(INDEXENT(params[arg_attacker])); + CAmxArgs args(amx, params); + g_ReGameFuncs->RadiusDamage(args[arg_vec], args[arg_inflictor], args[arg_attacker], args[arg_damage], args[arg_radius], args[arg_ignore_class], args[arg_dmg_type]); - Vector vecSrc(*(float *)&pSrc[0], *(float *)&pSrc[1], *(float *)&pSrc[2]); - g_ReGameFuncs->RadiusDamage(vecSrc, pevInflictor, pevAttacker, *(float *)¶ms[arg_damage], *(float *)¶ms[arg_radius], params[arg_ignore_class], params[arg_dmg_type]); return TRUE; } @@ -153,7 +166,7 @@ static cell AMX_NATIVE_CALL rg_dmg_radius(AMX *amx, cell *params) * * native rg_multidmg_clear(); */ -static cell AMX_NATIVE_CALL rg_multidmg_clear(AMX *amx, cell *params) +cell AMX_NATIVE_CALL rg_multidmg_clear(AMX *amx, cell *params) { g_ReGameFuncs->ClearMultiDamage(); return TRUE; @@ -169,14 +182,16 @@ static cell AMX_NATIVE_CALL rg_multidmg_clear(AMX *amx, cell *params) * * native rg_multidmg_apply(inflictor, attacker); */ -static cell AMX_NATIVE_CALL rg_multidmg_apply(AMX *amx, cell *params) +cell AMX_NATIVE_CALL rg_multidmg_apply(AMX *amx, cell *params) { enum args_e { arg_count, arg_inflictor, arg_attacker }; - entvars_t *pevInflictor = VARS(INDEXENT(params[arg_inflictor])); - entvars_t *pevAttacker = VARS(INDEXENT(params[arg_attacker])); + CHECK_ISENTITY(arg_inflictor); + CHECK_ISENTITY(arg_attacker); + + CAmxArgs args(amx, params); + g_ReGameFuncs->ApplyMultiDamage(args[arg_inflictor], args[arg_attacker]); - g_ReGameFuncs->ApplyMultiDamage(pevInflictor, pevAttacker); return TRUE; } @@ -192,18 +207,21 @@ static cell AMX_NATIVE_CALL rg_multidmg_apply(AMX *amx, cell *params) * * native rg_multidmg_add(inflictor, victim, Float:flDamage, bitsDamageType); */ -static cell AMX_NATIVE_CALL rg_multidmg_add(AMX *amx, cell *params) +cell AMX_NATIVE_CALL rg_multidmg_add(AMX *amx, cell *params) { enum args_e { arg_count, arg_inflictor, arg_victim, arg_damage, arg_dmg_type }; - entvars_t *pevInflictor = VARS(INDEXENT(params[arg_inflictor])); - CBaseEntity *pVictim = g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_inflictor]); + CHECK_ISENTITY(arg_inflictor); + CHECK_ISENTITY(arg_victim); - if (pVictim == nullptr) { + if (params[arg_victim] < 0) { // null + MF_LogError(amx, AMX_ERR_NATIVE, "%s: victim == null", __FUNCTION__); return FALSE; } - g_ReGameFuncs->AddMultiDamage(pevInflictor, pVictim, *(float *)¶ms[arg_damage], params[arg_dmg_type]); + CAmxArgs args(amx, params); + g_ReGameFuncs->AddMultiDamage(args[arg_inflictor], args[arg_victim], args[arg_damage], args[arg_dmg_type]); + return TRUE; } @@ -225,33 +243,27 @@ static cell AMX_NATIVE_CALL rg_multidmg_add(AMX *amx, cell *params) * * native rg_fire_bullets(inflictor, attacker, shots, Float:vecSrc[3], Float:vecDirShooting[3], Float::vecSpread[3], Float:flDistance, iBulletType, iTracerFreq, iDamage); */ -static cell AMX_NATIVE_CALL rg_fire_bullets(AMX *amx, cell *params) +cell AMX_NATIVE_CALL rg_fire_bullets(AMX *amx, cell *params) { enum args_e { arg_count, arg_inflictor, arg_attacker, arg_shots, arg_vecSrc, arg_dir, arg_spread, arg_dist, arg_bullet_type, arg_tracefrq, arg_dmg }; - ICSEntity *pInflictor = g_ReGameFuncs->INDEX_TO_CSENTITY(params[arg_inflictor]); + CHECK_ISENTITY(arg_inflictor); + CHECK_ISENTITY(arg_attacker); - cell *pSrc = getAmxAddr(amx, params[arg_vecSrc]); - cell *pDir = getAmxAddr(amx, params[arg_dir]); - cell *pSpread = getAmxAddr(amx, params[arg_spread]); - - Vector vecSrc(*(float *)&pSrc[0], *(float *)&pSrc[1], *(float *)&pSrc[2]); - Vector vecDirShooting(*(float *)&pDir[0], *(float *)&pDir[1], *(float *)&pDir[2]); - Vector vecSpread(*(float *)&pSpread[0], *(float *)&pSpread[1], *(float *)&pSpread[2]); - - entvars_t *pevAttacker = VARS(INDEXENT(params[arg_attacker])); + CAmxArgs args(amx, params); + ICSEntity *pInflictor = args[arg_inflictor]; pInflictor->FireBullets ( - params[arg_shots], - vecSrc, - vecDirShooting, - vecSpread, - *(float *)¶ms[arg_dist], - params[arg_bullet_type], - params[arg_tracefrq], - params[arg_dmg], - pevAttacker + args[arg_shots], + args[arg_vecSrc], + args[arg_dir], + args[arg_spread], + args[arg_dist], + args[arg_bullet_type], + args[arg_tracefrq], + args[arg_dmg], + args[arg_attacker] ); return TRUE; @@ -277,35 +289,30 @@ static cell AMX_NATIVE_CALL rg_fire_bullets(AMX *amx, cell *params) * * native Float:[3] rg_fire_bullets3(inflictor, attacker, Float:vecSrc[3], Float:vecDirShooting[3], Float:vecSpread, Float:flDistance, iPenetration, iBulletType, iDamage, Float:flRangeModifier, bool:bPistol, shared_rand); */ -static cell AMX_NATIVE_CALL rg_fire_bullets3(AMX *amx, cell *params) +cell AMX_NATIVE_CALL rg_fire_bullets3(AMX *amx, cell *params) { enum args_e { arg_count, arg_inflictor, arg_attacker, arg_vecSrc, arg_dir, arg_spread, arg_dist, arg_penetration, arg_bullet_type, arg_dmg, arg_range_mod, arg_pistol, arg_rand, arg_out }; - ICSEntity *pInflictor = g_ReGameFuncs->INDEX_TO_CSENTITY(params[arg_inflictor]); + CHECK_ISENTITY(arg_inflictor); + CHECK_ISENTITY(arg_attacker); - cell *pSrc = getAmxAddr(amx, params[arg_vecSrc]); - cell *pDir = getAmxAddr(amx, params[arg_dir]); + CAmxArgs args(amx, params); + ICSEntity *pInflictor = args[arg_inflictor]; + entvars_t *pAttacker = args[arg_attacker]; - Vector vecSrc(*(float *)&pSrc[0], *(float *)&pSrc[1], *(float *)&pSrc[2]); - Vector vecDirShooting(*(float *)&pDir[0], *(float *)&pDir[1], *(float *)&pDir[2]); - - entvars_t *pevAttacker = VARS(INDEXENT(params[arg_attacker])); - - Vector *pOut = (Vector *)getAmxAddr(amx, params[arg_out]); - - *pOut = pInflictor->FireBullets3 + args[arg_out].vector() = pInflictor->FireBullets3 ( - vecSrc, - vecDirShooting, - *(float *)¶ms[arg_spread], - *(float *)¶ms[arg_dist], - params[arg_penetration], - params[arg_bullet_type], - params[arg_dmg], - *(float *)¶ms[arg_range_mod], - pevAttacker, - params[arg_pistol] != 0, - params[arg_rand] + args[arg_vecSrc], + args[arg_dir], + args[arg_spread], + args[arg_dist], + args[arg_penetration], + args[arg_bullet_type], + args[arg_dmg], + args[arg_range_mod], + pAttacker, // icc fix + args[arg_pistol], + args[arg_rand] ); return TRUE; @@ -348,13 +355,13 @@ struct { * * native rg_round_end(Float:tmDelay, WinStatus:st, ScenarioEventEndRound:event = ROUND_NONE, const message[] = "default", const sentence[] = "default"); */ -static cell AMX_NATIVE_CALL rg_round_end(AMX *amx, cell *params) +cell AMX_NATIVE_CALL rg_round_end(AMX *amx, cell *params) { enum args_e { arg_count, arg_delay, arg_win, arg_event, arg_message, arg_sentence, arg_silent }; size_t winstatus = params[arg_win]; if (winstatus <= 0) { - MF_LogError(amx, AMX_ERR_NATIVE, "rg_round_end: unknown win-status %i", winstatus); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: unknown win status %i", __FUNCTION__, winstatus); return FALSE; } @@ -378,7 +385,7 @@ static cell AMX_NATIVE_CALL rg_round_end(AMX *amx, cell *params) if (_message[0]) g_ReGameFuncs->EndRoundMessage(_message, event); - (*g_pCSGameRules)->TerminateRound(*(float *)¶ms[arg_delay], winstatus); + CSGameRules()->TerminateRound(CAmxArg(amx, params[arg_delay]), winstatus); return TRUE; } @@ -393,18 +400,308 @@ static cell AMX_NATIVE_CALL rg_round_end(AMX *amx, cell *params) * * native rg_update_teamscores(iCtsWins = 0, iTsWins = 0, bool:bAdd = true); */ -static cell AMX_NATIVE_CALL rg_update_teamscores(AMX *amx, cell *params) +cell AMX_NATIVE_CALL rg_update_teamscores(AMX *amx, cell *params) { enum args_e { arg_count, arg_cts, arg_ts, arg_add }; - (*g_pCSGameRules)->m_iNumCTWins = ((params[arg_add] != 0) ? (*g_pCSGameRules)->m_iNumCTWins : 0) + params[arg_cts]; - (*g_pCSGameRules)->m_iNumTerroristWins = ((params[arg_add] != 0) ? (*g_pCSGameRules)->m_iNumTerroristWins : 0) + params[arg_ts]; + CSGameRules()->m_iNumCTWins = ((params[arg_add] != 0) ? CSGameRules()->m_iNumCTWins : 0) + params[arg_cts]; + CSGameRules()->m_iNumTerroristWins = ((params[arg_add] != 0) ? CSGameRules()->m_iNumTerroristWins : 0) + params[arg_ts]; UpdateTeamScores(); return TRUE; } -AMX_NATIVE_INFO Misc_Natives[] = +/* +* Creates an entity using Counter-Strike's custom CreateNamedEntity wrapper. +* +* @param classname Entity class name +* +* @return Index of the created entity or 0 otherwise +* +* native rg_create_entity(const classname[]); +*/ +cell AMX_NATIVE_CALL rg_create_entity(AMX *amx, cell *params) +{ + enum args_e { arg_count, arg_classname }; + + string_t iClass = g_engfuncs.pfnAllocString(getAmxString(amx, params[arg_classname])); + edict_t *pEnt = g_ReGameFuncs->CREATE_NAMED_ENTITY2(iClass); + + if (pEnt != nullptr) + { + return indexOfEdict(pEnt); + } + + return 0; +} + +/* +* Finds an entity in the world using Counter-Strike's custom FindEntityByString wrapper. +* +* @param start_index Entity index to start searching from. -1 to start from the first entity +* @param classname Classname to search for +* +* @return Entity index > 0 if found, 0 otherwise +* +* native rg_find_ent_by_class(start_index, const classname[]); +*/ +cell AMX_NATIVE_CALL rg_find_ent_by_class(AMX *amx, cell *params) +{ + enum args_e { arg_count, arg_start_index, arg_classname }; + + CBaseEntity *pStartEntity = getPrivate(params[arg_start_index]); + const char* value = getAmxString(amx, params[arg_classname]); + CBaseEntity *pEntity = g_ReGameFuncs->UTIL_FindEntityByString(pStartEntity, "classname", value); + + if (pEntity != nullptr) + { + return indexOfEdict(pEntity->pev); + } + + return 0; +} + +/* +* Finds an entity in the world using Counter-Strike's custom FindEntityByString wrapper, matching by owner. +* +* @param start_index Entity index to start searching from. -1 to start from the first entity +* @param classname Classname to search for +* +* @return 1 if found, 0 otherwise +* +* native rg_find_ent_by_owner(&start_index, const classname[], owner); +*/ +cell AMX_NATIVE_CALL rg_find_ent_by_owner(AMX *amx, cell *params) +{ + enum args_e { arg_count, arg_start_index, arg_classname, arg_onwer }; + + CHECK_ISENTITY(arg_onwer); + + cell& startIndex = *getAmxAddr(amx, params[arg_start_index]); + const char* value = getAmxString(amx, params[arg_classname]); + edict_t* pOwner = edictByIndexAmx(params[arg_onwer]); + edict_t* pEntity = g_pEdicts + startIndex; + + for (int i = startIndex; i < gpGlobals->maxEntities; i++, pEntity++) + { + if (pEntity->v.owner != pOwner) + continue; + + // yet not allocated + if (!pEntity->pvPrivateData || pEntity->free) + continue; + + if (!strcmp(STRING(pEntity->v.classname), value)) + { + startIndex = i; + return TRUE; + } + } + + return FALSE; +} + +/* +* Returns some information about a weapon. +* +* @param weapon name or id Weapon id, see WEAPON_* constants or weapon_* name +* @param WpnInfo:type Info type, see WI_* constants +* +* @return Weapon information value +* @error If weapon_id and type are out of bound, an error will be thrown. +* +* native rg_get_weapon_info(any:...); +*/ +cell AMX_NATIVE_CALL rg_get_weapon_info(AMX *amx, cell *params) +{ + enum args_e { arg_count, arg_weapon_id, arg_type, arg_3, arg_4 }; + + WeaponIdType weaponID = static_cast(params[arg_weapon_id]); + WpnInfo info_type = static_cast(*getAmxAddr(amx, params[arg_type])); + + if (!GetWeaponInfoRange(weaponID) && info_type != WI_ID) + { + MF_LogError(amx, AMX_ERR_NATIVE, "%s: invalid weapon id %i", __FUNCTION__, weaponID); + return 0; + } + + WeaponInfoStruct* info = g_ReGameApi->GetGameData()->GetWeaponInfo(weaponID); + char* szWeaponName = getAmxString(amx, params[arg_weapon_id]); + + switch (info_type) + { + case WI_ID: + if (szWeaponName == nullptr) { + return WEAPON_NONE; + } + + _strlwr(szWeaponName); + for (int i = 0; i < MAX_WEAPONS; ++i) { + info = g_ReGameApi->GetGameData()->GetWeaponInfo(i); + if (info == nullptr || info->id == WEAPON_NONE) + continue; + + if (strcmp(info->entityName, szWeaponName) == 0) { + return info->id; + } + } + return WEAPON_NONE; + case WI_COST: + return info->cost; + case WI_CLIP_COST: + return info->clipCost; + case WI_BUY_CLIP_SIZE: + return info->buyClipSize; + case WI_GUN_CLIP_SIZE: + return info->gunClipSize; + case WI_MAX_ROUNDS: + return info->maxRounds; + case WI_AMMO_TYPE: + return info->ammoType; + case WI_NAME: + { + if (PARAMS_COUNT != arg_4) { + MF_LogError(amx, AMX_ERR_NATIVE, "%s: bad parameter count, got %i, expected %i", __FUNCTION__, PARAMS_COUNT, arg_4); + return -1; + } + + // native rg_get_weapon_info(id, WPINFO_NAME, output[], maxlength); + cell* dest = getAmxAddr(amx, params[arg_3]); + size_t length = *getAmxAddr(amx, params[arg_4]); + + if (info->entityName == nullptr) { + setAmxString(dest, "", 1); + return 0; + } + + setAmxString(dest, info->entityName, length); + return 1; + } + default: + MF_LogError(amx, AMX_ERR_NATIVE, "%s: unknown type statement %i, params count %i", __FUNCTION__, info_type, PARAMS_COUNT); + return -1; + } +} + +/* +* Sets specific values of weapons info. +* +* @param weapon_id Weapon id, see WEAPON_* constants +* @param type Info type, see WI_* constants +* +* @return 1 if successfully, 0 otherwise +* +* native rg_set_weapon_info(const {WeaponIdType,_}:weapon_id, WpnInfo:type, any:...); +*/ +cell AMX_NATIVE_CALL rg_set_weapon_info(AMX *amx, cell *params) +{ + enum args_e { arg_count, arg_weapon_id, arg_type, arg_value }; + + WeaponIdType weaponID = static_cast(params[arg_weapon_id]); + if (!GetWeaponInfoRange(weaponID)) + { + MF_LogError(amx, AMX_ERR_NATIVE, "%s: invalid weapon id %i", __FUNCTION__, weaponID); + return 0; + } + + cell* value = getAmxAddr(amx, params[arg_value]); + WeaponInfoStruct *info = g_ReGameApi->GetGameData()->GetWeaponInfo(weaponID); + WpnInfo info_type = static_cast(params[arg_type]); + + switch (info_type) + { + case WI_COST: + info->cost = *value; + break; + case WI_CLIP_COST: + info->clipCost = *value; + break; + case WI_BUY_CLIP_SIZE: + case WI_GUN_CLIP_SIZE: + case WI_MAX_ROUNDS: + case WI_AMMO_TYPE: + case WI_NAME: + MF_LogError(amx, AMX_ERR_NATIVE, "%s: this change will have no effect", __FUNCTION__); + return 0; + default: + MF_LogError(amx, AMX_ERR_NATIVE, "%s: unknown type statement %i, params count %i", __FUNCTION__, info_type, PARAMS_COUNT); + return 0; + } + + return 1; +} + +/* +* Remove all the player's stuff +* +* @param index Client index +* +* @noreturn +* +* native rg_remove_all_items(const index, bool:bRemoveSuit); +*/ +cell AMX_NATIVE_CALL rg_remove_all_items(AMX *amx, cell *params) +{ + enum args_e { arg_count, arg_index, arg_suit }; + + CHECK_ISPLAYER(arg_index); + + ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]); + if (pPlayer == nullptr || !pPlayer->IsConnected()) { + MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]); + return FALSE; + } + + pPlayer->RemoveAllItems(params[arg_suit] != 0); + return TRUE; +} + +/* +* Remove specifed the player's item by class name +* +* @param index Client index +* @param item_name Class name item +* +* @noreturn +* +* native rg_remove_item(const index, const item_name[]); +*/ +cell AMX_NATIVE_CALL rg_remove_item(AMX *amx, cell *params) +{ + enum args_e { arg_count, arg_index, arg_item_name }; + + CHECK_ISPLAYER(arg_index); + + CBasePlayer *pPlayer = (CBasePlayer *)g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]); + if (pPlayer == nullptr || pPlayer->has_disconnected) { + MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]); + return FALSE; + } + + const char* szItemName = getAmxString(amx, params[arg_item_name]); + for (auto pItem : pPlayer->m_rgpPlayerItems) + { + while (pItem != nullptr) + { + if (FClassnameIs(pItem->pev, szItemName)) + { + CBasePlayerWeapon *pWeapon = static_cast(pItem); + if (pWeapon->IsWeapon()) { + pWeapon->RetireWeapon(); + } + + pPlayer->RemovePlayerItem(pItem); + return TRUE; + } + + pItem = pItem->m_pNext; + } + } + + return FALSE; +} + +AMX_NATIVE_INFO Misc_Natives_RG[] = { { "rg_set_animation", rg_set_animation }, { "rg_add_account", rg_add_account }, @@ -423,10 +720,21 @@ AMX_NATIVE_INFO Misc_Natives[] = { "rg_round_end", rg_round_end }, { "rg_update_teamscores", rg_update_teamscores }, + { "rg_create_entity", rg_create_entity }, + { "rg_find_ent_by_class", rg_find_ent_by_class }, + { "rg_find_ent_by_owner", rg_find_ent_by_owner }, + + { "rg_get_weapon_info", rg_get_weapon_info }, + { "rg_set_weapon_info", rg_set_weapon_info }, + + { "rg_remove_all_items", rg_remove_all_items }, + { "rg_remove_item", rg_remove_item }, + { nullptr, nullptr } }; void RegisterNatives_Misc() { - g_amxxapi.AddNatives(Misc_Natives); + if (api_cfg.hasReGameDLL()) + g_amxxapi.AddNatives(Misc_Natives_RG); } diff --git a/reapi/src/natives/natives_misc.h b/reapi/src/natives/natives_misc.h index 9272719..3991dd2 100644 --- a/reapi/src/natives/natives_misc.h +++ b/reapi/src/natives/natives_misc.h @@ -1,3 +1,15 @@ #pragma once +enum WpnInfo +{ + WI_ID, + WI_COST, + WI_CLIP_COST, + WI_BUY_CLIP_SIZE, + WI_GUN_CLIP_SIZE, + WI_MAX_ROUNDS, + WI_AMMO_TYPE, + WI_NAME +}; + void RegisterNatives_Misc(); diff --git a/reapi/src/natives/natives_vtc.cpp b/reapi/src/natives/natives_vtc.cpp deleted file mode 100644 index 5e02a12..0000000 --- a/reapi/src/natives/natives_vtc.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "precompiled.h" - -/* -* Checks whether the player is talking at this moment -* -* @param index Client index -* @return 1 if client is speaking, 0 otherwise -* -* native VTC_IsClientSpeaking(index); -*/ -static cell AMX_NATIVE_CALL VTC_IsClientSpeaking(AMX *amx, cell *params) -{ - enum args_e { arg_count, arg_index }; - return g_pVoiceTranscoderApi->IsClientSpeaking((size_t)params[arg_index]); -} - -/* -* Mutes this player -* -* @param index Client index -* @noreturn -* -* native VTC_MuteClient(index); -*/ -static cell AMX_NATIVE_CALL VTC_MuteClient(AMX *amx, cell *params) -{ - enum args_e { arg_count, arg_index }; - g_pVoiceTranscoderApi->MuteClient((size_t)params[arg_index]); - - return FALSE; -} - -/* -* Unmutes this player -* -* @param index Client index -* @noreturn -* -* native VTC_UnmuteClient(index); -*/ -static cell AMX_NATIVE_CALL VTC_UnmuteClient(AMX *amx, cell *params) -{ - enum args_e { arg_count, arg_index }; - g_pVoiceTranscoderApi->UnmuteClient((size_t)params[arg_index]); - - return FALSE; -} - -AMX_NATIVE_INFO Vtc_Natives[] = -{ - { "VTC_IsClientSpeaking", VTC_IsClientSpeaking }, - { "VTC_MuteClient", VTC_MuteClient }, - { "VTC_UnmuteClient", VTC_UnmuteClient }, - - { nullptr, nullptr } -}; - -void RegisterNatives_Vtc() -{ - g_amxxapi.AddNatives(Vtc_Natives); -} diff --git a/reapi/src/natives/natives_vtc.h b/reapi/src/natives/natives_vtc.h deleted file mode 100644 index d77db48..0000000 --- a/reapi/src/natives/natives_vtc.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void RegisterNatives_Vtc(); diff --git a/reapi/src/precompiled.h b/reapi/src/precompiled.h index 3987e23..879c965 100644 --- a/reapi/src/precompiled.h +++ b/reapi/src/precompiled.h @@ -10,7 +10,6 @@ #include // std::vector #include -#include "reapi_utils.h" #include #include "osdep.h" // win32 vsnprintf, etc @@ -26,6 +25,9 @@ #include "regamedll_api.h" #include "mod_regamedll_api.h" +#include "main.h" +#include "reapi_utils.h" + // rehlds API #include "rehlds_api.h" #include "mod_rehlds_api.h" @@ -34,6 +36,10 @@ #include "vtc_api.h" #include "mod_vtc_api.h" +// Reunion API +#include "reunion_api.h" +#include "mod_reunion_api.h" + #include "api_config.h" #include "hook_manager.h" #include "hook_callback.h" @@ -42,7 +48,8 @@ #include "natives_hookchains.h" #include "natives_members.h" #include "natives_misc.h" -#include "natives_vtc.h" +#include "natives_addons.h" +#include "natives_helper.h" #undef DLLEXPORT #ifdef _WIN32 diff --git a/reapi/src/reapi_const.inc b/reapi/src/reapi_const.inc deleted file mode 100644 index 16c7a3b..0000000 --- a/reapi/src/reapi_const.inc +++ /dev/null @@ -1,8 +0,0 @@ -#if defined _reapi_const_included - #endinput -#endif -#define _reapi_const_included - -// reapi version -#define REAPI_VERISON_MAJOR 1 -#define REAPI_VERISON_MINOR 0 diff --git a/reapi/src/reapi_utils.cpp b/reapi/src/reapi_utils.cpp index 452fba6..7ac1c4b 100644 --- a/reapi/src/reapi_utils.cpp +++ b/reapi/src/reapi_utils.cpp @@ -2,16 +2,10 @@ void Broadcast(const char *sentence) { - char text[32]; + char text[128]; + snprintf(text, sizeof text, "%!MRAD_%s", sentence); - strcpy(text, "%!MRAD_"); - strcat(text, UTIL_VarArgs("%s", sentence)); - - static int gmsgSendAudio = 0; - if (gmsgSendAudio == 0 && !(gmsgSendAudio = REG_USER_MSG("SendAudio", -1))) - return; - - g_pengfuncsTable->pfnMessageBegin(MSG_BROADCAST, REG_USER_MSG("SendAudio", -1), NULL, NULL); + g_pengfuncsTable->pfnMessageBegin(MSG_BROADCAST, gmsgSendAudio, NULL, NULL); g_pengfuncsTable->pfnWriteByte(0); g_pengfuncsTable->pfnWriteString(text); g_pengfuncsTable->pfnWriteShort(100); @@ -20,17 +14,13 @@ void Broadcast(const char *sentence) void UpdateTeamScores() { - static int gmsgTeamScore = 0; - if (gmsgTeamScore == 0 && !(gmsgTeamScore = REG_USER_MSG("TeamScore", -1))) - return; - g_pengfuncsTable->pfnMessageBegin(MSG_ALL, gmsgTeamScore, NULL, NULL); g_pengfuncsTable->pfnWriteString("CT"); - g_pengfuncsTable->pfnWriteShort((*g_pCSGameRules)->m_iNumCTWins); + g_pengfuncsTable->pfnWriteShort(CSGameRules()->m_iNumCTWins); g_pengfuncsTable->pfnMessageEnd(); g_pengfuncsTable->pfnMessageBegin(MSG_ALL, gmsgTeamScore, NULL, NULL); g_pengfuncsTable->pfnWriteString("TERRORIST"); - g_pengfuncsTable->pfnWriteShort((*g_pCSGameRules)->m_iNumTerroristWins); + g_pengfuncsTable->pfnWriteShort(CSGameRules()->m_iNumTerroristWins); g_pengfuncsTable->pfnMessageEnd(); } diff --git a/reapi/src/reapi_utils.h b/reapi/src/reapi_utils.h index b2b91d2..6d03399 100644 --- a/reapi/src/reapi_utils.h +++ b/reapi/src/reapi_utils.h @@ -7,7 +7,10 @@ char(&ArraySizeHelper(T(&array)[N]))[N]; #define INDEXENT edictByIndex #define ENTINDEX indexOfEdict -extern edict_t* g_pEdicts; +#ifndef _WIN32 +#define _strlwr(p) for (int i = 0; p[i] != 0; i++) p[i] = tolower(p[i]); +#endif + extern enginefuncs_t* g_pengfuncsTable; inline size_t indexOfEdict(edict_t* ed) @@ -20,7 +23,15 @@ inline size_t indexOfEdict(entvars_t* pev) return indexOfEdict(pev->pContainingEntity); } -inline edict_t* edictByIndex(size_t index) +// safe to index -1 +inline edict_t* edictByIndexAmx(int index) +{ + auto ed = g_pEdicts + index; + return index < 0 ? nullptr : ed; +} + +// fast +inline edict_t* edictByIndex(int index) { return g_pEdicts + index; } @@ -28,12 +39,12 @@ inline edict_t* edictByIndex(size_t index) template T* getPrivate(int index) { - return (T *)edictByIndex(index)->pvPrivateData; + return (T *)GET_PRIVATE(edictByIndexAmx(index)); } inline entvars_t* PEV(int index) { - return &edictByIndex(index)->v; + return VARS(edictByIndexAmx(index)); } // HLTypeConversion.h -> AMXModX @@ -79,6 +90,17 @@ inline T get_member_direct(edict_t *pEntity, int offset, int element = 0, int si return get_member_direct(pEntity->pvPrivateData, offset, element, size); } +inline bool GetWeaponInfoRange(WeaponIdType wpnid) +{ + if (wpnid == WEAPON_SHIELDGUN) + return true; + + if (wpnid > WEAPON_NONE && wpnid != WEAPON_C4 && wpnid != WEAPON_KNIFE && wpnid <= WEAPON_P90) + return true; + + return false; +} + void Broadcast(const char *sentence); void UpdateTeamScores(); diff --git a/reapi/src/reapi_version.inc b/reapi/src/reapi_version.inc new file mode 100644 index 0000000..1183145 --- /dev/null +++ b/reapi/src/reapi_version.inc @@ -0,0 +1,8 @@ +#if defined _reapi_version_included + #endinput +#endif +#define _reapi_version_included + +// reapi version +#define REAPI_VERSION_MAJOR 1 +#define REAPI_VERSION_MINOR 0