Регистрация - или - Войти
The Unknown MenaceThe Unknown Menace

Устраните потенциальную угрозу для человечества!...

19/01/2004

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


  • Описание
  • Ссылка и установка

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

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


Автор / ы урока : Maxwel
Просмотров : 389 ( +1 )
Прислал / (а) : Streit
Дата создания : 07.04.2011 18:09:27
Источник : http://www.hlfx.ru/forum
Рейтинг :
 ( 5 ) 
Поделиться :


Имеются следующие переводы : | русский |

Подопытный: 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, чтобы в чарджера появилось Имя, по которому мы будем на него наводить наш контроллер. Всё, готово, добавляйте и наслаждайтесь



Похожие1. Создание нового ствола - Создание нового ствола с новыми патронами
2. Новый монстр - В общем-то это самый лёгкий тутор который можно придумать.
3. Увеличение количества мяса от взрыв - Увеличение количества мяса от взрывов людей или инопланетян.
4. Создание сценариев - Для создания сценариев (aka скриптов) в Half-Life существуют две энтити: scripted_sequence и scripted_sentence. Первая отвечает за движения, выполняемые монстром/персонажем, будь то ходьба, бег, нажатие кнопки, тряска автомата с газировкой или почёсывание подбородка. Вторая служит для того, чтобы персонаж произнес какую-то фразу. При этом его голова повернётся в сторону слушателя, и рот будет открываться в соответствии с амплитудой звука.
5. Звук попадания как в HL2 - Работа на клиенте
Ссылки на объект
Полная ссылка на текущем языке :
Короткая ссылка :
Ссылка на превью-картинку :
Ссылка на картинку в полном размере :
Ссылка для вашего форума или сайта
BB код ссылка:
BB код ссылка с картинкой :
BB код картинки :
HTML код ссылка:
HTML код ссылка с картинкой :
HTML код картинки :
Вы не можете комментировать, т.к. вы не зарегистрированы.
    Counter-Strike: Classic Offensive
    Half-Life 2Counter-Strike: Classic Offensive
    Мод Counter-Strike: Classic Offensive
    Мод Counter-Strike: Classic Offensive
    Chunli Wonder Woman Cosplay
    Street Fighter VChunli Wonder Woman Cosplay
    Juri Beach Costume
    Street Fighter X TekkenJuri Beach Costume