| Эта статья предназначена для триггерщиков, которые не хотят использовать JASS в своём коде. Вступление. World Editor был создан Blizzard для того, чтобы можно было его просто использовать и модифицировать. В этой статье я расскажу о том, как добавить новые функции в Редактор триггеров. Вы сможете использовать Native-функции в GUI, это означает, что функция Custom Script для этого больше не понадобится. Вместо постоянного использования, к примеру, DestroyEffectBJ, можно создать триггерную функцию DestroyEffect! Так можно позаменять все BJ-функции, которые вызывают native, а это уже намного сокращает вызовы функций. Сможете создать RemoveLocation. Потом вам покажется, что триггеры стали намного лучше, чем JASS, но это заблуждение. Что бы ты не делал с триггерами, JASS останется более мощным. Эта статья научит вас только тому, как сделать триггеры немного более мощным инструментом. Первые шаги. Прежде всего вы хотите знать, что редактировать, разве не так? Создадим в директории WarCraft III новую папку, назовём её UI. Она будет выглядеть примерно как на этой картинке: Ещё нам понадобятся три файла: UI\TriggerData.txt UI\TriggerStrings.txt UI\WorldEditStrings.txt Скажу сразу: лучший редактор текстовых документов это Crimson Editor. Поверьте, он намного облегчит вам жизнь. С его помощью можно открыть все три этих файла в одном окне, а переключаться между ними вкладками. Эти файлы можно взять из War3Patch.mpq. Они находятся в режиме "Только чтение", если открыт World Editor, поэтому при внесении изменений в текстовые файлы сохраните их, закройте, а затем перезапустите World Editor для того, чтобы применить изменения. Формат. Теперь давайте посмотрим на формат файла. В TriggerData.txt вы увидете огромные блоки текста. Возле каждого большого блока написаны несколько слов в квадратных скобках ( [] ). [WorldEditStrings] - в этом файле находятся строки для категорий, типов переменных, значений переменных по умолчанию. 2. Добавление функции. Теперь вы, наверное, спросите: "Что и где мне прописать?". Если посмотреть внимательно, то можно увидеть, что файл разбит на секции (или категории, говорите, как хотите). Все они объявлены вверху. Сначала добавим действие. Так как нам требуется функция RemoveLocation в триггерах, давайте добавим её сюда. В TriggerData.txt найдите часть со всеми действиями, [TriggerActions]. Запустите в блокноте поиск и найдите, к примеру, функцию DestroyEffect, т.к. эти две функции почти одинаковы. Вы должны найти: DestroyEffectBJ=0,effect _DestroyEffectBJ_Defaults=GetLastCreatedEffectBJ _DestroyEffectBJ_Category=TC_SPECIALEFFECT DestroyEffectBJ - это имя функции (Позже мы оптимизируем её, заменив аналогичной функцией из Native). Первое значение, "0", утвержает, работает ли функция в RoC или TFT. "0" означает, что функция работает в любой версии WarCraft. "," просто разделяет значения. "effect" - тип значения, которое забирает функция. Когда вы уничтожаете спецэффект, вам нужно дать функции нужный спецэффект для уничтожения. верно? _DestroyEffectBJ_Defaults=GetLastCreatedEffectBJ - Устанавливает значение по умолчанию при создании действия. Нам это не нужно, т.к. не существует функции GetLastCreatedLocation. _DestroyEffectBJ_Category=TC_SPECIALEFFECT - Означает, что действие будет поставлено в категорию "Спецэффект". Как на картинке: Итак, что же это значит? Т.к. наша функция - RemoveLocation, мы делаем это: RemoveLocation=0,location _RemoveLocation_Defaults=_ _RemoveLocation_Category=TC_My_Functions Казалось бы, это всё. Но стойте! Категории TC_My_Functions не существует! Её надо создать. Весь список категорий можно увидеть в файле TriggerData.txt, возле начала которого будет большой блок текста, в котором каждая строка начинается с "ТС_". Нам требуется создать категорию TC_My_Functions. Для этого найдём: TC_AI=WESTRING_TRIGCAT_AI,ReplaceableTextures\WorldEditUI\Actions-AI Вы найдёте её где-то в начале документа. Это первая категория под действиями. Мы хотим, чтобы наша категория была НАД ней. В строке выше мы увидели основной синтаксис создания категорий. Создадим её: TC_My_Functions=WESTRING_TRIGCAT_My_Functions,ReplaceableTextures\WorldEditUI\Actions-SetVariables Я также выбрал хорошо смотрящуюся иконку. Вы можете использовать любую иконку, её можно увидеть при выборе действия из категории. Мы сделали функцию и категорию. Теперь - строки, которые будут отображаться. Откроем TriggerStrings.txt. Найдём там "[TriggerActionStrings]". Вы увидите большой блок действий. Найдите там DestroyEffectBJ. Вы увидите: DestroyEffectBJ="Destroy Special Effect" DestroyEffectBJ="Destroy ",~Special Effect DestroyEffectBJHint= Всё, что здесь написано, очень просто понять. DestroyEffectBJ="Destroy Special Effect" - это текст, который показывается возле категории "Спецэффект", соответственно оно покажет: "Спецэффект - Destroy Special Effect". DestroyEffectBJ="Destroy ",~Special Effect - определяет текст, который будет показан после выбора действия из списка. В данном случае покажет: "Destroy (Last Created Special Effect)" . Но в тексте видно только "Destroy". (Last Created Special Effect) взялся из ,~Special Effect. Запятая в этой строке похожа на действие "Concatenate Strings" для текста из триггеров. То есть запятая соединяет 2 части текста. Например, если ввести "Destroy ", "yourself.", то в резутьтате получится строка "Destroy yourself.". Префикс ~ определяет, откуда начинается часть с переменной. Переменная ~Special Effect имеет тип Спецэффект. Следующее - DestroyEffectBJHint=. Это определяет серый текст-подсказку внизу действия, который описывает, что это действие даёт. Пример такой подсказки находится здесь: DisableTrigger="Turn Off" DisableTrigger="Turn off ",~Trigger DisableTriggerHint="Does not interrupt existing executions of the trigger, but prevents future executions." Вот, как это будет выглядеть в Редакторе триггеров: RemoveLocation похожа на DestroyEffect. И не нужно ей описания. Итого у нас получится: RemoveLocation="Remove Location" RemoveLocation="Remove "~Location RemoveLocationHint= Добавьте эти строки где угодно под [TriggerActionStrings]. Итак, мы научились создавать новые действия и новые категории. Теперь научимся создавать новые условия. Найдите блок [TriggerConditions]. Условие выглядит так: OperatorCompareAbilityId=1,abilcode,EqualNotEqualOperator,abilcode _OperatorCompareAbilityId_Defaults=GetSpellAbilityId,OperatorEqualENE,AUan _OperatorCompareAbilityId_Category=TC_CONDITION Так как в триггерах уже есть сравнение точек, добавим сравнение трекейблов. Итак, посмотрим на код. OperatorCopmareAbilityId=1,abilcode,EqualNotEqualOperator,abilcode. Это параметры или аргументы, которые берёт условие. В Редакторе триггеров это выглядит так: Первый и третий параметры - это способности, а abilcode означает, что нужно ввести равкод способности. EqualNotEqualOperator - это оператор сравнения (больше, больше или равно, меньше, меньше или равно, равно, не равно). Итак, чтобы создать наше сравнение, нужно написать следующее: OperatorCompareTrackable=1,trackable,EqualNotEqualOperator,trackable _OperatorCompareTrackable_Default=_,OperatorEqualENE,_ _OperatorCompareTrackable_Category=TC_CONDITON После этого написать в файле TriggerStrings.txt: OperatorCompareTrackable="Trackable Comparison" OperatorCompareTrackable=~trackable," ",~Operator," ",~trackable OperatorCompareTrackableHint= Каждый, кто знаком с переменными, знает, что в GUI нет переменных-трекейблов. Поэтому создадим такие. Все типы переменных находятся в файле TriggerData.txt. Найдите там строку: // Trigger Variable Types Потом, там, где объявлены все переменные, напишите: trackable=1,1,1,WESTRING_TRIGTYPE_trackable Теперь найдите ту же строку в файле WorldEditStrings.txt. Напишите после неё: WESTRING_TRIGTYPE_trackable="Trackable" Отлично. Вы создали переменную типа Трекейбл! Итак, осталось научиться создавать события. Создадим в GUI событие для трекейбла. Всего для трекейбла 2 события. native TriggerRegisterTrackableHitEvent takes trigger whichTrigger, trackable t returns event native TriggerRegisterTrackableTrackEvent takes trigger whichTrigger, trackable t returns event Hit отлавливает нажатие, а Track - наведение мыши на трекейбл. Если внимательно посмотреть на другие события, то можно обнаружить, что они похожи на действия. Итак: // Destructible events TriggerRegisterDeathEvent=0,destructable _TriggerRegisterDeathEvent_Defaults=_ _TriggerRegisterDeathEvent_Category=TC_DESTRUCT Первая линия - комментарий. Он объясняет, что это такое, это - события разрушаемых объектов. TriggerRegisterDeathEvent=0,destructable. "0" означает, что функция совместима с Reign of Chaos. destructable означает объект, на который событие реагирует. TriggerRegisterDeathEvent регистрирует разрушение разрушаемого объекта (хоть это и тавтология ). Для трекейблов мы получим: // Trackable events TriggerRegisterTrackableHitEvent=1,trackable _TriggerRegisterDeathEvent_Defaults=_ - это значение по умолчанию. Здесь это "_". Оно означает, что по умолчанию нет декорации. Добавим это в код трекейбла. // Trackable events TriggerRegisterTrackableHitEvent=1,trackable _TriggerRegisterTrackableHitEvent_Defaults=_ _TriggerRegisterDeathEvent_Category=TC_DESTRUCT - это, как мы уже знаем, категория, к которой относится события. Добавим её в код. Получим: // Trackable events TriggerRegisterTrackableHitEvent=1,trackable _TriggerRegisterTrackableHitEvent_Defaults=_ _TriggerRegisterTrackableHitEvent_Category=TC_My_Functions Точно так же поступим и с Track-событием. // Trackable events TriggerRegisterTrackableTrackEvent=1,trackable _TriggerRegisterTrackableTrackEvent_Defaults=_ _TriggerRegisterTrackableTrackEvent_Category=TC_My_Functions Итак, мы научились добавлять события, условия и действия. Но нам также нужно научиться делать реагирующие на события объекты, а именно - Triggering Trackable, которой в GUI нет. Давайте разберёмся, как это делается на примере Triggering Unit. GetTriggerUnit=0,0,unit _GetTriggerUnit_Defaults= _GetTriggerUnit_Category=TC_EVENTRESPONSE GetTriggerUnit - Jass-функция, 0 означает, что она работает в RoC, второй 0 означает, что она не может быть использована в событиях, а unit - это тип, который она возвращает. Напишем нашу функцию для трекейбла: GetTriggerTrackable=1,0,trackable _GetTriggerTrackable_Defaults= _GetTriggerTrackable_Category=TC_EVENTRESPONSE Итак, мы уже прочитали о значениях по умолчанию и категориях. У нас есть функция, которая позволяет отловить трекейбл, на который навели мышку или нажали на него. Но нам нужно создать трекейбл, чтобы его отловить. Вот параметры, которые нужно дать функции создания трекейбла: native CreateTrackable takes string trackableModelPath, real x, real y, real facing returns trackable Итак, делаем такое действие: CreateTrackable=1,modelfile,real,real,real _CreateTrackable_Defaults=_,_,_,_, _CreateTrackable_Category=TC_TRACKABLE Наконец, нам надо научиться делать действия вида Set My_Var = (Last Created Trackable). Подумаем, как кодеры, написав Set My_Var = CreateTrackable(). Нужно запомнить, что такие функции нужно писать после [TriggerCalls], т.к. мы не можем присвоить переменной значение действия. Синтаксис этой функции немного другой. Чуть-чуть изменим синтаксис под параметры и получим: CreateTrackable=1,modelfile,real,real,real _CreateTrackable_Defaults="Abilities\Spells\Other\TalkToMe\TalkToMe.mdl",0,0,RealUnitFacing _CreateTrackable_Limits=_,_,_,_,_,_,0,360 _CreateTrackable_Category=TC_TRACKABLE Что ж, на этом я завершаю статью. Мы многое узнали об изменении Редактора триггеров, но всё же когда-нибудь вы поймёте, чем JASS лучше триггеров. |