Форум Pawn.Wiki - Воплоти мечту в реальность!: DialogTree - современный обработчик диалогов - Форум Pawn.Wiki - Воплоти мечту в реальность!

Перейти к содержимому

  • (4 Страниц) +
  • « Первая
  • 2
  • 3
  • 4
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

DialogTree - современный обработчик диалогов древовидный диалоговый процессор Оценка: ***** 1 Голосов

#31
Пользователь онлайн   M I S T E V 

  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияDeimoS (25 февраля 2025 - 23:05) писал:

Нажмите сюда, чтобы прочитать это сообщение. [Показать]

Изначально была идея сделать быстрый переход вперёд/назад по диалогам, для этого надо где-то хранить информацию о каждом диалоге. Потом начались сыпаться другие идеи по той или иной реализации, что приводило к ещё большему раздуванию кода :blush:

По итогу система писалась в разное время с большими промежутками, поэтому и допущены такие ошибки, как с GetDialogCount :facepalm:

В плане нагруженности при создании диалога - не сказал бы, я сам лично использую эту библиотеку и получается довольно удобно, но тут на любителя. Никто не мешает вносить данные напрямую в OpenPlayerDialog, которые можно получать как угодно, но зачем, если можно сделать для этого отдельные функции, которые можно размещать в удобном месте.

Переделать под ID уже давно думал, но всё не доходило до этого, в ближайшее время всё же исправлю.

DIALOG_BUTTON_ESC - условно экспериментальная функция, которая по умолчанию отключена. Кто понимает, как это работает, может воспользоваться - есть возможность :wink:

Насчёт страниц в DLG_STYLE_BOOK - не нашёл другого варианта реализации, смотрел твои же подобные темы, возможно, в коде сложно выглядит :unsure:

Не хотел создавать доп функцию strcpy для записи. Мне не сложно два раза указать массив для очистки и записи, в плане читаемости - не думаю что сильно портит

Насчёт FS подумаю как подобное реализовать. В плане лимита - он же будет для каждого скрипта свой, который можно подредактировать через макрос. Создам доп опцию, чтобы Local на Remote заменить :yes:

Любая критика и предложения - приветствуются, спасибо :yes:



Цитата

UPD: С минусом мисскликнул

Тема открыта: https://pawn.wiki/in...opki-reputacii/

Сообщение отредактировал M I S T E V: 25 февраля 2025 - 23:42

0

#32
Пользователь офлайн   DeimoS 

  • Evil Scripter
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияM I S T E V (25 февраля 2025 - 23:41) писал:

Изначально была идея сделать быстрый переход вперёд/назад по диалогам, для этого надо где-то хранить информацию о каждом диалоге. Потом начались сыпаться другие идеи по той или иной реализации, что приводило к ещё большему раздуванию кода :blush:


Может я чего-то не понимаю, но в mdialog и подобных ему обработчиках диалогов всё и так же максимально просто

new const dDialog_First[] = "dDialog_First";
new const dDialog_Second[] = "dDialog_Second";
new const dDialog_Third[] = "dDialog_Third";



DialogCreate:dDialog_First(playerid)
{
    Dialog_Open(playerid, dDialog_First, DIALOG_STYLE_MSGBOX, "Диалог 1", "Перейти в следующий диалог?", "Да", "Нет");
}

DialogResponse:dDialog_First(playerid, response, listitem, inputtext[])
{
    if(!response)
    {
        return 1;
    }
    
    Dialog_Show(playerid, dDialog_Second);
    return 1;
}


DialogCreate:dDialog_Second(playerid)
{
    Dialog_Open(playerid, dDialog_Second, DIALOG_STYLE_MSGBOX, "Диалог 2", "Перейти в следующий диалог или вернуться назад?", "Следующий", "Предыдущий");
}

DialogResponse:dDialog_Second(playerid, response, listitem, inputtext[])
{
    if(!response)
    {
        Dialog_Show(playerid, dDialog_First);
        return 1;
    }
    
    Dialog_Show(playerid, dDialog_Third);
    return 1;
}


DialogCreate:dDialog_Third(playerid)
{
    Dialog_Open(playerid, dDialog_Third, DIALOG_STYLE_MSGBOX, "Диалог 3", "Вы дошли до последнего диалога. Поздравляю!", "Назад", "");
}

DialogResponse:dDialog_Third(playerid, response, listitem, inputtext[])
{
    Dialog_Show(playerid, dDialog_Second);
    return 1;
}

Для изменения диалога-назначения нужно буквально 1 строку изменить. Что может быть проще?)
При этом, можно и код диалогов хранить рядом с кодом их вызова (например, с командой, созданной через Pawn.CMD), и текст диалога можно легко подменять, вызывая напрямую Dialog_Open (или оборачивая его отдельным "DialogCreate"), и написание кода для таких диалогов требует минимум времени (особенно если настроить сниппеты для автозаполнения, дабы вручную надо было только название диалога 1 раз ввести сразу в нескольких нужных местах и текст/тип диалога указать). :blush:

При желании, можно поверх всего этого накинуть создание связей между диалогами, как у тебя, дабы возврат автоматически происходил. Правда, имхо, такой вариант удобен только до тех пор, пока диалоги имеют простую структуру и количество "целей" для переходов/возвратов всегда равно одному конкретному диалогу. Когда же диалоги могут отличаться в зависимости от условий (или должно какое-то ещё действие происходить) - всё равно придётся городить исключения, из-за чего начнёт страдать читабельность, так как синтаксис внутри одной системы будет усложняться, как минимум, количественно (в плане того, что нужно будет помнить о том, какие варианты настроек есть).



Просмотр сообщенияM I S T E V (25 февраля 2025 - 23:41) писал:

По итогу система писалась в разное время с большими промежутками, поэтому и допущены такие ошибки, как с GetDialogCount :facepalm:

Это норма для таких крупных систем)


Просмотр сообщенияM I S T E V (25 февраля 2025 - 23:41) писал:

DIALOG_BUTTON_ESC - условно экспериментальная функция, которая по умолчанию отключена. Кто понимает, как это работает, может воспользоваться - есть возможность :wink:


Понятное дело) Речь лишь о том, что её можно улучшить, избавив конечного пользователя от возможных проблем + за него решив проблему с одновременным показом кликабельных текстдравов + диалога. Ну раз уж ты решил так сильно расширять функционал)

Просмотр сообщенияM I S T E V (25 февраля 2025 - 23:41) писал:

Насчёт страниц в DLG_STYLE_BOOK - не нашёл другого варианта реализации, смотрел твои же подобные темы, возможно, в коде сложно выглядит :unsure:


Ну, как минимум, я бы цикл, в котором ты ищешь символ переноса строки, попробовал переделать на strfind. Вполне вероятно, что strfind будет шустрее тут.
Так же не очень понятно разделение на indexStart и indexEnd, если всё можно вычислить из indexStart, вроде.
Ну и, в целом, количество циклов настораживает. Но тут уже нужно подробно изучать код - чем мне сейчас лениво заниматься)


Просмотр сообщенияM I S T E V (25 февраля 2025 - 23:41) писал:

Не хотел создавать доп функцию strcpy для записи. Мне не сложно два раза указать массив для очистки и записи, в плане читаемости - не думаю что сильно портит

К отсутствию strcpy вопросов 0. Сам не создаю функцию под подобное, а предпочитаю напрямую обнулять начало строки там, где это требуется.
Тут больше вопрос к тому, что всё в одну строку напихано, из-за чего читаемость немного страдает. Но это уже, наверное, дело вкуса.

Просмотр сообщенияM I S T E V (25 февраля 2025 - 23:41) писал:

Насчёт FS подумаю как подобное реализовать. В плане лимита - он же будет для каждого скрипта свой, который можно подредактировать через макрос. Создам доп опцию, чтобы Local на Remote заменить :yes:

Если я правильно понял принцип работы твоего скрипта - у тебя "внутренний ID" будет дублироваться у диалогов из FS и у диалогов из мода, когда ты в CallLocalFunction будешь подставлять название диалога, используя ID из "dtreePlayerDialogid[playerid]". Поэтому и придётся синхронизировать "занятые слоты". Ну либо при старте сервера нужно передавать скриптам смещение для dtreeCount основываясь на "MAX_DIALOG_ID", по типу:
// В инклуде, подключенном в моде
SetSVarInt("DLG_Script_Count", 1);
CallRemoteFunction("@__SomeFunc", "");

// В инклуде, подключенном в скрипте (видимо, ориентироваться на "#if defined FILTERSCRIPT")
@__SomeFunc();
@__SomeFunc()
{
    new script_id = GetSVarInt("DLG_Script_Count");
    SetSVarInt("DLG_Script_Count", script_id+1);

    dtreeCount = MAX_DIALOG_ID*script_id;
    // + записать "script_id" в глобальную переменную, дабы далее убирать смещение всякий раз, когда нужно значение из dtreeCount применять как индекс массива
}

1

#33
Пользователь онлайн   M I S T E V 

  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияDeimoS (26 февраля 2025 - 00:23) писал:

Нажмите сюда, чтобы прочитать это сообщение. [Показать]

Сначала отвечу насчёт FS - да точно, не учёл сейчас, что их ID будет одинаковый. За пример реализацией спасибо!

Насчёт создания диалога. В mdialog мы вызываем функцию по имени, которая вызывает функцию открытия и указывает данные, которые мы внесли. В плане 1 диалог 1 переход - пойдёт, но я решил это чуть по другому. Требуется потратить память, но есть возможность "привязать" к одному диалогу множество других (вплоть до MAX_DIALOG_ID-1).

Основная задумка такая, что бОльшее количество диалогов связано с друг другом и они идут по порядку (регистрация, меню игрока и т.д.), поэтому для удобства мы можем быстро переходить на следующий диалог через OpenNextPlayerDialog(playerid), система сама определит привязанный диалог и переключится на него. В данном случае даже имя его не нужно указывать. Если привязанных диалогов несколько, а список для перехода статичен, тогда можно воспользоваться GetDialogReferral, смещение будет равняться listitem. И только в случае, когда эти варианты не подходят, необходимо указать имя диалога.

Что касается OpenBackPlayerDialog - система так же автоматически определяет предыдущий диалог, что делает условие "если правая кнопка -> вернуться назад" очень простым. Или же переоткрыть диалог, достаточно использоваться OpenPlayerDialog(playerid), при условии, что у нас есть дефолт данные/функции для форматирования текста.

Я не претендую на звание "лучшее", но, как одна из реализаций, пусть будет :rolleyes: Чтобы понять все плюсы и минусы - нужно начать использовать это, но о минусах нужно сообщать в тему, я буду их фиксить :biggrin:

Сообщение отредактировал M I S T E V: 26 февраля 2025 - 00:49

0

#34
Пользователь онлайн   M I S T E V 

  • Вставить ник
  • Раскрыть информацию
Обновлено.

    ■   Изменены названия опций.


    Список [Показать]




    ■   Больше невозможно указывать цвет по умолчанию с помощью функций:


    Список [Показать]




    Теперь для указания цвета по умолчанию, необходимо активировать опцию:

    DIALOG_TREE_SETTING_ON_COLOR

    После чего становятся доступны функции:


    Список [Показать]




    ■   Добавлена новая опция, позволяющая получать dialogid из функции CreateDialog:

    DIALOG_TREE_SETTING_ON_ID

    После активации, данные функции будут принимать ID диалога, вместо его имени:


    Список [Показать]




    ■   Исправлен баг при использовании стилей диалогов BOOK<>, когда последняя строка не выводилась, если в конце строки не было '\n'.
    ■   Исправлен баг, когда при открытии нового диалога, данные могли перемешаться с уже открытым.
    ■   Обновлены названия переменных и функций внутри библиотеки.




* В ближайшее время обновлю данные в связанных темах

Сообщение отредактировал M I S T E V: 28 февраля 2025 - 21:12

2

#35
Пользователь онлайн   M I S T E V 

  • Вставить ник
  • Раскрыть информацию
Обновлено.

    ■   Теперь все функции, где использовалось имя диалога можно вызывать через dialogid, при активной опции DIALOG_TREE_SETTING_ON_ID.

    ■   Опции DIALOG_TREE_SETTING_ON_LITE и DIALOG_TREE_SETTING_ON_ID - несовместимы, при одновременном использовании будет выводиться сообщение об ошибке.

    ■   Добавлена новая функция для получения имени диалога по dialogid. Возможно использовать только если активна опция DIALOG_TREE_SETTING_ON_ID

    GetDialogName(dialogid, string[])

    ■   Добавлен новый callback, вызывается при использовании функции ClosePlayerDialog

    public OnPlayerDialogClosed(playerid, const dialogid[])

    ■   Добавлена возможность задать минимальное время отображения диалога. Если игрок нажимает какую-либо кнопку, что-то вводит или выбирает из списка - диалог отображается снова и это не вызывает OnDialog. Время измеряется в миллисекундах. Отключается с помощью опции:

    DIALOG_TREE_SETTING_OFF_MINIMUM_TIME

    Связанные функции:

    SetDefaultDialogMinimumTime(const dialog[], time)

    GetDefaultDialogMinimumTime(const dialog[])

    SetFunctionDialogMinimumTime(const dialog[], const string[])

    GetFunctionDialogMinimumTime(const dialog[], string[])

    UpdateDialogMinimumTime(playerid, const time)

    ■      Добавлена возможность задать максимальное время отображения диалога. По истечению времени диалог закрывается автоматически. Время измеряется в миллисекундах. Включается с помощью опции:

    DIALOG_TREE_SETTING_ON_MAXIMUM_TIME

    Связанные функции:

    SetDefaultDialogMaximumTime(const dialog[], time)

    GetDefaultDialogMaximumTime(const dialog[])

    SetFunctionDialogMaximumTime(const dialog[], const string[])

    GetFunctionDialogMaximumTime(const dialog[], string[])

    UpdateDialogMaximumTime(playerid, const time)

    ■   Исправлена ошибка со стилями диалога BOOK<>, когда допустимое количество строк на одной странице могло быть меньше фактического.

    ■   Обновлена архитектура кода.

Сообщение отредактировал M I S T E V: 13 марта 2025 - 18:28

1

#36
Пользователь онлайн   M I S T E V 

  • Вставить ник
  • Раскрыть информацию
Обновлено.

    ■   Добавлена новая функция (макрос), с помощью которой можно определить - была ли отображена правая кнопка в диалоге. Работает только в OnDialog.

    IsDialogEnableRight()

0

#37
Пользователь онлайн   M I S T E V 

  • Вставить ник
  • Раскрыть информацию
Обновлено.

    ■   Исправил проблему с функцией SetFunctionDialogRight, когда заданная пустая строка могла привести к рекурсии.

0

#38
Пользователь онлайн   M I S T E V 

  • Вставить ник
  • Раскрыть информацию
Обновлено.

    ■   Добавлены новые стили диалогов:

    DIALOG_STYLE_INPUT_PIN

    DIALOG_STYLE_PASSWORD_PIN


    Данные стили диалогов равносильны стилям DIALOG_STYLE_INPUT и DIALOG_STYLE_PASSWORD, но принимают только цифры. При вводе другого символа и нажатии левой кнопки - диалог не вызовет OnDialog и будет отображён снова с прежними данными.

    ■   Добавлены новые функции:

    ToggleDialogInputEmpty(const dialog[], bool:toggle)

    При вводе пустоты и нажатии левой кнопки - диалог не вызовет OnDialog и будет отображён снова с прежними данными. Срабатывает только для стилей:

    DIALOG_STYLE_INPUT
    DIALOG_STYLE_PASSWORD
    DIALOG_STYLE_INPUT_PIN
    DIALOG_STYLE_PASSWORD_PIN


    IsDialogInputEmpty(const dialog[], bool:toggle)

    Возвращает статус срабатывания OnDialog при пустом поле для ввода. По умолчанию установлено true для всех диалогов (при пустом поле для ввода будет вызываться OnDialog).

Сообщение отредактировал M I S T E V: 13 марта 2025 - 18:28

1

#39
Пользователь онлайн   M I S T E V 

  • Вставить ник
  • Раскрыть информацию
Обновлено.

    ■   Добавлена отдельная страница с документацией к библиотеке.

    ■   По умолчанию включён режим работы по ID. Данный режим представляет собой более гибкую и производительную версию. Теперь вся информация, все примеры будут приводиться только относительно этой версии. Для совместимости с прошлой версией необходимо создать макрос перед подключением инклуда:

    #define DIALOG_TREE_SETTING_OFF_ID

    ■   По умолчанию включён режим работы без двоеточия для функций OnDialog и DialogFunction. Для совместимости с прошлой версией необходимо создать макрос перед подключением инклуда:

    #define DIALOG_TREE_SETTING_ON_TAG

    ■   По умолчанию включёны функции, с помощью которых можно определить максимальное время открытого диалога. Для отключения, необходимо использовать опцию:

    DIALOG_TREE_SETTING_OFF_MAXIMUM_TIME

    ■   Полностью убрана опция DIALOG_TREE_SETTING_ON_LITE.

    ■   Уменьшен размер константы MAX_DIALOG_ID (100).

    ■   Исправлены все возвращаемые значения функций. Теперь возвращаемое значение 1 - обозначает успешное выполнение функции, а INVALID_DIALOG_ID - сбой. Исключение несколько функций, которые должны возвращать 1 или 0.

    ■   Исправлены проверки на dialogid внутри функций. В случае несуществующего диалога, функция вернёт INVALID_DIALOG_ID.

    ■   Доделан режим работы со включённой опцией DIALOG_TREE_SETTING_ON_COLOR. Теперь цвет будет задаваться всегда, независимо от источника данных, исключение если в начале строки уже указан цвет, так же цвет не задаётся для диалогов со стилем DIALOG_STYLE_LIST и ему подобных.

    ■   Теперь функция GetDialogReferral возвращает dialogid привязанного диалога, в ином случае INVALID_DIALOG_ID.

    ■   Добавлена новая функция (макрос):

    GetDialogInputsymbol(index)

    Данная функция возвращает указанный символ из inputtext в функции OnDialog. Раньше, чтобы выделить конкретный символ необходимо было использовать подобную конструкцию:

    GetDialogInputtext()[index]




Вроде бы ничего не упустил из обновления. В ближайшее время не планирую ничего обновлять. В случае нахождения какого-либо бага, прошу отписаться в данной теме или мне в Telegram

* Скоро обновлю данные в связанных темах

Сообщение отредактировал M I S T E V: 14 марта 2025 - 06:58

0

Поделиться темой:


  • (4 Страниц) +
  • « Первая
  • 2
  • 3
  • 4
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

1 человек читают эту тему
0 пользователей, 1 гостей, 0 скрытых пользователей


Яндекс.Метрика