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);
}