Регенерация здоровья

From Valve Developer Community
Jump to: navigation, search
English

При помощи данного туториала вы сможете добавить в свой проект систему регенерации здоровья как в Call Of Duty/Portal для синглплеера, а с небольшими изменениями, и для мультиплеера. Используемый код был взят из Alien Swarm SDK.

Обзор

Как это должно работать:

  • Проверяем, что здоровье игрока меньше максимального значения
  • Проверяем, что прошло достаточно времени между таймеров регенерации и временем последнего получения повреждения игроком
  • Добавляем количество здоровья для регенерации исходя из времени кадра
  • Если количество здоровья для регенерации больше одного - добавляем его игроку

Добавляем квары

Для этого туториала мы будем изменять базовый класс игрока. Откройте 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 );
	}	
}

Готово.