Правила форума Гаранты форума
Размещение рекламы AMX-X компилятор

Здравствуйте, гость Вход | Регистрация

Наши новости:

14-дек
24-апр
10-апр
11-апр

Как определить нажатие IN_ATTACK && IN_ATTACK2?

[РЕШЕНО]
Статус пользователя navigator19
сообщение 30.3.2016, 22:23
Сообщение #1
Стаж: 16 лет

Сообщений: 177
Благодарностей: 22
Полезность: 12

Как определить нажатие IN_ATTACK && IN_ATTACK2 только когда открыто меню?
Или как обновить открытое меню когда нажаты кнопки IN_ATTACK && IN_ATTACK2

spec_menu.sma
Код:

#include <amxmodx>
//#include <amxmisc>
#include <fakemeta>
#include <engine>

new onoff[33],onoff_idiot[33]

public plugin_init()
{
register_plugin("spec menu", "0.1", "P_L")
register_clcmd("amx_specmenu", "function_menu", ADMIN_KICK,"")
}

// public client_PreThink(id){
//if((entity_get_int(id,EV_INT_button) & IN_ATTACK) || (entity_get_int(id,EV_INT_button) & IN_ATTACK2))
//if((get_user_button(id) & IN_ATTACK) || (get_user_button(id) & IN_ATTACK2))
// if((pev( id,pev_oldbuttons) & IN_ATTACK) || (pev(id,pev_oldbuttons) & IN_ATTACK2))
// {
// client_print(id, print_chat, "Нажаты IN_ATTACK && IN_ATTACK2")
// function_menu(id)
// }
// }

public function_menu(id)
{
if(!(get_user_flags(id) & ADMIN_KICK)) return PLUGIN_HANDLED

new watchId = id
new isAlive = is_user_alive(id)
if(!isAlive)
{
watchId = pev(id,pev_iuser2)
if(!watchId) return PLUGIN_HANDLED
}

new langStr[255],player_name[32],authid[32],player_ip[23]
new obj = pev(id, pev_iuser2)
get_user_name(obj, player_name, 31)
get_user_authid(obj, authid, 31)
get_user_ip(obj, player_ip, 22,1)

formatex(langStr,254,"Действие над Игроком \w[\r%s\w] \w[\r%s\w] \w[\r%s\w]", player_name, authid, player_ip)

new menu = menu_create(langStr, "menu_handler")

menu_additem(menu, "\wУдарить игрока","1")
menu_additem(menu, "\wУбить игрока","2")
menu_additem(menu, "\wОслепить Игрока","3")
if(!onoff_idiot[id])
{
menu_additem( menu,"Превратить в идиота: \yВыкл", "4", 0)
}
else
{
menu_additem( menu,"Обратить из Идиота: \yВкл", "4", 0)
}

if(!onoff[id])
{
menu_additem( menu,"Закрыть глаза Игроку: \yОткрыты", "5", 0)
}
else
{
menu_additem( menu,"Открыть глаза Игроку: \yЗакрыты", "5", 0)
}
menu_additem(menu, "\wСделать 3 Скриншота Игроку","6")

menu_setprop(menu, MPROP_EXITNAME, "Выход")
menu_setprop(menu, MPROP_EXIT,MEXIT_ALL)
menu_display(id,menu,0)

return PLUGIN_HANDLED
}


public menu_handler(id, menu, item)
{
//if((entity_get_int(id,EV_INT_button) & IN_ATTACK) || (entity_get_int(id,EV_INT_button) & IN_ATTACK2))
//if((get_user_button(id) & IN_ATTACK) || (get_user_button(id) & IN_ATTACK2))
if((pev( id,pev_oldbuttons) & IN_ATTACK) || (pev(id,pev_oldbuttons) & IN_ATTACK2))
{
client_print(id, print_chat, "Нажаты IN_ATTACK && IN_ATTACK2")
function_menu(id)
}

if(item == MENU_EXIT)
{
menu_destroy(menu)
return PLUGIN_HANDLED
}

new obj = pev(id, pev_iuser2)
new data[6], iName[64], access, callback
new player_id = get_user_userid(obj)
menu_item_getinfo(menu, item, access, data, 5, iName, 63, callback)

new key = str_to_num(data)

switch(key)
{
case 1:
{
client_cmd(id, "amx_slap #%d", player_id)
}
case 2:
{
client_cmd(id, "amx_slay #%d", player_id)
}
case 3:
{
client_cmd(id, "amx_flash #%d", player_id)
}
case 4:
{
if(onoff_idiot[id])
{
client_cmd(id,"amx_unidiot #%d", player_id)
onoff_idiot[id] = 0
client_cmd(id, "spk ^"buttons/button5^"")
}
else
{
client_cmd(id,"amx_idiot #%d", player_id)
onoff_idiot[id] = 1
client_cmd(id, "spk ^"buttons/button5^"")
}
}
case 5:
{
if(onoff[id])
{
client_cmd(id,"amx_unblind #%d", player_id)
onoff[id] = 0
client_cmd(id, "spk ^"buttons/button5^"")
}
else
{
client_cmd(id,"amx_blind #%d", player_id)
onoff[id] = 1
client_cmd(id, "spk ^"buttons/button5^"")
}
}
}
function_menu(id)
return PLUGIN_HANDLED
}



Дополнительный вопрос: Какое определение нажатия кнопок лучше использовать?
Код:

if((entity_get_int(id,EV_INT_button) & IN_ATTACK) || (entity_get_int(id,EV_INT_button) & IN_ATTACK2))
if((get_user_button(id) & IN_ATTACK) || (get_user_button(id) & IN_ATTACK2))
if((fm_get_user_button(id) & IN_ATTACK) || (fm_get_user_button(id) & IN_ATTACK2))
if((pev( id,pev_oldbuttons) & IN_ATTACK) || (pev(id,pev_oldbuttons) & IN_ATTACK2))


Отредактировал: navigator19, - 30.3.2016, 23:18
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   Цитировать сообщение
Статус пользователя Stimul1
сообщение 30.3.2016, 23:05
Сообщение #2


Стаж: 13 лет

Сообщений: 227
Благодарностей: 262
Полезность: 977

http://amxxmodx.ru/lessons-on-pawn/299-kno...-konstanty.html
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя navigator19
сообщение 30.3.2016, 23:11
Сообщение #3
Стаж: 16 лет

Сообщений: 177
Благодарностей: 22
Полезность: 12

Stimul1, Это шутка, я и без этого знаю как отловить события нажатия кнопок!
Вопрос перечитайте, и на код посмотрите!
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
serfreeman1337
сообщение 30.3.2016, 23:13
Сообщение #4
Стаж: 13 лет

Сообщений: 912
Благодарности: выкл.

Тебе нужна функция, в которой будут проверки меню player_menu_info и клавиш pev_buttons, и которую нужно будет вызвать каждый раз.
В синке FM_PlayerPostThink или установкой повторяющегося set_task на эту функцию.

Для примера: Weapon Factory - Weapons and Items Spawner.
При открытии меню регаем синк, в котором у нас проверка:
Код:
public fw_EditPreThink(id){
if(idedit!=id)
return FMRES_IGNORED

Тебе эту проверку лучше сделать через player_menu_info. В этом синке у нас обновляется инфа в худе.

Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя SISA
сообщение 31.3.2016, 3:11
Сообщение #5
Стаж: 15 лет

Сообщений: 2774
Благодарностей: 2956
Полезность: 994

Цитата(serfreeman1337 @ 31.3.2016, 1:13) *
Тебе нужна функция, в которой будут проверки меню player_menu_info и клавиш pev_buttons, и которую нужно будет вызвать каждый раз.
В синке FM_PlayerPostThink или установкой повторяющегося set_task на эту функцию.

Для примера: Weapon Factory - Weapons and Items Spawner.
При открытии меню регаем синк, в котором у нас проверка:
Код:
public fw_EditPreThink(id){
if(idedit!=id)
return FMRES_IGNORED

Тебе эту проверку лучше сделать через player_menu_info. В этом синке у нас обновляется инфа в худе.


Идея верная. Я бы сделал запускаемый клиентский синк. Сам использую такой финт для оптимизации:

#define is_user_valid(%1) (1 <= %1 <= 32)

RegisterHam(Ham_Think, "player", "fw_Player_Think_Pre", 0);


public fw_Player_Think_Pre(ent)
{
// Если игрок Не Живой
if(!is_user_alive(ent))
return HAM_IGNORED;

// Если это Не Игрок
if(!is_user_valid(ent))
return HAM_SUPERCEDE;

время вызова следующего синка
set_pev(ent, pev_nextthink, get_gametime()+0.1)
тут проверка кнопок

return HAM_SUPERCEDE;
}


Соответственно, в самом меню запускаешь синк на игроке

set_pev(id, pev_nextthink, get_gametime()+0.1)

вот это задротская оптимизация -) Зато проверка кнопок без нагрузки.

Отредактировал: SISA, - 31.3.2016, 3:12
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
Статус пользователя navigator19
сообщение 31.3.2016, 4:02
Сообщение #6
Стаж: 16 лет

Сообщений: 177
Благодарностей: 22
Полезность: 12

serfreeman1337, Спасибо,
сделал так
Cкрытый текст
Код:

#include <amxmodx>
#include <fakemeta>

new onoff[33],onoff_idiot[33]
new spect_menu

public plugin_init()
{
register_plugin("spec menu", "0.1", "P_L")
register_clcmd("amx_specmenu", "function_menu", ADMIN_KICK,"")
}


public client_PostThink(id){

new menu,newmenu
player_menu_info(id,menu,newmenu)

if(newmenu == spect_menu && ((pev( id,pev_oldbuttons) & IN_ATTACK) || (pev(id,pev_oldbuttons) & IN_ATTACK2)))
{
function_menu(id)
}

}

public function_menu(id)
{

if(!(get_user_flags(id) & ADMIN_KICK)) return PLUGIN_HANDLED

new watchId = id
new isAlive = is_user_alive(id)
if(!isAlive)
{
watchId = pev(id,pev_iuser2)
if(!watchId) return PLUGIN_HANDLED
}

new langStr[255],player_name[32],authid[32],player_ip[23]
new obj = pev(id, pev_iuser2)
get_user_name(obj, player_name, 31)
get_user_authid(obj, authid, 31)
get_user_ip(obj, player_ip, 22,1)

formatex(langStr,254,"Действие над Игроком \w[\r%s\w] \w[\r%s\w] \w[\r%s\w]", player_name, authid, player_ip)
spect_menu = menu_create(langStr, "menu_handler")
menu_additem(spect_menu, "\wУдарить игрока","1")
menu_additem(spect_menu, "\wУбить игрока","2")
menu_additem(spect_menu, "\wОслепить Игрока","3")
if(!onoff_idiot[id])
{
menu_additem( spect_menu,"Превратить в идиота: \yВыкл", "4", 0)
}
else
{
menu_additem( spect_menu,"Обратить из Идиота: \yВкл", "4", 0)
}

if(!onoff[id])
{
menu_additem( spect_menu,"Закрыть глаза Игроку: \yОткрыты", "5", 0)
}
else
{
menu_additem( spect_menu,"Открыть глаза Игроку: \yЗакрыты", "5", 0)
}
menu_additem(spect_menu, "\wСделать 3 Скриншота Игроку","6")
menu_setprop(spect_menu, MPROP_EXITNAME, "Выход")
menu_setprop(spect_menu, MPROP_EXIT,MEXIT_ALL)
menu_display(id,spect_menu,0)

return PLUGIN_HANDLED
}

public menu_handler(id, menu, item)
{
if(item == MENU_EXIT) {
menu_destroy(menu)
return PLUGIN_HANDLED
}

new obj = pev(id, pev_iuser2)
new data[6], iName[64], access, callback
new player_id = get_user_userid(obj)
menu_item_getinfo(menu, item, access, data, 5, iName, 63, callback)

new key = str_to_num(data)

switch(key)
{
case 1:
{
client_cmd(id, "amx_slap #%d", player_id)
}
case 2:
{
client_cmd(id, "amx_slay #%d", player_id)
}
case 3:
{
client_cmd(id, "amx_flash #%d", player_id)
}
case 4:
{
if(onoff_idiot[id])
{
client_cmd(id,"amx_unidiot #%d", player_id)
onoff_idiot[id] = 0
client_cmd(id, "spk ^"buttons/button5^"")
}
else
{
client_cmd(id,"amx_idiot #%d", player_id)
onoff_idiot[id] = 1
client_cmd(id, "spk ^"buttons/button5^"")
}
}
case 5:
{
if(onoff[id])
{
client_cmd(id,"amx_unblind #%d", player_id)
onoff[id] = 0
client_cmd(id, "spk ^"buttons/button5^"")
}
else
{
client_cmd(id,"amx_blind #%d", player_id)
onoff[id] = 1
client_cmd(id, "spk ^"buttons/button5^"")
}
}
}
function_menu(id)
return PLUGIN_HANDLED
}


Хотел через таск но чета кода на много больше походу получится, понятно что с client_PostThink и client_PreThink нужно быть аккуратнее, 200 запросов в секунду это огого, погоняю на рабочем сервере посмотрю


SISA, Пасиб, попробую и твою идею

Отредактировал: navigator19, - 31.3.2016, 4:08
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя csnet
сообщение 31.3.2016, 4:55
Сообщение #7
Стаж: 12 лет

Сообщений: 4808
Благодарностей: 3849
Полезность: 690

для этих целей FM_CMDStart еще юзают.


go v cs:go
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
Статус пользователя navigator19
сообщение 31.3.2016, 5:48
Сообщение #8
Стаж: 16 лет

Сообщений: 177
Благодарностей: 22
Полезность: 12

csnet, Спасибо, хорошая идея, но чет мне кажется или когда работает этот форвард стрельба как-то меняется?
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя SISA
сообщение 31.3.2016, 11:14
Сообщение #9
Стаж: 15 лет

Сообщений: 2774
Благодарностей: 2956
Полезность: 994

navigator19,

не 200 вызовов, а количество игроков * на их FPS. Если играет 32 человека со 100FPS (и на сервере sv_maxupdaterate 100), значит будет 3200 вызовов в секунду. Из всех возможных вариантов, вы взяли самый прожорливый client_PostThink, который с энжина вызывается + дважды вызываете функцию "pev" в каждом синке, когда можно обойтись одним вызовом.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
Статус пользователя navigator19
сообщение 31.3.2016, 11:29
Сообщение #10
Стаж: 16 лет

Сообщений: 177
Благодарностей: 22
Полезность: 12

SISA, Да чет с 200 я не так посчитал, не спамши то, пытался разобраться в вашем примере но чета не смог, не могли бы вы скинуть то что предлагали в рабочем плагине, или мой переделать с вашим кодом?
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя SISA
сообщение 31.3.2016, 14:16
Сообщение #11
Стаж: 15 лет

Сообщений: 2774
Благодарностей: 2956
Полезность: 994

Цитата(navigator19 @ 31.3.2016, 13:29) *
SISA, Да чет с 200 я не так посчитал, не спамши то, пытался разобраться в вашем примере но чета не смог, не могли бы вы скинуть то что предлагали в рабочем плагине, или мой переделать с вашим кодом?


Мой пример немного для задротов smile.gif Там придется ещё ловить закрытие меню, чтобы остановить синк, а это уже геморр.

Код на разовый вызов функции меню при нажатии любой кнопкой атаки:

Код
#include <amxmisc>
#include <fakemeta>

public plugin_init()
{
    register_forward(FM_PlayerPreThink, "FM_PreThink_Pre", 0);
}

public FM_PreThink_Pre(id)
{
    static iOldButtons, iButton;

    iOldButtons = pev(id, pev_oldbuttons);
    iButton = pev(id, pev_button);

    if(iOldButtons & IN_ATTACK || iOldButtons & IN_ATTACK2)
        return FMRES_IGNORED;

    if(!(iButton & IN_ATTACK) && !(iButton & IN_ATTACK2))
        return FMRES_IGNORED;

    new menu, newmenu;
    player_menu_info(id, menu, newmenu);

    if(newmenu != spect_menu)
        return FMRES_IGNORED;

    console_print(0, "Test menu")

    return FMRES_IGNORED;
}
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
  Ответить в данную темуНачать новую тему
 
0 пользователей и 1 гостей читают эту тему: