- 6,068
- 4,413
Привет. Это очередная библиотека, наряду с easy_dialog, которая добавляет новый глоток воздуха в ванильную игру. С её помощью можно добавлять свои страницы или отдельные пункты в меню GTA:SA и SA-MP. Работоспособность на сторонних лаунчерах и сборках не гарантируется.
Установка: распакуйте архив
Идея была взята(и распотрошена) с исходного кода ModLoader. Спасибо thelink2012 за такую возможность в реализации библиотеки
Быстрый старт:
Пример вставки пункта прямо в системную страницу Options:
Полное описание API
Если привязка не используется, значение хранится только внутри самого пункта:
Доступные ограничения:
menuext в папку moonloader/lib/. Внутри должны оказаться файлы menuext_core.dll и menuext.lua.Идея была взята(и распотрошена) с исходного кода ModLoader. Спасибо thelink2012 за такую возможность в реализации библиотеки
Быстрый старт:
Lua:
local menu = require('menuext')
local cfg = { enabled = true, volume = 50 }
function main()
menu.ready() -- ждём загрузку библиотеки
-- Страница и ссылка в Options перед строкой Back
local page = menu.page {
title = 'ilyuxa korovam xvocti krutit',
open_from = 'OPTIONS',
insert_before = 'back',
}
-- Тумблер. Значение хранится в cfg.enabled
page:toggle('Enabled', menu.bind(cfg, 'enabled'))
-- Число со стрелками влево и вправо. Параметры min и max обязательны, step по умолчанию равен 1
page:number('Volume', menu.bind(cfg, 'volume'), {
min = 0,
max = 100,
step = 5,
format = '%d%%',
})
page:button('Apply', function()
print(cfg.enabled, cfg.volume)
end)
wait(-1)
end
Пример вставки пункта прямо в системную страницу Options:
Lua:
local options = menu.get_page('OPTIONS')
options:toggle('Quick option', menu.bind(cfg, 'flag'), {
insert_before = 'back', -- строка ставится перед Back на странице Options
help = 'Added by script',
})
Поля
Функции
Параметры menu.page { … }
| Поле | Тип | Описание |
|---|---|---|
| menu.version | строка | Версия библиотеки (сейчас "1.0.0") |
Функции
| Функция | Возвращает | Описание |
|---|---|---|
| menu.ready([timeout_ms]) | menu | Ждёт готовности библиотеки. Параметр timeout_ms задаёт лимит ожидания в миллисекундах, можно не указывать, аргумент необязательный |
| menu.page(title) или menu.page(options) | Page | Создаёт новую страницу. title может быть строкой или значением menu.gxt(...). options это таблица с параметрами (см. ниже). По умолчанию создаётся ссылка из страницы OPTIONS |
| menu.get_page(selector) | Page или nil | Ищет уже существующую страницу по alias (например 'OPTIONS'), по индексу страницы от 0 до 126, по значению menu.gxt(...) или принимает уже готовый объект Page |
| menu.bind(table, key[, on_change]) | Binding | Связывает пункт меню с полем table[key]. Необязательный on_change вызывается при изменении значения через меню или через item:set. Сигнатура: on_change(new, old[, item, info]). Аргументы item и info присутствуют только если изменение пришло из пункта меню |
| menu.gxt(key) | GXT-маркер | Ссылка на существующий в игре GXT-ключ длиной от 1 до 7 символов. Для собственного текста используйте обычную строку |
| menu.unload() | - | Удаляет все страницы и пункты, созданные текущим скриптом. Вызывать вручную не нужно, функция вызывается автоматически при завершении скрипта |
Lua:
local page = menu.page {
title = 'My settings', -- заголовок страницы
open_from = 'OPTIONS', -- откуда будет ссылка (по умолчанию OPTIONS)
insert_before = 'back', -- куда поставить ссылку на странице open_from
link_label = 'My settings', -- текст ссылки (по умолчанию совпадает с title)
link_help = 'Open…', -- подсказка при выборе ссылки
back = true, -- false убирает строку Back; строка или gxt задаёт свой текст
start_at = 0, -- какая строка будет выделена при входе (индекс от 0 до 11)
}
Параметры menu.page { … }
| Параметр | По умолчанию | Описание |
|---|---|---|
| title | обязателен | Заголовок страницы. Обычная строка или значение menu.gxt(...) |
| open_from | 'OPTIONS' | Страница, с которой будет вести ссылка. Можно указать alias, индекс, объект Page или menu.gxt(...). Значение false отключает создание ссылки |
| insert_before | перед Back (если он есть) | Позиция ссылки на странице open_from. Подробные правила описаны в спойлере про insert_before |
| link_label | совпадает с title | Текст пункта-ссылки на странице open_from |
| link_help | не задан | Текст подсказки, который показывается при выборе ссылки |
| back | строка Back создаётся автоматически | false убирает строку Back. Строка или menu.gxt(...) задаёт для неё свой текст |
| start_at | первая доступная для выбора строка | Индекс строки, которая будет выделена при входе на страницу. Целое число от 0 до 11 |
Параметр
Параметр используется в двух местах:
Чтобы вставить строку после строки с индексом
insert_before задаёт место строки в списке, а не координаты на экране. На одной странице помещается не больше 12 строк с индексами от 0 до 11, включая строку Back.Параметр используется в двух местах:
- в
menu.page { insert_before = ... }определяет, куда на страницеopen_fromпоставить ссылку на новую страницу; - в методах
page:button,page:toggleи остальных определяет, куда на этой же странице поставить создаваемый пункт.
| Значение | Результат |
|---|---|
| "back" | Строка ставится перед Back |
| "end" или false | Строка ставится в конец списка |
| число от 0 до 11 | Строка ставится перед строкой с этим индексом |
| menu.gxt("KEY") или строка-ключ GXT | Строка ставится перед пунктом с этим GXT-ключом |
| объект Item | Строка ставится перед уже созданным пунктом |
| не указано | Перед Back, если он есть на странице, иначе в конец |
x, укажите insert_before = x + 1. Если это значение выходит за пределы 11, используйте insert_before = 'end'.
Lua:
local b = menu.bind(cfg, 'volume')
-- или с обработчиком изменения:
local b = menu.bind(cfg, 'volume', function(new, old, item, info)
-- вызывается при изменении через меню, item:set или Binding:set
-- item и info присутствуют только если изменение пришло из пункта
end)
page:number('Volume', b, { min = 0, max = 100 })
| Действие | Результат |
|---|---|
| Изменение в меню или вызов item:set(value) | Значение записывается в cfg[key], текст пункта обновляется, вызывается on_change (если он задан) |
| Прямое изменение cfg[key] снаружи | Меню само об этом не узнает. Нужно вызвать item:refresh() |
| item:set(value, true) | Значение записывается без вызова on_change |
Lua:
page:toggle('Temp', false)
Каждый метод добавляет одну строку на страницу. Позиции строк на экране библиотека выставляет автоматически.
Общие параметры в таблице
Поля объекта Page (только для чтения)
Общие параметры в таблице
opts: help (текст подсказки), insert_before и on_change (там, где у пункта есть значение).| Метод | Возвращает | Описание |
|---|---|---|
| page:button(label, fn[, opts]) | Item | При нажатии Enter вызывается fn(item, info). Если функция вернёт true, нажатие Enter передаётся игре дальше |
| page:label(label[, opts]) | Item | Невыбираемая строка с текстом |
| page:toggle(label, src[, opts]) | Item | Переключатель ON/OFF. src это bool или Binding. Дополнительные параметры: on_text (по умолчанию "ON"), off_text (по умолчанию "OFF"), on_change |
| page:number(label, src, opts) | Item | Числовое значение, которое меняется стрелками влево и вправо. src это number или Binding. Параметры min и max обязательны. Дополнительно: step (по умолчанию 1), wrap, format (строка вида '%d' или функция), on_change |
| page:choice(label, src, list[, opts]) | Item | Выбор одного значения из списка. list это массив строк { 'A', 'B' } или массив таблиц { value = ..., label = ... }. Дополнительно: wrap (по умолчанию true), value_mode ('value' или 'index' от 1 до N), on_change |
| page:custom(label, src, opts) | Item | Пункт с произвольной логикой. Обязателен opts.change(value, direction[, info, item]), где direction равен -1 или +1. Дополнительно: format, validate, on_change |
| page:link(label, target[, opts]) | Item | Переход на другую страницу. target это объект Page, alias, индекс страницы или menu.gxt(...). Дополнительно: help, insert_before |
| page:submenu(label[, opts]) | Page | Создаёт дочернюю страницу и ссылку на неё. Дополнительно: title, help, insert_before, start_at (0…11), back |
| page:back([label[, opts]]) | Item | Строка Back. На нативной странице игры доступна только для чтения (нельзя менять label и help) |
| page:items() | таблица | Список актуальных объектов Item на странице (включая Back, если он создан скриптом) |
| page:refresh() | page | Заново читает значения из привязок и обновляет текст пунктов |
| page:show() | page | Открывает эту страницу |
| page:remove() | bool | Если страница создана скриптом, удаляет её целиком. Если страница нативная, удаляет только добавленные скриптом пункты |
| Поле | Описание |
|---|---|
| title | Заголовок страницы |
| index | Индекс страницы в меню (от 0 до 126). Это не номер строки |
| owned | true, если страница создана текущим скриптом. false, если это нативная страница игры |
| removed | true, если страница уже удалена |
| count | Количество актуальных пунктов, добавленных скриптом на этой странице (без учёта Back) |
| Член | Описание |
|---|---|
| value | Значение пункта (для типов toggle, number, choice, custom). Доступно для чтения и записи |
| kind | Тип пункта: 'button', 'toggle', 'number', 'choice', 'custom', 'link', 'label', 'back' и другие |
| index | Индекс строки на странице (от 0 до 11) |
| page | Объект Page, которому принадлежит пункт |
| removed | true, если пункт уже удалён |
| item:get() | Возвращает текущее значение пункта |
| item:set(value[, silent]) | Записывает новое значение. Если silent равен true, обработчик on_change не вызывается |
| item:refresh() | Обновляет значение пункта из привязки. Нужен после изменения таблицы в обход меню |
| item:remove() | Убирает строку со страницы |
В
В обработчиках
page:button функция получает аргументы fn(item, info).В обработчиках
on_change сигнатура выглядит так: function(new, old, item, info). Аргумент info присутствует, если изменение пришло из пункта меню.| Поле | Возможные значения | Описание |
|---|---|---|
| enter | true или false | Была ли нажата клавиша Enter |
| wheel | -1, 0 или +1 | Направление: влево, нет нажатия или вправо |
| direction | -1, 0 или +1 | Итоговое направление изменения значения. Если wheel не равен нулю, берётся значение wheel. Иначе, если нажат Enter, получается +1. В остальных случаях 0 |
| action | число | Внутренний код типа действия строки в GTA. В обычных случаях не нужен |
Ниже описан полный список экранов меню, куда можно вставить свою страницу. Так как тестировалось не на всех страницах, эффект может быть не предсказуем. Если есть какие-то проблемы, пишите. При создании строку указать необходимо точно так (регистр не важен:
Как использовать:
Полный список alias: индекс - экран
options или OPTIONS).Как использовать:
Lua:
-- ссылка на нашу страницу появится в главном меню
menu.page { title = 'My mod', open_from = 'MAIN_MENU', insert_before = 'back' }
-- то же из Options
menu.page { title = 'My mod', open_from = 'OPTIONS', insert_before = 'back' }
-- вставка пункта в уже существующий экран
local p = menu.get_page('SOUND_SETTINGS')
p:toggle('my grodno hack', menu.bind(cfg, 'x'), { insert_before = 'back' })
| Алиасы | Индекс | Что это за экран |
|---|---|---|
| STATS | 0 | Статистика |
| NEW_GAME | 1 | Новая игра |
| BRIEFS | 2 | Брифинги |
| SOUND_SETTINGS | 3 | Звук (Audio) |
| DISPLAY_SETTINGS | 4 | Экран (Display) |
| MAP | 5 | Карта |
| NEW_GAME_ASK | 6 | Подтверждение новой игры |
| SELECT_GAME | 7 | Выбор игры / слота старта |
| MISSIONPACK_LOADING_ASK | 8 | Mission pack - загрузка |
| CHOOSE_LOAD_SLOT | 9 | Выбор слота загрузки |
| CHOOSE_DELETE_SLOT | 10 | Выбор слота удаления |
| LOAD_GAME_ASK | 11 | Подтверждение загрузки |
| DELETE_GAME_ASK | 12 | Подтверждение удаления |
| LOAD_FIRST_SAVE | 13 | Загрузка первого сейва |
| DELETE_FINISHED | 14 | Удаление завершено |
| DELETE_SUCCESSFUL | 15 | Удаление успешно |
| CHOOSE_SAVE_SLOT | 16 | Выбор слота сохранения |
| SAVE_WRITE_ASK | 17 | Подтверждение записи сейва |
| SAVE_DONE_1 | 18 | Сейв записан (1) |
| SAVE_DONE_2 | 19 | Сейв записан (2) |
| GAME_SAVED | 20 | Игра сохранена |
| GAME_LOADED | 21 | Игра загружена |
| GAME_WARNING_DONT_SAVE | 22 | Предупреждение не сохранять |
| ASK_DISPLAY_DEFAULT_SETS | 23 | Сброс настроек экрана? |
| ASK_AUDIO_DEFAULT_SETS | 24 | Сброс настроек звука? |
| ASK_CONTROLLER_DEFAULT_SETS | 25 | Сброс контроллера? |
| USER_TRACKS_OPTIONS | 26 | User Tracks (своя музыка) |
| DISPLAY_ADVANCED | 27 | Доп. настройки экрана |
| LANGUAGE_SETTINGS | 28 | Язык |
| SAVE_GAME_DONE | 29 | Сохранение выполнено |
| SAVE_GAME_FAILED | 30 | Ошибка сохранения |
| SAVE_WRITE_FAILED | 31 | Ошибка записи сейва |
| SAVE_FAILED_FILE_ERROR | 32 | Ошибка файла сейва |
| OPTIONS | 33 | Настройки - главное место для настроек мода |
| MAIN_MENU | 34 | Главное меню (старт игры) |
| EXIT | 35 | Выход |
| CONTROLLER_PC | 36 | Контроллер (PC) |
| REDEFINE_CONTROLS | 37 | Переназначение клавиш |
| KEYBOARD_CONTROLS | 38 | Клавиатура |
| MOUSE_SETTINGS | 39 | Мышь |
| JOYPAD_SETTINGS | 40 | Геймпад |
| PAUSE_MENU | 41 | Меню паузы (ESC в игре) |
| QUIT | 42 | Выход в Windows / quit |
| EMPTY | 43 | Пустая служебная страница |
| Параметр | Значение |
|---|---|
| Строк на одной странице | 12 (индексы от 0 до 11), включая Back, label и ссылки |
| menu.gxt(key) | длина ключа от 1 до 7 символов |
| Свой текст ('строка') | длина не ограничена |
| page.index | от 0 до 126 (индекс страницы, а не строки) |
Кириллица в надписях работает так же, как у текстдравов. Поэтому, библиотека передаёт строки как есть. Если текст отображается неправильно, используйте те же функции перекодировки, что и для текстдравов. Добавлять в библиотеку лишний оверхед я не стал.
Вложения
Последнее редактирование: