M I S T E V (25 февраля 2025 - 23:41) писал:
Изначально была идея сделать быстрый переход вперёд/назад по диалогам, для этого надо где-то хранить информацию о каждом диалоге. Потом начались сыпаться другие идеи по той или иной реализации, что приводило к ещё большему раздуванию кода

Может я чего-то не понимаю, но в 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 раз ввести сразу в нескольких нужных местах и текст/тип диалога указать).
При желании, можно поверх всего этого накинуть создание связей между диалогами, как у тебя, дабы возврат автоматически происходил. Правда, имхо, такой вариант удобен только до тех пор, пока диалоги имеют простую структуру и количество "целей" для переходов/возвратов всегда равно одному конкретному диалогу. Когда же диалоги могут отличаться в зависимости от условий (или должно какое-то ещё действие происходить) - всё равно придётся городить исключения, из-за чего начнёт страдать читабельность, так как синтаксис внутри одной системы будет усложняться, как минимум, количественно (в плане того, что нужно будет помнить о том, какие варианты настроек есть).
M I S T E V (25 февраля 2025 - 23:41) писал:
По итогу система писалась в разное время с большими промежутками, поэтому и допущены такие ошибки, как с GetDialogCount

Это норма для таких крупных систем)
M I S T E V (25 февраля 2025 - 23:41) писал:
DIALOG_BUTTON_ESC - условно экспериментальная функция, которая по умолчанию отключена. Кто понимает, как это работает, может воспользоваться - есть возможность

Понятное дело) Речь лишь о том, что её можно улучшить, избавив конечного пользователя от возможных проблем + за него решив проблему с одновременным показом кликабельных текстдравов + диалога. Ну раз уж ты решил так сильно расширять функционал)
M I S T E V (25 февраля 2025 - 23:41) писал:
Насчёт страниц в DLG_STYLE_BOOK - не нашёл другого варианта реализации, смотрел твои же подобные темы, возможно, в коде сложно выглядит

Ну, как минимум, я бы цикл, в котором ты ищешь символ переноса строки, попробовал переделать на 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 заменить

Если я правильно понял принцип работы твоего скрипта - у тебя "внутренний 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 применять как индекс массива
}