Букв будет много, набирайтесь терпения.
Для начала общая информация о гампах:
1) Так как гампов может быть больше одного, то работа с ними идет через номер гампа в списке.Количество гампов в списке можно получить через GetGumpsCount При этом обычно идет перебор от нуля до GetGumpsCount -1 с проверкой, тот ли это гамп, который нам нужен
2) У гампа есть два поля - Serial и GumpID, которые обычно привязаны к действиям\скиллам и пр, и на которые можно ориентироваться для нахождения нужного гампа. Получать их можно через GetGumpID и GetGumpSerial
3) У всех гампов есть набор элементов, которые собственно и показываются на экране. Текст, картинки, кнопки, чекбоксы, поля ввода - это всё оно. Элементов одного типа в гампе может быть много. Полный список всех элементов и их полей тут. Отдельные элементы будем рассматривать дальше.
4) У гампов есть свойства (полный список по ссылке в п.3), для нас интересен только пункт NoClose, который можно проверить через IsGumpCanBeClosed. Обычно гампы, у которых NoClose = False - это простые информационные гампы, которые закрываются кликом правой кнопки мыши в клиенте. В стелсе это же можно сделать через CloseSimpleGump.
По гампэлементам в целом:
1) Каждый гампэлемент имеет поля: Page и ElemNum. Первое отвечает за номер страницы, на которой находится элемент, второе - за номер элемента в общем списке элементов гампа (без разделения по типу).
2) ВАЖНО! Те элементы, которые используются в скриптах - TextEntry, RadioButton, CheckBox, GumpButton - имеют поле return_value. Это одно их самых важных полей, поскольку именно оно передается как id элемента в функции, например TextEntryID в функции NumGumpTextEntry. Коряво и запутано, но имеем то, что имеем. Надо просто запомнить это.
3) все изменения в гампе, в частности TextEntry, RadioButton, CheckBox - должны делаться ДО нажатия кнопки - она закрывает, отправляет и уничтожает гамп в стелсе! Еще раз - NumGumpButton или WaitGump должно вызываться ПОСЛЕДНИМ!
Теперь по конкретным гампэлементам, которые чаще всего используются в скриптах:
1) TextEntry - поле ввода. Меняется через GumpAutoTextEntry либо NumGumpTextEntry. Параметр Value - устанавливаемое значение строки, параметр TextEntryID - это значение поля return_value элемента.
2) Radiobutton- переключатель. Может выглядеть как выбор из нескольких вариантов, так и как обычный chekbox. Меняется через GumpAutoRadiobutton либо NumGumpRadiobutton. Параметр Value - 0 для снятия выбора, любое другое - для выбирания. параметр RadiobuttonID - это значение поля return_value элемента.
3) CheckBox- флажок. Обычно выглядит как квадратик с галкой. Меняется через GumpAutoCheckBox либо NumGumpCheckBox. Параметр Value - 0 для снятия выбора, любое другое - для выбирания. параметр CBID- это значение поля return_value элемента.
4) GumpButton - кнопка. Всегда закрывает гамп, отправляя ответ серверу. Вызывается через WaitGump либо NumGumpButton. Параметр Value - это значение поля return_value кнопки.
Отличия серии методов NumGump* от GumpAuto* :
1) NumGump* - функции, которые возвращают результат выполнения. В них задается GumpIndex, а не простой перебор гампов до первого совпадения. Работает только с имеющимся гампом (GumpIndex), не устанавливает ловушки на приходящий гамп.
2) GumpAuto* - не возвращает результат выполнения. Перебираются все гампы до первого совпадения (которое может быть совсем не в том гампе, который нужен!). Если совпадений среди имеющихся гампов нет, то ставится ловушка на входящий гамп, в котором сразу будет искаться элемент, при обнаружении - сразу устанавливается значение.
Теория закончилась, переходим к практике.
Простые примеры из гампа с двумя кнопками - неинтересны, берем сразу что-то посложнее.
Наблюдаем тут прозрачный гамп (на самом деле просто гамп без "подложки" с картинкой), где визуально справа вроде бы чекбоксы с названиями мест. Задача - выбрать, ну например Minoc и телепортнуться туда.
Выполняется в 2 действия - 1) поставить галку 2) нажать кнопку.
Идем по шагам:
1) Сначала надо получить полную информацию о гампе, чтобы найти нужные элементы и получить их return_value
Можно получить разными путями (результат будет одинаков). Либо запустить граф. клиент из стелса, открыть в клиенте этот гамп, и написать ,infogump - вылетит окно с полной информацией о гампе. Другой вариант - получить эту информацию через скриптовый метод GetGumpFullLines:
Code: Select all
SetSilentMode(False);
GetGumpFullLines(GetGumpsCount-1, st);//var st : TStringList;
Полная инфа
Изначально казалось, что нам нужен Checkbox - но здесь вообще нет Checkbox элементов, зато полно RadioButtons. Смотрим те из них, у которых Page 1. Прикинув, что по стандартной логике они идут сверху вниз, смотрю на второй из них, беру его Return_value - 12. В сложных случаях приходится примеряться по координатам.
Насчет кнопки - они все идут в ряд, поэтому координата X одинакова. Нам нужна предпоследняя кнопка по Y, и это оказывается кнопка за номером 0, Return_value = 1.
Соответственно в итоге имеем:
Code: Select all
NumGumpRadiobutton(GetGumpsCount-1, 12, 1);
NumGumpButton(GetGumpsCount-1, 1);
Для того, чтобы проверить себя (либо в особо запущенных случаях, когда так сходу не находится) - можно поставить все нужные галки, заполнить поля ввода и отправить гамп из клиента, потом вызвать ,infogump и подсмотреть в самом конце инфы в Previous gump reply: нужные значения. В примере выше это как раз показано.
Способ, описанный выше - подходит для ручного поиска нужных элементов.
Когда же вам нужно искать что-то в скрипте, то самый лучший способ - это использовать метод тут и обращаться к элементам напрямую - перебирать их, находить нужный и использовать его.
Пример:
Code: Select all
if XXX then//тут мы проверили все, что надо, и уверены - гамп есть, и он именно тот, который нужен.
begin
GetGumpInfo(GetGumpsCount-1, gi);
NumGumpRadiobutton(GetGumpsCount-1, 12,1);
if Length(gi.Text)> 0 then
for k := 0 to Length(gi.Text) - 1 do
if BMSearch(1, gi.Text[k], 'Accept') > 0 then
NumGumpButton(GetGumpsCount-1, gi.GumpButtons[0].return_value);
wait(2000);
end;
1) не проверять, есть ли действительно нужный гамп. Например, в скрипте был вызван гамп, потом wait(3000), и дальше юзер действует исходя из того, что гамп 100% пришел. Но иногда он может и не прийти - например на сейве, на лаге, еще почему-то. Поэтому всегда проверяйте, что количество гампов больше нуля, и нужный вам действительно в их числе.
2) забывать создавать объект TStringList, передаваемый параметром в функции типа GetGumpTextLinesи похожие. Сейчас скрипт выкинет ошибку, получив в параметре не созданный объект, но лучше до такого не доводить.
3)Получив строки из GetGumpTextLines и похожих - ВСЕГДА проверяйте. что кол-во строк больше нуля. Очень часто не проверив гамп по п.1 - юзер работает не с тем гампом, и получает ноль строк, и скрипт с грохотом падает на обращении к несуществующим строкам в StringList.