diff --git a/core/smn_halflife.cpp b/core/smn_halflife.cpp index b27a7e4f..c49c6431 100644 --- a/core/smn_halflife.cpp +++ b/core/smn_halflife.cpp @@ -572,6 +572,47 @@ static cell_t ReferenceToBCompatRef(IPluginContext *pContext, const cell_t *para return g_HL2.ReferenceToBCompatRef(params[1]); } +// Must match ClientRangeType enum in halflife.inc +enum class ClientRangeType : cell_t +{ + Visibility = 0, + Audibility, +}; + +static cell_t GetClientsInRange(IPluginContext *pContext, const cell_t *params) +{ + cell_t *origin; + pContext->LocalToPhysAddr(params[1], &origin); + + Vector vOrigin(sp_ctof(origin[0]), sp_ctof(origin[1]), sp_ctof(origin[2])); + + ClientRangeType rangeType = (ClientRangeType) params[2]; + + CBitVec players; + engine->Message_DetermineMulticastRecipients(rangeType == ClientRangeType::Audibility, vOrigin, players); + + cell_t *outPlayers; + pContext->LocalToPhysAddr(params[3], &outPlayers); + + int maxPlayers = params[4]; + int curPlayers = 0; + + int index = players.FindNextSetBit(0); + while (index > -1 && curPlayers < maxPlayers) + { + int entidx = index + 1; + CPlayer *pPlayer = g_Players.GetPlayerByIndex(entidx); + if (pPlayer && pPlayer->IsInGame()) + { + outPlayers[curPlayers++] = entidx; + } + + index = players.FindNextSetBit(index + 1); + } + + return curPlayers; +} + REGISTER_NATIVES(halflifeNatives) { {"CreateFakeClient", CreateFakeClient}, @@ -607,5 +648,6 @@ REGISTER_NATIVES(halflifeNatives) {"EntIndexToEntRef", IndexToReference}, {"EntRefToEntIndex", ReferenceToIndex}, {"MakeCompatEntRef", ReferenceToBCompatRef}, + {"GetClientsInRange", GetClientsInRange}, {NULL, NULL}, }; diff --git a/plugins/include/halflife.inc b/plugins/include/halflife.inc index 22cc9d30..4514bb08 100644 --- a/plugins/include/halflife.inc +++ b/plugins/include/halflife.inc @@ -624,3 +624,21 @@ native EntRefToEntIndex(ref); */ native MakeCompatEntRef(ref); + +enum ClientRangeType +{ + RangeType_Visibility = 0, + RangeType_Audibility, +} + +/** + * Find clients that are potentially in range of a position. + * + * @param origin Coordinates from which to test range. + * @param rangeType Range type to use for filtering clients. + * @param clients Array to which found client indexes will be written. + * @param size Maximum size of clients array. + * @return Number of client indexes written to clients array. + */ +native int GetClientsInRange(float origin[3], ClientRangeType rangeType, int[] clients, int size); +