Registration - or - Enter
Fistful of FragsFistful of Frags

мультиплеер от первого лица в стиле вестерн...

20/11/2007
Jailbreak 2004Jailbreak 2004

Отправь всех своих противников в темницу и не попадись сам!...

26/05/2004

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


  • Description
  • Link and installation

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

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


Author/s of lesson : Maxwel
Views : 418 ( +1 )
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. weapon_flamethrower - Играя в Халф-Лайф, вы не задумывались над тем, что в нем чего-то не хватает? Чего-то очень близкого, родного, горячего...
2. Спрыгивающий Headcrab - Наверняка каждый, кто поиграл в Half-Life2 хотел, чтобы хедкрабы спрыгивали с зомбяков и в первом Half-Life
3. Фикс: func_healthcharger - Фикс: func_healthcharger и func_recharger
4. Water Splash - Добавляем брызги при выстреле по воде
You cannot comment, because you are not registered.
    UT3 Evangelion Model Pack v1.1 Final
    Unreal Tournament 3UT3 Evangelion Model Pack v1.1 Final
    OldSkool Amp'd
    Unreal Tournament 99OldSkool Amp'd
    Csejte Castle HerdCoop Map Pack V3
    Unreal Tournament 99Csejte Castle HerdCoop Map Pack V3
    Unreal Tournament 3 Original Soundtrack
    Unreal Tournament 3 Original Soundtrack