NCrashed
offline
Опыт:
13,553Активность: |
Изменение реадктора триггеров
Эта статья является вольным переводом оригинальной статьи с www.wc3jass.com автора Sevion. Очень полезная статья для всех, кто хочет перевести свои системы на GUI.
ВведениеWorld Editor изначально создавался так, чтобы его можно было легко редактировать. Сегодня я расскажу и покажу как добавлять свои команды в редактор триггеров (дальше GUI). Теперь вы сможете использовать родные, вшитые в движок функции, которые называются native, а не богомерзкими функциями из blizzard.j (далее бж). Вместо функции DestroyEffectBJ, которая кроме того как вызывает DestroyEffect ничего не делает, вы сможете напрямую вызывать вторую функцию. Можно привести множество таких примеров, когда функции из бж только вызывают свои аналоги native. Это само по себе не очень опасно, но часто в бж функциях возникают утечки, которые загрязняют память и вызывают тормоза. Теперь вы сможете оптимизировать свой код, не использую jass напрямую! Больше не будет никакого Custom Script! Но однако jass все равно остается более мощным и удобным инструментом. Эта статья поможет вам сделать GUI более мощным для вас. Если вы любите использовать GUI и вам нужно использовать некоторые функции из jass, то это статья написана для вас! НачалоТеперь, перво-наперво, надо знать где нужно редактировать. Создайте новую папку в директории игры и назовите ее “UI”. Теперь нам необходимы 3 файла: UI\TriggerData.txt UI\TriggerStrings.txt UI\WorldEditStrings.txt Их можно вытащить из War3Patch.mpq, или смотри приложение к статье. Положите их в директорию UI. Чтобы изменения в этих файлах вступили в силу, нужно каждый раз после редактирования перезапускать редактор. Структура TriggerData.txtТеперь рассмотрим структуру файла TriggerData.txt. Его можно открыть обычным блокнотом. Весь файл разбит на блоки, которые разделяются строками вида [NameOfBlock], где текст между скобками является именем блока. Рассмотрим назначение каждого блока: [TriggerCategories] – Категории триггеров, это условное разделение команд на группы. Пример «Юнит», «Спецэффекты», «Отряд» и тп. Все это должно быть знакомо. [TriggerTypes] – Все типы переменных объявлены здесь. Можно заметить, что здесь намного больше типов, чем мы можем найти в GUI. Это потому что некоторые типы являются служебными, и пользователь не может их создать. [TriggerTypeDefaults] – Некоторые переменные имеют значения по умолчанию. Например, целочисленные переменные имеют значение 0. Некоторые переменные, вроде таймера, необходимо инициализировать функциями CreateXXX() для правильной работы. Вот здесь и происходит вызов этих функций. [TriggerParams] - Это заранее заданные значения для переменных, константы, которые могут быть выбраны из выпадающего списка при определении переменной или при выборе аргумента для команды. Например, все способности в GUI и приказы (кроме строковых) являются этими константами. [TriggerEvents] – Все события триггеров определяются здесь [TriggerConditions] – Все условия триггеров описываются здесь [TriggerActions] – Все действия триггеров находятся здесь [TriggerCalls] – Функции, которые подставляются в аргумент команды. Например, Область – Центр области, Математика - Случайное число. [DefaultTriggerCategories],[DefaultTriggers] – Всегда когда создается карта, категории триггеров и сами триггеры создаются по умолчанию. Обычно здесь расположен только триггер для инициализации melee карт. В отличие от TriggerData.txt, который определяет структуру и команды редактора триггеров, остальные два файла, TriggerStrings.txt и WorldEditStrings.txt. Первый определяет весь текст, который вы видите, когда работаете в GUI. Второй является просто списком строк, которым пользуется редактор. Оба файла упрощают локализацию редактора под разные языки. Именно редактирование TriggerStrings.txt позволило некоторым создать “Русские триггеры”, из-за которых иногда очень сложно оказать помощь человеку, потому что некоторые команды неудачно переведены и привычка работать с английскими мешает быстро переориентироваться на русские. Структура TriggerStrings.txt[TriggerEventStrings] – Строки всех событий [TriggerConditionStrings] – Строки всех условий [TriggerActionStrings] – Строки всех действий [TriggerCallStrings] – Строки всех функций [AIFunctionStrings] – Строки для редактора ИИ (логичней было бы их держать в orldEditStrings.txt ) Добавление действийС форматом данных мы разобрались, теперь самое вкусное: добавим свою функцию в GUI. Открываем файл TriggerData.txt, как мы уже знаем, он разбит на блоки. Мы собираемся добавить функцию удаления точки, так как эту очень нужную функцию близзы нам не дали в GUI. Ищем блок [TriggerActions], дальше ищите записи с DestroyEffect, так как наша и эта функция похожи. Код:
DestroyEffectBJ – это имя нашей функции. (Потом оптимизируем эту функцию, заменив ее на native аналог) Первое число после равно отвечает за совместимость с дополнением TFT (0-совместима со всеми) Запятая разделяет параметры. “effect” – это то что функция берет, аргумент функции. Когда мы уничтожаем спецэффект нам надо указать какой именно мы уничтожаем. “_DestroyEffectBJ_Defaults=GetLastCreatedEffectBJ” - Эта строка отвечает за значение аргумента по умолчанию, то есть это то что вы увидите только выбрав функцию. Нам не надо добавлять это для нашей функции, так как в GUI нет функции GetLastCreatedLocation. “_DestroyEffectBJ_Category=TC_SPECIALEFFECT” - Эта строка указывает редактору в какой категории должна находиться функция. Как на этой картинке: DEAD URL Теперь по образу и подобию создаем свою функцию: Код:
Однако тут есть 1 ошибка. Категории My_Functions не существует. Значит, ищем блок категорий. Каждая категория начинается с “TC_”, сейчас добавим нашу категорию. Ищем строку Код:
Мы хотим, чтобы наша категория была под категорией искусственного интеллекта, значит добавляем свою категорию сразу после этой. Код:
После знака равно идет название строки, которую мы должны потом создать в TriggerStrings.txt и которая будет отображаться как название категории, второй параметр является путем к иконке, которая будет отображаться около каждого действия категории. Теперь отредактируем TriggerStrings.txt. Ищем блок “[TriggerActionStrings]”. В нем ищем DestroyEffectBJ: Код:
Первая строка – это то что будет отображаться в выпадающем списке после названия категории, то есть название функции. "Special Effect - Destroy Special Effect" Далее идет DestroyEffectBJ="Destroy ",~Special Effect . Это будет показываться в сером окошке под выпадающем списком. Знак ~ означает, что дальше идет название переменной. Здесь не проверяется ни тип ни существование этой переменной для функции, но редактор при загрузке карты вам об этом с радостью сообщит. Что-то вроде “Ошибка базы данных триггеров, название функции требовалось 3 аргумента, а сообщено 4”. Поэтому советую соблюдать количество аргументов такое, какое оно есть в TriggerData.txt. Следующая строка отвечает за серую подсказку под основным текстом функции. Например: Код:
DEAD URL Теперь добавьте где хотите в этом блоке текст: Код:
Отлично! Мы добавили свою функцию! Создание условияТеперь ищем блок [TriggerConditions]. Его типичный представитель: Код:
По образу и подобию нашей функции мы разбираем по кусочкам это условие: В функцию передаются равкод способности, некая переменная, определяющая тип сравнения, и равкод второй способности. Дальше идут значения по умолчанию и потом категория. Теперь вставьте в блок наше условие: Код:
И в TriggerStrings в нужном блоке вставляем: Код:
Но опять тут есть ошибка! В GUI нету переменно trackable! Ну так создадим ее. Ищем в TriggerData.txt “// Trigger Variable Types” Теперь по образу и подобию остальных переменных создаем свою: Код:
Теперь в WorldEditStrings.txt добавляем: Код:
Добавление событийТакже можно обнаружить, что в GUI нет вот таких событий для работы с trackable: Код:
Hit, когда нажимаем на trackable, Track, когда поводим мышкой над ним. Подробнее о trackable вы можете прочитать в соответствующей статье. Теперь посмотрим на определения событий: Код:
Первая строка – комментарий, она нам не интересна. Следующая: 0 означает, что это ROC событие; destructable – декорация, которая должна умереть, чтобы вызвать событие. _TriggerRegisterDeathEvent_Defaults=_ - эта отвечает за значения переменных по умолчанию. Как видно, по умолчанию ничего не стоит. “_TriggerRegisterDeathEvent_Category=TC_DESTRUCT” Эта строка говорит редактору в какой категории событий разместить это событие. Теперь мы можем составить наше событие: Код:
Теперь экзамен, сделай то же самое для Track события. Добавление функцииВроде все есть, действия, событие, переменная. Но нет такой нужной вещи как TriggeringTrackable! Ищем: Код:
Первый нуль отвечает за совместимость Второе число за использование в событиях: 0-нельзя, 1-можно. Третий параметр отвечает за возвращаемый тип переменной. Остальные 2 строки должны быть понятны. Вот наша функция: Код:
Немного практикиТеперь добавим действие создания trackable. Используя определение native функции: Код:
Получаем: Код:
!! Не забывайте добавлять описания функций в TriggerString.txt !! Теперь, чтобы можно было присвоить переменной значение созданного trackable, скопируйте этот текст в блок [TriggerCalls]: Код:
Теперь можно сделать вот так: Set My_Var = CreateTrackable() ScriptNameУ действий есть еще одно очень полезное поле (только у действий, к сожалению): ScriptName. Оно позволяет вам разделить имя jass функции от имени GUI действия. На практике оно оказывается очень полезным по следующим причинам. Первое преимущество – вы можете давать множество GUI имен для одной и той же функции. Может быть, вы хотите одну функцию, которая обрабатывала как целочисленный тип переменной, так и “unitcode” (далее равкод). В jass, конечно, это сработает без проблем, так как равкод представляет собой целое число, но в GUI это уже не так. Однако с использованием ScriptName вы сможете сделать так, чтобы обе GUI функции ссылались на одну jass функцию. И самое большое преимущество – это то, что это поле разделяет GUI реализацию скрипта от jass реализации. В GUI вы видите две различные функции, но когда вы сохраняете карту…, вместо них подставляются другие jass функции. Полезно знать, что происходит во время сохранения карты. Сначала все триггеры и остальные GUI структуры сохраняются в отдельный файл внутри карты. Этот файл необходим только редактору, для движка он не нужен (поэтому все протекторы вырезают его). В то же время все триггеры конвертятся в jass-код и сохраняются в главный скрипт карты. Этот файл уже как воздух нужен для нормальной игры, так как помимо всех триггеров там сохраняется информация о всех юнитах, которые должны быть созданы при инициализации карты (это все юниты которые поставили на карту через панель юнитов и тп), о всех регионах, инициализации переменных и стартовых позиций игроков. Когда вы меняете поле ScriptName, то меняется только jass код, сами GUI триггеры остаются без изменений. Таким образом можно оптимизировать карты даже ни разу не взглянув на их триггеры, просто карта будет скомпилирована по-другому, чем в других экземплярах редактора. Вот вам самый простой и полезный пример использования. Как я обещал мы оптимизируем функцию DestroyEffectBJ, так как она только вызывает jass функцию DestroyEffect. Изначально она выглядит так: Код:
Теперь нашим хитрым приемом сделаем так, чтобы эта GUI функция сразу вызывала правильный jass аналог: Код:
Теперь при сохранении карты вместо DestroyEffectBJ будет стоять DestroyEffect. Причем ваша карта будет открываться в других редакторах, но при сохранении в них бж функция вернется обратно. Одно из главный ограничений ScriptName –можно использовать только те функции, которые имеют то же количество аргументов и их типы, что и оригинал. По загадочной причине порядок аргументов в некоторых бж функциях перевернут относительно оригинала, что не может быть просто устранено ScriptName. УпражненияВот несколько направлений для совершенствования своего редактора триггеров:
На этом я заканчиваю. Надеюсь, что вы увидели как легко изменять редактор триггеров под свои нужды и, если вы это еще не осознали, то, надеюсь, что в один прекрасный день вы поймете, что спор “GUI vs Jass” в корне пропитан идиотизмом. Отредактировано NCrashed, 09.11.2009 в 10:21. |
09.11.2009, 00:58 | #1
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
Van Damm
wait... what?
offline
Опыт:
22,268Активность: |
Van Damm добавил:
Плюс к тому, слишком большая картинка Van Damm добавил: Не знал только про ScriptName |
09.11.2009, 01:16 | #2
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
NCrashed
offline
Опыт:
13,553Активность: |
Перевод бесполезен, если он пылится на винте. Я их делал много, теперь нахожу и выкладываю. ScriptName очень полезная штука, так как можно написать свой blizzard.j без утечек и прочего уг, а потом только пересохранить карту.
NCrashed добавил: Картинку вырежу, не информативна |
09.11.2009, 10:20 | #3
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
XOR
offline
Опыт:
38,159Активность: |
Переведено хорошо, но такая статья была. |
09.11.2009, 19:19 | #4
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
KotoBog
Meow
offline
Опыт:
36,046Активность: |
NCrashed:
Реактора триггеров? Прям Чернобыль, блин) |
10.11.2009, 00:04 | #5
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
bee
vjass.optimizer
offline
Опыт:
16,615Активность: |
NCrashed, у меня вопросик, хоть и глупый.
А если я так изменю свой редактор триггеров и с помощью него напису какойнибудь GUI спелл (аш както противно говорить "напишу GUI спелл" XD) и ктото скачает и начнет открывать, то WE не будет кричать на нововведенные фенечьки? Bee добавил: + опечатка в названии темы |
21.11.2009, 06:39 | #6
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
FaB0SS
offline
Опыт:
2,504Активность: |
|
22.01.2010, 22:38 | #7
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
Kemodonn
offline
Опыт:
1,665Активность: |
NCrashed, спасибо, кое что знал, но массу интересных вещей я узнал. |
27.01.2010, 21:40 | #8
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
Sergant1000
offline
Опыт:
11,308Активность: |
NCrashed, а что дает добавление своих тригеров? |
20.02.2010, 21:11 | #9
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
Nekit1234007
offline
Опыт:
11,916Активность: |
См. Введение Т_Т
|
20.02.2010, 21:13 | #10
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
Sergant1000
offline
Опыт:
11,308Активность: |
Nekit1234007, для меня это как жестами обьяснить слепому что это пролетело мимо. Можно в боле нубском варианте. |
21.02.2010, 01:25 | #11
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
Nekit1234007
offline
Опыт:
11,916Активность: |
Что именно не ясно?
|
21.02.2010, 01:27 | #12
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
Sergant1000
offline
Опыт:
11,308Активность: |
что это дает? |
21.02.2010, 03:38 | #13
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
bee
vjass.optimizer
offline
Опыт:
16,615Активность: |
вместо того чтобы прописывать все время самому код
можно выбирать из списка грубо говоря Bee добавил: прибавляет удобств |
21.02.2010, 20:57 | #14
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
Sergant1000
offline
Опыт:
11,308Активность: |
А можно пример кода, и что он делает или для чего он нужен. Просто думаю стоит его включать в проект или нет. |
21.02.2010, 22:14 | #15
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
St John
offline
Опыт:
156Активность: |
Полезная статья.
Скоро появятся всевозможные навороты и оптимизации гуи. Sergant1000 код ты пишешь сам, это для ускорения работы в гуи, чтобы не писать однотипные блоки, ты просто их переводишь в гуи команды следуя статье. |
21.02.2010, 22:44 | #16
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
bee
vjass.optimizer
offline
Опыт:
16,615Активность: |
Цитата:
первый пост полностью прочитай и отпадет желание флудить. на проект это никак не повлиет. т.к. это изменяет всеголиш настройки WE. игру это не изменит. |
|
21.02.2010, 23:00 | #17
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
XOR
offline
Опыт:
38,159Активность: |
В любом случае сами системы делаются сразу, а лишь потом добавляются специяльно для него действия в гуи что очень не удобно да и нужно лишь |
21.02.2010, 23:06 | #18
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
Death Master
offline
Опыт:
782Активность: |
Открыл америку, я это уже год знаю, но для новичков пригодится.
|
22.02.2010, 02:10 | #19
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|