• Регистрация на форуме отключена.
    Она будет открываться первого числа каждого месяца на 24 часа.

    Если вы хотите поделиться чем-то интересным и полезным, то обратитесь к администраторам в >> телеграм <<

Управление бомбой

Сообщения
408
Реакции
379
Помог
13 раз(а)


Гайд довольно подробно разжеван для новичков, но содержит информацию, которая будет полезна и опытным скриптерам.


Недавно писал плагин, в котором нужно было изменять время минирования/разминирования бомбы. И часть инфы было найти проблематично. Оффсеты для 6ххх билдов изменены, и где искать новые
значения - нипанятна. Единственный источник здесь содержит неверную информацию. Возможно, кто-то подскажет, где найти все "правильные" оффсеты для 6ххх билдов

1. Модуль CSX.
Код:
// Игрок разминировал бомбу. defuser - игрок, который разминировал
public bomb_defused(defuser)


Код:
// Игрок начал разминирование бомбы. defuser - игрок, который начал разминирование.
public bomb_defusing(defuser)


Код:
// Бомба взорвалась. planter установил бомбу,
// defuser - последний, кто пытался разминировать(если такой имеется)
bomb_explode(planter, defuser)


Код:
// Бомба установлена, установил planter.
public bomb_planted(planter)


Код:
// Бомба устанавливается игоком planter
public bomb_planting(planter)
Увы, модуль не содержит событий отмены установки и разминирования. Поэтому в bomb_planting/bomb_defusing запоминаем, кто ее ставит/разминирует, и юзаем эвент BarTime:
Код:
...
new g_iPlanting, g_iBarTime, g_iDefusing
public plugin_init()
{
...
g_iBarTime = get_user_msgid("BarTime");
register_event("BarTime", "event_bartime", "b", "1=0"); // Первый аргумент == 0, т.е. "пустой" bartime
}

public bomb_defusing(defuser)
{
g_iDefusing = defuser;
}

public bomb_planting(planter)
{
g_iDefusing = planter;
}

public event_bartime(id)
{
if(g_iDefusing == id)
g_iDefusing = 0;

else if(g_iPlanting == id)
g_iPlanting = 0;
}


2. Игрок находится в зоне установки бомбы. Как по мне, этот способ выгоднее, чем цикл по всем энтити:
Код:
...
new g_bInPlant[33]
public plugin_init() {
...
register_event("StatusIcon", "statusicon", "b", "2=c4") // Второй аргумент == c4, спрайт бомбы
}

public statusicon( id )
{
new status = read_data(1)

if(status == 1) // обычная иконка бомбы
g_bInPlant = false

else if (status == 2) // мигающая иконка бомбы, игрок может ставить бомбу
g_bInPlant = true

return PLUGIN_CONTINUE
}


3. Запрет/отмена установки бомбы. Код будет срабатывать даже если игрок вне зоны установки, поэтому потребуется код выше.

Не уверен, что при отмене не нужно отправлять "пустой" BarTime. Кто знает, уточните

Код:
...
public plugin_init() {
...
RegisterHam(Ham_Weapon_PrimaryAttack, "weapon_c4", "fw_C4Attack")
}

public fw_C4Attack(weapon_ent)
{
new owner = pev(weapon_ent, pev_owner) // получаем id игрока

if(!g_bInPlant[owner]) // если игрок вне зоны установки
return HAM_IGNORED

if(!g_CanPlant[owner]) // если игроку запрещено ставить бомбу
return HAM_SUPERCEDE

return HAM_IGNORED
}


4. Запрет/отмена разминирования бомбы:
Код:
...
public plugin_init() {
...
RegisterHam(Ham_Use,"grenade","UseButton")
}

public UseButton(ent, idcaller, idactivator, use_type, Float:value)
{
// Как показала практика, дополнительных проверок не требуется,
// USE для grenade-энтити вызывается только для установленной бомбы
if(!g_CanDefuse[idcaller]) // если игроку запрещено разминировать бомбу
return HAM_SUPERCEDE

return HAM_IGNORED
}


5. Изменение времени установки/разминирования:
Код:
...
#define m_flDefuseCountDown 99 // оффсет разминирования бомбы
#define m_fArmedTime 81 // оффсет установки бомбы
#define LINUXDIFF 4

#define PLANTING_TIME 5.0 // Время установки бомбы
#define DEFUSING_TIME 15.0 // Время разминирования бомбы

new g_iBarTime

public plugin_init()
{
...
g_iBarTime = get_user_msgid("BarTime")
}

public bomb_planting(planter)
{
new bomb
if(bomb = fm_find_ent_by_owner(-1, "weapon_c4", planter, 0)) // находим id энтити
{
set_pdata_float(bomb, m_fArmedTime, get_gametime() + PLANTING_TIME, LINUXDIFF) // задаем время установки
send_progress_bar(planter, floatround(BOMB_PLANTING_TIME)) // обновляем прогрессбар
}
}

public bomb_defusing(defuser)
{
new bomb
if ((bomb = fm_find_ent_by_model(-1, "grenade", "models/w_c4.mdl")))
{
set_pdata_float(bomb, m_flDefuseCountDown, get_gametime() + DEFUSING_TIME, LINUXDIFF) // задаем время разминирования
send_progress_bar(id, floatround(DEFUSING_TIME)) // обновляем прогрессбар
}
}

stock send_progress_bar(const id, const time)
{
message_begin(MSG_ONE, g_iBarTime, _, id)
write_short(time)
message_end()
}

  • Прогрессбар не воспринимает дробные числа, поэтому старайтесь избегать их, иначе прогрессбар будет идти медленнее/быстрее.
  • Не пытайтесь задать время установки/разминирования в UseButton и fwC4Attack. Эти функции, даже в post, выполняются раньше, чем движок определяет время установки/разминирования, соответственно, изменения не будут работать.



На этом все. Остальную инфу по работе с бомбой можно найти здесь или здесь, и немножко здесь
Спасибо AndrewZ, что помогал тестить
 
Сообщения
408
Реакции
379
Помог
13 раз(а)
Удаление дропнутой бомбы без утечек памяти

Код:
    new weaponbox = find_ent_by_model(0, "weaponbox", "models/w_backpack.mdl")
    if(is_entity(weaponbox))
    {
        new pWeapon = get_member(weaponbox, m_WeaponBox_rgpPlayerItems, C4_SLOT);
        if (!is_nullent(pWeapon))
            set_entvar(pWeapon, var_flags, FL_KILLME); //При удалении вепонбокса бомба не удаляется, необходимо удалять вручную

        set_entvar(weaponbox, var_flags, FL_KILLME);

        message_begin(MSG_ALL, get_user_msgid("BombPickup"))//Скрыть бомбу с радара
        message_end()
    }
 
Сообщения
138
Реакции
244
Помог
1 раз(а)
Удаление дропнутой бомбы без утечек памяти
Что-то сложно. Бомба это же веапонбокс и как любой веапонбокс, по идее, она должна иметь активный синк.

set_pev(weapbox, pev_flags, FL_KILLME);
ExecuteHam(Ham_Think, weapbox);

разве так не удаляется ?
 
Сообщения
408
Реакции
379
Помог
13 раз(а)
Что-то сложно. Бомба это же веапонбокс и как любой веапонбокс, по идее, она должна иметь активный синк.

set_pev(weapbox, pev_flags, FL_KILLME);
ExecuteHam(Ham_Think, weapbox);

разве так не удаляется ?
Как раз сегодня обсуждали, у вепонбокса бомбы синк CWeaponBox::BombThink, поэтому CWeaponBox::Kill не вызовется и сама бомба не ремувнется при удалении вепонбокса. s1lent добавил в todo и в будущем починит это, но я решил все равно отписать, поскольку это нигде не указано
 
Сообщения
26
Реакции
12
интересно бы узнать как удалить установленную бомбу
 
Сообщения
408
Реакции
379
Помог
13 раз(а)
maFFyoZZyk,
Код:
    new bomb = find_ent_by_model(0, "grenade", "models/w_c4.mdl");
    if(is_valid_ent(bomb))
        remove_entity(bomb)
НО это сломает весь игровой процесс, таймер раунда остановится и раунд будет бесконечным.
 
Сообщения
26
Реакции
12
voed, если ее удалять после конца раунда, к примеру если победа террористов будет раньше взрыва бомбы, то не должно
25 Ноя 2019
этот способ я знал, думал может на реапи такая приблуда есть
 

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу