Всё о Готике
Miranda Dialog Creator


автор статьи - marazmus

Miranda Dialog Creator – программа от создателей мода “Das Mirandadorf” для Готики и Готики2.

1. Предварительные замечания.

Здесь я хочу предложить уважаемым готам и модостроителям небольшой FAQ по использованию этой замечательной программы. FAQ по большей части – перевод на русский язык оригинального readme, но я постарался добавить немного примеров и картинок, для людей, у которых мало времени заморачиваться на техническом аспекте дела – для непосредственно творческих людей. :)

Последняя версия на момент написания этого FAQ – 1.2.

Страничка с описанием программы (немецкий язык): http://www.fizzban.net/creator.html
Прямая ссылка: http://www.fizzban.net/mirandadialogcreator1.2.zip
Зеркало на сайте:

Требования:
1) Установленная J2SE (Java Runtime Environment)
Примечание – версия желательна самая последняя. Не буду обобщать на всех, но лично у меня не запускалось на версии 1.4, пришлось скачать версию 1.5 J2SE. Посетите http://java.sun.com/j2se/1.5.0/download.jsp
Внимание – размер инсталлятора J2SE для Windows около 16 Мб.
Но эти мегабайты стократно окупятся радикальным уменьшением затрат времени на чисто техническую работу по скриптингу.

Основная цель этой программы – исключить неблагодарную техническую работу по написанию скриптов диалогов, всяческие copy/paste и т.п.

Сама программа весит крайне мало – всего 20 кб.

После получения распакуйте ее куда будет удобней и начинайте работу.

2. Простой пример.

Здесь и дальше я исхожу из того, что программа находится в том же каталоге, что и создаваемые примеры скриптов.
Создайте сразу в этом каталоге подпапку sripts, для дальнейшей работы.

У меня это выглядит так, к примеру:
catalog example

Давайте начнем сразу с небольшого примера.

Создаем в любимом текстовом редакторе файл с названием, к примеру, example1.dia
Сохраним его тут же, в рабочем каталоге.
Вот его содержимое:

code:
person: NONE_101_Gustaf, 16

info: SimpleDialog

> Доброе утро, Густав!
< И тебе того же, коли не шутишь...

Запускаем командную строку, или любимый файловый менеджер, неважно какой – лишь бы в нем была возможность ввести и выполнить следующую команду:

MirandaDialogCreator.jar example1.dia scripts

Первый пункт – это имя самой программы. Второй – имя файла, который она будет “разбирать”. Третий (scripts) – имя папки, в которую будут складываться готовые скрипты, сформированные программой.

Если все прошло нормально, появится окно лога программы.
Например:
log example

Видим, что все прошло нормально.
Идем в папку scripts.
Что мы видим здесь?
А видим, что сформирован файлик, названный по стандартам готических скриптов.
new dialog file created

Имя NONE_101_Gustaf взято из нашего DIA-файла.
За это отвечает строка
person: NONE_101_Gustaf, 16

Что же внутри готового файла скрипта?

code:
instance NONE_101_Gustaf_SimpleDialog (C_INFO)
{
npc = NONE_101_Gustaf;
condition = NONE_101_Gustaf_SimpleDialog_Condition;
information = NONE_101_Gustaf_SimpleDialog_Info;
important = FALSE;
permanent = FALSE;
description = " Доброе утро, Густав!";
};

func int NONE_101_Gustaf_SimpleDialog_Condition()
{
return TRUE;
};

func void NONE_101_Gustaf_SimpleDialog_Info()
{
AI_Output(other, self, "NONE_101_Gustaf_SimpleDialog_Info_15_01"); // Доброе утро, Густав!
AI_Output(self, other, "NONE_101_Gustaf_SimpleDialog_Info_16_02"); // И тебе того же, коли не шутишь...
};

Клево. Сфомирован полностью готовый и рабочий пункт диалога. Без механической работы по написанию и copy/paste. Всего четырьмя строками исходного файла.
Это воодушевляет. :)

3. Разбор конкретных операторов.

Оператор person.

person: NONE_101_Gustaf, 16

Оператор person определяет скриптовое имя персонажа, для которого пишется диалог.
В данном случае это NPC, который участвует в скриптах под именем NONE_101_Gustaf.

Первый параметр – скриптовое имя, используется так:

а) формирует имя D-файла (у нас это будет DIA_NONE_101_Gustaf.D)
б) участвует в именах instance “своих” пунктов диалога, например:
instance NONE_101_Gustaf_SimpleDialog (C_INFO)
в) участвует в формировании имен Condition и Info функций данного пункта диалога, например:

code:
npc           = NONE_101_Gustaf;
condition       = NONE_101_Gustaf_SimpleDialog_Condition;
information     = NONE_101_Gustaf_SimpleDialog_Info;

Второй параметр (число 16) – это номер голоса, которым будет говорить наш персонаж.
Конкретное использование этого числа – в функции AI_Output, к примеру, в нашем диалоге:

code:
AI_Output(other, self, "NONE_101_Gustaf_SimpleDialog_Info_15_01"); // Доброе утро, Густав!

Нужно сразу отметить, что по по умолчанию программы ГГ говорит голосом № 15. Но это можно изменить, просто поставив в начале файла оператор

person: PC_Hero, 4

Это укажет программе использовать для функции AI_Output число 4 ( _04_XX). Этот оператор не влияет больше ни на что, кроме номера голоса.

Также сразу скажу, что в одном DIA-файле можно использовать несколько операторов person – в этом случае программа просто “распределит” скрипты разных персонажей по разным D-файлам. Но если диалоги большие, лучше бы, конечно, делать отдельный DIA-файл для каждого NPC. На любителя, в общем.

Оператор info

info: SimpleDialog

Оператор info – основной оператор формирования диалогов. Именно он отвечает за “появление” в готовых скриптах конструкции типа

instance NONE_101_Gustaf_SimpleDialog (C_INFO)

У него один параметр – имя диалога. В нашем случае это SimpleDialog.

Для описания простого диалога достаточно одного такого оператора, что мы и видим в примере.

Операторы “<" и ">”.

Эти операторы отвечают за сам “разговор”. А точнее – именно они формируют конструкцию AI_Output в файле готового скрипта. В нашем примере это очевидно. Вот “исходник”:

> Доброе утро, Густав!
< И тебе того же, коли не шутишь...

А получилось:

code:
func void NONE_101_Gustaf_SimpleDialog_Info()
{
AI_Output(other, self, "NONE_101_Gustaf_SimpleDialog_Info_15_01"); // Доброе утро, Густав!
AI_Output(self, other, "NONE_101_Gustaf_SimpleDialog_Info_16_02"); // И тебе того же, коли не шутишь...
};

Оператор ”>” (больше) – это обращение ГГ к персонажу, с которым ведется диалог.
А оператор ”<” (меньше) – наоборот, обращение персонажа к ГГ,
Все очень просто. :)

Оператор flags.

Этот оператор “ставит” флаги в instance диалога, такие как important или permanent.

1) Флаг important – отвечает за то, чтобы персонаж сам обращался к ГГ, не дожидаясь, пока игрок начнет разговор.

Простой пример (example2.dia):

code:
person: NONE_101_Gustaf, 16

info: ImportantDialog

flags: important

< Эй, погоди-ка, парень!
> Ну что тебе надо опять?
А вот что получилось:

code:
instance NONE_101_Gustaf_ImportantDialog (C_INFO)
{
npc         = NONE_101_Gustaf;
condition         = NONE_101_Gustaf_ImportantDialog_Condition;
information         = NONE_101_Gustaf_ImportantDialog_Info;
important         = TRUE;
permanent         = FALSE;
};

Здесь Густав сам обратится к проходящему мимо него ГГ.

2) Флаг permanent – отвечает за то, чтобы этот пункт диалога не исчезал после разговора, а оставался в меню выбора постоянно.

Простой пример (example3.dia):

code:
person: NONE_101_Gustaf, 16

Info: PermanentDialog

flags: permanent

> Мое почтение!
>!t_GreetNov

< Ну-ну, подлиза. Говори уже - чего надо?

А вот что получится:

code:
instance NONE_101_Gustaf_PermanentDialog (C_INFO)
{
npc = NONE_101_Gustaf;
condition = NONE_101_Gustaf_PermanentDialog_Condition;
information = NONE_101_Gustaf_PermanentDialog_Info;
important = FALSE;
permanent = TRUE;
description = " Мое почтение!";
};

func int NONE_101_Gustaf_PermanentDialog_Condition()
{
return TRUE;
};

func void NONE_101_Gustaf_PermanentDialog_Info()
{
AI_Output(other, self, "NONE_101_Gustaf_PermanentDialog_Info_15_01"); // Мое почтение!
AI_PlayAni(other, "T_GREETNOV");
AI_Output(self, other, "NONE_101_Gustaf_PermanentDialog_Info_16_02"); // Ну-ну, подлиза. Говори уже - чего надо?
AI_PlayAni(self, "T_GETLOST");
};

Этот диалог будет доступен всегда.

3) Флаг permanent обычно используется в паре с флагом trade – формируя постоянно доступный пункт диалога торговли.

Пример (example4.dia):

code:
person: NONE_101_Gustaf, 16

Info: LetsTrade
flags: permanent, trade
Num: 998

> Поторгуем?

А вот что получится:

code:
instance NONE_101_Gustaf_LetsTrade (C_INFO)
{
npc        = NONE_101_Gustaf;
condition        = NONE_101_Gustaf_LetsTrade_Condition;
information        = NONE_101_Gustaf_LetsTrade_Info;
important        = FALSE;
permanent        = TRUE;
nr        = 998;
description        = " Поторгуем?";
trade        = TRUE;
};

func int NONE_101_Gustaf_LetsTrade_Condition()
{
return TRUE;
};

func void NONE_101_Gustaf_LetsTrade_Info()
{
AI_Output(other, self, "NONE_101_Gustaf_LetsTrade_Info_15_01"); // Поторгуем?
};

Операторы cond_

Операторы этого типа формируют условия, которые определяют, будет показан конкретный пункт диалога или нет.

1) Оператор conddia – проверка на то, говорил ли ГГ уже с данным NPC по какой-либо теме (был ли выбран и отображен конкретный пункт диалога); технически – формирование функции Npc_KnowsInfo().

Пример (example5.dia):

code:
person: NONE_101_Gustaf, 16

info: SimpleCond

conddia: SimpleDialog

conddia: NONE_102_Peter, IAwaitedYou

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

А вот что получится (приведу здесь только функцию _Condition):

code:
func int NONE_101_Gustaf_SimpleCond_Condition()
{
if ((Npc_KnowsInfo(hero, NONE_101_Gustaf_SimpleDialog)) && (Npc_KnowsInfo(hero, NONE_102_Peter_IAwaitedYou)))
{
return TRUE;
};
};

Как видно из примера, можно формировать как простые, так и составные условия.
Также видно, что у оператора conddia есть параметры.
Если указать только один параметр – имя instance диалога, на которое нужно првести сравнение, то в Npc_KnowsInfo подставляется имя текущего NPC – для которого пишется данный диалог.
А если указать перед именем instance диалога, на которое нужно првести сравнение, еще и имя другого NPC, то в Npc_KnowsInfo подставится это имя.

Что касается логики – два отдельных оператора cond* будут связаны логическим оператором “И”.

2) Оператор conditem – проверка на наличие определенных предметов.

Пример (example6.dia):

code:
person: NONE_101_Gustaf, 16

info: SimpleCond2

conditem: ItFoMuttonRaw, 4

> Я принес тебе то, что ты хотел.

>>ItFoMuttonRaw, 4

< Оо, йа-йа, зер гут, Вольдемар Иванович!
< Вот тебе твоя награда.

А вот что получится:

code:
instance NONE_101_Gustaf_SimpleCond2 (C_INFO)
{
npc = NONE_101_Gustaf;
condition = NONE_101_Gustaf_SimpleCond2_Condition;
information = NONE_101_Gustaf_SimpleCond2_Info;
important = FALSE;
permanent = FALSE;
description = " Я принес тебе то, что ты хотел.";
};

func int NONE_101_Gustaf_SimpleCond2_Condition()
{
if (Npc_HasItems(other, ItFoMuttonRaw) >= 4)
{
return TRUE;
};
};

func void NONE_101_Gustaf_SimpleCond2_Info()
{
AI_Output(other, self, "NONE_101_Gustaf_SimpleCond2_Info_15_01"); // Я принес тебе то, что ты хотел.
B_GiveInvItems(other, self, ItFoMuttonRaw, 4);
AI_Output(self, other, "NONE_101_Gustaf_SimpleCond2_Info_16_02"); // Оо, йа-йа, зер гут, Вольдемар Иванович!
AI_Output(self, other, "NONE_101_Gustaf_SimpleCond2_Info_16_03"); // Вот тебе твоя награда.
CreateInvItems(self, ItFoBooze, 1);
B_GiveInvItems(self, other, ItFoBooze, 1);
CreateInvItems(self, ItFoLoaf, 2);
B_GiveInvItems(self, other, ItFoLoaf, 2);
};

Как видим, использование этого оператора – проще некуда.

Одно неприятно – два отдельных оператора conditem всегда будут связаны логикой “И”. А вот как сделать их связку логикой “ИЛИ”, я пока не нашел.

Кстати, “всплыли” еще два оператора – ”>>” – ГГ отдает персонажу определенный/е предмет/ы, и ”<<” – NPC отдает ГГ определенный/е предмет/ы.

3) Другие операторы.

Сразу приведу пример (example7.dia):

code:
person: NONE_101_Gustaf, 16

info: SimpleCond3

conddia: SimpleDialog; Pers_203_Hark, IAwaitedYou

conddia: !SimpleCond2

conditem: !ItFo_Potion_GruenerTrank;
conditem: ItFoMuttonRaw, 4

condcode: Npc_GetDistToWP(self, "abbc") < 500
> Я, к сожалению, не смог найти все.
< Тогда ищи дальше!

Как видим, можно использовать оператор "!", чтобы ставить условие "НЕ" на операторы cond*.

code:
func int NONE_101_Gustaf_SimpleCond3_Condition()
{
if ((Npc_KnowsInfo(hero, NONE_101_Gustaf_SimpleDialog) || Npc_KnowsInfo(hero, Pers_203_Hark_IAwaitedYou)) && (!Npc_KnowsInfo(hero, NONE_101_Gustaf_SimpleCond2)) && (Npc_HasItems(other, ItFo_Potion_GruenerTrank;) < 1) && (Npc_HasItems(other, ItFoMuttonRaw) >= 4) && (Npc_GetDistToWP(self, "abbc") < 500))
{
return TRUE;
};
};

Также, оператор conddia в явном виде поддерживает условие “ИЛИ” – просто нужно поставить ”;” между параметрами.

А еще появился новый оператор – condcode. Его смысл – просто подстановка “чистого” кода скриптов готик в формируемое услове. Из примера все видно очень хорошо.

Пока не совсем понял назначение оператора condfunc, поэтому сейчас пропущу его описание. Может, кто подскажет, потом.

Еще один пример (example9.dia):

code:
person: NONE_101_Gustaf, 16

Info: DescDialog

desc: Официальное приветствие

$IF Npc_GetTrueGuild(hero) == GIL_NONE
>!t_GreetNov
$ELSE
>!t_GreetGrd
$ENDIF

>Hallo!

!Npc_ExchangeRoutine(self, "StandEntry");

$END

Результат (только функция _info):

code:
func void NONE_101_Gustaf_DescDialog_Info()
{
if (Npc_GetTrueGuild(hero) == GIL_NONE)
{
AI_PlayAni(other, "T_GREETNOV");
}
else
{
AI_PlayAni(other, "T_GREETGRD");
};
AI_Output(other, self, "NONE_101_Gustaf_DescDialog_Info_15_01"); // Hallo!
Npc_ExchangeRoutine(self, "StandEntry");
AI_StopProcessInfos(self);
};

Как видно из примера, можно использовать конструкцию
$IF .. $ELSE .. $ENDIF
Причем, как я понял, в параметре $IF нужно ставить скрипт готики, а не операторы MDC (Miranda Dialog Creator). В блока же можно применять как операторы MDC, так и скриптовые конструкции готики. В этом случае в начале строки нужно просто поставить оператор ”!”. Это дает возможность писать скриптами готики прямо в DIA-файле – все, что оформлено таким образом, попадет в файл-результат без изменений.

И еще один пример (example10.dia):

code:
person: NONE_101_Gustaf, 16

info: Exit

Результат:

code:
instance NONE_101_Gustaf_Exit (C_INFO)
{
npc = NONE_101_Gustaf;
condition = NONE_101_Gustaf_Exit_Condition;
information = NONE_101_Gustaf_Exit_Info;
important = FALSE;
permanent = TRUE;
nr = 999;
description = DIALOG_ENDE;
};

func int NONE_101_Gustaf_Exit_Condition()
{
return TRUE;
};

func void NONE_101_Gustaf_Exit_Info()
{
AI_StopProcessInfos(self);
};

Краткость изначальной конструкции и результат – просто поражают. :)
В общем, чтобы сделать стандартный пункт диалога “Закончить разговор”, нужно просто написать вышеприведенный оператор с параметром Exit. И все.

4. Ветвление диалогов.

Реализация ветвления диалогов через конструкцию Info_AddChoice – довольно удобный инструмент, но уж больно много кода приходится иногда писать. MDC спасает нас и здесь. :)

Простой пример (example11.dia):

code:
person: NONE_102_Peter, 11

info: IAwaitedYou
flags: important
< Давай-ка, поиграем в угадайку.
< Вот скажи, кто сильней - кит или слон?
%

opt: optKit
> Кит?
< Нет, не угадал.

opt: optSlon
desc: Слон, наверное?
> Эээ... Слон, наверное, так?
< Конечно!
%%

opt: Back

Результат:

code:
instance NONE_102_Peter_IAwaitedYou (C_INFO)
{
npc = NONE_102_Peter;
condition = NONE_102_Peter_IAwaitedYou_Condition;
information = NONE_102_Peter_IAwaitedYou_Info;
important = TRUE;
permanent = FALSE;
};

func int NONE_102_Peter_IAwaitedYou_Condition()
{
return TRUE;
};

func void NONE_102_Peter_IAwaitedYou_Info()
{
AI_Output(self, other, "NONE_102_Peter_IAwaitedYou_Info_11_01"); // Уф, дядя, я уже тебя заждался совсем! Где тебя носит?!
AI_Output(self, other, "NONE_102_Peter_IAwaitedYou_Info_11_02"); // Давай-ка, поиграем в угадайку.
AI_Output(self, other, "NONE_102_Peter_IAwaitedYou_Info_11_03"); // Вот скажи, кто сильней - кит или слон?
Info_ClearChoices(NONE_102_Peter_IAwaitedYou);
Info_AddChoice(NONE_102_Peter_IAwaitedYou, " Кит?", NONE_102_Peter_IAwaitedYou_optKit);
Info_AddChoice(NONE_102_Peter_IAwaitedYou, "Слон, наверное?", NONE_102_Peter_IAwaitedYou_optSlon);
Info_AddChoice(NONE_102_Peter_IAwaitedYou, DIALOG_BACK, NONE_102_Peter_IAwaitedYou_Back);
};

func void NONE_102_Peter_IAwaitedYou_optKit()
{
AI_Output(other, self, "NONE_102_Peter_IAwaitedYou_optKit_15_01"); // Кит?
AI_Output(self, other, "NONE_102_Peter_IAwaitedYou_optKit_11_02"); // Нет, не угадал.
};

func void NONE_102_Peter_IAwaitedYou_optSlon()
{
AI_Output(other, self, "NONE_102_Peter_IAwaitedYou_optSlon_15_01"); // Эээ... Слон, наверное, так?
AI_Output(self, other, "NONE_102_Peter_IAwaitedYou_optSlon_11_02"); // Конечно, глупый ты дяденька!
Info_ClearChoices(NONE_102_Peter_IAwaitedYou);
};

func void NONE_102_Peter_IAwaitedYou_Back()
{
Info_ClearChoices(NONE_102_Peter_IAwaitedYou);
};

В общем, если говорить кратко:
Пункты выбора формируются оператором opt. В качестве параметра – наименование пункта выбора.
Если добавить оператор desc сразу после opt, то можно изменить текст подсказки; если не ставить desc, то в качестве подсказки будет выведена первая фраза ГГ.
Оператор “” формирует конструкцию Info_ClearChoices, то есть “чистит” список пунктов выбора для его последующего наполнения операторами opt.
Если конструкция Info_ClearChoices нужна в обработке пункта выбора, то есть нужно “закончить выбор”, то в пределах нужного оператора opt ставим оператор “
%”.

Иногда бывает нужно “сослаться” на уже созданные ранее функции-реакции на пункты выбора.
В этом случае делаем так (добавляем следующий код):

code:
person: NONE_102_Peter, 11

Info: EinAndererDialog

> Я что вспомнил-то. Про кита и слона.
< А, про угадайку. Ну и кто сильней, на этот раз?

%IAwaitedYou, optKit
%IAwaitedYou, optSlon

Результат:

code:
func void NONE_102_Peter_EinAndererDialog_Info()
{
AI_Output(other, self, "NONE_102_Peter_EinAndererDialog_Info_15_01"); // Я что вспомнил-то. Про кита и слона.
AI_Output(self, other, "NONE_102_Peter_EinAndererDialog_Info_11_02"); // А, про угадайку. Ну и кто сильней, на этот раз?
Info_ClearChoices(NONE_102_Peter_EinAndererDialog);
Info_AddChoice(NONE_102_Peter_EinAndererDialog, " Кит?", NONE_102_Peter_IAwaitedYou_optKit);
Info_AddChoice(NONE_102_Peter_EinAndererDialog, "Слон, наверное?", NONE_102_Peter_IAwaitedYou_optSlon);
};

То есть используем оператор ”%” с параметрами ИмяПунктаДиалога и наименованиями уже описанных ранее/выше функций реакции.

5. “Обработка” квестов.

“Начать” квест совсем-совсем нетрудно :).
Простой пример (example13.dia):

code:
person: NONE_103_Anna, 8

Info: StartMis
> Что тебе нужно?
< Принеси мне Цветочек Аленький, молодец удаленький.

$STARTMIS RedFlower

$LOGMISS RedFlower, Аленький Цветочек для Анны

Результат:

code:
func void NONE_103_Anna_StartMis_Info()
{
AI_Output(other, self, "NONE_103_Anna_StartMis_Info_15_01"); // Что тебе нужно?
AI_Output(self, other, "NONE_103_Anna_StartMis_Info_08_02"); // Принеси мне Цветочек Аленький, молодец удаленький.
MIS_RedFlower = LOG_RUNNING;
Log_CreateTopic(TOPIC_RedFlower, LOG_MISSION);
Log_SetTopicStatus(TOPIC_RedFlower, LOG_RUNNING);
B_LogEntry(TOPIC_RedFlower, "Аленький Цветочек для Анны");
};

Ну, тут все понятно и без обьяснений. :)
За добавление записей в журнал (??B_LogEntry??) отвечает оператор $LOGMISS.

Результат работы конструкции

code:
$MISFAIL TestQuest

выглядит так:

code:
MIS_TestQuest = LOG_FAILED;
Log_SetTopicStatus(TOPIC_TestQuest, LOG_FAILED);

а конструкции

code:
$MISSUCC TestQuest

$EXP XP_TestQuest

$EXP 100

так:

code:
MIS_TestQuest = LOG_SUCCESS;
Log_SetTopicStatus(TOPIC_TestQuest, LOG_SUCCESS);
B_GivePlayerXP(XP_TestQuest);
B_GivePlayerXP(100);

Примечания в журнале формируем так:

code:
$LOGNOTE CityTraderz, Торговцы в основном обретаются на Торговой площади.

Результат:

code:
Log_CreateTopic(TOPIC_CityTraderz, LOG_NOTE);
B_LogEntry(TOPIC_CityTraderz, "Торговцы в основном обретаются на Торговой площади.");

6. Дополнения.

Еще одна интересная фишка – “автоформирование” диалога кражи.
Я думаю, тут все понятно без лишних слов. Для мужского персонажа букву W в параметрах оператора info нужно убрать.
Вот пример (example14.dia):

code:
person: NONE_103_Anna, 8

Info: Pickpocket w 20 45

Результат:

code:
instance NONE_103_Anna_PICKPOCKET (C_INFO)
{
npc = NONE_103_Anna;
condition = NONE_103_Anna_PICKPOCKET_Condition;
information = NONE_103_Anna_PICKPOCKET_Info;
important = FALSE;
permanent = TRUE;
nr = 900;
description = Pickpocket_20_Female;
};

func int NONE_103_Anna_PICKPOCKET_Condition()
{
if (C_Beklauen(20, 45))
{
return TRUE;
};
};

func void NONE_103_Anna_PICKPOCKET_Info()
{
Info_ClearChoices(NONE_103_Anna_PICKPOCKET);
Info_AddChoice(NONE_103_Anna_PICKPOCKET,DIALOG_BACK, NONE_103_Anna_PICKPOCKET_BACK);
Info_AddChoice(NONE_103_Anna_PICKPOCKET,DIALOG_PICKPOCKET, NONE_103_Anna_PICKPOCKET_DoIt);
};

func void NONE_103_Anna_PICKPOCKET_BACK()
{
Info_ClearChoices(NONE_103_Anna_PICKPOCKET);
};

func void NONE_103_Anna_PICKPOCKET_DoIt()
{
B_Beklauen();
Info_ClearChoices(NONE_103_Anna_PICKPOCKET);
};

Прошу в комментарии - замечания, исправления, пожелания.
Спасибо за внимание.

 
 
Copyright © 2008 GotomanRambler's Top100

 
Hosted by uCoz