diff --git a/reapi/extra/amxmodx/scripting/include/reapi_gamedll.inc b/reapi/extra/amxmodx/scripting/include/reapi_gamedll.inc index dd855c0..a6e65ce 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,58 @@ 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 Entity index > 0 if found, 0 otherwise +* +*/ +native rg_find_ent_by_owner(start_index, const classname[], owner); + +/** +* Returns some information about a weapon. +* +* @param weapon_id Weapon id, see WEAPON_* constants +* @param type Info type, see WPINFO_* 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(const {WeaponIdType,_}:weapon_id, WpnInfo:type, any:...); + +/** +* 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..425e399 100644 --- a/reapi/extra/amxmodx/scripting/include/reapi_gamedll_const.inc +++ b/reapi/extra/amxmodx/scripting/include/reapi_gamedll_const.inc @@ -11,6 +11,54 @@ #define SIGNAL_ESCAPE (1<<3) #define SIGNAL_VIPSAFETY (1<<4) +enum WeaponIdType +{ + WEAPON_NONE, + WEAPON_P228, + WEAPON_GLOCK, + WEAPON_SCOUT, + WEAPON_HEGRENADE, + WEAPON_XM1014, + WEAPON_C4, + WEAPON_MAC10, + WEAPON_AUG, + WEAPON_SMOKEGRENADE, + WEAPON_ELITE, + WEAPON_FIVESEVEN, + WEAPON_UMP45, + WEAPON_SG550, + WEAPON_GALIL, + WEAPON_FAMAS, + WEAPON_USP, + WEAPON_GLOCK18, + WEAPON_AWP, + WEAPON_MP5N, + WEAPON_M249, + WEAPON_M3, + WEAPON_M4A1, + WEAPON_TMP, + WEAPON_G3SG1, + WEAPON_FLASHBANG, + WEAPON_DEAGLE, + WEAPON_SG552, + WEAPON_AK47, + WEAPON_KNIFE, + WEAPON_P90, + WEAPON_SHIELDGUN = 99 +}; + +/* Weapon info types for use with rg_get_weapon_info() */ +enum WpnInfo +{ + WPINFO_COST, + WPINFO_CLIP_COST, + WPINFO_BUY_CLIP_SIZE, + WPINFO_GUN_CLIP_SIZE, + WPINFO_MAX_ROUNDS, + WPINFO_AMMO_TYPE, + WPINFO_NAME +}; + enum WinStatus { WINSTATUS_CTS = 1, @@ -19,7 +67,7 @@ enum WinStatus }; // used for EndRoundMessage() logged messages -enum ScenarionEventEndRound +enum ScenarioEventEndRound { ROUND_NONE, ROUND_TARGET_BOMB, @@ -78,10 +126,16 @@ enum GamedllFunc /** * Description: - - * Params: (WinStatus:status, ScenarionEventEndRound:event, Float:tmDelay) + * Params: (WinStatus:status, ScenarioEventEndRound:event, Float:tmDelay) */ RG_RoundEnd, + /** + * Description: - + * Params: (const index, const iWeapon) + */ + RG_CanBuyThis, + // [...] RG_End }; diff --git a/reapi/extra/amxmodx/scripting/include/reapi_misc.inc b/reapi/extra/amxmodx/scripting/include/reapi_misc.inc index 91886f0..7b6a559 100644 --- a/reapi/extra/amxmodx/scripting/include/reapi_misc.inc +++ b/reapi/extra/amxmodx/scripting/include/reapi_misc.inc @@ -3,6 +3,46 @@ #endif #define _reapi_misc_included +enum client_auth +{ + /** + * Description: - + * Return type: int + * Params: get_client_data(const index, CA_PROTOCOL) + */ + CA_PROTOCOL, + + /** + * Description: - + * Return type: client_auth_type + * Params: get_client_data(const index, CA_TYPE) + */ + CA_TYPE, + + /** + * Description: - + * Return type: - + * Params: get_client_data(const index, CA_STRING, output[], maxlength) + */ + CA_STRING, +}; + +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 * @@ -43,3 +83,11 @@ forward VTC_OnClientStartSpeak(index); * @noreturn */ forward VTC_OnClientStopSpeak(index); + +/* +* Get out information of the client +* +* @param index Client index +* @type to look enum client_auth +*/ +native get_client_data(const index, client_auth:type, any:...); diff --git a/reapi/include/cssdk/dlls/regamedll_api.h b/reapi/include/cssdk/dlls/regamedll_api.h index 1f6ea12..dda1fc2 100644 --- a/reapi/include/cssdk/dlls/regamedll_api.h +++ b/reapi/include/cssdk/dlls/regamedll_api.h @@ -174,6 +174,14 @@ typedef IVoidHookChainRegistry 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,8 @@ 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); + struct WeaponInfoStruct *(*GetWeaponInfo)(int weaponID); }; class IReGameApi { diff --git a/reapi/include/cssdk/dlls/regamedll_interfaces.h b/reapi/include/cssdk/dlls/regamedll_interfaces.h index e2d3fd0..8abddd4 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 { 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 593bb2c..21d4318 100644 --- a/reapi/msvc/reapi.vcxproj +++ b/reapi/msvc/reapi.vcxproj @@ -204,6 +204,7 @@ + @@ -243,6 +244,7 @@ + diff --git a/reapi/msvc/reapi.vcxproj.filters b/reapi/msvc/reapi.vcxproj.filters index 0bc343b..8b17e67 100644 --- a/reapi/msvc/reapi.vcxproj.filters +++ b/reapi/msvc/reapi.vcxproj.filters @@ -648,6 +648,9 @@ src + + src\mods + @@ -725,6 +728,9 @@ src\natives + + src\mods + diff --git a/reapi/src/api_config.cpp b/reapi/src/api_config.cpp index 54bc442..583257d 100644 --- a/reapi/src/api_config.cpp +++ b/reapi/src/api_config.cpp @@ -2,28 +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) { } 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(); -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 500b395..488cd73 100644 --- a/reapi/src/api_config.h +++ b/reapi/src/api_config.h @@ -11,8 +11,8 @@ public: 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/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..043ad57 100644 --- a/reapi/src/hook_callback.cpp +++ b/reapi/src/hook_callback.cpp @@ -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 dfdf1f1..82ddb31 100644 --- a/reapi/src/hook_list.cpp +++ b/reapi/src/hook_list.cpp @@ -73,7 +73,8 @@ hook_t hooklist_gamedll[] = { DLL(GetForceCamera), DLL(PlayerBlind), DLL(RadiusFlash_TraceLine), - DLL(RoundEnd) + DLL(RoundEnd), + DLL(CanBuyThis) }; hook_t hooklist_animating[] = { @@ -141,7 +142,6 @@ void hooklist_t::clear() h.clear(); } - void hook_t::clear() { if (pre.size() || post.size()) { diff --git a/reapi/src/hook_list.h b/reapi/src/hook_list.h index 3024150..355dada 100644 --- a/reapi/src/hook_list.h +++ b/reapi/src/hook_list.h @@ -79,6 +79,7 @@ enum GamedllFunc RG_PlayerBlind, RG_RadiusFlash_TraceLine, RG_RoundEnd, + RG_CanBuyThis, // [...] RG_End diff --git a/reapi/src/main.cpp b/reapi/src/main.cpp index 52b2e95..eea0c48 100644 --- a/reapi/src/main.cpp +++ b/reapi/src/main.cpp @@ -24,6 +24,10 @@ void OnMetaDetach() g_pVoiceTranscoderApi->ClientStartSpeak()->unregisterCallback(&ClientStartSpeak); g_pVoiceTranscoderApi->ClientStopSpeak()->unregisterCallback(&ClientStopSpeak); } + + if (api_cfg.hasReGameDLL()) { + g_ReGameHookchains->InstallGameRules()->unregisterHook(&InstallGameRules); + } } void ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax) @@ -31,15 +35,19 @@ void ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax) g_pEdicts = pEdictList; gmsgSendAudio = GET_USER_MSG_ID(PLID, "SendAudio", NULL); gmsgTeamScore = GET_USER_MSG_ID(PLID, "TeamScore", NULL); - api_cfg.ServerActivate(); 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 index 7d06d20..3a7033c 100644 --- a/reapi/src/main.h +++ b/reapi/src/main.h @@ -10,3 +10,4 @@ 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/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_hookchains.cpp b/reapi/src/natives/natives_hookchains.cpp index bff5a0a..a6712d0 100644 --- a/reapi/src/natives/natives_hookchains.cpp +++ b/reapi/src/natives/natives_hookchains.cpp @@ -197,7 +197,7 @@ 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; diff --git a/reapi/src/natives/natives_members.cpp b/reapi/src/natives/natives_members.cpp index cacdbc0..adee8fb 100644 --- a/reapi/src/natives/natives_members.cpp +++ b/reapi/src/natives/natives_members.cpp @@ -16,7 +16,7 @@ cell AMX_NATIVE_CALL set_member(AMX *amx, cell *params) MF_LogError(amx, AMX_ERR_NATIVE, "set_member: invalid or uninitialized entity"); return FALSE; } - + cell* value = getAmxAddr(amx, params[arg_value]); size_t element = (PARAMS_COUNT == 4) ? *getAmxAddr(amx, params[arg_elem]) : 0; @@ -78,7 +78,7 @@ cell AMX_NATIVE_CALL set_member_game(AMX *amx, cell *params) return FALSE; } - if (g_pCSGameRules == nullptr || *g_pCSGameRules == nullptr) { + if (g_pGameRules == nullptr) { MF_LogError(amx, AMX_ERR_NATIVE, "get_member_game: gamerules not initialized"); return FALSE; } @@ -86,7 +86,7 @@ cell AMX_NATIVE_CALL set_member_game(AMX *amx, cell *params) 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:...); @@ -100,14 +100,14 @@ cell AMX_NATIVE_CALL get_member_game(AMX *amx, cell *params) return FALSE; } - if (g_pCSGameRules == nullptr || *g_pCSGameRules == nullptr) { + if (g_pGameRules == nullptr) { MF_LogError(amx, AMX_ERR_NATIVE, "get_member_game: gamerules not initialized"); 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 @@ 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 }, @@ -254,7 +254,7 @@ 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); diff --git a/reapi/src/natives/natives_misc.cpp b/reapi/src/natives/natives_misc.cpp index 4b86208..e8146f5 100644 --- a/reapi/src/natives/natives_misc.cpp +++ b/reapi/src/natives/natives_misc.cpp @@ -21,7 +21,7 @@ cell AMX_NATIVE_CALL rg_set_animation(AMX *amx, cell *params) MF_LogError(amx, AMX_ERR_NATIVE, "player %i is not connected", params[arg_index]); return FALSE; } - + pPlayer->SetAnimation(CAmxArg(amx, params[arg_anim])); return TRUE; } @@ -94,7 +94,7 @@ cell AMX_NATIVE_CALL rg_give_default_items(AMX *amx, cell *params) enum args_e { arg_count, arg_index }; CHECK_ISPLAYER(params[arg_index]); - + ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]); if (pPlayer == nullptr || !pPlayer->IsConnected()) { MF_LogError(amx, AMX_ERR_NATIVE, "player %i is not connected", params[arg_index]); @@ -384,7 +384,7 @@ cell AMX_NATIVE_CALL rg_round_end(AMX *amx, cell *params) if (_message[0]) g_ReGameFuncs->EndRoundMessage(_message, event); - (*g_pCSGameRules)->TerminateRound(CAmxArg(amx, params[arg_delay]), winstatus); + CSGameRules()->TerminateRound(CAmxArg(amx, params[arg_delay]), winstatus); return TRUE; } @@ -403,13 +403,227 @@ 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; } +/* +* 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) +{ + //g_ReGameFuncs->CREATE_NAMED_ENTITY2(); + 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 (!FNullEnt(pEnt)) + { + return ENTINDEX(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 && !FNullEnt(pEntity->edict())) + { + 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 Entity index > 0 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(params[arg_onwer]); + + CBaseEntity *pEntity = getPrivate(params[arg_start_index]); + const char* value = getAmxString(amx, params[arg_classname]); + + edict_t *pOwner = edictByIndex(params[arg_onwer]); + while ((pEntity = g_ReGameFuncs->UTIL_FindEntityByString(pEntity, "classname", value)) != nullptr) + { + if (pEntity != nullptr && !FNullEnt(pEntity->edict()) && pEntity->pev->owner == pOwner) + { + return indexOfEdict(pEntity->pev); + } + } + + return 0; +} + +/** +* Returns some information about a weapon. +* +* @param weapon_id Weapon id, see WEAPON_* constants +* @param type Info type, see WPINFO_* 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(const {WeaponIdType,_}:weapon_id, WpnInfo:type, 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 }; + + int weapon_id = params[arg_weapon_id]; + if (weapon_id <= WEAPON_NONE || weapon_id == WEAPON_C4 || weapon_id == WEAPON_KNIFE || weapon_id > WEAPON_P90) + { + MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %i", weapon_id); + return 0; + } + + WeaponInfoStruct *info = g_ReGameFuncs->GetWeaponInfo(weapon_id); + WpnInfo info_type = static_cast(params[arg_type]); + + switch (info_type) + { + case WPINFO_COST: + return info->cost; + case WPINFO_CLIP_COST: + return info->clipCost; + case WPINFO_BUY_CLIP_SIZE: + return info->buyClipSize; + case WPINFO_GUN_CLIP_SIZE: + return info->gunClipSize; + case WPINFO_MAX_ROUNDS: + return info->maxRounds; + case WPINFO_AMMO_TYPE: + return info->ammoType; + case WPINFO_NAME: + { + if (PARAMS_COUNT != arg_4) { + MF_LogError(amx, AMX_ERR_NATIVE, "rg_get_weapon_info: bad parameter count, got %i, expected %i", 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]); + setAmxString(dest, info->entityName, length); + return 1; + } + default: + { + MF_LogError(amx, AMX_ERR_NATIVE, "rg_get_weapon_info: unknown type statement %i, params count %i", info_type, PARAMS_COUNT); + return -1; + } + } +} + +/** +* Remove all the player's stuff +* +* @param index Client index +* +* @noreturn +* +* native rg_remove_all_items(const index, bool:bRemove); +*/ +cell AMX_NATIVE_CALL rg_remove_all_items(AMX *amx, cell *params) +{ + enum args_e { arg_count, arg_index, arg_suit }; + + CHECK_ISPLAYER(params[arg_index]); + + ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]); + if (pPlayer == nullptr || !pPlayer->IsConnected()) { + MF_LogError(amx, AMX_ERR_NATIVE, "player %i is not connected", 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(params[arg_index]); + + CBasePlayer *pPlayer = (CBasePlayer *)g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_index]); + if (pPlayer == nullptr || pPlayer->has_disconnected) { + MF_LogError(amx, AMX_ERR_NATIVE, "player %i is not connected", params[arg_index]); + return FALSE; + } + + const char* szItemName = getAmxString(amx, params[arg_item_name]); + for (auto& item : pPlayer->m_rgpPlayerItems) + { + CBasePlayerItem *pItem = item; + 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 }, @@ -429,6 +643,97 @@ AMX_NATIVE_INFO Misc_Natives_RG[] = { "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_remove_all_items", rg_remove_all_items }, + { "rg_remove_item", rg_remove_item }, + + { nullptr, nullptr } +}; + +enum client_auth +{ + /** + * Description: - + * Return type: int + * Params: get_client_data(const index, CA_PROTOCOL) + */ + CA_PROTOCOL, + + /** + * Description: - + * Return type: client_auth_type + * Params: get_client_data(const index, CA_TYPE) + */ + CA_TYPE, + + /** + * Description: - + * Return type: - + * Params: get_client_data(const index, CA_STRING, output[], maxlength) + */ + CA_STRING, +}; + +/* +* Get out information of the client +* +* @param index Client index +* @type to look enum client_auth +* +* native get_client_data(const index, client_auth:type, any:...); +*/ +cell AMX_NATIVE_CALL get_client_data(AMX *amx, cell *params) +{ + enum args_e { arg_count, arg_index, arg_type, arg_3, arg_4 }; + + CHECK_ISPLAYER(params[arg_index]); + + client_auth type = static_cast(params[arg_type]); + switch (type) + { + case CA_PROTOCOL: + { + // native get_client_data(id, CA_PROTOCOL); + return g_ReunionApi->GetClientProtocol(params[arg_index] - 1); + } + case CA_TYPE: + { + // native client_auth_type:get_client_data(id, CA_TYPE); + return g_ReunionApi->GetClientAuthtype(params[arg_index] - 1); + } + case CA_STRING: + { + if (PARAMS_COUNT != arg_4) { + MF_LogError(amx, AMX_ERR_NATIVE, "get_client_data: bad parameter count, got %i, expected %i", PARAMS_COUNT, arg_4); + return -1; + } + + // native get_client_data(id, CA_STRING, output[], maxlength); + cell* dest = getAmxAddr(amx, params[arg_3]); + size_t length = *getAmxAddr(amx, params[arg_4]); + + char data[128]; + g_ReunionApi->GetClientAuthdataString(params[arg_index] - 1, data, sizeof data); + setAmxString(dest, data, length); + + return 1; + } + default: + { + MF_LogError(amx, AMX_ERR_NATIVE, "get_client_data: unknown type statement %i, params count %i", type, PARAMS_COUNT); + return -1; + } + } +} + +AMX_NATIVE_INFO Misc_Natives_Reunion[] = +{ + { "get_client_data", get_client_data }, + { nullptr, nullptr } }; @@ -436,4 +741,7 @@ void RegisterNatives_Misc() { if (api_cfg.hasReGameDLL()) g_amxxapi.AddNatives(Misc_Natives_RG); + + if (api_cfg.hasReunion()) + g_amxxapi.AddNatives(Misc_Natives_Reunion); } diff --git a/reapi/src/natives/natives_misc.h b/reapi/src/natives/natives_misc.h index 9272719..e2ca32b 100644 --- a/reapi/src/natives/natives_misc.h +++ b/reapi/src/natives/natives_misc.h @@ -1,3 +1,14 @@ #pragma once +enum WpnInfo +{ + WPINFO_COST, + WPINFO_CLIP_COST, + WPINFO_BUY_CLIP_SIZE, + WPINFO_GUN_CLIP_SIZE, + WPINFO_MAX_ROUNDS, + WPINFO_AMMO_TYPE, + WPINFO_NAME +}; + void RegisterNatives_Misc(); diff --git a/reapi/src/precompiled.h b/reapi/src/precompiled.h index 12f71de..99b87d8 100644 --- a/reapi/src/precompiled.h +++ b/reapi/src/precompiled.h @@ -10,8 +10,6 @@ #include // std::vector #include -#include "main.h" -#include "reapi_utils.h" #include #include "osdep.h" // win32 vsnprintf, etc @@ -27,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" @@ -35,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" diff --git a/reapi/src/reapi_utils.cpp b/reapi/src/reapi_utils.cpp index 73a5cc1..7ac1c4b 100644 --- a/reapi/src/reapi_utils.cpp +++ b/reapi/src/reapi_utils.cpp @@ -16,11 +16,11 @@ void UpdateTeamScores() { 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(); }