Продвинутая работа с диалогами в Pawn

Активный
Статус
Сообщения
516
Лайки
32

8

месяц на сайте

Диалоги - основной способ взаимодействия. Разберем продвинутые техники.

Многостраничные диалоги
Код:
new DialogPage[MAX_PLAYERS];
new DialogData[MAX_PLAYERS][32];

ShowMultiPageDialog(playerid, dialogid, page)
{
    new string[512], items = 20; // 20 элементов на страницу
    new start = page * items;
    new end = start + items;
    
    if(end > TotalItems)
    {
        end = TotalItems;
    }
    
    for(new i = start; i < end; i++)
    {
        format(string, sizeof(string), "%s%s\n", string, ItemList[i][itemName]);
    }
    
    // Добавление навигации
    if(page > 0)
    {
        format(string, sizeof(string), "%s<< Предыдущая\n", string);
    }
    if(end < TotalItems)
    {
        format(string, sizeof(string), "%sСледующая >>\n", string);
    }
    
    DialogPage[playerid] = page;
    ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_LIST, "Многостраничный список", string, "Выбрать", "Отмена");
}

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
    if(dialogid == DIALOG_MULTIPAGE)
    {
        if(response)
        {
            new page = DialogPage[playerid];
            new items = 20;
            new start = page * items;
            
            // Проверка навигации
            if(listitem == items && page > 0)
            {
                ShowMultiPageDialog(playerid, dialogid, page - 1);
                return 1;
            }
            if(listitem == items + 1 && (start + items) < TotalItems)
            {
                ShowMultiPageDialog(playerid, dialogid, page + 1);
                return 1;
            }
            
            // Обработка выбора
            new selectedIndex = start + listitem;
            ProcessItemSelection(playerid, selectedIndex);
        }
    }
    return 1;
}

Динамические диалоги
Код:
ShowDynamicListDialog(playerid, title[], items[][], count)
{
    new string[512] = "";
    for(new i = 0; i < count && i < 20; i++)
    {
        format(string, sizeof(string), "%s%s\n", string, items[i]);
    }
    
    ShowPlayerDialog(playerid, DIALOG_DYNAMIC, DIALOG_STYLE_LIST, title, string, "Выбрать", "Отмена");
    DialogData[playerid][0] = count; // Сохранение количества
}

// Использование
CMD:weapons(playerid, params[])
{
    new weapons[10][32], count = 0;
    
    // Заполнение списка доступного оружия
    for(new i = 0; i < sizeof(WeaponList); i++)
    {
        if(PlayerHasAccess(playerid, WeaponList[i][wLevel]))
        {
            format(weapons[count], sizeof(weapons[]), "%s", WeaponList[i][wName]);
            count++;
        }
    }
    
    ShowDynamicListDialog(playerid, "Доступное оружие", weapons, count);
    return 1;
}

Вложенные диалоги
Код:
new DialogStack[MAX_PLAYERS][10]; // Стек диалогов
new DialogStackSize[MAX_PLAYERS];

PushDialog(playerid, dialogid)
{
    if(DialogStackSize[playerid] < sizeof(DialogStack[]))
    {
        DialogStack[playerid][DialogStackSize[playerid]++] = dialogid;
    }
}

PopDialog(playerid)
{
    if(DialogStackSize[playerid] > 0)
    {
        DialogStackSize[playerid]--;
        return DialogStack[playerid][DialogStackSize[playerid]];
    }
    return -1;
}

ShowMainMenu(playerid)
{
    PushDialog(playerid, DIALOG_MAIN);
    ShowPlayerDialog(playerid, DIALOG_MAIN, DIALOG_STYLE_LIST, 
        "Главное меню", "Настройки\nИнвентарь\nСтатистика", "Выбрать", "Закрыть");
}

ShowSettingsMenu(playerid)
{
    PushDialog(playerid, DIALOG_SETTINGS);
    ShowPlayerDialog(playerid, DIALOG_SETTINGS, DIALOG_STYLE_LIST,
        "Настройки", "Звук\nГрафика\nУправление", "Выбрать", "Назад");
}

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
    if(dialogid == DIALOG_SETTINGS)
    {
        if(!response) // Нажата кнопка "Назад"
        {
            PopDialog(playerid);
            ShowMainMenu(playerid);
            return 1;
        }
        // Обработка выбора
    }
    return 1;
}

Диалоги с валидацией
Код:
ShowLoginDialog(playerid)
{
    ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD,
        "Вход в систему", "Введите ваш пароль:", "Войти", "Отмена");
    PlayerLoginAttempts[playerid] = 0;
}

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
    if(dialogid == DIALOG_LOGIN)
    {
        if(response)
        {
            if(strlen(inputtext) == 0)
            {
                SendClientMessage(playerid, -1, "Пароль не может быть пустым");
                ShowLoginDialog(playerid);
                return 1;
            }
            
            if(strlen(inputtext) < 6)
            {
                SendClientMessage(playerid, -1, "Пароль должен быть не менее 6 символов");
                ShowLoginDialog(playerid);
                return 1;
            }
            
            // Проверка пароля
            if(CheckPassword(playerid, inputtext))
            {
                PlayerInfo[playerid][pLoggedIn] = true;
                SendClientMessage(playerid, -1, "Успешный вход!");
            }
            else
            {
                PlayerLoginAttempts[playerid]++;
                if(PlayerLoginAttempts[playerid] >= 3)
                {
                    Kick(playerid);
                }
                else
                {
                    new string[128];
                    format(string, sizeof(string), "Неверный пароль. Осталось попыток: %d", 
                        3 - PlayerLoginAttempts[playerid]);
                    SendClientMessage(playerid, -1, string);
                    ShowLoginDialog(playerid);
                }
            }
        }
    }
    return 1;
}

Важные моменты:
- Ограничивайте размеры списков
- Реализуйте навигацию для больших списков
- Валидируйте пользовательский ввод
- Используйте стеки для вложенных диалогов

Продвинутые диалоги улучшают пользовательский опыт!
 

1 человек читают эту тему (Всего: 1, Пользователей: 0, Гостей: 1)

Сверху