Загрузка данных


stock corpseFitBox(iEnt)
{
    if (!pev_valid(iEnt))
        return;

    new Float:fOrigin[3];
    new Float:fBone[3];
    new Float:fBoneAngles[3];

    new Float:fMins[3];
    new Float:fMaxs[3];

    pev(iEnt, pev_origin, fOrigin);

    // Инициализация границ.
    fMins[0] = fMins[1] = 9999.0;
    fMaxs[0] = fMaxs[1] = -9999.0;

    new iFound;

    // Сбор координат костей.
    for (new iBone = 0; iBone < CORPSE_BONES; iBone++)
    {
        engfunc(
            EngFunc_GetBonePosition,
            iEnt,
            iBone,
            fBone,
            fBoneAngles
        );

        // Отсекаем кости, которые явно находятся
        // слишком далеко от origin модели.
        if (get_distance_f(fBone, fOrigin) > CORPSE_MAX_BONE_DIST)
            continue;

        // Координаты костей в мировом пространстве.
        // Переводим в смещения относительно origin.
        new Float:fLocalX = fBone[0] - fOrigin[0];
        new Float:fLocalY = fBone[1] - fOrigin[1];

        fMins[0] = floatmin(fMins[0], fLocalX);
        fMins[1] = floatmin(fMins[1], fLocalY);

        fMaxs[0] = floatmax(fMaxs[0], fLocalX);
        fMaxs[1] = floatmax(fMaxs[1], fLocalY);

        iFound++;
    }

    // Если кости не удалось получить,
    // используем предсказуемый fallback.
    if (!iFound)
    {
        fMins[0] = -32.0;
        fMins[1] = -32.0;

        fMaxs[0] = 32.0;
        fMaxs[1] = 32.0;
    }
    else
    {
        // Небольшой запас вокруг тела.
        fMins[0] -= CORPSE_PAD;
        fMins[1] -= CORPSE_PAD;

        fMaxs[0] += CORPSE_PAD;
        fMaxs[1] += CORPSE_PAD;

        // Защита от аномальных размеров.
        fMins[0] = floatmax(fMins[0], -CORPSE_MAX_X);
        fMins[1] = floatmax(fMins[1], -CORPSE_MAX_Y);

        fMaxs[0] = floatmin(fMaxs[0], CORPSE_MAX_X);
        fMaxs[1] = floatmin(fMaxs[1], CORPSE_MAX_Y);
    }

    // Определяем положение пола.
    new Float:fTraceStart[3];
    new Float:fTraceEnd[3];
    new Float:fFloorZ;

    fTraceStart[0] = fOrigin[0];
    fTraceStart[1] = fOrigin[1];
    fTraceStart[2] = fOrigin[2] + 16.0;

    fTraceEnd[0] = fOrigin[0];
    fTraceEnd[1] = fOrigin[1];
    fTraceEnd[2] = fOrigin[2] - 64.0;

    engfunc(
        EngFunc_TraceLine,
        fTraceStart,
        fTraceEnd,
        IGNORE_MONSTERS,
        iEnt,
        0
    );

    new Float:fFraction;
    get_tr2(0, TR_flFraction, fFraction);

    if (fFraction < 1.0)
    {
        new Float:fHitPos[3];
        get_tr2(0, TR_vecEndPos, fHitPos);

        fFloorZ = fHitPos[2] - fOrigin[2];
    }
    else
    {
        // Если trace не нашёл поверхность,
        // не создаём огромный вертикальный бокс.
        fFloorZ = -8.0;
    }

    // Тонкий бокс на уровне пола.
    fMins[2] = fFloorZ;
    fMaxs[2] = fFloorZ + CORPSE_HEIGHT;

    engfunc(EngFunc_SetSize, iEnt, fMins, fMaxs);
    engfunc(EngFunc_SetOrigin, iEnt, fOrigin);
}