Registration - or - Enter
Zombies HL v072bZombies HL v072b

Демо версия....

22/10/2010
Codename: CURECodename: CURE

First Person Shooter...

1/10/2013

Всегда хотелось, чтобы зарядник в хл был управляемым.


  • Description
  • Link and installation

Удалённый контроль зарядника

Всегда хотелось, чтобы зарядник в хл был управляемым.


Author/s of lesson : Maxwel
Views : 374 ( +2 )
Uploaded by : Streit
Created : 04/07/2011 6:09:27 PM
Source : http://www.hlfx.ru/forum
Rating :
 ( 5 ) 
Share :


Available following translations : | russian |

Подопытный: func_recharge

Всегда хотелось, чтобы зарядник в хл был управляемым. А то стоит он себе и ждёт, пока его разрядят. А хочется, чтобы он ещё включался/выключался нажатим кнопки/событием в игре. Вот я и зделал специальную функицию для контроля зарядника. Она состоит из усовершенствования самого зарядника (необязательно, но полезно) и дополнительной энтити.

Часть 1. Модифицируем зарядник. Файл: h_battery.cpp Класс: CRecharge Цель: модификация

Находим блок подключения заголовочных модулей (#include) и после него (строка 29) вписываем два дефайна:

Code:

#define SF_RECHARGE_SPEC 1
#define SF_RECHARGE_SKILL 2

это два дополнительных флага для нашего зарядника. Первый значит, что зарядник будет использовать особое значение заряда, а не стандартное. Второй значит, что значения будет взято из переменной в skill.cfg (нужно, чтобы был установлен первый флаг). Теперь надо наши флаги привязать к заряднику, чтобы от них что-то зависило. Это зделаем в процедуре CRecharge::Spawn. Находим вот эту строку:

Code:

m_iJuice = gSkillData.suitchargerCapacity;

заменяем её на такой код:

Code:

if (pev->spawnflags & SF_RECHARGE_SKILL)
{
   pev->armorvalue = (int)GetSkillCvar( (char *)STRING(pev->message) );
}

if (pev->spawnflags & SF_RECHARGE_SPEC)
{
   m_iJuice = max( pev->armorvalue, 0);
}
else
   m_iJuice = gSkillData.suitchargerCapacity;

это мы заставили наши флаги работать. То есть, когда установлен первый флаг, то значению энергии присваивается значение с параметра armorvalue (но не меньше ноля), в противном случае устанавливается стандартное значение. Когда установлен второй - параметру armorvalue присваивается skill-значение, имя переменной берём с параметра message. Далее найдём такую строку (она следующая после этого блока ):

Code:

pev->frame = 0;

Заменяем на это:

Code:

if ( m_iJuice > 0 )
{
   pev->frame = 0;
}
else
   pev->frame = 1;

это мы ставим условие, что если стартовое значение энергии - нулевое, то зарядник выглядит разряженным. Теперь мы имеем усовершенствованный зарядник, но чтобы его использовать надо прописать новые флаги и настройки в fgd-файл. Откройте его, найдите SolidClass func_recharge, допишите в него слелующие настройки:

Code:

spawnflags(Flags) =
[
   1 : "Spec. Juice" : 0
   2 : "Skill Juice" : 0
]
armorvalue(integer) : "Juice (if spec)" : 0
message(string) : "Juice (if skill)"

По первому сабжу - всё.

Часть 2. Энтитя контроля. Файл: h_battery.cpp Класс: CRechargeControl Цель: создание

Спускайтесь в самый низ файла, сейчас будем мноооого писать. Для начала обьявим дефайны:

Code:

#define SF_RECHARGE_CONTROL_ONCE 1
#define SF_RECHARGE_CONTROL_AWARD 2
#define SF_RECHARGE_CONTROL_SKILL 4
#define SF_RECHARGE_CONTROL_NSND 8

это четыре спаунфлага: первый - для одноразового срабатывания энтити; второй - для того, чтобы значение не просто устанавливалось, а прибавлялось/отнималось; третий - для использования значения из skill.cfg; четвёртый - для того, чтобы от речарджера не производились звуки при включении/выключении. Далее пишем наш класс:

Code:

class CRechargeControl : public CPointEntity
{
   public:
   void Spawn( void );
   void Precache( void );
   void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
   private:
   int m_iPrevJuice;
};

переменная m_iPrevJuice нужна, чтобы энтитя "думала" производить звук или нет. Далее привязываем класс к энтити:

Code:

LINK_ENTITY_TO_CLASS( trigger_recharge_control, CRechargeControl );

Тут я назвал энтитю как trigger_recharge_control, но Вы можете обозвать её и по другому Далее идёт процедура кеширования:

Code:

void CRechargeControl::Precache( void )
{
   PRECACHE_SOUND("items/suitchargeno1.wav");
   PRECACHE_SOUND("items/suitchargeok1.wav");
}

это мы кешируем два звучка, которые будут исходить от зарядника при включении/выключении. Далее процедура создания:

Code:

void CRechargeControl::Spawn(void)
{
   Precache();
   pev->solid = SOLID_NOT;
   pev->movetype = MOVETYPE_NONE;

   if (pev->spawnflags & SF_RECHARGE_CONTROL_SKILL)
   {
     pev->armorvalue = (int)GetSkillCvar( (char *)STRING(pev->message) );
   }
}

я думаю, тут всё понятно Теперь самая главная процедура вызова:

Code:

void CRechargeControl::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
   CRecharge *pRecharge = NULL;
   pRecharge = (CRecharge *)UTIL_FindEntityByTargetname( NULL, STRING(pev->target) );

   if (pRecharge)
   {
     m_iPrevJuice = pRecharge->m_iJuice;

     if (pev->spawnflags & SF_RECHARGE_CONTROL_AWARD)
     {
       pRecharge->m_iJuice += (int)pev->armorvalue;
     }
     else
       pRecharge->m_iJuice = (int)pev->armorvalue;

     if (pRecharge->m_iJuice > 0)
     {
       pRecharge->pev->frame = 0;
     }
     else
       pRecharge->pev->frame = 1;

     if (!(pev->spawnflags & SF_RECHARGE_CONTROL_NSND))
     {
       if ( (m_iPrevJuice <= 0) && (pRecharge->m_iJuice > 0) )
       {
         EMIT_SOUND_DYN( ENT(pRecharge->pev), CHAN_STATIC, "items/suitchargeok1.wav", 1, ATTN_NORM, 0, 150 );
       }
       if ( (m_iPrevJuice > 0) && (pRecharge->m_iJuice <= 0) )
       {
         EMIT_SOUND_DYN( ENT(pRecharge->pev), CHAN_STATIC, "items/suitchargeno1.wav", 1, ATTN_NORM, 0, 150 );
       }
     }
   }

   if (pev->spawnflags & SF_RECHARGE_CONTROL_ONCE)
   {
     UTIL_Remove( this );
   }
}

если Вы программируете для хл, то Вы всё поймёте без обьяснений Вот наша энтитя готова, теперь добавим её в fgd-файл. Вот её описание:

Code:

@PointClass base(Targetname,Target) = trigger_recharge_control : "Recharger control entity"
[
   spawnflags(flags) =
   [
     1: "Remove on fire" : 0
     2: "Award/Deduct" : 0
     4: "Skill value" : 0
     8: "No Sound" : 0
   ]
   armorvalue(integer) : "Juice" : 100
   message(string) : "Juice (skill)"
]

О, и не забудьте к func_recharge добавить base Targetname, чтобы в чарджера появилось Имя, по которому мы будем на него наводить наш контроллер. Всё, готово, добавляйте и наслаждайтесь

Подопытный: func_healthcharger

Часть 1. Модифицируем зарядник. Файл: healthkit.cpp Класс: CWallHealth Цель: модификация

Находим блок подключения заголовочных модулей (#include) и после него (строка 24) вписываем два дефайна:

Code:

#define SF_WALLHEALTH_SPEC 1
#define SF_WALLHEALTH_SKILL 2

это два дополнительных флага для нашего зарядника. Первый значит, что зарядник будет использовать особое значение заряда, а не стандартное. Второй значит, что значения будет взято из переменной в skill.cfg (нужно, чтобы был установлен первый флаг). Теперь надо наши флаги привязать к заряднику, чтобы от них что-то зависило. Это зделаем в процедуре CWallHealth::Spawn. Находим вот эту строку:

Code:

m_iJuice = gSkillData.healthchargerCapacity;

заменяем её на такой код:

Code:

if (pev->spawnflags & SF_WALLHEALTH_SKILL)
{
   pev->health = (int)GetSkillCvar( (char *)STRING(pev->message) );
}

if (pev->spawnflags & SF_WALLHEALTH_SPEC)
{
   m_iJuice = max( pev->health, 0);
}
else
   m_iJuice = gSkillData.healthchargerCapacity;

это мы заставили наши флаги работать. То есть, когда установлен первый флаг, то значению энергии присваивается значение с параметра health (но не меньше ноля), в противном случае устанавливается стандартное значение. Когда установлен второй - параметру health присваивается skill-значение, имя переменной берём с параметра message. Далее найдём такую строку (она следующая после этого блока ):

Code:

pev->frame = 0;

Заменяем на это:

Code:

if ( m_iJuice > 0 )
{
   pev->frame = 0;
}
else
   pev->frame = 1;

это мы ставим условие, что если стартовое значение энергии - нулевое, то зарядник выглядит разряженным. Теперь мы имеем усовершенствованный зарядник, но чтобы его использовать надо прописать новые флаги и настройки в fgd-файл. Откройте его, найдите SolidClass func_healthcharger, допишите в него слелующие настройки:

Code:

spawnflags(Flags) =
[
   1 : "Spec. Juice" : 0
   2 : "Skill Juice" : 0
]
health(integer) : "Juice (if spec)" : 0
message(string) : "Juice (if skill)"

По первому сабжу - всё.

Часть 2. Энтитя контроля. Файл: healthkit.cpp Класс: CWallHealthControl Цель: создание

Спускайтесь в самый низ файла, сейчас будем мноооого писать. Для начала обьявим дефайны:

Code:

#define SF_WALLHEALTH_CONTROL_ONCE 1
#define SF_WALLHEALTH_CONTROL_AWARD 2
#define SF_WALLHEALTH_CONTROL_SKILL 4
#define SF_WALLHEALTH_CONTROL_NSND 8

это четыре спаунфлага: первый - для одноразового срабатывания энтити; второй - для того, чтобы значение не просто устанавливалось, а прибавлялось/отнималось; третий - для использования значения из skill.cfg; четвёртый - для того, чтобы от речарджера не производились звуки при включении/выключении. Далее пишем наш класс:

Code:

class CWallHealthControl : public CPointEntity
{
   public:
   void Spawn( void );
   void Precache( void );
   void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
   private:
   int m_iPrevJuice;
};

переменная m_iPrevJuice нужна, чтобы энтитя "думала" производить звук или нет. Далее привязываем класс к энтити:

Code:

LINK_ENTITY_TO_CLASS( trigger_healthcharger_control, CWallHealthControl );

Тут я назвал энтитю как trigger_healthcharger_control, но Вы можете обозвать её и по другому Далее идёт процедура кеширования:

Code:

void CWallHealthControl::Precache( void )
{
   PRECACHE_SOUND("items/medshotno1.wav");
   PRECACHE_SOUND("items/medcharge4.wav");
}

это мы кешируем два звучка, которые будут исходить от зарядника при включении/выключении. Далее процедура создания:

Code:

void CWallHealthControl::Spawn(void)
{
   Precache();
   pev->solid = SOLID_NOT;
   pev->movetype = MOVETYPE_NONE;

   if (pev->spawnflags & SF_WALLHEALTH_CONTROL_SKILL)
   {
     pev->health = (int)GetSkillCvar( (char *)STRING(pev->message) );
   }
}

я думаю, тут всё понятно Теперь самая главная процедура вызова:

Code:

void CWallHealthControl::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
   CWallHealth *pRecharge = NULL;
   pRecharge = (CWallHealth *)UTIL_FindEntityByTargetname( NULL, STRING(pev->target) );

   if (pRecharge)
   {
     m_iPrevJuice = pRecharge->m_iJuice;

     if (pev->spawnflags & SF_WALLHEALTH_CONTROL_AWARD)
     {
       pRecharge->m_iJuice += (int)pev->health;
     }
     else
       pRecharge->m_iJuice = (int)pev->health;

     if (pRecharge->m_iJuice > 0)
     {
       pRecharge->pev->frame = 0;
     }
     else
       pRecharge->pev->frame = 1;

     if (!(pev->spawnflags & SF_WALLHEALTH_CONTROL_NSND))
     {
       if ( (m_iPrevJuice <= 0) && (pRecharge->m_iJuice > 0) )
       {
         EMIT_SOUND_DYN( ENT(pRecharge->pev), CHAN_STATIC, "items/medcharge4.wav", 1, ATTN_NORM, 0, 150 );
       }
       if ( (m_iPrevJuice > 0) && (pRecharge->m_iJuice <= 0) )
       {
         EMIT_SOUND_DYN( ENT(pRecharge->pev), CHAN_STATIC, "items/medshotno1.wav", 1, ATTN_NORM, 0, 150 );
       }
     }
   }

   if (pev->spawnflags & SF_WALLHEALTH_CONTROL_ONCE)
   {
     UTIL_Remove( this );
   }
}

если Вы программируете для хл, то Вы всё поймёте без обьяснений Вот наша энтитя готова, теперь добавим её в fgd-файл. Вот её описание:

Code:

@PointClass base(Targetname,Target) = trigger_healthcharger_control : "Healthcharger control entity"
[
   spawnflags(flags) =
   [
     1: "Remove on fire" : 0
     2: "Award/Deduct" : 0
     4: "Skill value" : 0
     8: "No Sound" : 0
   ]
   health(integer) : "Juice" : 100
   message(string) : "Juice (skill)"
]

О, и не забудьте к func_healthcharger добавить base Targetname, чтобы в чарджера появилось Имя, по которому мы будем на него наводить наш контроллер. Всё, готово, добавляйте и наслаждайтесь



Similar1. учёные не отставали - Как сделать так, чтобы учёные не отставали на каждом препятствии
2. Переключение оружия a la HL2 - Мне не нравится, как переключается оружие в ХЛ. Может, кому-то и интересно тыкать по менюшкам худа, но мне больше нравится реализация переключения в Unreal RTN, Quake Mission Packs и HL2
3. Создание сценариев - Для создания сценариев (aka скриптов) в Half-Life существуют две энтити: scripted_sequence и scripted_sentence. Первая отвечает за движения, выполняемые монстром/персонажем, будь то ходьба, бег, нажатие кнопки, тряска автомата с газировкой или почёсывание подбородка. Вторая служит для того, чтобы персонаж произнес какую-то фразу. При этом его голова повернётся в сторону слушателя, и рот будет открываться в соответствии с амплитудой звука.
4. Изменение цвета HUD'а(полное)! - Изменение цвета HUD'а(полное)! Но прицелы придётся переделывать вам самим! Сдесь я перевевёл туториал с twhl.info на русский язык!
Ссылки на объект
Полная ссылка на текущем языке :
Короткая ссылка :
Ссылка на превью-картинку :
Ссылка на картинку в полном размере :
Ссылка для вашего форума или сайта
BB код ссылка:
BB код ссылка с картинкой :
BB код картинки :
HTML код ссылка:
HTML код ссылка с картинкой :
HTML код картинки :
You cannot comment, because you are not registered.
    Leon Scott Kennedy R.P.D. For BIlly Normal
    Leon Scott Kennedy R.P.D. For BIlly Normal
    Chris Redfield (RECVX Costume)
    Chris Redfield (RECVX Costume)
    PlayStation Button Mod
    PlayStation Button Mod
    Русификатор (звук) от Team Raccoon
    Русификатор (звук) от Team Raccoon