Half-Life SDK: Заполняющаяся шкала здоровья
Суть: Сделать заполняющуюся шкалу здоровья игрока.
1) Создать спрайт. Я взял шкалу здоровья из "Mass Effect 3" ("Umodel Viewer": пакет "Startup").
Для обработки изображений использовал "GIMP" (Под шкалой создать чёрный фон->Объединить слои->"Изображение"->"Режим"->"Индексированный"->"Создать оптимальную палитру"->"Максимальное количество цветов": 256->"Преобразовать"->Сохранить как "Windows BMP").
Для создания файла спрайта использовал "QSpriteViewer" от "FreeSlave" (https://bitbucket.org/FreeSlave/qspriteviewer/src/master/). Для этого в окне программы: "Tools"->"Sprite creator"->Оставляем "Format: Half-Life" и жмём "Next"->"Load palette from sample image"->Выбираем наш "BMP"-файл->"Next"->"Add images"->Выбираем наш "BMP"-файл снова->Выбираем место сохранения спрайта в папку "sprites" проекта.
2) Редактуем файл "hud.txt". В файл вписываем:
health_empty 640 zdrvo 0 128 256 128 health_full 640 zdrvo 0 0 256 128
где "zdrvo" — имя створенного спрайта.
3) Редактуем "cl_dll/health.h". Фактично код для шкалы здоровья повторяет код батареи ("cl_dll/battery.cpp").
В "private"-секцию "class CHudHealth : public CHudBase" вписываем:
HSPRITE m_hSprite1; HSPRITE m_hSprite2; Rect* m_prc1; Rect* m_prc2; int m_iHeight;
3) Редактуем "cl_dll/health.cpp". Вносим в "bool CHudHealth::VidInit()" следующее:
int HUD_health_empty = gHUD.GetSpriteIndex("health_empty");
int HUD_health_full = gHUD.GetSpriteIndex("health_full");
m_hSprite1 = m_hSprite2 = 0;
m_prc1 = &gHUD.GetSpriteRect(HUD_health_empty);
m_prc2 = &gHUD.GetSpriteRect(HUD_health_full);
m_iHeight = m_prc2->left - m_prc1->right;
m_fFade = 0;Функция "bool CHudHealth::Draw(float flTime)" выглядит так:
bool CHudHealth::Draw(float flTime)
{
if ((gHUD.m_iHideHUDDisplay & HIDEHUD_HEALTH) != 0 || 0 != gEngfuncs.IsSpectateOnly())
return true;
int r, g, b, x, y, a;
Rect rc;
rc = *m_prc2;
rc.right += m_iHeight * ((float)(100 - (V_min(100, m_iHealth))) * 0.01);
UnpackRGB(r, g, b, RGB_YELLOWISH);
if (!gHUD.HasSuit())
return true;
if (0 != m_fFade)
{
if (m_fFade > FADE_TIME)
m_fFade = FADE_TIME;
m_fFade -= (gHUD.m_flTimeDelta * 20);
if (m_fFade <= 0)
{
a = 128;
m_fFade = 0;
}
// Fade the health number back to dim
a = MIN_ALPHA + (m_fFade / FADE_TIME) * 128;
}
else
a = MIN_ALPHA;
ScaleColors(r, g, b, a);
int iOffset = (m_prc1->bottom - m_prc1->top) / 6;
y = ScreenHeight - gHUD.m_iFontHeight - gHUD.m_iFontHeight / 2;
x = ScreenWidth / 3;
if (0 == m_hSprite1)
m_hSprite1 = gHUD.GetSprite(gHUD.GetSpriteIndex("health_empty"));
if (0 == m_hSprite2)
m_hSprite2 = gHUD.GetSprite(gHUD.GetSpriteIndex("health_full"));
SPR_Set(m_hSprite1, r, g, b);
SPR_DrawAdditive(0, x, y - iOffset, m_prc1);
if (rc.bottom > rc.top)
{
SPR_Set(m_hSprite2, r, g, b);
SPR_DrawAdditive(0, x, y - iOffset + (rc.top - m_prc2->top), &rc);
}
return true;
}В этом коде не ествует часть, отвечающая за отображение сторон-источников урона ("DrawDamage(flTime)" и т.д.).