Город Мастеров
IPB

Здравствуйте, гость ( Вход | Регистрация )

 Правила этого форума ПРАВИЛА РАЗДЕЛА
> Журналы, динамические диалоги и журналы, лигбез
_kaa_
сообщение Oct 1 2005, 19:10
Сообщение #1


Level 9
Иконки Групп

Класс: Волшебник
Характер: Chaotic Good
Раса: Дракон
NWN: Скриптинг [PW]



Часть 1.

Журналы
Краткая статья о журналах.
Что это такое, для чего, как использовать и немного про динамические журналы.

Начнем с примеров. Отрываем тулсет, заходим в редактор журнала (tools->Journal Editor , или жмем CTRL-ALT-J)

(IMG:http://kaa.mhost.ru/nwn/img/shot1-1.gif)
рисунок 1.1

Структура журнала – двухуровневая. Первый уровень – название записи, т.е. то что будет видно в игре когда запись не раскрыта, так сказать заголовок конкретного под-журнала.
Второй уровень добавляется к указанной записи, обычное использование – шаги выполнения квеста.
\(корень журнала)
+запись 1 – квест (уровень 1)
+квест 1, шаг 1 (уровень 2)
+квест 1, шаг 2 (уровень 1)

+ запись 2, (уровень 1)


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

Пока вернемся к рисунку 1.1, разберем все что там есть.

Category: Тут описываются основные параметры записи.
Name: Название записи, отображается в игре
Tag Тег записи, используется для управления из диалога/из скрипта . Тег надо делать уникальным в пределах модуля.
Priority Приоритет записи. Если будут активны более одной записи, можно менять порядок отображения квестов в игре, задавая больший приоритет записи (квесту).
XP Тут можно задать количество опыта, получаемого за квест. Это значение можно получить из скрипта, используя функцию GetJournalQuestExperience(string sTag), где sTag – тег нужной записи.

(IMG:http://kaa.mhost.ru/nwn/img/shot1-2.gif)
рисунок 1.2

Добавляем шаги квеста. Каждый шаг имеет свое название (поле text), которое будет показываться игроку, когда он раскроет запись в журнале, ID – обычно номер шага и флажок – является ли этот шаг завершающим. Если достигнут этот шаг – запись переходит из категории «активные квесты» в категорию «выполненные квесты» в журнале игрока в игре.

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

Напомню про «цвета», как их можно использовать. НВН понимает теги цветов, т.е. можно кусок текста покрасить в нужный цвет. Делается это примерно так:
<cRGB>text</c>
т.е. парным тегом <c> задается область текста, которая будет окрашена в цвет RGB. Вся сложность в задании параметров. Каждый символ имеет свой код, его числовое значение и используется в качестве параметра.

(IMG:http://kaa.mhost.ru/nwn/img/shot1-3.gif)
рисунок 1.3

Не любой символ можно задать напрямую через тулсет, но выбрать «близко» к 0 или к 255 можно, обычно использую символ “ ” (код 32) и русскую “ю” (код 224).
Т.е. если мы хотим выбрать красный цвет – задаем <cю >text</c>. Полученный RGB цвет будет иметь значение R:224,G:32,B:32, что довольно близко к красному цвету.
Для «продвинутых»: Если есть желание – можно сделать библиотеку и в ней после компиляции попробовать поменять цвета на близкие к 0 и к 255


Добавлено в 20:12
Часть 2.

Как редактировать журнал – разобрались, посмотрим как ими управлять. Т.е. зачем вообще нам нужны записи в журнале.
Для примера создадим примерно такую запись в журнале:

(IMG:http://kaa.mhost.ru/nwn/img/shot2-1.gif)
рисунок 2.1

Создадим простой диалог, в котором можно будет получить наш «квест»
Открываем редактор диалогов (tools->Converstion Editor, или CTRL-ALT-V)
Создаем простой диалог, используя кнопку “add”-добавить.

(IMG:http://kaa.mhost.ru/nwn/img/shot2-2.gif)
рисунок 2.2

В ответе игрока «Да» переходим на закладку «Other Action» (Другие действия) и в поле Journal выбираем нашу запись и начальный шаг квеста.

Теперь, если игрок поговорит с НПС, которому назначен этот диалог и ответит «Да» - у него в журнале появится новая запись, текст которой будет содержать информацию из шага номер 1 (именно его мы задали в диалоге)

Если вы еще не знаете, что такое «скрипты» - дальше можно не читать, вся работа с журналом требует как минимум умения работы с помощником.

Посмотрим, как можно организовать проверку условий выполнения «квеста», проверить выполнение «шагов» и перейти на следующий шаг.

Пусть у нас все тот-же НПС в том же диалоге должен
1) выдать квест,
2) проверить выполнение «шага 1».,
3) выдать задание «шаг 2» и так далее до конца.

Основная «трудность» при работе с журналом – нельзя получить из скриптов\диалогов номер активного в данный момент шага. Т.е. нам приходится помнить это самим.

Давайте заведем локальную переменную для игрока, которая будет отображать, какой сейчас шаг активен. (расмотрим вариант для сингл-модуля, с шардами чуть сложнее из-за необходимости идентифицирования игрока)

Вернемся к нашему диалогу (рисунок 2.2). Перейдем на закладку “Action Taken” (Пункт был выбран), т.е. какой скрипт запустить в случае, если игрок выбрал данный пункт диалога.
Пишем имя скрипт, пусть будет «my_q001_taken01» (my_ - преффикс, чтобы не пересечься случайно со скриптами bioware или любыми другими, q001- номер квеста, taken01 –номер «взятого» шага. Уже по имени нам будет понятно, что примерно скрипт делает.

Жмем кнопку редактировать, тулсет скажет нам что такого скрипта нет, жмем ОК и пишем скрипт.
Neverwinter Script Source
void main()
{
    SetLocalInt(GetModule(),"my_q001_step",1);
}


Скрипт просто устанавливает «глобальную» переменную, т.е. переменную модуля, по имени «my_q001_step» равным 1. Теперь из других скриптов мы можем узнать, какой шаг активен в квесте.


Жмем F7 – компилировать и сохранить скрипт, если ошибок нет – выходим из редактора скриптов.


Давайте добавим в диалог новую запись, ответ НПС в случае если шаг 1 выбран. И заодно уберем из диалога фразу о получении квеста, если квест уже был взят.
Для этого нужно написать скрипт на закладке Text Appears When (Текст появится при условии). Сначала для уже существующей записи, проверим что квест еще не получен и только в этом случае выводим фразу, предлагающую взять квест.
Скрипты с условием выглядят чуть по другому, даже если мы начинаем новый скрипт – сразу формируется шаблон скрипта. Дело в том, что такой скрипт должен возвращать число, если это будет 0 (FALSE, ложь) – фраза в диалоге не появится, 1 – появится.
Назовем скрипт «my_q001_when01», т.е. условие появления шага 01 для квеста номер 001.
Neverwinter Script Source
int StartingConditional()
{
    int iResult;

    iResult = GetLocalInt(GetModule(),"my_q001_step") == 0;
    return iResult;
}


В скрипте мы проверяем переменную, в которой хранится (или еще только будет храниться) номер шага. Если там храниться 0 (в нашем случае там будет 0 до ответа «Да» в диалоге), то возвращается 1 (т.е. верно условие «номер_шага равен 0»).

После того как мы получи квест и попытаемся снова поговорить с НПС – ничего не произойдет, НПС выдаст приветствие и больше ничего. Чего мы пока и добивались.
Теперь добавим в диалог вторую фразу, которая появится в случае, если шаг 1 уже был взят. Там же по идее должна быть проверка на то, что условия квеста для завершения шага 1 выполнены, но у нас пока нет такой цели.

(IMG:http://kaa.mhost.ru/nwn/img/shot2-3.gif)
рисунок 2.3

Скрипты для проверки условий появления фразы и после ответа «Да» отличаются только одной цифрой, номером шага который они проверяют.

Вот и все, закончили самое простое.
В принципе такие простые квесты проще строить Plot Wizard’ом, он позволяет основные простые типы квестов (убить, убить и принести докозательство, найти и принести) сконструировать прямо в нем, просто выбирая нужных НПС, вещи или создавая новых (прям в нем). Правда полученный в результате код будет не оптимальным и вряд ли подойдет для шардов.

Добавлено в 20:13
Часть 3. Custom tokens. (Метки пользователя)


Что такое custom tokens и для чего они используются.
Метки {Метка – token (маркер, токен)} используют тот же механизм, что и раскраска цвета. В текст вставляется тег вида
<CUSTOMXXXX>, где XXXX – просто номер. Номера с 0 до 9 используются bioware в своих скриптах, их использовать нельзя. На место метки при выводе информации подставляется значение метки, которое задается с помощью скриптов функцией
Neverwinter Script Source
void SetCustomToken(
    int nCustomTokenNumber,     // номер метки
    string sTokenValue          // текст
);


Самый простой пример использования в диалогах. При обращении НПС к игроку можно менять часть фразы, в зависимости от пола игрока, т.е. он\она, лорд/леди и т.п., включая окончания. Вот к примеру скрипт Олвина, задающий 20 возможных меток в зависимости от пола персонажа, добавляется в условие Text Appears When (хотя можно куда угодно, до вывода токена)
Neverwinter Script Source
int StartingConditional()
{
    object oPC = GetPCSpeaker();
    if (GetGender(oPC)==GENDER_MALE)
    {
        SetCustomToken(2001, "он");
        SetCustomToken(2002, "его");
        SetCustomToken(2003, "ему");
        SetCustomToken(2004, "друг");
        SetCustomToken(2005, "мужчина");
        SetCustomToken(2006, "мой");
        SetCustomToken(2007, "Ясень копий");
        SetCustomToken(2008, "ся");
        SetCustomToken(2009, "");
        SetCustomToken(2010, "Хозяин");
        SetCustomToken(2011, "пришел");
        SetCustomToken(2012, "ел");
        SetCustomToken(2013, "мог");
        SetCustomToken(2014, "приятель");
        SetCustomToken(2015, "гость");
        SetCustomToken(2016, "ый");
        SetCustomToken(2017, "");
        SetCustomToken(2018, "ец");
        SetCustomToken(2019, "господин");
        SetCustomToken(2020, "человек");
    }
    else
    {
        SetCustomToken(2001, "она");
        SetCustomToken(2002, "ее");
        SetCustomToken(2003, "ей");
        SetCustomToken(2004, "подруга");
        SetCustomToken(2005, "женщина");
        SetCustomToken(2006, "моя");
        SetCustomToken(2007, "Фрейя обручий");
        SetCustomToken(2008, "ась");
        SetCustomToken(2009, "а");
        SetCustomToken(2010, "Хозяйка");
        SetCustomToken(2011, "пришла");
        SetCustomToken(2012, "ла");
        SetCustomToken(2013, "могла");
        SetCustomToken(2014, "красавица");
        SetCustomToken(2015, "гостья");
        SetCustomToken(2016, "ая");
        SetCustomToken(2017, "ла");
        SetCustomToken(2018, "ка");
        SetCustomToken(2019, "госпожа");
        SetCustomToken(2020, "женщина");
    }
    return TRUE;
}

Теперь если в диалоге напишем
CODE

Добрый день <CUSTOM2006> <CUSTOM2019>

и поставим этот скрипт в условие показа скрипта, то в зависимости от пола НПС будет говорить «Добрый день мой господин» или «Добрый день моя госпожа»
Для английского языка (и других, на которые переведена игра) проще, там токены можно выбрать прямо в диалоге.

Надеюсь идея понятна – метка позволяет нам из скрипта менять содержимое диалогов, журнала и много чего еще.

При работе над шардом стоит помнить, что инициализировать метки нужно в каждой ветке диалога перед самым использованием. Ведь на шарде играет много людей, и если вы начали диалог, а в это время другой игрок начал другой диалог, использующий те же токены – возможны наложения.

К сожалению метки плохо работают в именах объектов. Если вы зададите имя объекта в виде <CUSTOMZZZZ> и инициализируете токен – на существующие объекты это не окажет влияния. Если вы создадите новый объект – имя изменится на заданное вами значение. Но если вы измените это значение – имя на объекте останется не изменным до смены локации игроком.
Это применимо к именам placable object’ов, с item’ами даже такое не работает.
Поле “description” тоже не изменится.
Получить значение метки из скрипта тоже нельзя.
Добавлено в [mergetime]1128183350[/mergetime]
Попозже допишу про динамические диалоги, как сделать один диалог для множества действий.

Сообщение отредактировал _kaa_ - Oct 1 2005, 19:14
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения

Сообщений в этой теме


Тема закрытаОткрыть новую тему
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



Текстовая версия Сейчас: 28th March 2024 - 16:45