Начинаем работать с weiDU (автор: Japheth)...

Я пишу это руководство, предполагая что вы СОВСЕМ ничего не знаете о WeiDU. Если вы читаете это и думаете "Что, черт возьми, такое этот WeiDU&", пожалуйста сходите на эту страницу и скачайте WeiDU.

Теперь собственно о руководстве...

Во-первых, я расскажу вам, как установить WeiDU (не беспокойтесь, это не очень сложно). Затем я вкратце расскажу вам об основах синтаксиса диалогового файла, и, что более важно, как использовать сам WeiDU. После этого я продемонстрирую вам как использовать APPEND (метод Применить) и EXTEND (метод Распространить), а также EXTERN (метод Внешний?) и тому подобные. В заключение я покажу вам как настроить и инсталлировать файл для WeiDU.

Инсталляция WeiDU

Окей, вы скачали последнюю версию WeiDU с того сайта, на который я давал ссылку выше (для информации: Weimer обновляет WeiDU достаточно часто, поэтому советую вам регулярно заходить туда за самой свежей версией) и теперь вы хотите ее инсталлировать, так? Вот что вы должны сделать. Откройте zip-файл программой-архиватором (WinAce, WinZip, WinRAR, и т.п.), и затем извлеките файл из архива пока что просто на Рабочий Стол. (когда WeiDU разархивируется, он создает свою собственную папку, которая называется WeiDU, поэтому не нужно создавать папку, в которую вы будете разархивировать файлы) Теперь на вашем Рабочем Столе должна находиться папка с названием "WeiDU" Откройте ее и удалите папки src и obj. (Они правда вам не нужны - в src находится исходный код для WeiDU, а папка obj все равно пуста). Теперь выделите все остальные папки и файлы, кликните на них правой кнопкой мыши и выберите "Вырезать". (Вы должны выделить 2 папки, которые называются examples и test, а также много файлов, в том числе и сам WeiDu.exe) Теперь перейдите в корневую папку с BG2. (Обычно это С:\Program Files\Black Isle\BGII - SOA) Просто кликните там правой кнопкой мыши и нажмите "Вставить". Ну вот, вы установили WeiDU, достаточно просто, правда?

(Примечание: WeiDU's readme называется readme.txt и, как ни странно, так же называется readme файл к BG2:SOA, поэтому если вы не хотите перезаписать свой BG2 readme, нажмите "нет", когда вас спросят, хотите ли вы заменить readme.txt)

Основы синтакса файла диалога

 

Окей, вы хотите сделать файла диалога, но после того, как вы посмотрели примеры, которые прилагаются к WeiDU, вы все равно пока ничего не понимаете? Сейчас я пробегусь по некоторым основам, а потом мы углубимся в сам WeiDU.

В WeiDU все диалоги, условия и действия (об условиях и действиях читайте ниже) должны заключаться либо в кавычки, либо в тильды. (Тильда (~) - получается, если в английской раскладке клавиатуры удерживать SHIFT и нажать кнопку прямо над кнопкой TAB.) В данных примерах я использовал тильды, но вы можете выбирать. Во-вторых, при кодировании диалога очень помогает расстановка пробелов и переносов. Вы заметите, например, что если у меня есть более двух условий/действий (опять же, подробнее о них - дальше), я ставлю перенос, и размещаю второе условие сразу под первым. Продолжайте поступать так же, если у вас есть несколько условий в одном блоке.

В диалогах часто используется два вида функций: условия и действия. Даю пример одного и другого:

IF ~I'm being attacked by big scary wolves~ THEN BEGIN WOLFATTACK0
SAY ~Holy shit, look at those wolves, I'm out of here!~
IF ~~ THEN DO ~Running away from big scary wolves~ EXIT
END

Примечание переводчика. Даю перевод всего блока, в дальнейшем перевод операторов делать не буду.

ЕСЛИ ~Меня атакуют большие страшные волки~ ТОГДА НАЧАТЬ АТАКУНАВОЛКОВ0
СКАЗАТЬ ~Боже, посмотрите на этих волков, я смываюсь отсюда!~
ЕСЛИ ~~ ТОГДА ДЕЛАТЬ ~Убегать от больших серых волков~ ВЫХОД
КОНЕЦ

Таким образом, если кто еще не знал, вот вам объяснение для основных операторов:
IF... THEN - ЕСЛИ... ТОГДА
SAY - CКАЗАТЬ
DO - ДЕЛАТЬ
EXIT - ВЫХОД
END - КОНЕЦ
И дальше я переводить эти операторы не буду.

Часть после SAY относится собственно к диалогу. Персонаж скажет: ~Holy shit, look at these wolves, I'm out of here!~.

Эти условия и действия именно в таком виде не существуют ни в одной из игр на Infinity Engine, но вы теперь видите как оно все работает? Условие здесь: "I'm being attacked by big scary wolves" ("Меня атакуют большие страшные волки"), а действие - "Running away from big scary wolves" ("Убегать от больших серых волков") . И, как вы заметите, чтобы в начале определить условие, вы просто ставите IF ~Здесь идет условие~ THEN BEGIN BLAH. BLAH - это просто внутренний ярлык, который я решил здесь использовать. Вы можете заменить BLAH чем хотите, например, WOLFIE, WOLFMEISTER, WOLFENSTEIN3D...думаю, понятно. Однако, довольно полезно использовать один и тот же внутренний ярлык на протяжении всего диалога и просто ставить номер рядом с каждым из таких ярлыков для каждого нового блока. (например, у меня есть два блока диалога. Я могу отметить первый блок ярлыком MYFIRSTNPC0, а затем отметить второй блок ярлыком MYFIRSTNPC1).

Чтобы персонаж совершил действие, вам нужно указать: DO ~здесь описание действия~ EXIT. Вы можете указать больше одного условия или действия одновременно. Также, если мы еще раз посмотрим на пример вверху, и захотим ответить тому парню, который решил убежать от волков мы можем написать следующее:

IF ~Меня атакуют большие страшные волки~ THEN BEGIN WOLFATTACK0
SAY ~Боже, посмотрите на этих волков, я смываюсь отсюда!~
IF ~~ THEN REPLY ~Ты сволочь!~ DO ~убить больших страшных волков~ EXIT
IF ~~ THEN REPLY ~Ээ.. Хорошая идея, давай убираться отсюда!~ DO ~Убегать от больших страшных волков~ EXIT
END

Так что теперь, когда парень скажет вам "Боже, посмотрите на этих волков, я смываюсь отсюда!", вы можете ему ответить так: "Ты сволочь!", что повлечет за собой действие - убийство больших страшных волков, или " or "Ээ.. Хорошая идея, давай убираться отсюда!", после чего герой будет убегать от волков.

Команда EXIT используется, когда вы хотите завершить диалог. Например, после того как вы скажете: "Ээ.. Хорошая идея, давай убираться отсюда!", диалог завершится, и вы будете убегать от волков. Однако, если вы не хотите, чтобы диалог завершался после того, как вы убежали от волков, вместо того, чтобы ставить EXIT, вы можете сделать так:

IF ~Меня атакуют большие страшные волки~ THEN BEGIN WOLFATTACK0
SAY ~Боже, посмотрите на этих волков, я смываюсь отсюда!~
IF ~~ THEN REPLY ~Ты сволочь!~ DO ~убить больших страшных волков~ EXIT
IF ~~ THEN REPLY ~Ээ.. Хорошая идея, давай убираться отсюда!~ DO ~Убегать от больших страшных волков~ GOTO WOLFATTACK1
END

IF ~~ THEN BEGIN WOLFATTACK1
SAY ~Эй, ты придурок! Это я просто пошутил! Арррххх!~
IF ~~ THEN REPLY ~Ты ***! Сейчас ты у меня получишь, слабак!~ DO ~побить слабака~ EXIT
END

Теперь вместо того, чтобы закончиться после вашего ответа "Ээ.. Хорошая идея, давай убираться отсюда!", диалог продолжается и переходит к следующему блоку, который обозначен ярлыком WOLFATTACK1. Таким образом, оператор GOTO говорит WeiDU, что нужно перейти к обозначенному ярлыку.

Команда END в WeiDU просто обозначает "Этот блок диалога закончился, переходим к следующему!"

Вот это вкратце описывает основы WeiDU. надеюсь, вы понимаете его теперь чуть лучше. Теперь я приведу вам пример простого диалога (он был написан Death), а затем покажу, как его правильно кодировать.

БЛОК 1(Квест не получен, разговариваем в первый раз)
Скримир (Skrymir) - Приветствую тебя, смертный! Иди, отобедай со мной, раздели со мной мой хлеб и вино.
Ответ
1: Кто ты? (к БЛОКУ 3)
2: Конечно. (Партия отдыхает)
3: Может быть в другой раз. (к БЛОКУ 4)
4: Не сейчас, я очень занят. (Диалог заканчивается)
5: Ты, чудище, готовься к смерти! (Начинается битва)

БЛОК 2 (Если партия уже получила квест, разговариваем в первый раз)
Скримир - Ха! Смертные лакеи Одина явились! Вы пришли испытать свою судьбу в битве против Короля Гигантов Холода, Скримира? Даже могучий Тор не решился бы на такую глупость, хотя бы он и был со своим молотом Мьолльниром.
Ответ
1: Кто ты? (к БЛОКУ 5)
2: Отдай мне то, что ты украл у богов и тогда я, возможно, сохраню тебе жизнь!(к БЛОКУ 6)
3: Умри, злобное чудище! (Начинается битва)
4: Пожалуйста, не трогай меня!! (к БЛОКУ 7)

БЛОК 3 (из БЛОКА 1/Ответ #1)
Скримир - Ха-ха! Я - Скримир, Король Гигантов Холода! Я - злейший враг Эзира!(к БЛОКУ 1)

БЛОК 4 (из БЛОКА 1/Ответ #3)
Скримир - Как хочешь. (диалог заканчивается)

БЛОК 5 (из БЛОКА 2/Ответ #1)
Скримир - Ха-ха! Я - Скримир, Король Гигантов Холода! Я - злейший враг Эзира! Но ты и так это знал.(к БЛОКУ 2)
БЛОК 6 (из БЛОКА 2/Ответ #2)
Скримир - Ха-ха! Да, сохрани МНЕ жизнь! Здорово! Почему ты считаешь, что тебе по плечу то, что даже боги пока не смогли сделать? (Начинается битва)

БЛОК 7 (из БЛОКА 2/Ответ #4)
Скримир - Беги, трусливый смертный! (репутация -1, диалог заканчивается)

БЛОК 8 (Разговариваем не в первый раз, квест не получен)
Скримир - А, ты вернулся, теперь хочешь побеседовать и отобедать со мной?
Ответ
1: Да, мы передумали. (Партия отдыхает)
2: Извини, у нас нет времени на это. (Диалог заканчивается)
3: Твое зло должно быть уничтожено! Приготовься к смерти! (Начинается битва)

БЛОК 9 (Разговариваем не в первый раз, квест получен)
Скримир - Ха, бродяги вернулись!
Ответe
1: Бродяги? Ты скоро увидишь, как бродяги разделаются с такой мразью как ты! (Начинается битва)
2: И-извини, Скримир. Мы не хотели тебя побеспокоить. (к БЛОКУ 7)
3: Ты отдашь нам вещи, которые ты украл у богов! (к БЛОКУ 10)

БЛОК 10
Скримир - Ха-ха! Я так не думаю, червяки. Вы для меня не больше чем грязь под моим сапогом! (Начинается битва)

Вот как нужно кодировать этот диалог. Вы уже заметили, что я специально отмечал такие подробности: разговариваем уже не в первый раз, квест получен, разговариваем в первый раз и т.д. Это все условия, которые должны выполняться. Дальше вы поймете как это делается. Например, чтобы сообщить Infinity Engine, что этот блок должен начинаться только в том случае, если персонаж еще не разговаривал с этим NPC, вы будете использовать переменную NumTimesTalkedTo(0). А вместо такого неясного определения, как "Начинается битва", я использовал следующий набор инструкций

ChangeEnemyAlly(Myself,EVILCUTOFF)
Enemy()
Attack(NearestEnemyOf(Myself))

Это изменяет его расположение к вам (переменная ENEMY/ALLY) на враждебное (EVILCUTOFF), делает его врагом, и затем он вас атакует, или, если вы перемещаетесь достаточно далеко от него, он атакует ближайшего к нему члена партии, и т.д.

(Вы можете найти список возможных действий в файле actions.ids, список всех возможных условий в файле triggers.ids и все возможные состояния Enemy/Ally в файле ea.ids. Все эти файлы находятся в директории script compiler в корневой папке BG2)

Итак, вот он код!

BEGIN fwdskrym

IF ~NumTimesTalkedTo(0)
Global("GiantQuestCheck","GLOBAL",0)~ THEN BEGIN D#SKY0
SAY ~Приветствую тебя, смертный! Иди, отобедай со мной, раздели со мной мой хлеб и вино.~
IF ~~ THEN REPLY ~Кто ты?~ GOTO D#SKY2
IF ~~ THEN REPLY ~Конечно.~ DO ~Rest()~ EXIT
IF ~~ THEN REPLY ~Может быть в другой раз.~ GOTO D#SKY3
IF ~~ THEN REPLY ~Не сейчас, я очень занят.~ EXIT
IF ~~ THEN REPLY ~Ты, чудище, готовься к смерти! ~ DO ~ChangeEnemyAlly(Myself,EVILCUTOFF)
Enemy()
Attack(NearestEnemyOf(Myself))~ EXIT
END

IF ~NumTimesTalkedTo(0)
Global("GiantQuestCheck","GLOBAL",1)~ THEN BEGIN D#SKY1
SAY ~Ха! Смертные лакеи Одина явились! Вы пришли испытать свою судьбу в битве против Короля Гигантов Холода, Скримира? Даже могучий Тор не решился бы на такую глупость, хотя бы он и был со своим молотом Мьолльниром.~
IF ~~ THEN REPLY ~Кто ты?~ GOTO D#SKY4
IF ~~ THEN REPLY ~Отдай мне то, что ты украл у богов и тогда я, возможно, сохраню тебе жизнь!~ GOTO D#SKY5
IF ~~ THEN REPLY ~Умри, злобное чудище!~ DO ~ChangeEnemyAlly(Myself,EVILCUTOFF)
Enemy()
Attack(NearestEnemyOf(Myself))~ EXIT
IF ~~ THEN REPLY ~Пожалуйста, не трогай меня!!~ GOTO D#SKY6
END

IF ~~ THEN BEGIN D#SKY2
SAY ~Ха-ха! Я - Скримир, Король Гигантов Холода! Я - злейший враг Эзира!~
IF ~~ THEN GOTO D#SKY0
END

IF ~~ THEN BEGIN D#SKY3
SAY ~Как хочешь.~
IF ~~ THEN EXIT
END

IF ~~ THEN BEGIN D#SKY4
SAY ~Ха-ха! Я - Скримир, Король Гигантов Холода! Я - злейший враг Эзира! Но ты и так это знал.~
IF ~~ THEN GOTO D#SKY1
END

IF ~~ THEN BEGIN D#SKY5
SAY ~Ха-ха! Да, сохрани МНЕ жизнь! Здорово! Почему ты считаешь, что тебе по плечу то, что даже боги пока не смогли сделать? ~
IF ~~ THEN DO ~ChangeEnemyAlly(Myself,EVILCUTOFF)
Enemy()
Attack(NearestEnemyOf(Myself))~ EXIT
END

IF ~~ THEN BEGIN D#SKY6
SAY ~Беги, трусливый смертный!~
IF ~~ THEN DO ~ReputationInc(-1)~ EXIT
END

IF ~NumTimesTalkedToGT(0)
Global("GiantQuestCheck","GLOBAL",0)~ THEN BEGIN D#SKY7
SAY ~А, ты вернулся, теперь хочешь побеседовать и отобедать со мной?~
IF ~~ THEN REPLY ~Да, мы передумали.~ DO ~Rest()~ EXIT
IF ~~ THEN REPLY ~Извини, у нас нет времени на это.~ EXIT
IF ~~ THEN REPLY ~Твое зло должно быть уничтожено! Приготовься к смерти!~ DO ~ChangeEnemyAlly(Myself,EVILCUTOFF)
Enemy()
Attack(NearestEnemyOf(Myself))~ EXIT
END

IF ~NumTimesTalkedToGT(0)
Global("GiantQuestCheck","GLOBAL",1)~ THEN BEGIN D#SKY8
SAY ~Ха, бродяги вернулись!~
IF ~~ THEN REPLY ~Бродяги? Ты скоро увидишь, как бродяги разделаются с такой мразью как ты!~ DO ~ChangeEnemyAlly (Myself,EVILCUTOFF)
Enemy()
Attack(NearestEnemyOf(Myself))~ EXIT
IF ~~ THEN REPLY ~И-извини, Скримир. Мы не хотели тебя побеспокоить.~ GOTO D#SKY6
IF ~~ THEN REPLY ~Ты отдашь нам вещи, которые ты украл у богов!~ GOTO D#SKY9
END

IF ~~ THEN BEGIN D#SKY9
SAY ~Ха-ха! Я так не думаю, червяки. Вы для меня не больше чем грязь под моим сапогом!~
IF ~~ THEN DO ~ChangeEnemyAlly(Myself,EVILCUTOFF)
Enemy()
Attack(NearestEnemyOf(Myself))~ EXIT
END

На этом код заканчивается. Сейчас я покажу вам, как использовать некоторые функции WeiDU.

Компиляция диалогов

Чтобы скомпилировать диалог вы должны находиться в режиме командной строки. Например, запустите команду "Выполнить..." ("Run...") из главного меню Windows и напечатайте там команду. Перейдите в корневую директорию BG2, напечатав в строке:

cd x:pathtobg2directory (где x=название диска, а pathtobg2directory=путь к корневой директории BG2. В большинстве случаев это будет c:Program FilesBlack IsleBGII - SOA)

Теперь, когда вы находитесь в корневой директории bg2, чтобы скомпилировать диалог с помощью WeiDU вам нужно напечатать следующее:

weidu pathtofile/filename.d --tlkout dialog.tlk --out override (где path to filename - директория, где находится ваш файл .d и filename - имя файла)

В этом случае, WeiDU скомпилирует диалог, а затем разместит этот диалог и обновленную копию dialog.tlk в папку override. Затем просто перейдите в вашу папку override и переместите файл dialog.tlk обратно в корневую директорию bg2. Ваш диалог готов к запуску!

Декомпиляция диалогов

Чтобы вы могли посмотреть на диалоги с Аэри в формате .d, вы можете с помощью WeiDU декомпилировать диалог. Все что вам нужно сделать для этого - напечатать в командной строке следующее:

weidu aerie.dlg --out override

После этого файл aerie.d будет помещен в вашу папку override.