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

Сообщения
432
Реакции
410
Помог
14 раз(а)


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


Недавно писал плагин, в котором нужно было изменять время минирования/разминирования бомбы. И часть инфы было найти проблематично. Оффсеты для 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, что помогал тестить
 
Сообщения
432
Реакции
410
Помог
14 раз(а)
Удаление дропнутой бомбы без утечек памяти

Код:
    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()
    }
 
Сообщения
145
Реакции
276
Помог
1 раз(а)
Удаление дропнутой бомбы без утечек памяти
Что-то сложно. Бомба это же веапонбокс и как любой веапонбокс, по идее, она должна иметь активный синк.

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

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

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

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

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

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