Beispiel #1
0
static cell_t FindEntityByClassname(IPluginContext *pContext, const cell_t *params)
{
	static ValveCall *pCall = NULL;
	static bool bProbablyNoFEBC = false;

#if SOURCE_ENGINE >= SE_ORANGEBOX
	if (bProbablyNoFEBC)
	{
		return NativeFindEntityByClassname(pContext, params);
	}
#endif

	if (!pCall)
	{
		ValvePassInfo pass[3];
		InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL|VDECODE_FLAG_ALLOWWORLD);
		InitPass(pass[1], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
		InitPass(pass[2], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);

		char error[256];
		error[0] = '\0';
		if (!CreateBaseCall("FindEntityByClassname", ValveCall_EntityList, &pass[2], pass, 2, &pCall))
		{
			g_pSM->Format(error, sizeof(error), "\"FindEntityByClassname\" not supported by this mod");
		} else if (!pCall) {
			g_pSM->Format(error, sizeof(error), "\"FindEntityByClassname\" wrapper failed to initialize");
		}

		if (error[0] != '\0')
		{
#if SOURCE_ENGINE >= SE_ORANGEBOX
			if (!bProbablyNoFEBC)
			{
				bProbablyNoFEBC = true;
				g_pSM->LogError(myself, "%s, falling back to IServerTools method.", error);
			}
			return NativeFindEntityByClassname(pContext, params);
#else
			return pContext->ThrowNativeError("%s", error);
#endif
		}
	}

	CBaseEntity *pEntity;
	START_CALL();
	*(void **)vptr = g_EntList; 
	DECODE_VALVE_PARAM(1, vparams, 0);
	DECODE_VALVE_PARAM(2, vparams, 1);
	FINISH_CALL_SIMPLE(&pEntity);

	return gamehelpers->EntityToBCompatRef(pEntity);
}
Beispiel #2
0
static cell_t FindEntityByClassname(IPluginContext *pContext, const cell_t *params)
{
#if SOURCE_ENGINE == SE_TF2        \
	|| SOURCE_ENGINE == SE_DODS    \
	|| SOURCE_ENGINE == SE_HL2DM   \
	|| SOURCE_ENGINE == SE_CSS     \
	|| SOURCE_ENGINE == SE_BMS     \
	|| SOURCE_ENGINE == SE_SDK2013 \
	|| SOURCE_ENGINE == SE_NUCLEARDAWN

    static bool bHasServerTools3 = !!g_SMAPI->GetServerFactory(false)("VSERVERTOOLS003", nullptr);
    if (bHasServerTools3)
    {
        CBaseEntity *pStartEnt = NULL;
        if (params[1] != -1)
        {
            pStartEnt = gamehelpers->ReferenceToEntity(params[1]);
            if (!pStartEnt)
            {
                return pContext->ThrowNativeError("Entity %d (%d) is invalid",
                                                  gamehelpers->ReferenceToIndex(params[1]),
                                                  params[1]);
            }
        }

        char *searchname;
        pContext->LocalToString(params[2], &searchname);

        CBaseEntity *pEntity = servertools->FindEntityByClassname(pStartEnt, searchname);
        return gamehelpers->EntityToBCompatRef(pEntity);
    }
#endif

    static ValveCall *pCall = NULL;
    static bool bProbablyNoFEBC = false;

#if SOURCE_ENGINE >= SE_ORANGEBOX
    if (bProbablyNoFEBC)
    {
        return NativeFindEntityByClassname(pContext, params);
    }
#endif // >= SE_ORANGEBOX

    if (!pCall)
    {
        ValvePassInfo pass[3];
        InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL|VDECODE_FLAG_ALLOWWORLD);
        InitPass(pass[1], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
        InitPass(pass[2], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);

        char error[256];
        error[0] = '\0';
        if (!CreateBaseCall("FindEntityByClassname", ValveCall_EntityList, &pass[2], pass, 2, &pCall))
        {
            g_pSM->Format(error, sizeof(error), "\"FindEntityByClassname\" not supported by this mod");
        } else if (!pCall) {
            g_pSM->Format(error, sizeof(error), "\"FindEntityByClassname\" wrapper failed to initialize");
        }

        if (error[0] != '\0')
        {
#if SOURCE_ENGINE >= SE_ORANGEBOX
            if (!bProbablyNoFEBC)
            {
                bProbablyNoFEBC = true;

                // CreateBaseCall above abstracts all of the gamedata logic, but we need to know if the key was even found.
                // We don't want to log an error if key isn't present (knowing falling back to native method), only throw
                // error if signature/symbol was not found.
                void *dummy;
                if (g_pGameConf->GetMemSig("FindEntityByClassname", &dummy))
                {
                    g_pSM->LogError(myself, "%s, falling back to IServerTools method.", error);
                }
            }
            return NativeFindEntityByClassname(pContext, params);
#else
            return pContext->ThrowNativeError("%s", error);
#endif // >= ORANGEBOX
        }
    }

    CBaseEntity *pEntity;
    START_CALL();
    *(void **)vptr = g_EntList;
    DECODE_VALVE_PARAM(1, vparams, 0);
    DECODE_VALVE_PARAM(2, vparams, 1);
    FINISH_CALL_SIMPLE(&pEntity);

    return gamehelpers->EntityToBCompatRef(pEntity);
}