1. Уважаемые гости и новички, приветствуем Вас на нашем форуме
    Здесь вы можете найти ответы практически на все свои вопросы о серии игр «Готика» (в том числе различных модах на нее), «Ведьмак», «Ризен», «Древние свитки», «Эра дракона» и о многих других играх. Можете также узнать свежие новости о разработке новых проектов, сыграть в увлекательные ФРПГ, восхититься творчеством наших форумчан, либо самим показать, что вы умеете. Ну и наконец, можете обсудить общие увлечения или просто весело пообщаться с посетителями «Таверны».

    Чтобы получить возможность писать на форуме, оставьте сообщение в этой теме.
    Удачи!
    Скрыть объявление
  2. Форум аддона "Возвращение" 2.0:
    — Обсудить игру, почитать о прохождениях и/или разрешить свои вопросы по игре вы можете в одной из тем одноименного форума. Посетить...
    — Прочитать историю изменения и/или скачать последнюю версию аддона "Возвращение", вы можете на страницах наших ресурсов. Скачать...
    Скрыть объявление

Важно Miranda Dialog Creator - ускорение скриптинга для Г1 и Г2а

Тема в разделе "Скриптинг", создана пользователем MEG@VOLT, 18 сен 2013.

Статус темы:
Закрыта.
  1. MEG@VOLT

    MEG@VOLT ★★★★★★★
    Модератор

    Регистрация:
    24 мар 2006
    Сообщения:
    1.691
    Благодарности:
    723
    Баллы:
    290
    Miranda Dialog Creator - программа от создателей мода Das Mirandadorf для создания скриптов под Готику и Готику 2 Ночь Ворона. В этой статье есть ссылки на закачку и подробное описание работы с программой.
    Скачать Miranda Dialog Creator

    Для работы программы необходима установленная J2SE (Java Runtime Environment), версия не ниже 1.5. Внимание - размер инсталлятора J2SE для Windows около 16 Мб. Но эти мегабайты стократно окупятся радикальным уменьшением затрат времени на чисто техническую работу по скриптингу.
    Основная цель этой программы - исключить неблагодарную техническую работу по написанию скриптов диалогов, всяческие copy/paste и т.п. Сама программа весит крайне мало - всего 20 кб.
    После получения распакуйте программу (jar-файл) куда будет удобней и начинайте работу.
    1. Предварительные замечания

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

    Здесь и дальше я исхожу из того, что программа находится в том же каталоге, что и создаваемые примеры скриптов. Создайте сразу в этом каталоге подпапку sripts, для дальнейшей работы.
    У меня это выглядит так, к примеру:
    [​IMG]
    Давайте начнем сразу с небольшого примера.
    Создаем в любимом текстовом редакторе файл с названием, к примеру, example1.dia. Сохраним его тут же, в рабочем каталоге. Вот его содержимое:
    Код:
    person: NONE_101_Gustaf, 16
     
    info: SimpleDialog
     
    > Доброе утро, Густав!
    < И тебе того же, коли не шутишь...
    Запускаем командную строку, или любимый файловый менеджер, неважно какой - лишь бы в нем была возможность ввести и выполнить следующую команду:
    Код:
    MirandaDialogCreator.jar example1.dia scripts
    Первый пункт - это имя самой программы. Второй - имя файла, который она будет «разбирать». Третий (scripts) - имя папки, в которую будут складываться готовые скрипты, сформированные программой.
    Если все прошло нормально, появится окно лога программы. Например:
    [​IMG]
    Видим, что все прошло нормально.
    Идем в папку scripts. Что мы видим здесь? А видим, что сформирован файлик, названный по стандартам готических скриптов.
    [​IMG]
    Имя NONE_101_Gustaf взято из нашего DIA-файла. За это отвечает строка
    Код:
    person: NONE_101_Gustaf, 16
    Что же внутри готового файла скрипта?
    Код:
    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 функций данного пункта диалога, например:
    Код:
        npc            = NONE_101_Gustaf;
        condition      = NONE_101_Gustaf_SimpleDialog_Condition;
        information    = NONE_101_Gustaf_SimpleDialog_Info;
    Второй параметр (число 16) - это номер голоса, которым будет говорить наш персонаж. Конкретное использование этого числа - в функции AI_Output, к примеру, в нашем диалоге:
    Код:
    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 в файле готового скрипта. В нашем примере это очевидно. Вот «исходник»:
    Код:
    > Доброе утро, Густав!
    < И тебе того же, коли не шутишь...
    А получилось:
    Код:
    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.
    Флаг important - отвечает за то, чтобы персонаж сам обращался к ГГ, не дожидаясь, пока игрок начнет разговор.
    Простой пример (example2.dia):
    Код:
    person: NONE_101_Gustaf, 16
     
    info: ImportantDialog
     
    flags: important
     
    < Эй, погоди-ка, парень!
    > Ну что тебе надо опять?
    А вот что получилось:
    Код:
    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;
    };
     
    func int NONE_101_Gustaf_ImportantDialog_Condition()
    {
        return TRUE;
    };
     
    func void NONE_101_Gustaf_ImportantDialog_Info()
    {
        AI_Output(self, other, "NONE_101_Gustaf_ImportantDialog_Info_16_01"); // Эй, погоди-ка, парень!
        AI_Output(other, self, "NONE_101_Gustaf_ImportantDialog_Info_15_02"); // Ну что тебе надо опять?
    };
    Здесь Густав сам обратится к проходящему мимо него ГГ.
    Флаг permanent - отвечает за то, чтобы этот пункт диалога не исчезал после разговора, а оставался в меню выбора постоянно.
    Простой пример (example3.dia):
    Код:
    person: NONE_101_Gustaf, 16
     
    Info: PermanentDialog
     
    flags: permanent
     
    > Мое почтение!
    >!t_GreetNov
     
    < Ну-ну, подлиза. Говори уже - чего надо?
    <!t_GetLost
    А вот что получится:
    Код:
    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");
    };
    Этот диалог будет доступен всегда.
    Флаг permanent обычно используется в паре с флагом trade - формируя постоянно доступный пункт диалога торговли.
    Пример (example4.dia):
    Код:
    person: NONE_101_Gustaf, 16
     
    Info: LetsTrade
    flags: permanent, trade
    Num: 998
     
    > Поторгуем?
    А вот что получится:
    Код:
    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_

    Операторы этого типа формируют условия, которые определяют, будет показан конкретный пункт диалога или нет.
    Оператор conddia - проверка на то, говорил ли ГГ уже с данным NPC по какой-либо теме (был ли выбран и отображен конкретный пункт диалога); технически - формирование функции Npc_KnowsInfo().
    Пример (example5.dia):
    Код:
    person: NONE_101_Gustaf, 16
     
    info: SimpleCond
     
    conddia: SimpleDialog
     
    conddia: NONE_102_Peter, IAwaitedYou
     
    > Привет. Я от Петера, только что с ним поговорил.
    < Хорошо. Давай к делу теперь.
    А вот что получится (приведу здесь только функцию _Condition):
    Код:
    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* будут связаны логическим оператором «И».
    Оператор conditem - проверка на наличие определенных предметов

    Пример (example6.dia):
    Код:
    person: NONE_101_Gustaf, 16
     
    info: SimpleCond2
     
    conditem: ItFoMuttonRaw, 4
     
    > Я принес тебе то, что ты хотел.
     
    >>ItFoMuttonRaw, 4
     
    < Оо, йа-йа, зер гут, Вольдемар Иванович!
    < Вот тебе твоя награда.
     
    <<ItFoBooze
    <<ItFoLoaf, 2
    А вот что получится:
    Код:
    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 отдает ГГ определенный/е предмет/ы.
    Другие операторы

    Сразу приведу пример (example7.dia):
    Код:
    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*.
    Код:
    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):
    Код:
    person: NONE_101_Gustaf, 16
     
    Info: DescDialog
     
    desc: Официальное приветствие
     
    $IF Npc_GetTrueGuild(hero) == GIL_NONE
    >!t_GreetNov
    $ELSE
    >!t_GreetGrd
    $ENDIF
     
    >Hello!
     
    !Npc_ExchangeRoutine(self, "StandEntry");
     
    $END
    Результат (только функция _info):
    Код:
    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"); // Hello!
        Npc_ExchangeRoutine(self, "StandEntry");
        AI_StopProcessInfos(self);
    };
    Как видно из примера, можно использовать конструкцию $IF .. $ELSE .. $ENDIF
    Причем, как я понял, в параметре $IF нужно ставить скрипт готики, а не операторы MDC (Miranda Dialog Creator). В блока же можно применять как операторы MDC, так и скриптовые конструкции готики. В этом случае в начале строки нужно просто поставить оператор »!». Это дает возможность писать скриптами готики прямо в DIA-файле - все, что оформлено таким образом, попадет в файл-результат без изменений.
    И еще один пример (example10.dia):
    Код:
    person: NONE_101_Gustaf, 16
     
    info: Exit
    Результат:
    Код:
    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):
    Код:
    person: NONE_102_Peter, 11
     
    info: IAwaitedYou
    flags: important
    < Давай-ка, поиграем в угадайку.
    < Вот скажи, кто сильней - кит или слон?
    %
     
    opt: optKit
    > Кит?
    < Нет, не угадал.
     
    opt: optSlon
    desc: Слон, наверное?
    > Эээ... Слон, наверное, так?
    < Конечно!
    %%
     
    opt: Back
    Результат:
    Код:
    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 ставим оператор »%%».
    Иногда бывает нужно «сослаться» на уже созданные ранее функции-реакции на пункты выбора. В этом случае делаем так (добавляем следующий код):
    Код:
    person: NONE_102_Peter, 11
     
    Info: EinAndererDialog
     
    > Я что вспомнил-то. Про кита и слона.
    < А, про угадайку. Ну и кто сильней, на этот раз?
     
    %IAwaitedYou, optKit
    %IAwaitedYou, optSlon
    Результат:
    Код:
    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):
    Код:
    person: NONE_103_Anna, 8
     
    Info: StartMis
    > Что тебе нужно?
    < Принеси мне Цветочек Аленький, молодец удаленький.
     
    $STARTMIS RedFlower
     
    $LOGMISS RedFlower, Аленький Цветочек для Анны
    Результат:
    Код:
    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.
    Результат работы конструкции
    Код:
    $MISFAIL TestQuest
    выглядит так:
    Код:
        MIS_TestQuest = LOG_FAILED;
        Log_SetTopicStatus(TOPIC_TestQuest, LOG_FAILED);
    а конструкции
    Код:
    $MISSUCC TestQuest
     
    $EXP XP_TestQuest
     
    $EXP 10
    так:
    Код:
    MIS_TestQuest = LOG_SUCCESS;
    Log_SetTopicStatus(TOPIC_TestQuest, LOG_SUCCESS);
    B_GivePlayerXP(XP_TestQuest);
    B_GivePlayerXP(100);
    Примечания в журнале формируем так:
    Код:
    $LOGNOTE CityTraderz, Торговцы в основном обретаются на Торговой площади.
    Результат:
    Код:
    Log_CreateTopic(TOPIC_CityTraderz, LOG_NOTE);
    B_LogEntry(TOPIC_CityTraderz, "Торговцы в основном обретаются на Торговой площади.");
    6. Дополнения

    Еще одна интересная фишка - «автоформирование» диалога кражи. Я думаю, тут все понятно без лишних слов. Для мужского персонажа букву W в параметрах оператора info нужно убрать. Вот пример (example14.dia):
    Код:
    person: NONE_103_Anna, 8
     
    Info: Pickpocket w 20 45
    Результат:
    Код:
    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);
    };

    Автор МАРАЗМУС.
     
Статус темы:
Закрыта.

Поделиться этой страницей