Редактирование пунктов меню

Сообщения
134
Реакции
40
Помог
2 раз(а)
Решил модифицировать меню сервера. Решил менять цвет/название пунктов в зависимости от выполнения нужных мне условий.
Получается как-то так:

Код:
    switch (kz_get_timer_state(id)){
    case TIMER_ENABLED: {
    formatex(szMsg, charsmax(szMsg), "%L^n", id, "MAINMENU_ONPAUSE");
        }
    case TIMER_PAUSED: {
        formatex(szMsg, charsmax(szMsg), "\y%L^n", id, "MAINMENU_OFFPAUSE");
        }
    case TIMER_DISABLED: {
        formatex(szMsg, charsmax(szMsg), "\d%L^n", id, "MAINMENU_ONPAUSE");
        }
        }
    menu_additem(iMenu, szMsg);

    formatex(szMsg, charsmax(szMsg), "%L^n", id, "MAINMENU_START");
    menu_additem(iMenu, szMsg);

    if(is_user_alive(id)){
    formatex(szMsg, charsmax(szMsg), "%L", id, "MAINMENU_LSPEC");
        }else{
        formatex(szMsg, charsmax(szMsg), "%L", id, "MAINMENU_DSPEC");
        }
        menu_additem(iMenu, szMsg);
Хотел узнать правильный ли это подход или я что-то упускаю.
А так же возникает одна неприятная вещь, например пункт с паузой должен гореть серым цветом, визуальная давая понять игроку, что он неактивен. Но когда условия его активации соблюдены, если в этот момент меню у игрока уже было открыто, соответственно оно само по себе не обновляется и пункт остается серым, хотя его и можно нажать. Как можно выйти из этой ситуации? У меня крутится вариант обновлять меню игроку через amxclient_cmd(id, "menu");, в момент соблюдения всех условий, в конкретно данном случаи, когда игрок нажмет на кнопку старта, но тогда надо отлавливать открыто ли конкретно это меню у игрока в момент нажатия кнопки, что бы не открывать его тем, кто в этом не нуждается. Если этот вариант верный, то можете подсказать как это сделать для нового меню? Я видел варианты на этом форуме, но они все были для меню старого типа.
 
Сообщения
3,582
Реакции
1,570
Помог
137 раз(а)
Сообщения
134
Реакции
40
Помог
2 раз(а)
Nordic Warrior, спасибо, если я правильно разобрался на простом примере у меня получилось так, работает. а как быть если, нужно менять название пункта и цвета, только как я делал выше?

Код:
    new g_cpCallback = menu_makecallback("cpCallback")

    formatex(szMsg, charsmax(szMsg), "%L", id, "MAINMENU_TP");
    menu_additem(iMenu, szMsg,"1", 0, g_cpCallback);

public cpCallback(id, menu, item){

    if(item < 0) return PLUGIN_CONTINUE

    if(kz_get_cp_num(id) == 0){
        return ITEM_DISABLED
    }

    return ITEM_ENABLED
}
 
Сообщения
3,582
Реакции
1,570
Помог
137 раз(а)
Space Impact, отключённый пункт и так серый.
А что касается названия, получаешь название пункта, форматируешь новое название и задаешь название пункту.
 
Сообщения
134
Реакции
40
Помог
2 раз(а)
Nordic Warrior, насчет цвета, я имел ввиду немного другое. допустим при выходе в спектра менять название и цвет пункта, оставляя его активным. можешь показать пример пожалуйста, как поменять названия пункта твоим способом и сказать в чем его преимущество?
 
Сообщения
892
Реакции
149
Помог
25 раз(а)
Space Impact, menu_item_getinfo + menu_item_setname. Можешь получать название пункта через name, namelen в item_getinfo, и заменяешь через item_setname.

C++:
public cpCallback(id, menu, item){
    new szName[64];
    menu_item_getinfo(menu, item, .name = szName, .namelen = charsmax(szName));
  
    if(item < 0) return PLUGIN_CONTINUE

    menu_item_setname(menu, item, fmt("%s твой текст", szName));

    if(kz_get_cp_num(id) == 0){
        return ITEM_DISABLED
    }

    return ITEM_ENABLED
}
Правда тут для AmxModX 1.9.0
 
Сообщения
134
Реакции
40
Помог
2 раз(а)
ImmortalAmxx, спасибо! Вчера уже сам нашел под ночь, только не разобрался, как подставлять текст со словаря, но с твоим примером стало понятно. Только пока не могу понять, получается кода будет в два раза больше и проверок, еще буду проверять на конкретный итем пункта меню. а преимущество в чем? И не понял насчет AmxModX 1.9.0, его и использую)
 
Сообщения
3,582
Реакции
1,570
Помог
137 раз(а)
Space Impact, так я не сказал, что твой способ был неправильный.
Мне способ с коллбеком больше нравится, так как получается форматирование отдельно от самого создания меню, проще воспринимается.
 
Сообщения
892
Реакции
149
Помог
25 раз(а)
Space Impact, кстати, тебе не обязательно указывать все параметры в menu_additem, что бы добавить callback, вроде с 1.8.3 эта фишка есть.
Можешь заменить
C++:
menu_additem(iMenu, szMsg,"1", 0, g_cpCallback);
На
Код:
menu_additem(iMenu, szMsg, .callback = g_cpCallback);
Если не ошибаюсь, просто, указывая после имени цифру в "", как у тебя это "1", нужно получать ещё menu_item_getinfo, и через str_to_num получать стринг в число, и затем уже там гонять их через if/switch. А так, можно просто сделать:
if(item == 0) // первый пункт меню. И так далее.
И еще, у тебя калбек называется g_cpCallback, но разве она глобальная у тебя? Ты её только в этом меню используешь, но это уже придирка.
 
Сообщения
134
Реакции
40
Помог
2 раз(а)
ImmortalAmxx, Nordic Warrior, я понял, спасибо, все учту.

насчет обновления пунктов меню если оно уже было открыто у игрока. я сделал так:

Код:
kz_register_cmd("remenu", "cmdreMainMenu");

public cmdreMainMenu(id){
        new iOldMenu, iNewMenu
        player_menu_info(id, iOldMenu, iNewMenu)
        if(iNewMenu != NO_MENU && iNewMenu == iMenu)
        {
        cmdMainMenu(id);
        }

    return PLUGIN_HANDLED;

}
и потом в нужном мне плагине использую amxclient_cmd(id, "remenu"); .
приемлемый способ или есть варианты получше?
 
Сообщения
3,582
Реакции
1,570
Помог
137 раз(а)
Space Impact, для чего использовать команду? Вызывай функцию напрямую. Или тебе надо в других плагинах?
 
Сообщения
134
Реакции
40
Помог
2 раз(а)
Nordic Warrior, да, меню идет отдельным плагином. да и в целом вся сборка kz, которую я использую разделена на отдельные модули. и например функция отлова нажатия кнопки таймера находится в kz_core, и мне надо в это же событие вставить обновление меню из kz_menu.
 

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

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