2
0
mirror of https://github.com/rehlds/reapi.git synced 2024-12-28 15:45:31 +03:00

Reworked rg_give_item, now returns the index of the entity.

Add native rg_get_user_footsteps, rg_set_user_footsteps, rg_remove_items_by_slot, rg_drop_item, rg_internal_cmd
This commit is contained in:
s1lentq 2017-01-21 22:58:46 +07:00
parent 001d26c359
commit 799f0f8f82
6 changed files with 321 additions and 131 deletions

View File

@ -127,7 +127,7 @@ native rg_add_account(const index, amount, AccountSet:typeSet = AS_ADD, const bo
* @param pszName Classname item
* @param type Look at the enum's with name GiveType
*
* @return 1 if successfully, 0 otherwise
* @return Index of entity if successfully, -1 otherwise
*/
native rg_give_item(const index, const pszName[], GiveType:type = GT_APPEND);
@ -259,7 +259,7 @@ native rg_update_teamscores(const iCtsWins = 0, const iTsWins = 0, const bool:bA
/*
* Creates an entity using Counter-Strike's custom CreateNamedEntity wrapper.
*
* @param classname Entity class name
* @param classname Entity classname
* @param useHashTable Use this only for known game entities.
* NOTE: Do not use this if you use a custom classname.
*
@ -338,20 +338,55 @@ native any:rg_get_weapon_info(any:...);
native rg_set_weapon_info(const {WeaponIdType,_}:weapon_id, WpnInfo:type, any:...);
/*
* Remove all the player's stuff
* Remove all the player's stuff by specific slot.
*
* @param index Client index
* @param slot Specific slot for remove of each item.
*
* @noreturn
* @return 1 if successfully, 0 otherwise
*
*/
native rg_remove_all_items(const index, const bool:bRemoveSuit = false);
native rg_remove_items_by_slot(const index, const InventorySlotType:slot);
/*
* Remove specifed the player's item by class name
* Remove all the player's stuff.
*
* @param index Client index
* @param item_name Class name item
* @param removeSuit Remove suit
*
* @return 1 if successfully, 0 otherwise
*
*/
native rg_remove_all_items(const index, const bool:removeSuit = false);
/*
* Drop specifed the player's item by classname.
*
* @param index Client index
* @param item_name Classname of item
*
* @return 1 if successfully, 0 otherwise
*
*/
native rg_drop_item(const index, const item_name[]);
/*
* Execute a client command on the gamedll side.
*
* @param index Client index
* @param command Client command to execute on
* @param arg Optional command arguments
*
* @return 1 if successfully, 0 otherwise
*
*/
native rg_internal_cmd(const index, const cmd[], const arg[] = "");
/*
* Remove specifed the player's item by classname
*
* @param index Client index
* @param item_name Classname of item
*
* @return 1 if found and remove, 0 otherwise
*
@ -456,6 +491,27 @@ native rg_set_user_model(const index, const model[], const bool:update_index = f
*/
native rg_reset_user_model(const index);
/*
* Enable/Disable footsteps of the player.
*
* @param index Client index
* @param silent To enable silent footsteps of player's
*
* @return 1 if successfully, 0 otherwise
*
*/
native rg_set_user_footsteps(const index, bool:silent = false);
/*
* Get the current state footsteps of the player.
*
* @param index Client index
*
* @return 1 if have silent footsteps, 0 otherwise
*
*/
native rg_get_user_footsteps(const index);
/*
* Transfer C4 to player
*

View File

@ -42,7 +42,7 @@ static struct funcreq_t
//DECLARE_REQ(BuildPathname),
//DECLARE_REQ(BuildPathnameR),
DECLARE_REQ(GetAmxAddr),
//DECLARE_REQ(GetAmxVectorNull),
//DECLARE_REQ(GetAmxVectorNull), // AMXX 1.8.3-dev
//DECLARE_REQ(PrintSrvConsole),
//DECLARE_REQ(GetModname),
DECLARE_REQ(GetAmxScriptName),
@ -50,10 +50,10 @@ static struct funcreq_t
DECLARE_REQ(FindAmxScriptByAmx),
//DECLARE_REQ(FindAmxScriptByName),
DECLARE_REQ(SetAmxString),
//DECLARE_REQ(SetAmxStringUTF8Char),
//DECLARE_REQ(SetAmxStringUTF8Cell),
//DECLARE_REQ(SetAmxStringUTF8Char), // AMXX 1.8.3-dev
//DECLARE_REQ(SetAmxStringUTF8Cell), // AMXX 1.8.3-dev
DECLARE_REQ(GetAmxString),
//DECLARE_REQ(GetAmxStringNull),
//DECLARE_REQ(GetAmxStringNull), // AMXX 1.8.3-dev
//DECLARE_REQ(GetAmxStringLen),
//DECLARE_REQ(FormatAmxString),
//DECLARE_REQ(CopyAmxMemory),
@ -97,7 +97,7 @@ static struct funcreq_t
DECLARE_REQ(RegisterSPForward),
DECLARE_REQ(RegisterSPForwardByName),
DECLARE_REQ(UnregisterSPForward),
//DECLARE_REQ(MergeDefinition_File),
//DECLARE_REQ(MergeDefinitionFile),
//DECLARE_REQ(amx_FindNative),
//DECLARE_REQ(GetPlayerFlags),
//DECLARE_REQ(GetPlayerEdict),
@ -114,7 +114,7 @@ static struct funcreq_t
//DECLARE_REQ(RemoveLibraries),
//DECLARE_REQ(OverrideNatives),
//DECLARE_REQ(GetLocalInfo),
//DECLARE_REQ(AmxReRegister),
//DECLARE_REQ(AmxReregister),
//DECLARE_REQ(RegisterFunctionEx),
//DECLARE_REQ(MessageBlock),
};

View File

@ -8,24 +8,24 @@
#define decltypefx(cx, pref, dt, mx) decltype(cx::pref##mx)
#endif
#define CLASS_MEMBERS(cx, mx, postf, pref) ((!(postf & (MAX_REGION_RANGE - 1)) ? regmember::current_cell = 1, true : false) || (postf & (MAX_REGION_RANGE - 1)) == regmember::current_cell++) ? regmember([](member_t* ptr){ decltypefx(cx, pref, ., mx) f = {};ptr->size = getTypeSize(f);ptr->max_size = sizeof(f);ptr->offset = offsetof(##cx, ##pref##mx);ptr->type = getMemberType(f);ptr->name = #postf;}) : regmember(#pref#mx)
#define CLASS_MEMBERS(cx, mx, postf, pref, mtbl) ((!(postf & (MAX_REGION_RANGE - 1)) ? regmember::current_cell = 1, true : false) || (postf & (MAX_REGION_RANGE - 1)) == regmember::current_cell++) ? regmember([](member_t* ptr){ decltypefx(cx, pref, ., mx) f = {};ptr->size = getTypeSize(f);ptr->max_size = sizeof(f);ptr->offset = offsetof(##cx, ##pref##mx);ptr->type = getMemberType(f);ptr->name = #postf;ptr->table = memberlist_t::members_tables_e::mtbl;}) : regmember(#pref#mx)
#define GM_MEMBERS(mx) CLASS_MEMBERS(CHalfLifeMultiplay, mx, mx,)
#define GM_VOICE_MEMBERS(mx) CLASS_MEMBERS(CHalfLifeMultiplay, mx, mx, m_VoiceGameMgr.)
#define BASE_MEMBERS(mx) CLASS_MEMBERS(CBaseEntity, mx, mx,)
#define ANIM_MEMBERS(mx) CLASS_MEMBERS(CBaseAnimating, mx, mx,)
#define MONST_MEMBERS(mx) CLASS_MEMBERS(CBaseMonster, mx, mx,)
#define PL_MEMBERS(mx) CLASS_MEMBERS(CBasePlayer, mx, mx,)
#define EVAR_MEMBERS(mx) CLASS_MEMBERS(com_entvars, mx, var_##mx,)
#define PMOVE_MEMBERS(mx) CLASS_MEMBERS(com_playermove, mx, pm_##mx,)
#define MOVEVAR_MEMBERS(mx) CLASS_MEMBERS(movevars_t, mx, mv_##mx,)
#define UCMD_MEMBERS(mx) CLASS_MEMBERS(usercmd_s, mx, ucmd_##mx,)
#define PMTRACE_MEMBERS(mx) CLASS_MEMBERS(pmtrace_s, mx, pmt_##mx,)
#define CSPL_MEMBERS(mx) CLASS_MEMBERS(CCSPlayer, mx, mx,)
#define BASEITEM_MEMBERS(mx) CLASS_MEMBERS(CBasePlayerItem, mx, mx,)
#define BASEWPN_MEMBERS(mx) CLASS_MEMBERS(CBasePlayerWeapon, mx, m_Weapon_##mx, m_)
#define WPNBOX_MEMBERS(mx) CLASS_MEMBERS(CWeaponBox_COM, mx, m_WeaponBox_##mx, m_)
#define ARMOURY_MEMBERS(mx) CLASS_MEMBERS(CArmoury, mx, m_Armoury_##mx, m_)
#define GM_MEMBERS(mx) CLASS_MEMBERS(CHalfLifeMultiplay, mx, mx, , mt_gamerules)
#define GM_VOICE_MEMBERS(mx) CLASS_MEMBERS(CHalfLifeMultiplay, mx, mx, m_VoiceGameMgr., mt_gamerules)
#define BASE_MEMBERS(mx) CLASS_MEMBERS(CBaseEntity, mx, mx, , mt_base)
#define ANIM_MEMBERS(mx) CLASS_MEMBERS(CBaseAnimating, mx, mx, , mt_animating)
#define MONST_MEMBERS(mx) CLASS_MEMBERS(CBaseMonster, mx, mx, , mt_basemonster)
#define PL_MEMBERS(mx) CLASS_MEMBERS(CBasePlayer, mx, mx, , mt_player)
#define EVAR_MEMBERS(mx) CLASS_MEMBERS(com_entvars, mx, var_##mx, , mt_entvars)
#define PMOVE_MEMBERS(mx) CLASS_MEMBERS(com_playermove, mx, pm_##mx, , mt_playermove)
#define MOVEVAR_MEMBERS(mx) CLASS_MEMBERS(movevars_t, mx, mv_##mx, , mt_movevars)
#define UCMD_MEMBERS(mx) CLASS_MEMBERS(usercmd_s, mx, ucmd_##mx, , mt_usercmd)
#define PMTRACE_MEMBERS(mx) CLASS_MEMBERS(pmtrace_s, mx, pmt_##mx, , mt_pmtrace)
#define CSPL_MEMBERS(mx) CLASS_MEMBERS(CCSPlayer, mx, mx, , mt_csplayer)
#define BASEITEM_MEMBERS(mx) CLASS_MEMBERS(CBasePlayerItem, mx, mx, , mt_baseitem)
#define BASEWPN_MEMBERS(mx) CLASS_MEMBERS(CBasePlayerWeapon, mx, m_Weapon_##mx, m_, mt_baseweapon)
#define WPNBOX_MEMBERS(mx) CLASS_MEMBERS(CWeaponBox_COM, mx, m_WeaponBox_##mx, m_, mt_weaponbox)
#define ARMOURY_MEMBERS(mx) CLASS_MEMBERS(CArmoury, mx, m_Armoury_##mx, m_, mt_armoury)
inline MType getMemberType(float*) { return MEMBER_FLOAT; }
inline MType getMemberType(float) { return MEMBER_FLOAT; }

View File

@ -26,18 +26,9 @@ enum MType
MEBMER_USERCMD, // struct usercmd_s
};
struct member_t
{
uint16 size;
uint16 max_size;
uint32 offset;
const char *name;
MType type;
};
struct memberlist_t
{
member_t *operator[](size_t members) const;
struct member_t *operator[](size_t members) const;
enum members_tables_e
{
@ -59,6 +50,49 @@ struct memberlist_t
};
};
struct member_t
{
bool hasTable(memberlist_t::members_tables_e tbl) const;
bool isTypeReturnable() const;
uint16 size;
uint16 max_size;
uint32 offset;
const char *name;
MType type;
memberlist_t::members_tables_e table;
};
inline bool member_t::hasTable(memberlist_t::members_tables_e tbl) const
{
if (likely(table != tbl))
return false;
return true;
}
inline bool member_t::isTypeReturnable() const
{
switch (type) {
case MEMBER_FLOAT:
case MEMBER_DOUBLE:
case MEMBER_ENTITY:
case MEMBER_CLASSPTR:
case MEMBER_EDICT:
case MEMBER_INTEGER:
case MEMBER_SHORT:
case MEMBER_BYTE:
case MEMBER_BOOL:
case MEMBER_EVARS:
case MEMBER_PMTRACE:
case MEBMER_USERCMD:
return true;
default:
return false;
}
}
extern memberlist_t memberlist;
// CSGameRules

View File

@ -20,10 +20,9 @@ cell AMX_NATIVE_CALL set_member(AMX *amx, cell *params)
cell* value = getAmxAddr(amx, params[arg_value]);
size_t element = (PARAMS_COUNT == 4) ? *getAmxAddr(amx, params[arg_elem]) : 0;
const auto table = memberlist_t::members_tables_e(params[arg_member] / MAX_REGION_RANGE);
if (table == memberlist_t::mt_csplayer) {
CBasePlayer *pPlayer = UTIL_PlayerByIndex(indexOfEdict(pEdict));
if (unlikely(!pPlayer || !pPlayer->CSPlayer())) {
if (member->hasTable(memberlist_t::mt_csplayer)) {
CBasePlayer *pPlayer = (CBasePlayer *)pEdict->pvPrivateData;
if (unlikely(pPlayer->CSPlayer() == nullptr)) {
return FALSE;
}
@ -69,8 +68,7 @@ cell AMX_NATIVE_CALL get_member(AMX *amx, cell *params)
case 3:
{
cell* arg3 = getAmxAddr(amx, params[arg_3]);
if (isTypeReturnable(member->type)) {
if (member->isTypeReturnable()) {
dest = nullptr;
element = *arg3;
}
@ -88,10 +86,9 @@ cell AMX_NATIVE_CALL get_member(AMX *amx, cell *params)
break;
}
const auto table = memberlist_t::members_tables_e(params[arg_member] / MAX_REGION_RANGE);
if (table == memberlist_t::mt_csplayer) {
CBasePlayer *pPlayer = UTIL_PlayerByIndex(indexOfEdict(pEdict));
if (!pPlayer || !pPlayer->CSPlayer()) {
if (member->hasTable(memberlist_t::mt_csplayer)) {
CBasePlayer *pPlayer = (CBasePlayer *)pEdict->pvPrivateData;
if (unlikely(pPlayer->CSPlayer() == nullptr)) {
return FALSE;
}
@ -140,7 +137,7 @@ cell AMX_NATIVE_CALL get_member_game(AMX *amx, cell *params)
if (PARAMS_COUNT == 2)
{
cell* arg3 = getAmxAddr(amx, params[arg_2]);
if (isTypeReturnable(member->type)) {
if (member->isTypeReturnable()) {
dest = nullptr;
element = *arg3;
}
@ -213,7 +210,7 @@ cell AMX_NATIVE_CALL get_entvar(AMX *amx, cell *params)
else if (PARAMS_COUNT == 3) {
cell* arg3 = getAmxAddr(amx, params[arg_3]);
if (isTypeReturnable(member->type))
if (member->isTypeReturnable())
{
if (member->type == MEMBER_FLOAT) {
dest = arg3;
@ -702,25 +699,3 @@ cell get_member(void* pdata, const member_t *member, cell* dest, size_t element,
return 0;
}
bool isTypeReturnable(MType type)
{
switch (type) {
case MEMBER_FLOAT:
case MEMBER_DOUBLE:
case MEMBER_ENTITY:
case MEMBER_CLASSPTR:
case MEMBER_EDICT:
case MEMBER_INTEGER:
case MEMBER_SHORT:
case MEMBER_BYTE:
case MEMBER_BOOL:
case MEMBER_EVARS:
case MEMBER_PMTRACE:
case MEBMER_USERCMD:
return true;
default:
return false;
}
}

View File

@ -62,7 +62,7 @@ enum GiveType { GT_APPEND, GT_REPLACE, GT_DROP_AND_REPLACE };
* @param pszName Classname item
* @param type Look at the enum's with name GiveType
*
* @return 1 if successfully, 0 otherwise
* @return Index of entity if successfully, -1 otherwise
*
* native rg_give_item(index, const pszName[], GiveType:type = GT_APPEND);
*/
@ -81,36 +81,38 @@ cell AMX_NATIVE_CALL rg_give_item(AMX *amx, cell *params)
if (type > GT_APPEND) {
auto pInfo = g_ReGameApi->GetWeaponSlot(itemName);
if (pInfo != nullptr)
if (pInfo)
{
auto pItem = pPlayer->m_rgpPlayerItems[ pInfo->slot ];
while (pItem != nullptr) {
if (pItem->m_iId == pInfo->id) {
pItem = pItem->m_pNext;
continue;
}
switch (type)
pPlayer->ForEachItem(pInfo->slot, [pPlayer, pInfo, type](CBasePlayerItem *pItem)
{
if (pItem->m_iId != pInfo->id)
{
case GT_DROP_AND_REPLACE:
pPlayer->CSPlayer()->DropPlayerItem(STRING(pItem->pev->classname));
break;
case GT_REPLACE:
pPlayer->pev->weapons &= ~(1 << pItem->m_iId);
pPlayer->RemovePlayerItem(pItem);
pItem->Kill();
break;
case GT_APPEND: break;
default: break;
switch (type)
{
case GT_DROP_AND_REPLACE:
pPlayer->CSPlayer()->DropPlayerItem(STRING(pItem->pev->classname));
break;
case GT_REPLACE:
pPlayer->pev->weapons &= ~(1 << pItem->m_iId);
pPlayer->RemovePlayerItem(pItem);
pItem->Kill();
break;
case GT_APPEND:
default:
break;
}
}
pItem = pItem->m_pNext;
}
return false;
});
}
}
pPlayer->CSPlayer()->GiveNamedItemEx(itemName);
return TRUE;
auto pEntity = pPlayer->CSPlayer()->GiveNamedItemEx(itemName);
if (pEntity)
return indexOfPDataAmx(pEntity);
return AMX_NULLENT;
}
/*
@ -388,7 +390,7 @@ cell AMX_NATIVE_CALL rg_round_end(AMX *amx, cell *params)
CHECK_GAMERULES();
size_t winstatus = params[arg_win];
auto winstatus = params[arg_win];
if (winstatus <= 0) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: unknown win status %i", __FUNCTION__, winstatus);
return FALSE;
@ -411,9 +413,7 @@ cell AMX_NATIVE_CALL rg_round_end(AMX *amx, cell *params)
if (_sentence[0])
Broadcast(_sentence);
if (_message[0])
CSGameRules()->EndRoundMessage(_message, event);
CSGameRules()->EndRoundMessage(_message, event);
CSGameRules()->TerminateRound(CAmxArg(amx, params[arg_delay]), winstatus);
return TRUE;
}
@ -445,7 +445,7 @@ cell AMX_NATIVE_CALL rg_update_teamscores(AMX *amx, cell *params)
/*
* Creates an entity using Counter-Strike's custom CreateNamedEntity wrapper.
*
* @param classname Entity class name
* @param classname Entity classname
* @param useHashTable Use this only for known game entities.
* NOTE: Do not use this if you use a custom classname.
*
@ -786,14 +786,44 @@ cell AMX_NATIVE_CALL rg_set_weapon_info(AMX *amx, cell *params)
return 1;
}
/*
* Remove all the player's stuff by specific slot.
*
* @param index Client index
* @param slot Specific slot for remove of each item.
*
* @return 1 if successfully, 0 otherwise
*
* native rg_remove_items_by_slot(const index, const InventorySlotType:slot);
*/
cell AMX_NATIVE_CALL rg_remove_items_by_slot(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index, arg_slot };
CHECK_ISPLAYER(arg_index);
CBasePlayer *pPlayer = UTIL_PlayerByIndex(params[arg_index]);
CHECK_CONNECTED(pPlayer, arg_index);
pPlayer->ForEachItem(params[arg_slot], [pPlayer](CBasePlayerItem *pItem) {
pPlayer->pev->weapons &= ~(1 << pItem->m_iId);
pPlayer->RemovePlayerItem(pItem);
pItem->Kill();
return false;
});
return TRUE;
}
/*
* Remove all the player's stuff
*
* @param index Client index
* @param removeSuit Remove suit
*
* @noreturn
* @return 1 if successfully, 0 otherwise
*
* native rg_remove_all_items(const index, const bool:bRemoveSuit);
* native rg_remove_all_items(const index, const bool:removeSuit = false);
*/
cell AMX_NATIVE_CALL rg_remove_all_items(AMX *amx, cell *params)
{
@ -809,12 +839,60 @@ cell AMX_NATIVE_CALL rg_remove_all_items(AMX *amx, cell *params)
}
/*
* Remove specifed the player's item by class name
* Drop specifed the player's item by classname.
*
* @param index Client index
* @param item_name Class name item
* @param item_name Classname of item
*
* @noreturn
* @return 1 if successfully, 0 otherwise
*
* native rg_drop_item(const index, const item_name[]);
*/
cell AMX_NATIVE_CALL rg_drop_item(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index, arg_item_name };
CHECK_ISPLAYER(arg_index);
CBasePlayer *pPlayer = UTIL_PlayerByIndex(params[arg_index]);
CHECK_CONNECTED(pPlayer, arg_index);
pPlayer->CSPlayer()->DropPlayerItem(getAmxString(amx, params[arg_item_name]));
return TRUE;
}
/*
* Execute a client command on the gamedll side.
*
* @param index Client index
* @param command Client command to execute on
* @param arg Optional command arguments
*
* @return 1 if successfully, 0 otherwise
*
* native rg_internal_cmd(const index, const cmd[], const arg[] = "");
*/
cell AMX_NATIVE_CALL rg_internal_cmd(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index, arg_cmd, arg_arg };
CHECK_ISPLAYER(arg_index);
CBasePlayer *pPlayer = UTIL_PlayerByIndex(params[arg_index]);
CHECK_CONNECTED(pPlayer, arg_index);
pPlayer->CSPlayer()->ClientCommand(getAmxString(amx, params[arg_cmd]), getAmxString(amx, params[arg_arg]));
return TRUE;
}
/*
* Remove specifed the player's item by classname.
*
* @param index Client index
* @param item_name Classname of item
*
* @return 1 if successfully, 0 otherwise
*
* native rg_remove_item(const index, const item_name[]);
*/
@ -861,16 +939,12 @@ cell AMX_NATIVE_CALL rg_get_user_bpammo(AMX *amx, cell *params)
return FALSE;
}
for (auto pItem : pPlayer->m_rgpPlayerItems)
{
while (pItem != nullptr)
{
if (pItem->m_iId == weaponId) {
return pPlayer->m_rgAmmo[ static_cast<CBasePlayerWeapon *>(pItem)->m_iPrimaryAmmoType ];
}
auto itemFound = (CBasePlayerWeapon *)pPlayer->ForEachItem([pPlayer, weaponId](CBasePlayerItem *pItem) {
return pItem->m_iId == weaponId;
});
pItem = pItem->m_pNext;
}
if (itemFound) {
return (cell)pPlayer->m_rgAmmo[ itemFound->m_iPrimaryAmmoType ];
}
return FALSE;
@ -903,17 +977,13 @@ cell AMX_NATIVE_CALL rg_set_user_bpammo(AMX *amx, cell *params)
return FALSE;
}
for (auto pItem : pPlayer->m_rgpPlayerItems)
{
while (pItem != nullptr)
{
if (pItem->m_iId == weaponId) {
pPlayer->m_rgAmmo[ static_cast<CBasePlayerWeapon *>(pItem)->m_iPrimaryAmmoType ] = params[arg_amount];
return TRUE;
}
auto itemFound = (CBasePlayerWeapon *)pPlayer->ForEachItem([pPlayer, weaponId](CBasePlayerItem *pItem) {
return pItem->m_iId == weaponId;
});
pItem = pItem->m_pNext;
}
if (itemFound) {
pPlayer->m_rgAmmo[ itemFound->m_iPrimaryAmmoType ] = params[arg_amount];
return TRUE;
}
return FALSE;
@ -1185,6 +1255,57 @@ cell AMX_NATIVE_CALL rg_reset_user_model(AMX *amx, cell *params)
return TRUE;
}
/*
* Enable/Disable footsteps of the player.
*
* @param index Client index
* @param silent To enable silent footsteps of player's
*
* @return 1 if successfully, 0 otherwise
*
* native rg_set_user_footsteps(const index, bool:silent = false);
*/
cell AMX_NATIVE_CALL rg_set_user_footsteps(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index, arg_silent };
CHECK_ISPLAYER(arg_index);
CBasePlayer *pPlayer = UTIL_PlayerByIndex(params[arg_index]);
CHECK_CONNECTED(pPlayer, arg_index);
if (params[arg_silent]) {
pPlayer->m_flTimeStepSound = 999;
pPlayer->pev->flTimeStepSound = 999;
} else {
pPlayer->m_flTimeStepSound = 0;
pPlayer->pev->flTimeStepSound = 400;
}
return TRUE;
}
/*
* Get the current state footsteps of the player.
*
* @param index Client index
*
* @return 1 if have silent footsteps, 0 otherwise
*
* native rg_get_user_footsteps(const index);
*/
cell AMX_NATIVE_CALL rg_get_user_footsteps(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index };
CHECK_ISPLAYER(arg_index);
CBasePlayer *pPlayer = UTIL_PlayerByIndex(params[arg_index]);
CHECK_CONNECTED(pPlayer, arg_index);
return (cell)(pPlayer->m_flTimeStepSound == 999);
}
/*
* Transfer C4 to player
*
@ -1654,22 +1775,26 @@ AMX_NATIVE_INFO Misc_Natives_RG[] =
{ "rg_get_weapon_info", rg_get_weapon_info },
{ "rg_set_weapon_info", rg_set_weapon_info },
{ "rg_remove_items_by_slot", rg_remove_items_by_slot },
{ "rg_remove_all_items", rg_remove_all_items },
{ "rg_remove_item", rg_remove_item },
{ "rg_drop_item", rg_drop_item },
{ "rg_internal_cmd", rg_internal_cmd },
{ "rg_give_defusekit", rg_give_defusekit },
{ "rg_get_user_bpammo", rg_get_user_bpammo },
{ "rg_set_user_bpammo", rg_set_user_bpammo },
{ "rg_give_defusekit", rg_give_defusekit },
{ "rg_get_user_armor", rg_get_user_armor },
{ "rg_set_user_armor", rg_set_user_armor },
{ "rg_set_user_team", rg_set_user_team },
{ "rg_set_user_model", rg_set_user_model },
{ "rg_reset_user_model", rg_reset_user_model },
{ "rg_set_user_footsteps", rg_set_user_footsteps },
{ "rg_get_user_footsteps", rg_get_user_footsteps },
{ "rg_transfer_c4", rg_transfer_c4 },
{ "rg_instant_reload_weapons", rg_instant_reload_weapons },