Всегда хотелось, чтобы зарядник в хл был управляемым.
Удалённый контроль зарядника
Всегда хотелось, чтобы зарядник в хл был управляемым.
Author/s of tutorial : Maxwel Views : 1191 ( +1 ) Uploader : Streit Created : 04/07/2011 9:09:27 PM Source : http://www.hlfx.ru/forum Rating : ( 5 ) Share :
Following translations are available : |
russian |
Подопытный: func_recharge
Всегда хотелось, чтобы зарядник в хл был управляемым. А то стоит он себе и ждёт, пока его разрядят. А хочется, чтобы он ещё включался/выключался нажатим кнопки/событием в игре. Вот я и зделал специальную функицию для контроля зарядника. Она состоит из усовершенствования самого зарядника (необязательно, но полезно) и дополнительной энтити.
Часть 1. Модифицируем зарядник.
Файл: h_battery.cpp
Класс: CRecharge
Цель: модификация
Находим блок подключения заголовочных модулей (#include) и после него (строка 29) вписываем два дефайна:
#define SF_RECHARGE_SPEC 1
#define SF_RECHARGE_SKILL 2
это два дополнительных флага для нашего зарядника. Первый значит, что зарядник будет использовать особое значение заряда, а не стандартное. Второй значит, что значения будет взято из переменной в skill.cfg (нужно, чтобы был установлен первый флаг).
Теперь надо наши флаги привязать к заряднику, чтобы от них что-то зависило. Это зделаем в процедуре CRecharge::Spawn. Находим вот эту строку:
m_iJuice = gSkillData.suitchargerCapacity;
заменяем её на такой код:
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.
Далее найдём такую строку (она следующая после этого блока ):
if ( m_iJuice > 0 )
{
pev->frame = 0;
}
else
pev->frame = 1;
это мы ставим условие, что если стартовое значение энергии - нулевое, то зарядник выглядит разряженным.
Теперь мы имеем усовершенствованный зарядник, но чтобы его использовать надо прописать новые флаги и настройки в fgd-файл. Откройте его, найдите SolidClass func_recharge, допишите в него слелующие настройки:
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
Цель: создание
Спускайтесь в самый низ файла, сейчас будем мноооого писать.
Для начала обьявим дефайны:
#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; четвёртый - для того, чтобы от речарджера не производились звуки при включении/выключении.
Далее пишем наш класс:
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 нужна, чтобы энтитя "думала" производить звук или нет.
Далее привязываем класс к энтити:
LINK_ENTITY_TO_CLASS( trigger_recharge_control, CRechargeControl );
Тут я назвал энтитю как trigger_recharge_control, но Вы можете обозвать её и по другому
Далее идёт процедура кеширования:
void CRechargeControl::Precache( void )
{
PRECACHE_SOUND("items/suitchargeno1.wav");
PRECACHE_SOUND("items/suitchargeok1.wav");
}
это мы кешируем два звучка, которые будут исходить от зарядника при включении/выключении.
Далее процедура создания:
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) );
}
}
я думаю, тут всё понятно
Теперь самая главная процедура вызова:
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-файл. Вот её описание:
@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) вписываем два дефайна:
#define SF_WALLHEALTH_SPEC 1
#define SF_WALLHEALTH_SKILL 2
это два дополнительных флага для нашего зарядника. Первый значит, что зарядник будет использовать особое значение заряда, а не стандартное. Второй значит, что значения будет взято из переменной в skill.cfg (нужно, чтобы был установлен первый флаг).
Теперь надо наши флаги привязать к заряднику, чтобы от них что-то зависило. Это зделаем в процедуре CWallHealth::Spawn. Находим вот эту строку:
m_iJuice = gSkillData.healthchargerCapacity;
заменяем её на такой код:
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.
Далее найдём такую строку (она следующая после этого блока ):
if ( m_iJuice > 0 )
{
pev->frame = 0;
}
else
pev->frame = 1;
это мы ставим условие, что если стартовое значение энергии - нулевое, то зарядник выглядит разряженным.
Теперь мы имеем усовершенствованный зарядник, но чтобы его использовать надо прописать новые флаги и настройки в fgd-файл. Откройте его, найдите SolidClass func_healthcharger, допишите в него слелующие настройки:
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
Цель: создание
Спускайтесь в самый низ файла, сейчас будем мноооого писать.
Для начала обьявим дефайны:
#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; четвёртый - для того, чтобы от речарджера не производились звуки при включении/выключении.
Далее пишем наш класс:
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 нужна, чтобы энтитя "думала" производить звук или нет.
Далее привязываем класс к энтити:
LINK_ENTITY_TO_CLASS( trigger_healthcharger_control, CWallHealthControl );
Тут я назвал энтитю как trigger_healthcharger_control, но Вы можете обозвать её и по другому
Далее идёт процедура кеширования:
void CWallHealthControl::Precache( void )
{
PRECACHE_SOUND("items/medshotno1.wav");
PRECACHE_SOUND("items/medcharge4.wav");
}
это мы кешируем два звучка, которые будут исходить от зарядника при включении/выключении.
Далее процедура создания:
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) );
}
}
я думаю, тут всё понятно
Теперь самая главная процедура вызова:
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-файл. Вот её описание:
@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, чтобы в чарджера появилось Имя, по которому мы будем на него наводить наш контроллер.
Всё, готово, добавляйте и наслаждайтесь
Similar 1. Цвет спрайтов HUD - Итак, как же сменить цвет спрайтов в HUD-системе 2. Создание сценариев - Для создания сценариев (aka скриптов) в Half-Life существуют две энтити: scripted_sequence и scripted_sentence. Первая отвечает за движения, выполняемые монстром/персонажем, будь то ходьба, бег, нажатие кнопки, тряска автомата с газировкой или почёсывание подбородка. Вторая служит для того, чтобы персонаж произнес какую-то фразу. При этом его голова повернётся в сторону слушателя, и рот будет открываться в соответствии с амплитудой звука. 3. Sparks - Как добавить искры
You cannot comment, because you are not logged-in.