Ru/Regenerating Health

При помощи данного туториала вы сможете добавить в свой проект систему регенерации здоровья, как в Call Of Duty/ для синглплеера, а с небольшими изменениями - и для мультиплеера. Используемый код был взят из .
== Обзор ==
Как это должно работать:
* Проверяем, что здоровье игрока меньше максимального значения
* Проверяем, что прошло достаточно времени между таймером регенерации и временем последнего получения повреждения игроком
* Добавляем количество здоровья для регенерации, исходя из времени кадра
* Если количество здоровья для регенерации больше одного - добавляем его игроку
== Добавляем квары == 
Для этого туториала мы будем изменять базовый класс игрока. Откройте server/player.cpp и добавьте в него следующие квары:
ConVar sv_regeneration ("sv_regeneration", "0", FCVAR_REPLICATED ); // Регенерация включена/отключена
ConVar sv_regeneration_wait_time ("sv_regeneration_wait_time", "1.0", FCVAR_REPLICATED ); // Время до старта регенерации после получения урона
ConVar sv_regeneration_rate ("sv_regeneration_rate", "0.5", FCVAR_REPLICATED ); // Частота регенерации (раз в пол-секунды, в данном случае)
Это позволит изменять настройки регенерации прямо в игре. Также нам понадобится значение, в котором будет храниться текущее количество здоровья для регенерации. Добавьте: 
float m_fRegenRemander;
после
int gEvilImpulse101;
Нам нужно инициализировать нашу переменную, поэтому в файле player.cpp: CBasePlayer::CBasePlayer( ) под m_iHealth = 0; после строки 552 добавьте это:
m_fRegenRemander = 0;
== Получаем время последнего получения урона игроком ==
Заметка: Если используете HL2 синглплеер базу, просто используйте m_flLastDamageTime , а не добавляйте m_fTimeLastHurt.
Теперь нам нужно получить время с последнего получения урона игроком. Нам нужно это, потому что мы хотим, чтобы имелся промежуток во времени перед стартом регенерации, и игрок не начинал регенерировать сразу после получения урона.
Чтобы сделать это, откройте player.h и добавьте где-нибудь около строки 860 
float m_fTimeLastHurt;
А в player.cpp поместите:
DEFINE_FIELD( m_fTimeLastHurt, FIELD_TIME ), 
после
DEFINE_FIELD( m_tbdPrev, FIELD_TIME ), 
где-нибудь около строки 306.
Теперь, когда мы добавили переменную, которая указывает на время последнего получения игроком урона, нам нужно держать её в актуальном состоянии. Для этого добавьте:
if ( GetHealth() < 100 )
{
 m_fTimeLastHurt = gpGlobals->curtime;
}
в конце метода CBasePlayer::OnTakeDamage. 
== Регенерация ==
Теперь настало самое время писать логику регенерации. В конце CBasePlayer::PostThink добавьте:
// Регенерация здоровья
if ( IsAlive() && GetHealth() < GetMaxHealth() && (sv_regeneration.GetInt() == 1) )
{
	// Цвет, которым накладывается на экран игрока при получении урона
	color32 hurtScreenOverlay = {80,0,0,64};
	if ( gpGlobals->curtime > m_fTimeLastHurt + sv_regeneration_wait_time.GetFloat() )
	{
 // Регенерация по частоте
		m_fRegenRemander += sv_regeneration_rate.GetFloat() * gpGlobals->frametime;
		
		if(m_fRegenRemander >= 1)
		{
			TakeHealth( m_fRegenRemander, DMG_GENERIC );
			m_fRegenRemander = 0;
		}
	}
	else
	{
		UTIL_ScreenFade( this, hurtScreenOverlay, 1.0f, 0.1f, FFADE_IN|FFADE_PURGE );
	}	
}
Готово.
Category:Russian