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

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

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

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

2 страниц V   1 2

Закрытие меню

voed
сообщение 8.12.2014, 22:21
Сообщение #1
Стаж: 11 лет

Сообщений: 2593
Благодарностей: 1760
Полезность: 405

Добрый день. Пытаюсь закрыть меню из таска с помощью menu_destroy. В итоге менюшка у игрока продолжает висеть, когда он жмет кнопку вылетает ошибка "Invalid menu id 0(1)". Что я делаю не так?)


код
Код:
public startVote(id)
{
new title[192]
format(title, 191, "%L", id, "AMM_VOTE_MENU_TITLE")
startVoteMenu = menu_create(title, "startVoteHandler", 1)
menu_setprop( startVoteMenu, MPROP_PERPAGE, 0 )
menu_setprop( startVoteMenu, MPROP_EXIT, MEXIT_NEVER )
for(new i=0; i<g_MapsInVoteCount; i++)
{
new key[3]
num_to_str(i, key, 2)
menu_additem(startVoteMenu, g_MapsInVote[i], key, 0)
}
for(new player=1; player<33; player++)
{
if(is_user_connected(player))
{
menu_display(player, startVoteMenu)
}
}

set_task(1.0, "startVoteTask", VOTE_TASK, _, _, "a", 15)
return PLUGIN_HANDLED
}

public startVoteHandler(id, menu, item)
{
if (item == MENU_EXIT)
{
clearvote(id)
return PLUGIN_HANDLED
}

new s_Data[6], s_Name[64], i_Access, i_Callback, name[64]
menu_item_getinfo(menu, item, i_Access, s_Data, charsmax(s_Data), s_Name, charsmax(s_Name), i_Callback)
new key = str_to_num(s_Data)
get_user_name(id, name, 63)
client_print(id, print_chat, "key %i", key)
client_print(id, print_chat, "%s voted for %s", name, g_MapsInVote[key])
g_MapVotes[key]++

clearvote(id)
return PLUGIN_HANDLED
}

public startVoteTask(id)
{
new pid=id-100
g_VoteSeconds--
set_hudmessage(.holdtime=2, .channel=2)
show_hudmessage(pid, "%i seconds", g_VoteSeconds)
if(g_VoteSeconds < 1)
{
clearvote(pid)
return PLUGIN_HANDLED
}
return PLUGIN_CONTINUE
}
public clearvote(id)
{
if(task_exists(VOTE_TASK))
{
remove_task(VOTE_TASK)
}
menu_cancel(id)
menu_destroy(startVoteMenu)
g_MapsInVoteCount = 0;
g_VoteSeconds = 15;
return PLUGIN_HANDLED
}


Отредактировал: voed, - 8.12.2014, 22:24
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   Цитировать сообщение
Статус пользователя Legenda
сообщение 8.12.2014, 22:44
Сообщение #2


Иконка группы

Стаж: 16 лет

Сообщений: 3619
Благодарностей: 1706
Полезность: 1010

Меценат Меценат

ты думаешь не верно..

для начала прочитать
http://amxxmodx.ru/core/amxmodxinc/newmenu...nnoe-menyu.html

и понять разницу между уничтожение меню и закрытием меню у клиента
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
voed
сообщение 8.12.2014, 22:51
Сообщение #3
Стаж: 11 лет

Сообщений: 2593
Благодарностей: 1760
Полезность: 405

Цитата(Legenda @ 8.12.2014, 21:40) *
ты думаешь не верно..

для начала прочитать
http://amxxmodx.ru/core/amxmodxinc/newmenu...nnoe-menyu.html

и понять разницу между уничтожение меню и закрытием меню у клиента

Код:
   menu_cancel(id)
menu_destroy(startVoteMenu)

Как видишь, я пытаюсь сначала закрыть меню, а затем уже уничтожить его. Но оно не закрывается.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя Legenda
сообщение 8.12.2014, 22:59
Сообщение #4


Иконка группы

Стаж: 16 лет

Сообщений: 3619
Благодарностей: 1706
Полезность: 1010

Меценат Меценат

значит id не верный
проверь
player_menu_info
и hud обнови на всякий случай)
что тут думать-то)
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
voed
сообщение 8.12.2014, 23:01
Сообщение #5
Стаж: 11 лет

Сообщений: 2593
Благодарностей: 1760
Полезность: 405

Цитата(Legenda @ 8.12.2014, 21:55) *
значит id не верный
что тут думать-то)

Если бы id был неверный, вылетала бы ошибка, так что проблема не в этом)
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя Legenda
сообщение 8.12.2014, 23:03
Сообщение #6


Иконка группы

Стаж: 16 лет

Сообщений: 3619
Благодарностей: 1706
Полезность: 1010

Меценат Меценат

Цитата(voed @ 8.12.2014, 22:57) *
Если бы id был неверный, вылетала бы ошибка, так что проблема не в этом)

с чего бы это?
кто тебе такое сказал?)

и зачем ты везде пихаешь return PLUGIN_HANDLED ?
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
voed
сообщение 8.12.2014, 23:06
Сообщение #7
Стаж: 11 лет

Сообщений: 2593
Благодарностей: 1760
Полезность: 405

Цитата(Legenda @ 8.12.2014, 21:59) *
с чего бы это?
кто тебе такое сказал?)

Я проверил)
Цитата
и зачем ты везде пихаешь return PLUGIN_HANDLED ?

В этом нет ничего плохого
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя Legenda
сообщение 8.12.2014, 23:09
Сообщение #8


Иконка группы

Стаж: 16 лет

Сообщений: 3619
Благодарностей: 1706
Полезность: 1010

Меценат Меценат

set_task(1.0, "startVoteTask", VOTE_TASK, _, _, "a", 15)


public startVoteTask(id)

какую-то ерунду ты написал
откуда id взял? ответ - ни откуда

правильно передавай параметры в функциях



Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
voed
сообщение 8.12.2014, 23:13
Сообщение #9
Стаж: 11 лет

Сообщений: 2593
Благодарностей: 1760
Полезность: 405

Цитата(Legenda @ 8.12.2014, 22:05) *
set_task(1.0, "startVoteTask", VOTE_TASK, _, _, "a", 15)


public startVoteTask(id)

какую-то ерунду ты написал
откуда id взял? ответ - ни откуда

правильно передавай параметры в функциях

#define VOTE_TASK id+100
Никакой ерунды нет, проблема не в этом
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя Legenda
сообщение 8.12.2014, 23:21
Сообщение #10


Иконка группы

Стаж: 16 лет

Сообщений: 3619
Благодарностей: 1706
Полезность: 1010

Меценат Меценат

Цитата
#define VOTE_TASK id+100
Никакой ерунды нет, проблема не в этом

знатный костыль
id игрока приравнивать к id задачи.(((( это не правильно и так лучше не делать....


условие проверь
залогируй его
Код:
   if(g_VoteSeconds < 1)
{
clearvote(pid)
return PLUGIN_HANDLED
}
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
voed
сообщение 8.12.2014, 23:24
Сообщение #11
Стаж: 11 лет

Сообщений: 2593
Благодарностей: 1760
Полезность: 405

Цитата(Legenda @ 8.12.2014, 22:17) *
знатный костыль
id игрока приравнивать к id задачи.(((( это не правильно и так лучше не делать....


условие проверь
залогируй его
Код:
   if(g_VoteSeconds < 1)
{
clearvote(pid)
return PLUGIN_HANDLED
}

Это нормально, если мне нужен отдельный таск для каждого игрока. С условием все нормально, проблема именно в menu_cancel
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя [WPMG]PRoSToTeM@
сообщение 8.12.2014, 23:27
Сообщение #12
Стаж: 13 лет

Сообщений: 1514
Благодарностей: 1025
Полезность: 725

У тебя же одна менюшка на всех игроков, а ты уничтожаешь её после cancel только одному игроку, а надо всем cancel вызывать.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
voed
сообщение 8.12.2014, 23:32
Сообщение #13
Стаж: 11 лет

Сообщений: 2593
Благодарностей: 1760
Полезность: 405

Цитата([WPMG]PRoSToTeM@ @ 8.12.2014, 22:23) *

У тебя же одна менюшка на всех игроков

Нет, не одна. Да и я один был на сервере, когда тестил
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя [WPMG]PRoSToTeM@
сообщение 8.12.2014, 23:36
Сообщение #14
Стаж: 13 лет

Сообщений: 1514
Благодарностей: 1025
Полезность: 725

Цитата(voed @ 8.12.2014, 23:28) *
Нет, не одна.

Т.е. это не одна?
Код:
   for(new player=1; player<33; player++)
{
if(is_user_connected(player))
{
menu_display(player, startVoteMenu)
}
}


И зачем здесь проверка task_exists?
Код:
   if(task_exists(VOTE_TASK))
{
remove_task(VOTE_TASK)
}
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя [WPMG]PRoSToTeM@
сообщение 8.12.2014, 23:47
Сообщение #15
Стаж: 13 лет

Сообщений: 1514
Благодарностей: 1025
Полезность: 725

menu_cancel вызывает обработчик меню с item MENU_EXIT. Ты из обработчика вызываешь menu_cancel, он снова вызывает обработчик, снова вызывается menu_cancel (только уже ничего не происходит, т.к. у игрока уже меню "закрыто"), затем вызывается menu_destroy (менюшка нормально уничтожается), а затем ещё раз menu_destroy (который после первого menu_cancel должен был вызваться) и вылетает ошибка.

Код
startVoteHandler
    menu_cancel (newmenu = -1, вызываем обработчик)
        startVoteHandler
            menu_cancel (newmenu уже -1, не вызываем обработчик)
            menu_destroy (удаляем menu)
    menu_destroy (удаляемое меню не существует, здесь ошибка)


Можешь прологировать вызовы, по идее должно быть именно так.

Вызывай menu_destroy именно из обработчика, а menu_cancel именно в тот момент когда его надо "скрывать".

Отредактировал: [WPMG]PRoSToTeM@, - 8.12.2014, 23:45
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
voed
сообщение 8.12.2014, 23:57
Сообщение #16
Стаж: 11 лет

Сообщений: 2593
Благодарностей: 1760
Полезность: 405

[WPMG]PRoSToTeM@, ты видимо так и не понял сути проблемы)
Взял код из примера
Скрытый текст
Код:
#include <amxmodx>

//This will hold the VoteMenu
new gVoteMenu;
//This will hold the votes for each option
new gVotes[2];
//This determines if a vote is already happening
new gVoting;

public plugin_init()
{
//Register a way to get to your vote...
register_clcmd( "start_vote","StartVote" );
}
public StartVote( id )
{
//If there is already a vote, don't start another
if ( gVoting )
{
client_print( id, print_chat, "There is already a vote going." );
//We return PLUGIN_HANDLED so the person does not get Unknown Command in console
return PLUGIN_HANDLED;
}

//Reset vote counts from any previous votes
gVotes[0] = gVotes[1] = 0;
//Note that if you have more than 2 options, it would be better to use the line below:
//arrayset( gVotes, 0, sizeof gVotes );

//Store the menu in the global
gVoteMenu = menu_create( "\rLook at this Vote Menu!:", "menu_handler" );

//Add some vote options
menu_additem( gVoteMenu, "Vote Option 1", "", 0 );
menu_additem( gVoteMenu, "Vote Option 2", "", 0 );

//We will need to create some variables so we can loop through all the players
new players[32], pnum, tempid;

//Fill players with available players
get_players( players, pnum );

//Start looping through all players to show the vote to
for ( new i; i < pnum; i++ )
{
//Save a tempid so we do not re-index
tempid = players[i];

//Show the vote to this player
menu_display( tempid, gVoteMenu, 0 );

//Increase how many players are voting
gVoting++;
}

//End the vote in 10 seconds
set_task(10.0, "EndVote" );

return PLUGIN_HANDLED;
}
public menu_handler( id, menu, item )
{
//If the menu was exited or if there is not a vote
if ( item == MENU_EXIT || !gVoting )
{
//Note were not destroying the menu
return PLUGIN_HANDLED;
}

//Increase the votes for what they selected
gVotes[ item ]++;

//Note were not destroying the menu
return PLUGIN_HANDLED;
}
public EndVote()
{
//If the first option recieved the most votes
if ( gVotes[0] > gVotes[1] )
client_print(0, print_chat, "First option recieved most votes (%d )", gVotes[0] );

//Else if the second option recieved the most votes
else if ( gVotes[0] < gVotes[1] )
client_print(0, print_chat, "Second option recieved most votes (%d )", gVotes[1] );

//Otherwise the vote tied
else
client_print(0, print_chat, "The vote tied at %d votes each.", gVotes[0] );

//Don't forget to destroy the menu now that we are completely done with it
menu_destroy( gVoteMenu );

//Reset that no players are voting
gVoting = 0;
}


Скомпилировал, затестил - спустя 10 секунд меню продолжает висеть на клиенте.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя [WPMG]PRoSToTeM@
сообщение 9.12.2014, 0:03
Сообщение #17
Стаж: 13 лет

Сообщений: 1514
Благодарностей: 1025
Полезность: 725

voed, я тебе объяснил, почему у тебя вылетает ошибка. Если хочешь скрывать меню более менее нормально, то вот код:
Код:
    show_menu(id, 0, "^n", 1) 


Только удалять не забывай.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
voed
сообщение 9.12.2014, 0:04
Сообщение #18
Стаж: 11 лет

Сообщений: 2593
Благодарностей: 1760
Полезность: 405

Цитата([WPMG]PRoSToTeM@ @ 8.12.2014, 22:56) *

voed, я тебе объяснил, почему у тебя вылетает ошибка. Если хочешь скрывать меню более менее нормально, то вот код:
Код:
    show_menu(id, 0, "^n", 1) 

Именно этого я и пытался добиться. Спасибо
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Safety1st
сообщение 9.12.2014, 0:43
Сообщение #19
Стаж: 14 лет
Город: Moscow

Сообщений: 7228
Благодарностей: 8071
Полезность: 196

voed, у тебя пока алгоритм неверный.

Уничтожать и скрывать меню (оно у тебя одно) нужно однократно после окончания голосования. Сначала menu_destroy(), при этом у всех, кто не воспользовался меню, автоматически вызовется действие, выполняющееся по menu_close(). Другими словами, меню 'закроется' на сервере у всех, у кого оно было открыто. А чтобы закрыть у игроков - уже show_menu() выше, самый простой способ - поставить id=0, выборочно - сложнее. Важно не перепутать порядок действий: сначала 'уничтожить' меню голосования, потом показать пустое.

Кстати, в AMXX 1.8.3-dev такой проблемы вообще нет: там и new menus с возможностью задать время, и автозакрытие меню при показе нового.

Отредактировал: Safety1st, - 9.12.2014, 2:45
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 2 раз
   + Цитировать сообщение
voed
сообщение 9.12.2014, 0:49
Сообщение #20
Стаж: 11 лет

Сообщений: 2593
Благодарностей: 1760
Полезность: 405

Цитата(Safety1st @ 8.12.2014, 23:39) *
voed, у тебя пока алгоритм неверный.

Уничтожать и скрывать меню (оно у тебя одно) нужно однократно после окончания голосования. Сначала menu_destroy(), при этом у всех, кто не воспользовался меню, автоматически вызовется действие, выполняющееся по menu_close(). Другими словами, меню 'закроется' на сервере у всех, у кого оно было открыто. А чтобы закрыть у игроков - уже show_menu() выше, самый простой способ - поставить id=0, выборочно - сложнее. Важно не перепутать порядок действий: сначала 'уничтожить' меню голосования, потом показать пустое.

Кстати, в AMXX 1.8.3-dev такой проблемы вообще нет: там и new menus с возможностью задать время, и автозакрытие меню при показе нового.

Я уже переписал алгоритм, мне было важно понять, почему менюшка не закрывается)
Кстати, именно 1.8.3, но когда задавал время ничего не происходило
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
2 страниц V   1 2
 
Ответить в данную темуНачать новую тему
 
0 пользователей и 1 гостей читают эту тему: