diff --git a/modules/cstrike/cstrike/CstrikeItemsInfos.cpp b/modules/cstrike/cstrike/CstrikeItemsInfos.cpp index 36018e8c..44644bd5 100644 --- a/modules/cstrike/cstrike/CstrikeItemsInfos.cpp +++ b/modules/cstrike/cstrike/CstrikeItemsInfos.cpp @@ -15,7 +15,7 @@ #include "CstrikeHacks.h" CsItemInfo ItemsManager; -char WeaponNameList[MAX_WEAPONS][64]; +ItemInfo WeaponsList[MAX_WEAPONS]; #define PSTATE_ALIASES_TYPE 0 #define PSTATE_ALIASES_ALIAS 1 @@ -200,9 +200,9 @@ bool CsItemInfo::GetAliasInfosFromName(const char *name, AliasInfo *info) name += prefix_item_length + 1; } - for (size_t id = 0; id < ARRAYSIZE(WeaponNameList); ++id) + for (size_t id = 0; id < ARRAYSIZE(WeaponsList); ++id) { - const char *weapon = WeaponNameList[id]; + const char *weapon = WeaponsList[id].name.chars(); if (weapon[prefix_weapon_length] == '_' && !strncmp(weapon, prefix_weapon, prefix_weapon_length)) { diff --git a/modules/cstrike/cstrike/CstrikeItemsInfos.h b/modules/cstrike/cstrike/CstrikeItemsInfos.h index e3d886e9..294843a9 100644 --- a/modules/cstrike/cstrike/CstrikeItemsInfos.h +++ b/modules/cstrike/cstrike/CstrikeItemsInfos.h @@ -20,6 +20,37 @@ #include #include +struct ItemInfo +{ + ItemInfo() : name("Empty"), ammoIndex1(-1), maxAmmo1(0), ammoIndex2(-1), maxAmmo2(0), slot(0), position(0), id(0), flags(0) + {} + + ItemInfo &operator = (ItemInfo &other) + { + name = other.name; + ammoIndex1 = other.ammoIndex1; + maxAmmo1 = other.maxAmmo1; + ammoIndex2 = other.ammoIndex2; + maxAmmo2 = other.maxAmmo2; + slot = other.slot; + position = other.position; + id = other.id; + flags = other.flags; + + return *this; + } + + ke::AString name; + int ammoIndex1; + int maxAmmo1; + int ammoIndex2; + int maxAmmo2; + int slot; + int position; + int id; + int flags; +}; + struct AliasInfo { AliasInfo() @@ -102,7 +133,7 @@ class CsItemInfo : public ITextListener_SMC int m_EquipmentsPrice[static_cast(Equipments::Count)]; }; -extern char WeaponNameList[MAX_WEAPONS][64]; +extern ItemInfo WeaponsList[MAX_WEAPONS]; extern CsItemInfo ItemsManager; #endif // _CSTRIKE_WEAPONS_INFOS_H_ diff --git a/modules/cstrike/cstrike/CstrikeNatives.cpp b/modules/cstrike/cstrike/CstrikeNatives.cpp index 47b3386c..8bb65684 100644 --- a/modules/cstrike/cstrike/CstrikeNatives.cpp +++ b/modules/cstrike/cstrike/CstrikeNatives.cpp @@ -115,7 +115,7 @@ static cell AMX_NATIVE_CALL cs_get_hostage_id(AMX *amx, cell *params) int index = params[1]; CHECK_NONPLAYER(index); - edict_t *pHostage = INDEXENT(index); + edict_t *pHostage = TypeConversion.id_to_edict(index); CHECK_HOSTAGE(pHostage); @@ -131,7 +131,7 @@ static cell AMX_NATIVE_CALL cs_get_weapon_silenced(AMX *amx, cell *params) int index = params[1]; CHECK_NONPLAYER(index); - edict_t *pWeapon = INDEXENT(index); + edict_t *pWeapon = TypeConversion.id_to_edict(index); switch (get_pdata(pWeapon, m_iId)) { @@ -162,7 +162,7 @@ static cell AMX_NATIVE_CALL cs_get_weapon_id(AMX *amx, cell *params) int index = params[1]; CHECK_NONPLAYER(index); - edict_t *pWeapon = INDEXENT(index); + edict_t *pWeapon = TypeConversion.id_to_edict(index); return get_pdata(pWeapon, m_iId); } @@ -177,7 +177,7 @@ static cell AMX_NATIVE_CALL cs_set_weapon_silenced(AMX *amx, cell *params) int silence = params[2]; CHECK_NONPLAYER(index); - edict_t *pWeapon = INDEXENT(index); + edict_t *pWeapon = TypeConversion.id_to_edict(index); int draw_animation = 1; @@ -231,7 +231,7 @@ static cell AMX_NATIVE_CALL cs_set_weapon_silenced(AMX *amx, cell *params) if (draw_animation > 0 && UTIL_IsPlayer(pPlayer)) { - int currentWeapon = *static_cast(MF_PlayerPropAddr(ENTINDEX(pPlayer), Player_CurrentWeapon)); + int currentWeapon = *static_cast(MF_PlayerPropAddr(TypeConversion.edict_to_id(pPlayer), Player_CurrentWeapon)); if (currentWeapon != weaponType) { @@ -299,7 +299,7 @@ static cell AMX_NATIVE_CALL cs_get_weapon_burstmode(AMX *amx, cell *params) int index = params[1]; CHECK_NONPLAYER(index); - edict_t *pWeapon = INDEXENT(index); + edict_t *pWeapon = TypeConversion.id_to_edict(index); int flag = 0; @@ -327,7 +327,7 @@ static cell AMX_NATIVE_CALL cs_set_weapon_burstmode(AMX *amx, cell *params) int burst = params[2]; CHECK_NONPLAYER(index); - edict_t *pWeapon = INDEXENT(index); + edict_t *pWeapon = TypeConversion.id_to_edict(index); int weaponState = get_pdata(pWeapon, m_iWeaponState); int weaponNewState = weaponState; @@ -731,81 +731,46 @@ static cell AMX_NATIVE_CALL cs_set_user_defusekit(AMX *amx, cell *params) // native cs_get_user_bpammo(index, weapon); static cell AMX_NATIVE_CALL cs_get_user_backpackammo(AMX *amx, cell *params) { - GET_OFFSET("CBasePlayer" , m_rgpPlayerItems ); - GET_OFFSET("CBasePlayer" , m_rgAmmo ); - GET_OFFSET("CBasePlayerItem" , m_pNext ); - GET_OFFSET("CBasePlayerItem" , m_iId ); - GET_OFFSET("CBasePlayerWeapon", m_iPrimaryAmmoType); + GET_OFFSET("CBasePlayer", m_rgAmmo); - int index = params[1]; + int index = params[1]; int weaponId = params[2]; CHECK_PLAYER(index); - edict_t *pPlayer = MF_GetPlayerEdict(index); - if (weaponId < CSW_P228 || weaponId > CSW_P90 || weaponId == CSW_KNIFE) + int ammoIndex; + + if (weaponId <= CSW_NONE || weaponId >= MAX_WEAPONS || (ammoIndex = WeaponsList[weaponId].ammoIndex1) < 0) { - MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %d", params[2]); + MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %d", weaponId); return 0; } - for (size_t i = 0; i < MAX_WEAPON_SLOTS; ++i) - { - uintptr_t *pItem = get_pdata(pPlayer, m_rgpPlayerItems, i); - - while (pItem) - { - if (weaponId == get_pdata(pItem, m_iId)) - { - return get_pdata(pPlayer, m_rgAmmo, get_pdata(pItem, m_iPrimaryAmmoType)); - } - - pItem = get_pdata(pItem, m_pNext); - } - } - - return 0; + return get_pdata(MF_GetPlayerEdict(index), m_rgAmmo, ammoIndex); } // native cs_set_user_bpammo(index, weapon, amount); static cell AMX_NATIVE_CALL cs_set_user_backpackammo(AMX *amx, cell *params) { - GET_OFFSET("CBasePlayer" , m_rgpPlayerItems ); - GET_OFFSET("CBasePlayer" , m_rgAmmo ); - GET_OFFSET("CBasePlayerItem" , m_pNext ); - GET_OFFSET("CBasePlayerItem" , m_iId ); - GET_OFFSET("CBasePlayerWeapon", m_iPrimaryAmmoType); + GET_OFFSET("CBasePlayer", m_rgAmmo); int index = params[1]; int weaponId = params[2]; int amount = params[3]; CHECK_PLAYER(index); - edict_t *pPlayer = MF_GetPlayerEdict(index); - if (weaponId < CSW_P228 || weaponId > CSW_P90 || weaponId == CSW_KNIFE) + int ammoIndex; + + if (weaponId <= CSW_NONE || weaponId >= MAX_WEAPONS || (ammoIndex = WeaponsList[weaponId].ammoIndex1) < 0) { - MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %d", params[2]); + MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %d", weaponId); return 0; } - for (size_t i = 0; i < MAX_WEAPON_SLOTS; ++i) - { - uintptr_t *pItem = get_pdata(pPlayer, m_rgpPlayerItems, i); + set_pdata(MF_GetPlayerEdict(index), m_rgAmmo, amount, ammoIndex); - while (pItem) - { - if (weaponId == get_pdata(pItem, m_iId)) - { - set_pdata(pPlayer, m_rgAmmo, amount, get_pdata(pItem, m_iPrimaryAmmoType)); - return 1; - } - - pItem = get_pdata(pItem, m_pNext); - } - } - - return 0; + return 1; } // native cs_get_user_nvg(index); @@ -943,7 +908,7 @@ static cell AMX_NATIVE_CALL cs_get_hostage_follow(AMX *amx, cell *params) int index = params[1]; CHECK_NONPLAYER(index); - edict_t* pHostage = INDEXENT(index); + edict_t* pHostage = TypeConversion.id_to_edict(index); CHECK_HOSTAGE(pHostage); @@ -967,7 +932,7 @@ static cell AMX_NATIVE_CALL cs_get_hostage_follow(AMX *amx, cell *params) pEntity = get_pdata(pHostage, m_hTargetEnt).Get(); } - return pEntity ? ENTINDEX(pEntity) : 0; + return pEntity ? TypeConversion.edict_to_id(pEntity) : 0; } // native cs_set_hostage_foll(index, followedindex = 0); @@ -980,7 +945,7 @@ static cell AMX_NATIVE_CALL cs_set_hostage_follow(AMX *amx, cell *params) int target = params[2]; CHECK_NONPLAYER(index); - edict_t* pHostage = INDEXENT(index); + edict_t* pHostage = TypeConversion.id_to_edict(index); if (target != 0) { @@ -1031,7 +996,7 @@ static cell AMX_NATIVE_CALL cs_get_weapon_ammo(AMX *amx, cell *params) int index = params[1]; CHECK_NONPLAYER(index); - edict_t *pWeapon = INDEXENT(index); + edict_t *pWeapon = TypeConversion.id_to_edict(index); return get_pdata(pWeapon, m_iClip); } @@ -1045,7 +1010,7 @@ static cell AMX_NATIVE_CALL cs_set_weapon_ammo(AMX *amx, cell *params) int ammo = params[2]; CHECK_NONPLAYER(index); - edict_t *pWeapon = INDEXENT(index); + edict_t *pWeapon = TypeConversion.id_to_edict(index); set_pdata(pWeapon, m_iClip, ammo); @@ -1220,7 +1185,7 @@ static cell AMX_NATIVE_CALL cs_get_armoury_type(AMX *amx, cell *params) int index = params[1]; CHECK_NONPLAYER(index); - edict_t *pArmoury = INDEXENT(index); + edict_t *pArmoury = TypeConversion.id_to_edict(index); if (strcmp(STRING(pArmoury->v.classname), "armoury_entity")) { @@ -1278,7 +1243,7 @@ static cell AMX_NATIVE_CALL cs_set_armoury_type(AMX *amx, cell *params) int type = params[2]; CHECK_NONPLAYER(index); - edict_t *pArmoury = INDEXENT(index); + edict_t *pArmoury = TypeConversion.id_to_edict(index); if (strcmp(STRING(pArmoury->v.classname), "armoury_entity")) { @@ -1544,7 +1509,7 @@ static cell AMX_NATIVE_CALL cs_get_hostage_lastuse(AMX *amx, cell *params) int index = params[1]; CHECK_NONPLAYER(index); - edict_t *pHostage = INDEXENT(index); + edict_t *pHostage = TypeConversion.id_to_edict(index); CHECK_HOSTAGE(pHostage); @@ -1570,7 +1535,7 @@ static cell AMX_NATIVE_CALL cs_set_hostage_lastuse(AMX *amx, cell *params) int index = params[1]; CHECK_NONPLAYER(index); - edict_t *pHostage = INDEXENT(index); + edict_t *pHostage = TypeConversion.id_to_edict(index); CHECK_HOSTAGE(pHostage); @@ -1597,7 +1562,7 @@ static cell AMX_NATIVE_CALL cs_get_hostage_nextuse(AMX* amx, cell* params) int index = params[1]; CHECK_NONPLAYER(index); - edict_t *pHostage = INDEXENT(index); + edict_t *pHostage = TypeConversion.id_to_edict(index); CHECK_HOSTAGE(pHostage); @@ -1612,7 +1577,7 @@ static cell AMX_NATIVE_CALL cs_set_hostage_nextuse(AMX* amx, cell* params) int index = params[1]; CHECK_NONPLAYER(index); - edict_t *pHostage = INDEXENT(index); + edict_t *pHostage = TypeConversion.id_to_edict(index); CHECK_HOSTAGE(pHostage); @@ -1629,7 +1594,7 @@ static cell AMX_NATIVE_CALL cs_get_c4_explode_time(AMX* amx, cell* params) int index = params[1]; CHECK_NONPLAYER(index); - edict_t *pC4 = INDEXENT(index); + edict_t *pC4 = TypeConversion.id_to_edict(index); if (strcmp(STRING(pC4->v.classname), "grenade") != 0) { @@ -1648,7 +1613,7 @@ static cell AMX_NATIVE_CALL cs_set_c4_explode_time(AMX* amx, cell* params) int index = params[1]; CHECK_NONPLAYER(index); - edict_t *pC4 = INDEXENT(index); + edict_t *pC4 = TypeConversion.id_to_edict(index); if (strcmp(STRING(pC4->v.classname), "grenade") != 0) { @@ -1669,7 +1634,7 @@ static cell AMX_NATIVE_CALL cs_get_c4_defusing(AMX* amx, cell* params) int index = params[1]; CHECK_NONPLAYER(index); - edict_t *pC4 = INDEXENT(index); + edict_t *pC4 = TypeConversion.id_to_edict(index); if (strcmp(STRING(pC4->v.classname), "grenade") != 0) { @@ -1688,7 +1653,7 @@ static cell AMX_NATIVE_CALL cs_set_c4_defusing(AMX* amx, cell* params) int index = params[1]; CHECK_NONPLAYER(index); - edict_t *pC4 = INDEXENT(index); + edict_t *pC4 = TypeConversion.id_to_edict(index); if (strcmp(STRING(pC4->v.classname), "grenade") != 0) { @@ -1717,7 +1682,7 @@ static cell AMX_NATIVE_CALL cs_create_entity(AMX* amx, cell* params) if (!FNullEnt(pEnt)) { - return ENTINDEX(pEnt); + return TypeConversion.edict_to_id(pEnt); } return 0; @@ -1903,13 +1868,13 @@ static cell AMX_NATIVE_CALL cs_get_translated_item_alias(AMX* amx, cell* params) default: { // weapon_* retrieved from WeaponList messages at map change. - name = WeaponNameList[info.itemid]; + name = WeaponsList[info.itemid].name.chars(); break; } } } - MF_SetAmxString(amx, params[2], alias, params[3]); + MF_SetAmxString(amx, params[2], name, params[3]); return info.itemid != CSI_NONE; } @@ -1924,40 +1889,41 @@ static cell AMX_NATIVE_CALL cs_get_weapon_info(AMX* amx, cell* params) } int weapon_id = params[1]; + int info_type = params[2]; - if (weapon_id <= CSW_NONE || weapon_id == CSW_C4 || weapon_id == CSW_KNIFE || weapon_id > CSW_LAST_WEAPON) + WeaponInfoStruct *info; + + if (weapon_id <= CSW_NONE || weapon_id > CSW_LAST_WEAPON || !(info = GetWeaponInfo(weapon_id))) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id: %d", weapon_id); return 0; } - int info_type = params[2]; - switch (info_type) { case CS_WEAPONINFO_COST: { - return GetWeaponInfo(weapon_id)->cost; + return info->cost; } case CS_WEAPONINFO_CLIP_COST: { - return GetWeaponInfo(weapon_id)->clipCost; + return info->clipCost; } case CS_WEAPONINFO_BUY_CLIP_SIZE: { - return GetWeaponInfo(weapon_id)->buyClipSize; + return info->buyClipSize; } case CS_WEAPONINFO_GUN_CLIP_SIZE: { - return GetWeaponInfo(weapon_id)->gunClipSize; + return info->gunClipSize; } case CS_WEAPONINFO_MAX_ROUNDS: { - return GetWeaponInfo(weapon_id)->maxRounds; + return info->maxRounds; } case CS_WEAPONINFO_AMMO_TYPE: { - return GetWeaponInfo(weapon_id)->ammoType; + return info->ammoType; } } diff --git a/modules/cstrike/cstrike/CstrikePlayer.cpp b/modules/cstrike/cstrike/CstrikePlayer.cpp index 05099bce..690d1a90 100644 --- a/modules/cstrike/cstrike/CstrikePlayer.cpp +++ b/modules/cstrike/cstrike/CstrikePlayer.cpp @@ -18,7 +18,7 @@ ke::Vector ModelsUpdateQueue; void ClientDisconnect(edict_t *pEntity) { - int index = ENTINDEX(pEntity); + int index = TypeConversion.edict_to_id(pEntity); Players[index].ResetModel(); Players[index].ResetZoom(); @@ -30,7 +30,7 @@ void ClientUserInfoChanged(edict_t *pEntity, char *infobuffer) { if (pEntity->pvPrivateData) { - Players[ENTINDEX(pEntity)].UpdateModel(pEntity); + Players[TypeConversion.edict_to_id(pEntity)].UpdateModel(pEntity); } RETURN_META(MRES_IGNORED); diff --git a/modules/cstrike/cstrike/CstrikePlayer.h b/modules/cstrike/cstrike/CstrikePlayer.h index 8fdd34bf..c3bf2e60 100644 --- a/modules/cstrike/cstrike/CstrikePlayer.h +++ b/modules/cstrike/cstrike/CstrikePlayer.h @@ -70,7 +70,7 @@ class CPlayer { MDLL_ClientUserInfoChanged(pPlayer, GETINFOKEYBUFFER(pPlayer)); - PostponeModelUpdate(ENTINDEX(pPlayer) - 1); + PostponeModelUpdate(TypeConversion.edict_to_id(pPlayer) - 1); } } @@ -85,7 +85,7 @@ class CPlayer if (strcmp(GETCLIENTKEYVALUE(infobuffer, "model"), m_Model) != 0) { - int index = ENTINDEX(pPlayer); + int index = TypeConversion.edict_to_id(pPlayer); SETCLIENTKEYVALUE(index, infobuffer, "model", m_Model); diff --git a/modules/cstrike/cstrike/CstrikeUserMessages.cpp b/modules/cstrike/cstrike/CstrikeUserMessages.cpp index 4d646765..e05329d1 100644 --- a/modules/cstrike/cstrike/CstrikeUserMessages.cpp +++ b/modules/cstrike/cstrike/CstrikeUserMessages.cpp @@ -21,8 +21,8 @@ bool ShouldBlock; bool ShouldBlockHLTV; bool ShouldDisableHooks; -bool RetrieveWeaponName; -ke::AString CurrentWeaponName; +bool RetrieveWeaponList; +ItemInfo CurrentWeaponList; int ArgPosition; int MessageIdArmorType; @@ -87,7 +87,7 @@ void OnMessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *p { if (msg_type == MessageIdSetFOV) { - int index = ENTINDEX(pEntity); + int index = TypeConversion.edict_to_id(pEntity); int zoom = Players[index].GetZoom(); if (zoom) @@ -107,7 +107,7 @@ void OnMessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *p } else if (msg_type == MessageIdResetHUD) { - int index = ENTINDEX(pEntity); + int index = TypeConversion.edict_to_id(pEntity); if (Players[index].GetZoom()) { @@ -132,7 +132,19 @@ void OnMessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *p { if (msg_type == MessageIdWeaponList) { - RetrieveWeaponName = true; + // MESSAGE_BEGIN(MSG_INIT, gmsgWeaponList); + // WRITE_STRING(pszName); + // WRITE_BYTE(CBasePlayer::GetAmmoIndex(II.pszAmmo1)); + // WRITE_BYTE(II.iMaxAmmo1); + // WRITE_BYTE(CBasePlayer::GetAmmoIndex(II.pszAmmo2)); + // WRITE_BYTE(II.iMaxAmmo2); + // WRITE_BYTE(II.iSlot); + // WRITE_BYTE(II.iPosition); + // WRITE_BYTE(II.iId); + // WRITE_BYTE(II.iFlags); + // MESSAGE_END(); + // + RetrieveWeaponList = true; } } } @@ -152,9 +164,19 @@ void OnWriteByte(int value) RETURN_META(MRES_SUPERCEDE); } - if (RetrieveWeaponName && ++ArgPosition == 7 && value >= 0 && value < MAX_WEAPONS) + if (RetrieveWeaponList) { - strncopy(WeaponNameList[value], CurrentWeaponName.chars(), sizeof(WeaponNameList[value])); + switch (++ArgPosition) + { + case 1: CurrentWeaponList.ammoIndex1 = value; + case 2: CurrentWeaponList.maxAmmo1 = value; + case 3: CurrentWeaponList.ammoIndex2 = value; + case 4: CurrentWeaponList.maxAmmo2 = value; + case 5: CurrentWeaponList.slot = value; + case 6: CurrentWeaponList.position = value; + case 7: CurrentWeaponList.id = value; + case 8: CurrentWeaponList.flags = value; + } } RETURN_META(MRES_IGNORED); @@ -167,9 +189,9 @@ void OnWriteString(const char *value) RETURN_META(MRES_SUPERCEDE); } - if (RetrieveWeaponName) + if (RetrieveWeaponList) { - CurrentWeaponName = value; + CurrentWeaponList.name = value; } RETURN_META(MRES_IGNORED); @@ -190,10 +212,12 @@ void OnMessageEnd(void) RETURN_META(MRES_SUPERCEDE); } - if (RetrieveWeaponName) + if (RetrieveWeaponList) { - RetrieveWeaponName = false; + RetrieveWeaponList = false; ArgPosition = 0; + + WeaponsList[CurrentWeaponList.id] = CurrentWeaponList; } RETURN_META(MRES_IGNORED); diff --git a/modules/cstrike/cstrike/CstrikeUtils.h b/modules/cstrike/cstrike/CstrikeUtils.h index 34e3d103..c5b9acdc 100644 --- a/modules/cstrike/cstrike/CstrikeUtils.h +++ b/modules/cstrike/cstrike/CstrikeUtils.h @@ -33,7 +33,7 @@ void UTIL_StringToLower(const char *str, char *buffer, size_t maxlength); MF_LogError(amx, AMX_ERR_NATIVE, "Entity out of range (%d)", x); \ return 0; \ } else { \ - if (x != 0 && FNullEnt(INDEXENT(x))) { \ + if (x != 0 && FNullEnt(TypeConversion.id_to_edict(x))) { \ MF_LogError(amx, AMX_ERR_NATIVE, "Invalid entity %d", x); \ return 0; \ } \ @@ -50,7 +50,7 @@ void UTIL_StringToLower(const char *str, char *buffer, size_t maxlength); return 0; \ } \ } else { \ - if (x != 0 && FNullEnt(INDEXENT(x))) { \ + if (x != 0 && FNullEnt(TypeConversion.id_to_edict(x))) { \ MF_LogError(amx, AMX_ERR_NATIVE, "Invalid entity %d", x); \ return 0; \ } \ @@ -73,7 +73,7 @@ void UTIL_StringToLower(const char *str, char *buffer, size_t maxlength); MF_LogError(amx, AMX_ERR_NATIVE, "Non-player entity %d out of range", x); \ return 0; \ } else { \ - if (FNullEnt(INDEXENT(x))) { \ + if (FNullEnt(TypeConversion.id_to_edict(x))) { \ MF_LogError(amx, AMX_ERR_NATIVE, "Invalid non-player entity %d", x); \ return 0; \ } \