Урок 23 Задача: Создать инсталлятор (установочный файл) мода используя программу InnoSetup.
Создадим инсталлятор с выбором дополнительных (в том чмсле и взаимоисключающих) компонентов. Будем использовать сборку InnoUltra.
После установки программы, на рабочем столе появится ярлык Inno Setup Compiler, запускаем его. При запуске мы увидим окно в котором нам нужно будет выбрать "Создать новый скрипт используя Мастер" и нажать "ОК". Нажимаем кнопку "Далее" и переходим в окно выбора информации о приложении. Нам предлагают указать папку установки, можно оставить "Program Files" или выбрать "Другой" и указать путь до папки игры (в дальнейшем информация об установленной игре будет браться из реестра, так что этот шаг можно пропустить), например: {pf}/GSC Game World/S.T.A.L.K.E.R. - Call Of Pripyat. {pf} - это переменная папки Program Files, остальные переменные вы можете узнать в файле IS_Help\%%_Windows.txt установленного InnoUltra. Меняем название папки приложения например на "STALKER COP". Так как идет установка простого мода (т.е. безо всяких exe-конфигураторов и хитрых лаунчеров), ставим галочку напротив пунтка "Приложение не имеет основного файла запуска". Теперь добавим папки\файлы мода нажимая соответствующие кнопки (лучше переместить мод куда-нибудь ближе к корню диска, папки мода должны лежать в gamedata) на папки подтверждаем использование подпапок. Далее нам необходимо указать папку в меню пуск, ставим интересующий нас путь, а также даем возможность юзеру отказаться от создания папки в пуске (если хотите, можете сделать UninStaller). Следующим шагом мы можем включить в состав сборки файлы ReadMe в форматах RTF и TXT. Далее выберем язык, я отключаю все и выбираю русский. Последний шаг относиться к компиляции, тут можно указать имя выходного файла, его иконку. Потом спросят использовать ли define переменные в скрипте - отвечаем да (могут пригодиться в дальнейшем). Также на создание нового скрипта отвечаем отрицательно.
[ Компоненты ]
Цитата
Мы получили скрипт, сразу удаляем строчку AppId и три коммента перед ней. Теперь необходимо сделать компоненты для установки, для примера я разберу копирование обязательного мода (SGM), фикса (также обязательного) и двух аддонов (два взаимоисключающих друг-друга). Создаем типы установки - "Чистый SGM", "Сборка от albor", "New Artefacts Mod", "Выборочная" Для этого после секции Languages создаем секцию Types примерно вот такого содержания:
Разберем стуктуру: Name - Структурное имя типа Description - Название типа Flags: isCustom - Предоставляет доступ к структурному древу чекбоксов и радиобаттонов.
Со структурой разобрались, теперь ниже создаем секцию Components c таким содержанием:
Код
[Components] Name: "ClearSGM"; Description: "SGM 1.7"; Types: OnlySGM Albor NAM Custom; Flags: fixed Name: "FIX"; Description: "FIX 31.08"; Types: OnlySGM Albor NAM Custom; Flags: fixed Name: "Addon"; Description: "Дополнения"; Types: Albor NAM Name: "Addon/Albor"; Description: "Сборка от albor"; Types: Albor; Flags: exclusive Name: "Addon/NAM"; Description: "New Artefacts Mod v2.8"; Types: NAM; Flags: exclusive
Разберемся: Name - Имя компонента, если нужно создать дочерний, пишется имя_родителя/имя_нового_компонента (пример: последние две строки) Description - Название компонента в выборе компонентов Types - Принадлежность компонента к типам, указываются через пробел. Например если юзер выберет тип NAM то автоматом отметятся компоненты ClearSGM, FIX, Addon, Addon/NAM Flags fixed - это серый (неработающий) чекбокс exclusive - это радиобаттон, для взаимоисключающих компонентов. Работает по группам
Теперь необходимо сопоставить файлы с компонентами. Для этого поправим секцию Files:
Разберемся: Source - путь до оригинального файла Components - имя компонента к которому относиться файл Flags - дополнительные параметры для файлов
Все, компоненты готовы!
[ Скрипт на папку с игрой ]
В секции Setup изменяем строчку DefaultDirName на эту: DefaultDirName={code:GetInstallDir} Далее, в самом конце скрипта создаем секцию Code и вставляем туда эту функцию:
Код
[Code] Function GetInstallDir(Path: String ): String; begin // Проверяем в реестре значение параметра InstallPath в ветке HKEY_LOCAL_MACHINE\SOFTWARE\GSC Game World\STALKER-COP\ if RegQueryStringValue(HKLM, 'SOFTWARE\GSC Game World\STALKER-COP\', 'InstallPath', Path) then // Если успешно - мы вернем переменную Path, со значением InstallPath Result := Path else begin // Если пути нет, мы вернем путь Programm Files\Stalker Cop\ Path:={pf}+'\stalker cop\'; Result := Path; end; end;
Вот и все, проект можно компилировать и смотреть что вы натворили.
P.S. Параметр compression из секции Setupотвечает за сжатие, стандартный (lzma) неплохо сжимает - быстро и качественно, если вы хотите сжать сильнее можете использовать значение lzma2\ultra (выигрыш с текстовыми файлами был около 5%)
P.S. Если вас не устраивает дефолтное оформление вы можете изменить его во вкладке "Редактор Форм" В левом столбце выбираем интересующую страницу, потом в центровой колонке кликаем на необходимый объект (на некоторые допускается двойной клик) и все доступные свойства объекта будут показаны в правом столбце... Также, можно использовать скины (есть куча скинов в составе InnoUltra, есть возможность создать свои)
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
В строке <menu_sound random="4"> число "4" - колисество проигрываемых песен, а <menu_music>music\menu_1</menu_music> путь к музыкальному файлу относительно папки sounds\, в нашем случае это файл sounds\music\menu_1.ogg
Те-же самые действия проделываем и в файле ui_mm_main_16 для широкоформатных мониторов
Далее идём по адресу sounds\music\ и вставляем туда выбранные вами песни, соответственно названия песен меняем на menu_1, menu_2, menu_3 и menu_4
Примечание: *.ogg - формат музыкальных файлов.
Вы можете создать большее количество проигрываемых мелодий, указывая их число и прописывая путь к ним.
Урок 25 Задача: Зарегестрировать в скриптах, подключённую локацию к ЗП.
Итак, мы подключили локацию к Зову Припяти, но на ней не происходят выбросы не летают вороны и т.д. Чтобы исправить эту оплошность, нам надо зарегестрировать локацию в скриптах.
Для того чтобы на локации работали некоторые скриптовые фишки, необходимо ее правильно прописать в скриптах.
Примечание: В этом туторе я прописывал кордон. Поэтому вместо l01_escape напишите имя своей локации.
Урок 26 Задача: Разобраться с описанием текстур в xml-файлах на примере прицела, а также добавить новый
I. Как это работает
a) Текстуры прицелов
Текстуры прицелов представляют собой графические файлы разрешением 1024х1024 в формате dds
b) Файл configs\ui\textures_descr\ui_ingame.xml
Здесь описывают размеры сегментов\участков прицела в DDS-текстуре. Например:
Код
<file name="wpn\wpn_crosshair_l85"> <!-- Имя файла относительно папки textures\ из которого будут браться сегменты\участки --> <texture id="wpn_crosshair_l85" x="0" y="0" width="1024" height="1024" /> <!-- ID сегмента, для дальнейшего использования в описании. X, Y - координаты левого верхнего угла сегмента. Width, Height - Ширина и высота сегмента соответсвенно --> </file>
Большинство из них используют только один участок, охватывающий всю текстуру, но некоторые имеют два дополнительных: wpn_crosshair_add_l и wpn_crosshair_add_r. Это дополнительные участки, которые появляются на правой и левой стороне экрана в широкоформатном режиме. Например:
Файл scopes.xml используется при стандартном формате монитора (4:3, 5:4), а scopes_16.xml в широкоэкранном (16:10, 16:9)
Первый файл содержит только "главные" текстуры, определенные выше в ui_ingame.xml, масштабируемыми до разрешения 1024x768, который является своего рода «эталоном» всех элементов GUI (пользовательского интерфейса). Этот размер затем автоматически масштабируется до установленного разрешения экрана. Например:
Код
<wpn_crosshair x="0" y="0" width="1024" height="768"> <!-- wpn_crosshair - это название прицельной сетки для параметра scope_texture --> <auto_static x="0" y="0" width="1024" height="768" stretch="1"> <!-- stretch="1" - параметр который отвечает за то, будет ли текстура подгонятся под размеры статического сегмента (="1") или нет (="0") --> <texture>wpn_crosshair</texture> <!-- В значении принимается ID сегмента из файла ui_ingame.xml --> </auto_static> </wpn_crosshair>
Во втором начинаются лестницы тегов. Опять же, «эталон» составляет 1024x768, но это масштабируется до широкоэкранного режима (1280x768), а затем переходит в установленное разрешение. Так что мы должны поделить ширину текстуры на 0.8 (1024\0.8=1280) и переместить ее в центр. Кроме того, мы добавляем по бокам правый и левый сегменты wpn_crosshair_add_l и wpn_crosshair_add_r Например:
II. Добавление нового прицела Добавим новый прицел, типа "Gnomys"
a) Текстура
Берем текстуру в пропорции 4:3 (1024x768, 1360x1024, возможно 1280x1024) выключаем опцию "Сохранять пропорции", чтобы изменить разрешение на 1024x1024. Мы сохраняем файл в textures\WPN\my_crosshair.dds как DXT5, 8bit альфа, MIP-Maps - нет.
b) Определяем участок
В файле configs\ui\textures_descr\ui_ingame.xml определяем участок текстуры с дополнительными частями на левый и правый сегмент. Мы должны сделать это, потому что если вы будете использовать стандартные сегменты прицел будет иметь 2 черных полосы в широкоэкранном режиме. Поэтому, вместо wpn_crosshair пишем my_crosshair. Добавляем:
Для теста, пропишем наш прицел Винторезу. Открываем файл configs\weapons\w_vintorez.ltx и изменяем параметр scope_texture на scope_texture = my_crosshair
Запускаем игру и любуемся новым прицелом. ##### Примечание: Описанный выше метод описания текстур подходит для всех элементов GUI во всех играх серии STALKER, и может быть использован для создания собственного HUD'-a
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
Урок 27 Задача: Познать азы скриптования, научиться самому писать примитивные скрипты в Сталкере
Я не профессионал, я не программист, я не изучал официальную справку по Lua, я не считаю себя гением и еще кем-либо. В данном топе вы найдете готовые, самые используемые скриптовые функции, начальные сведения по скриптованию, научитесь писать примитивные скрипты(хотя их такими не назовешь), но я не смогу передать вам мой образ мышления и способность находить ответы на многие вопросы самому методом общего анализа...
(Данный материал я считаю своей интеллектуальной собственностью, если вы хотите опубликовать его еще где-то, то обязательно указывайте автора(да и пора бы уже научиться всегда указывать авторов, даже без требования) и не так: "ой забыл", "где-то видел", "какой-то чувак", а ник. Если вам понравился материал, можете и ссылку на данный форум скинуть(замаскировав под гиперссылку с текстом), я буду только благодарен.)
[ Урок первый. Что такое скрипт? ]
1. Все файлы скрипты находятся в папке gamedata\scrips. 2. Файл скрипта - это текстовый файл имеющий расширение .script. 3. В С.Т.А.Л.К.Е.Р используется немного изменённый скриптовый язык Lua 5.1. 4. Для редактирования скриптов я советую NotePad c++, данная программа имеет подсветку синтаксиса для многих языков, в том числе и для Lua. Чтобы активировать подсветку нажмите клините Стиль - Lua. 5. Чтобы закоментировать строку (код игры не будет ёё читать) , необходимо перед строкой поставить -- . Если вы хотите закоментировать кусок (много строк) то --[[ .... ]] , ваш текст будет закоментирован.
[ Начнём... ]
1)Создадим свой my.scripts и поместим его в папку scrips. Откроем с помощью НотПада и настроим подсветку. 2) Внутри файла-скрипта должны содержаться только КОД скрипта и ваши ЗАКОМЕНТИРОВАННЫе пометки. Если будет лишний текст, т.е какие-то знаки и слова, то будет вылет на этот скрипт. Так как код игры полностью собирает весь скрипт в стек и выбирает только то, что вы задали, но если будет мусор, то игра не воспримет код. 3)Архитектур. Для создания функций нужны лишь знания синтаксиса и игровые методы и глобальные функции(которые записаны в движке) можете почитать lua_help.script, но я советую посетить тему на АМК. Там собраны все методы, классы и полное их описание. 4) Функция. Это то, что будет делать игра.
[ Любая функция начинается со слов ]
function my_function() ... end
И заканчивается тегом end. Этот тег означает конец функции, сравнения, он закрывающий и обязателен. Я советую при составлении функций , чтобы не забыть чего-нибудь, писать скелет извне, т.е сначала функция, потом закрывающий тег, и по нарастающей во внутрь. () -Обязательный элемент. Позже расскажу как передавать переменные через этот тег.Между окончание функции и этим тегом ПРОБЕЛА НЕТ.
Обращаю внимание, что все функции вызываются из других скриптов. Допустим нам из одного скрипта, нужно вызвать(запустить функцию в другом) для этого мы пишем название скрипта . название функции в скрипте (парметр если есть) my.my_function()
[ Объявляем перменные и глобальные. ]
Чтобы объявить какой-либо элемент для функции локальным используется тег local local helth = db.actor.helth Т.е мы расшифровали helth, и показали, что это значение db.actor.helth. Если вы хотите вставить слово или свой текст нужно заключить слово в кавычки. local helth = "Уровень здоровья." Если вы хотите вставить слово с кавычками или свой текст нужно сделать так: local helth = "\"Уровень здоровья."\" Чтобы объявить глобальну нужно всего лишь сделать так helth = db.actor.helth
Глобальные можно объявлять вначале скрипта и она будет сохранятся в коде, в памяти процесса (если я правильно понял) Переменная объявляется только перед функцией и логическими выражениями, где используется переменная и её использует только та функция, перед которой она объявляется (На пальцах перед строкой с вашей функцией). Т.е еслии функция простая без логических решений(if, elseif, for и.т.д) То ставим перед функцией, если же есть переменная, которая находится в теле такого логического решения, то она ставится строго перед этим логическим решением!
local helth = db.actor.helth function my_function() ... end
Чтобы сосчитать значение переменной из другого скрипта достаточно в другом скрипте сделать так: text="Я иду гулять по бродвею" Теперь в нашем скрипте вызываем этот параметр local pisanina = название скрипта . text () - При таком обращении этот тег НЕ СТАВИТСЯ !
[ Смысловые значения функций. ]
if ..... then .... end Перевожу Если что-то то конец тега. Пример:
if db.actor.psy==0.5 then db.actor:kill(db.actor) end Если пси-здоровье ГГ - половина, то мы его убиваем. Полная функция:
function my_function() if db.actor.psy==0.5 then db.actor:kill(db.actor) end end
[ Переделал с переменными(Для чего нужны объявления?): ]
local acter = db.actor function my_function() local psy_zdorovie = acter.psy if psy_zdorovie==0.5 then acter:kill(acter) end end Что я сделал? Обозначил кусок db.actor локальной acter. А acter.psy (db.actor)+.psy равносильно db.actor.psy
Вы поняли? Я поразбивал куски на локальные и код получился короче, функция имеет куда меньше знаков и удобнее к пониманию. ВНИМАНИЕ!!!! Переменные должны объявлятся так, чтобы самое то, к чему обращаются было известно. Допустим...
local psy_zdorovie = acter.psy Нам нужна эта acter перменная, и мы ДОЛЖНЫ ОБЪЯВИТЬ её перед переменной local psy_zdorovie = acter.psy Мы ее и объявили local acter = db.actor Думаю смысл понятен?
[ Комбинации логических выражений. ]
if ...... then 1 действие. else 2 действие. end
Перевод: Если подходит условие то 1 действие иначе (т.е условие не выполняется) 2 действие конец тега Пример:
function my_function() if db.actor.psy==0.5 then db.actor:kill(db.actor) else db.actor.give_info_portion("info") end end
Если пси-здоровье актора равно половине, то мы его убиваем, если же значение другое(любое) , то даем ему инфопоршень.
[ Проверка нескольких условий ]
Допустим нам нужно проверить несколько условий: Чтобы они все выполнялись!
if (db.actor) and (db.actor.helth==1) and (db.actor.psy ==0.5) then действие end Функция сработает если есть актор и здоровье актора полное и псиздоровье половина.
Тег and - означает И . Если один из элементов не выполняется, то функция не срабатывает. Кстати - это ленивый метод, как писал Kamikaze, если не выполняется первый элемент, то другие - уже не просчитывааются. Т.е. не загнружается процесс....
Если подходит хоть один элемент. if (db.actor) or (db.actor.helth==1) or (db.actor.psy ==0.5) then действие end
Тег or обозначает ИЛИ. Или один, или другой. Функция сработает при условии соответствия хоть одного элемента. Так же ленивый метод. Проверяет до получения утвердительного решения, потом проверка не идет.
[ Цепочка elseif. ]
Данный метод заменяет перебор через таблицу. Отличается простотой и потерей производительности.
if ...... then самое основное действие elseif ...... then действие 1 elseif ...... then действие 2 elseif ...... then действие 3 elseif ...... then действие 4 elseif ...... then действие 5 end Здесь представлен перебор elseif иначе если, т.е не подходит первый вариант, мы проверяем второй и так по цепочке , до первого подходящего(где выполняется заданное условие), если же ни одно не подойдет, то ничего не произойдет. Если бы мы просто в функции написали кучу
function perebor() if ..... then действие end if ..... then действие end if ..... then действие end if ..... then действие end if ..... then действие end if ..... then действие end end
То ничего хорошего не вышло бы. Так как проверялись бы все функции. А в первом варианте до первого попавшегося...
[ Переменная nil ]
Пременная нил указывает, что объекта , условия, да чего угодно НЕТ, его не существует. ВСЕГДА проверяйте некоторые объекты на nil Во первых это актор. Можно написать
if (db.actor ~= nil) then .... end
Но правильнее и эстетичнее, сразу писать так.
if (db.actor) then .... end
Проверкой советую проверять многие элементы, так как в игре они зачастую не существуют в определенные моменты...
При обращении к функция из сторонних скриптов(других скрипт-файлов) я советую проверять на наличие этих скриптов:
if имя скрипта then ...... end
if my then ...... end
И делайте всегда, потому как, просто удалите этот скрипт из каталога и не надо будет мучаться с переписыванием других скриптов.
[ Рандом. ]
Числовой.
math.random(1,100) Данная функция рандомно выберет число от 1 до 100. Сначала ставится наименьшее, потом наибольшее. Если ставить десятичные , допустим (0.0005, 1), то перебуеруться ВСЕ значения, т.е числа с несколькими знаками, ТАКДЕЛАТЬ НЕ НУЖНО. вы перегрузите некоторые элементы кода. Использование
if math.random(0,1) < 1 then действие end Если выбранное число меньше 1, то срабатывает функция.
Или так.
if math.random(0,1) < 1 then действие else ......
end Добвавляется другое действие. Советую брать целые числа от 1 до 10 для создания процентного срабатывания, но лучше 0 и 1.
Текстовый.
Допустим вы отправляете сообщение и хотите выбрать рандомный текст. Создается таблица с вашими переменными (Это может быть и секция для спавна, и слово, и любая другая переменная)
local my frazi = {"ага","да","нет!","конечно","несомненно"}
Так создается примитивная таблица, каждый элмент записывается в кавычках и отделяется отдельно. Далее, обозначаем за переменную которая нам нужна. Допустим в функции вам нужна пременная text. Мы и пишем . local text = my frazi[#(my frazi)] И пр и срабатывании функции, обращении к переменной text, выберается рандомная переменная из таблицы my frazi.
[ Перебор, повтор действия. ]
for i=1, 5000 do действие end
Это цикл, который прокрутнет ваше действие 5000 раз. Переменная i любая буква, число 5000 обозначает количество циклов(сколько раз пройдет ваше действие).
[ Передача параметра. ]
Допустим мы сделали такую функцию
-- удаляем объект из игры(Взято из АМК )
function remove(remove_item) if remove_item~=nil then alife():release(alife():object(remove_item:id()), true) return true end return false end remove_item - это наш параметр, в данном случае это секция объекта, которую нужно удалить. (немного по секция , если это уникальный объект, то это то,ч то в его конфиге, если нет, то нужно искать другим методом) Нам нужно удалить уникального НПС vasek Если функция находится в скрипте, где мы хотим удалить объект, то пишем
Код
remove(vasek)
Если в другом скрипте, то
Код
имя скрипта.remove(vasek)
Вот такой пример передачи параметра, передавать можно что угодно и как угодно. Было бы воображение.
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
Урок 28 Задача: Данный урок посвящен обучению принципу построения и работы с диалогами в игре на примере Зова Припяти.
Все диалоги в STALKER создаются по средствам языка разметки XML. Хранятся они в специальных XML- файлах. Соответственно изначально скажу несколько слов про этот язык.
XML – представляет собой расширяемый язык разметки. Файл XML - документ, в котором использованы теги для определения объектов и их атрибутов. Форматирование данных напоминает язык разметки HTML-документов. Но в отличие от HTML, в XML используются теги, которые задаются пользователями.
Структура XML-документа представляет собой дерево элементов. Некоторые элементы имеют содержимое и атрибуты.
Например,
Код
<cell id="number">value</ cell >
Здесь <cell>,</cell> - открывающий и закрывающий теги элемента, id- атрибут, number - значение атрибута,value - содержимое.
XML-файлы и файлы других расширений, основанные на языке XML, получили очень широкое распространение. В XML-файлах хранятся самые различные данные - от настроек приложений до баз данных. Файлы на основе XML используются для обмена информацией в Интернете и между программами (для этого данный язык разметки и был изначально задуман). Т.к. файлы формата XML содержат текстовые данные, их можно легко отредактировать в любом текстовом редакторе. Например Notepad++
Теперь собственно приступим к разбору и созданию диалогов в игре S.T.A.L.K.E.R. Зов Припяти.
1. Базовые сведения.
Для создания своего диалога нам потребуются два файла. Первый это сам файл диалога- в котором будет отображаться его структура. Второй- это файл с текстами- где будут находиться его фразы на русском языке. Для начала не будем создавать и подключать свои собственный XML- файлы для диалогов, а используем уже имеющиеся в игре.
Файлы с самими диалогами храняться в S.T.A.L.K.E.R. - Зов Припяти\gamedata\configs\gameplay\
Файлы с готовыми фразами на русском языке в S.T.A.L.K.E.R. - Зов Припяти\gamedata\configs\text\rus\
Откроем два файла- st_dialogs_zaton.xml и dialogs_zaton.xml. К примеру будем редактировать их программой Notepad++
Рассмотрим общую структуру построения диалогов на простейших примерах.
- Создадим самый простой диалог в две фразы:
В файл dialogs_zaton.xml в самом низу то тега </game_dialogs> добавим следующий код:
Это скелет нашего диалога. Рассмотим конкретно что означает каждая строчка. Буду давать пояснение для “полного” тега.
Код
<dialog id="…………."> ... </dialog>
Собственно это сам диалог- его начало с указанием уникального имени (в примере это first_test_dialog) и закрывающий тег в конце.
Код
<phrase_list> .............. </phrase_list>
Дословно- список фраз. Внутри него будут располагаться сами фразы.
Код
<phrase id="….."> ………………… </phrase>
Простейшая фраза диалога. Каждая фраза диалога имеет свой уникальный порядковый номер внутри него. Отсчет номера фразы начитается с 0. Дальше порядковые номера задает сам пользователь. Желательно для самого себя выбрать последовательную систему нумерации фраз, для удобства в написании диалога.
Код
<text>……………..</text>
Тег текста- внутри него будет расположено уникальное название секции на английском языке (также имеющая свою порядковую последовательность) для связи со вторым XML- файлом с русскими фразами.
Код
<next>……</next>
Тег следующей фразы. Внутри него указывается уникальной номер следующий фразы диалога.
Теперь пропишем русские фразы для нашего диалога. Открываем файл st_dialogs_zaton.xml И в самом конце до тега </string_table> прописываем следующий код
Это тег текстовой фразы. В нем внутри тегов <text>……………..</text> будет приводиться русский текст. Уникальное имя фразы должно соответсвовать внутреннему значению тегов <text>……………..</text> Из основного файла (в нашем случае это first_test_dialog_ )
Некоторые пояснения: 1. первая фраза в диалоге такой структуры будет принадлежать ГГ (майору Дягтереву). 2. данный диалог является зацикленным- тобишь будет всегда повторяться.
В процессе продолжения урока буду рассказывать как изменить то что указано в пояснениях.
Теперь осталось только добавить этот диалог какому-нибудь НПС. К примеру Бороде. Для этого откроем файл character_desc_zaton.xml (S.T.A.L.K.E.R. - Зов Припяти\gamedata\configs\gameplay\) найдем в нем секцию НПС Бороды <specific_character id="zat_a2_stalker_barmen" team_default="1"> … </specific_character> и добавим наш диалог
Инфопорции в игре играют едва ли не ключевую роль. По сути дела это еденица информации несущая в себе определенный смысл. Инфопорции используются практичеки во всех диалогах. Они имеют свое уникальное имя. Прописываются также в XML-файлах. К примеру мы будем их добавлять в файл-info_zaton.xml. (\gamedata\configs\gameplay\)
От наличия или отсутствия той или иной инфопорции будет зависить какие фразы будут генерироваться в диалоге. Также в диалоге будет происходить выдача, либо запрет тех инфопорций которые используются для других целей.
Приведу основные операции над инфопорциями в диалогах:
- <give_info>zat_info_test_1</give_info> - выдача инфопорции с именем, записанным в теле тега. - <has_info> zat_info_test_1</has_info> - проверка на наличие инфопорции с именем, записанным в теле тега. - <dont_has_info> zat_info_test_1</dont_has_info> - проверка на отсутствие инфопорции с именем, записанным в теле тега.
- Теперь перепишем самый первый диалог так чтобы он исчезал после его прочтения.
В данном примере перед началом списка фраз стоит тег обеспечивающий блок диалога при наличии инфопорции с именемzat_info_test_1. Соответсвенно ее выдача происходит внутри диалога.
В завершении этого вводного урока подробно рассмотрим и прокомментируем один готовый диалог из оригинальной игры.
Этот диалог принадлежит Султану. Вот его фразы на русском языке чтобы было понятно о чем в нем речь.
Код
<string id="zat_b7_bandit_boss_sultan_b30_start_actor_dialog_0"> <text>Борода должен мне денег. Сыч сказал, что ты можешь помочь.</text> </string> <string id="zat_b7_bandit_boss_sultan_b30_start_actor_dialog_1"> <text>Могу, есть мыслишка... Расклад такой: обламываем Бороде бизнес, я его беру под себя, ты получаешь долю и свой бабос. Идет?</text> </string> <string id="zat_b7_bandit_boss_sultan_b30_start_actor_dialog_2"> <text>Фиг там. Нет возможности на него повлиять. Хотел пережать ему каналы поставок, так этот гад бородатый всё равно где-то достал «Компас». Считай, у него всё бархатом... пока что.</text> </string> <string id="zat_b7_bandit_boss_sultan_b30_start_actor_dialog_11"> <text>Идёт.</text> </string> <string id="zat_b7_bandit_boss_sultan_b30_start_actor_dialog_111"> <text>Тогда твое дело - узнать, что за дела Борода вертит конкретно сейчас. Похерим ему каналы поставок, и все будет в ажуре.</text> </string> <string id="zat_b7_bandit_boss_sultan_b30_start_actor_dialog_12"> <text>Я подумаю.</text> </string> <string id="zat_b7_bandit_boss_sultan_b30_start_actor_dialog_121"> <text>Учти, много думать - вредно для здоровья.</text> </string>
Итак: 1. <has_info>zat_b30_owl_to_sultan</has_info> - говорит о том что для появлении этого диалога у Султана необходиио начичии инфопорции zat_b30_owl_to_sultan. 2. <dont_has_info>zat_b30_actor_with_sultan</dont_has_info>- значит диалог не будет доступен в случае наличия выданной инфопорции zat_b30_actor_with_sultan. 3. после генерации первой фразы происходит разветвление диалога и выбор ветки в зависимости от наличия или отсутсвия поршня zat_b30_barmen_got_af соответсвенно в диалоге это <dont_has_info>zat_b30_barmen_got_af</dont_has_info> и <has_info>zat_b30_barmen_got_af</has_info> В случае наличия этого поршня выбирается фраза с айди номером 2, в противоположном случае фраза с айди номером 1. 4. первый вариант ведет к завершению диалога, второй же так же имеет разветвление на фразы с идентификаторами 11 и 12. 5. При выборе одной из этих фраз будет доступно повторение диалога или же его окончательное завершение происходящее после выдачи инфопорции <give_info>zat_b30_actor_with_sultan</give_info>
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
Урок 29 Задача: Снятия денег с трупов в ЗП по алгоритму SGM.
Создаем скрипт scripts\use_corps.script с функцией on_use_corpse(npc) в которой будем выдавать деньги при юзаньи трупа НПС. Функция приблизительно текая:
Код
function on_use_corpse(npc) local extract_value=0 local npc_rank = ranks.get_obj_rank_name(npc) if npc_rank~=nil then if npc_rank=="novice" then extract_value=math.random(10,50)+math.random(5,25) elseif npc_rank=="experienced" then extract_value=math.random(20,100)+math.random(10,50) elseif npc_rank=="veteran" then extract_value=math.random(100,200)+math.random(50,100) elseif npc_rank=="master" then extract_value=math.random(200,500)+math.random(100,250) end if extract_value ~= 0 then local bringed_money=math.floor(extract_value) db.actor:give_money(bringed_money) news_manager.send_tip(db.actor,"Получены деньги "..tostring(bringed_money),0,"kingpin",4000,nil) end end end
extract_value - количество "извлеченных" денег, npc_rank - ранг НПС. Далее проверяем, что ранг существует и равен одному из четырех вариантов. В зависимости от ранга назначаем случайную сумму (двойное использование генератора случайных чисел повышает разнообразие вариантов). Потом округляем сумму, выдаем деньги ГГ и посылаем сообщение о количестве "снятых" денег. Осталось только вызывать функцию при первом юзаньи мертвого НПС. Давайте скопируем файл scripts\xr_motivator.script из ресурсов игры и начнем его редактировать. Для начала в функции motivator_binder:use_callback(obj, who) после
Код
if self.st.active_section then xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "use_callback", obj, who) end
добавим:
Код
else if self.once_use_processed == false then self.once_use_processed = true use_corps.on_use_corpse(self.object) end
Функция motivator_binder:use_callback(obj, who) - вызывается каждый раз при юзаньи НПС, мы добавили вызов своей функции в случае если НПС не жив (тоесть мертв). К тому же ввели параметр once_use_processed - показывающий что текущий НПС уже был юзан (чтобы не выдавать деньги до бесконечности). Теперь нужно про инициализировать параметр и обеспечить его сохранение и загрузку: Инициализация: В функции motivator_binder:__init (obj) super(obj) добавим
Код
self.once_use_processed = false
Сохранение: В функции
Код
motivator_binder:save(packet)
после
Код
trade_manager.save(self.object, packet)
добавим
Код
packet:w_bool(self.once_use_processed)
Загрузка: В функции
Код
motivator_binder:load(reader)
после
Код
trade_manager.load(self.object, reader)
добавим
Код
self.once_use_processed = reader:r_bool()
Все можно проверять.
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
Урок 30 Задача: Данный урок посвящен обучению принципу построения однотипного квеста на одновременный поиск двух разных предметов в Зове Припяти.
Итак, предположим нам необходимо создать простой квест для Зова Припяти на одновременный поиск двух различных предметов. Пусть идея квеста будет такой: Сыч дает ГГ поручение найти два артефакта Снежинка и Пламя.
Необходимые для редактирования файлы: 1. конфигурационные в (gamedata\configs\gameplay\) - character_desc_zaton.xml - dialogs_zaton.xml - info_zaton.xml - character_desc_general.xml (необязательно) 2. конфигурационные в (gamedata\configs\misc\) - tm_zaton.ltx 3. конфигурационные в (gamedata\configs\text\rus\) - st_dialogs_zaton.xml - st_quests_zaton.xml 4. скриптовый в (gamedata\scripts\) - dialogs_zaton.script
Для начала создадим два простеньких диалога для выдачи и завершения квеста.
В файл dialogs_zaton.xml в самом низу добавим два диалога:
Ну и чтобы понимать о чем в диалогах идет речь сразу пропишем их транскрипцию в файле st_dialogs_zaton.xml
Код
<string id="zat_b30_owl_stalker_trader_small_quests_0"> <text>Есть какое дело?</text> </string> <string id="zat_b30_owl_stalker_trader_small_quests_1"> <text>Нужны артефакты Пламя и Снежинка. Достанешь, хорошо заплачу.</text> </string> <string id="zat_b30_owl_stalker_trader_small_quests_2"> <text>Нет, друг- сам ищи.</text> </string> <string id="zat_b30_owl_stalker_trader_small_quests_3"> <text>Сделаю.</text> </string> <string id="zat_b30_owl_stalker_trader_small_quests_4"> <text>Вот и отлично.</text> </string> <string id="zat_b30_owl_stalker_trader_small_quests_5"> <text>Я нашел артефакты, наш уговор в силе?</text> </string> <string id="zat_b30_owl_stalker_trader_small_quests_6"> <text>Да, отличная работа, давай артефакты сюда.</text> </string> <string id="zat_b30_owl_stalker_trader_small_quests_7"> <text>Держи.</text> </string> <string id="zat_b30_owl_stalker_trader_small_quests_8"> <text>Вот твои деньги.</text> </string> <string id="zat_b30_owl_stalker_trader_small_quests_9"> <text>Бывай.</text> </string>
Теперь разберем по порядку то что добавили.
Диалог на выдачу квеста имеет следующую элементарную структуру:
- ГГ предлагают задание и он на выбор может отказаться от него, тогда второй раз диалог уже не будет доступен. Либо же согласиться на исполение. - Соответсвенно происходит выдача инфопоршней zat_b30_owl_stalker_trader_quest_init (при старте квеста) и zat_b30_owl_stalker_trader_quest_no_quest (при отказе от выполнения). - Наличие в диалоге тегов <dont_has_info>имя поршня</dont_has_info> обеспечивает его блокировку при выборе одной из веток. - Наличие прекондишина <precondition>dialogs_zaton.zat_b30_owl_stalker_trader_have_arts</precondition> также блокирует стартовый диалог при наличии квестовых предметов (в данном случае это артефакты) в рюкзаке ГГ. - акшион <action>dialogs_zaton.zat_b30_owl_stalker_trader_give_quest</action> обеспечивает выдачу квеста.
Теперь поясню особенности второго диалога:
- наличие тега <has_info>zat_b30_owl_stalker_trader_quest_init</has_info> обеспечивает возможность инициализации диалога после выдачи квеста. - наличие <dont_has_info>zat_b30_owl_stalker_trader_quest_end</dont_has_info> обеспечивает блокировку диалога после завершение квеста. - прекондишн <precondition>dialogs_zaton.zat_b30_owl_stalker_trader_have_arts</precondition> обеспечивает блокирование диалога до момента наличия в инвентаре ГГ нужных квестовых предметов. - акшионы <action>dialogs_zaton.zat_b30_owl_stalker_trader_relocates_arts</action> и <action>dialogs_zaton.zat_b30_owl_stalker_trader_relocates_money_to_actor</action> обеспечивают передачу квестовых предметов от ГГ к НПС, и последующего денежного вознаграждения для ГГ от него.
Объявим используемые инфопоршни в info_zaton.xml Добавим в конце файла код:
Код
<!-- New quest --> <info_portion id="zat_b30_owl_stalker_trader_quest_no_quest"></info_portion> <info_portion id="zat_b30_owl_stalker_trader_quest_init"></info_portion> <info_portion id="zat_b30_owl_stalker_trader_quest_end"></info_portion>
Добавим наши диалоги НПС (В данном случае Сычу) для этого в файл character_desc_zaton.xml в его профиль <specific_character id="zat_b30_owl_stalker_trader" team_default="1"> добавим две строки диалогов
С диалогами и инфопоршнями разобрались теперь раccмотрим необходимые скриптовые функции:
Код
function zat_b30_owl_stalker_trader_give_quest() task_manager.get_task_manager():give_task("geonezis_zat_b30_owl_quest") end
function zat_b30_owl_stalker_trader_have_arts(first_speaker, second_speaker) return ((db.actor:object("af_ice") ~= nil) and (db.actor:object("af_fire") ~= nil)) end
function zat_b30_owl_stalker_trader_not_have_arts(first_speaker, second_speaker) return ((db.actor:object("af_ice") == nil) and (db.actor:object("af_fire") == nil)) end
function zat_b30_owl_stalker_trader_relocates_arts(first_speaker, second_speaker) dialogs.relocate_item_section_from_actor(first_speaker, second_speaker, "af_ice") dialogs.relocate_item_section_from_actor(first_speaker, second_speaker, "af_fire") end
function zat_b30_owl_stalker_trader_relocates_money_to_actor(first_speaker, second_speaker) dialogs.relocate_money_to_actor(first_speaker, second_speaker, 30000) end
Теперь по порядку разберем эти функции:
- zat_b30_owl_stalker_trader_give_quest - выдача квеста - zat_b30_owl_stalker_trader_have_arts - возвращает true при проверки на наличие в инвентаре ГГ двух необходимвх предметов (в данном случае артефактов af_ice и af_fire) - zat_b30_owl_stalker_trader_not_have_arts - возвращает false при аналогичной проверке. - zat_b30_owl_stalker_trader_relocates_arts - передача НПС артефактов - zat_b30_owl_stalker_trader_relocates_money_to_actor - выдача денежной награды ГГ.
Разберем то что происходит в процессе выполнения квеста и собственно его структуру.
- [geonezis_zat_b30_owl_quest] - название задение в таск менеджере - icon = ui_inGame2_Kontrakt_s_uchenimi - иконка квеста (в данном случае от задания Контракт с Учеными) - prior = 2 - приоретет задания - storyline = false - сюжеткный ли квест или нет - title = - заголовки при обновлении задания - descr = - дескрипшины при обновлении задания - target = - цели, метки квеста при его обьнавлении. - condlist_0 = - кондишн (спец. условия) в квесте (в данном случае один на завершение)
Основная особенность задания это последовательная проверка структурных условий посредством функции actor_has_item(...). Это вызываемая из xr_conditions.script функция на проверку наличия у актора того или иного предмета. Соответсвенно в структуре этого квеста используют два варианта когда значениее функции false (!actor_has_item(...)) и true (=actor_has_item(...))
В квесте рассматриваются все возможные сочетания вариантов наличия или отсутсвия найденного того или иного предмета.
1. когда нет ни одного. 2. первый (арт снежинка) есть, второго (арт пламя) нет. 3. первого нет, второй есть 4. оба есть.
Соответсвенно в независимости от того какой арт был найден первым- произойдет точное обновление дескрипшина и титла задания с указанием текущего состояния. Также если игрок выложит из инвентаря уже найденный арт, то задание будет обновляться снова. Метка на цели в квесте (Сыч) появиться только при наличии обоих предметов.
По выдачи инфопоршня zat_b30_owl_stalker_trader_quest_end квест будет завершен.
Пропишим рускую транскрипцию дескрипшинов и тайтлов квеста в st_quests_zaton.xml
Код
<string id="zat_b30_owl_stalker_trader_small_quest_title_0"> <text>Поручение Сыча: найти артефакты Снежинка и Пламя</text> </string> <string id="zat_b30_owl_stalker_trader_small_quest_text_0"> <text>Сыч попросил найти для него два арта- Снежинка и Пламя.</text> </string> <string id="zat_b30_owl_stalker_trader_small_quest_title_1"> <text>Поручение Сыча: найти артефакт Снежинка</text> </string> <string id="zat_b30_owl_stalker_trader_small_quest_text_1"> <text>Артефакт Пламя найден. Найдите Снежинку.</text> </string> <string id="zat_b30_owl_stalker_trader_small_quest_title_2"> <text>Поручение Сыча: найти артефакт Пламя</text> </string> <string id="zat_b30_owl_stalker_trader_small_quest_text_2"> <text>Артефакт Снежинка найден. Найдите Пламя.</text> </string> <string id="zat_b30_owl_stalker_trader_small_quest_title_3"> <text>Поручение Сыча: передайте найденные артефакты Сычу.</text> </string> <string id="zat_b30_owl_stalker_trader_small_quest_text_3"> <text>Оба артефакта найдено. Отдайте их Сычу, и заберите награду.</text> </string>
По желанию для проверки в character_desc_general.xml при старте ГГ пропишем нужный арты.
На этом урок завершен.
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
Урок 31 Задача: Данный урок посвящен обучению принципу построения квестов с использованием рестрикторов в Зове Припяти.
Предположим нам необходимо реализовать квест следующего типа: ГГ будет выдано задание на извлечение определенного предмета из физического обьекта на локации. Пусть будет такой вариант: Сыч дает Дягтереву задание на изьятие из старой антенны и генератора на ВНЗ Круг различных деталей. Для осуществления подобных заданий необходимо использовать рестрикторы. Данный тип квестов в корне отличается от простых, когда по заданным меткам необходимо было просто подобрать заспавненные ранее предметы.
Необходимые для редактирования файлы: 1. конфигурационные в (gamedata\configs\gameplay\) - character_desc_zaton.xml - dialogs_zaton.xml - info_zaton.xml 2. конфигурационные в (gamedata\configs\misc\) - tm_zaton.ltx - quest_items.ltx - death_generic.ltx 3. конфигурационные в (gamedata\configs\text\rus\) - st_dialogs_zaton.xml - st_quests_zaton.xml - ui_st_screen.xml - st_items_quest.xml 4. конфигурационные в (gamedata\configs\ui\) - game_tutorials.xml 5. логики рескрипторов в (gamedata\configs\scripts\zaton\) - zat_restr_logic_1.ltx - zat_restr_logic_2.ltx 6. скриптовый в (gamedata\scripts\) - dialogs_zaton.script - xr_effects.script - ui_si.script 7. Спавн в файле all.spawn (gamedata\spawns\) - alife_zaton.ltx
Для начала добавим один общий диалог на выдачу и завершения квеста. (В принципе можно было не усложнять и сделать два простых диалога, но рассмотрим более сложный вариант)
В файл dialogs_zaton.xml в самом низу добавим диалог:
Ну и чтобы понимать о чем в диалогах идет речь сразу пропишем русскую транскрипцию фраз в файле st_dialogs_zaton.xml
Код
<string id="zat_b106_stalker_sich_test_quest_dialog_0"> <text>Я по поводу работы.</text> </string> <string id="zat_b106_stalker_sich_test_quest_dialog_1"> <text>Работы, хм. Ах да забыл. Есть у меня одно поручение. Нужно сходить на ВНЗ Круг и снять показатели нескольких старых приборов. С одной антенны и старого генератора. Ну что, согласен?</text> </string> <string id="zat_b106_stalker_sich_test_quest_dialog_11"> <text>Да, сделаю.</text> </string> <string id="zat_b106_stalker_sich_test_quest_dialog_12"> <text>Пока есть другие дела.</text> </string> <string id="zat_b106_stalker_sich_test_quest_dialog_112"> <text>Отлично, жду. Награду достойную получишь.</text> </string> <string id="zat_b106_stalker_sich_test_quest_dialog_2"> <text>Ну что, сделал что я просил?</text> </string> <string id="zat_b106_stalker_sich_test_quest_dialog_4"> <text>Нет, работаю над этим.</text> </string> <string id="zat_b106_stalker_sich_test_quest_dialog_3"> <text>Да. Все сделано.</text> </string> <string id="zat_b106_stalker_sich_test_quest_dialog_331"> <text>Отлично, давай сюда приборы.</text> </string> <string id="zat_b106_stalker_sich_test_quest_dialog_332"> <text>Забирай.</text> </string> <string id="zat_b106_stalker_sich_test_quest_dialog_333"> <text>Вот твоя награда. Успехов сталкер.</text> </string> <string id="zat_b106_stalker_sich_test_quest_dialog_334"> <text>Бывай.</text> </string>
Теперь разберем по порядку то что добавили.
Диалог на выдачу и завершение квеста имеет следующую структуру: 1. Первая часть диалога на выдачу задания. (ветка <next>1</next>) - ГГ предлагают задание и он на выбор может временно отказаться от него, тогда диалог будет доступен во второй раз. Либо же согласиться на исполение. - Соответсвенно при согласии происходит выдача инфопоршня zat_b106_sich_quest_begin (при старте квеста) и выдача самого квеста через актшион <action>dialogs_zaton.zat_b106_sich_give_tasks</action>. - На этом генерация ветки диалога на выдачу задания будет заблокирована, из-за наличия во фразе 1 условия <dont_has_info>zat_b106_sich_quest_begin</dont_has_info> 2. Вторая часть диалога доступная уже после взятия задания. - Ее генерация происходит путем активации ветки (<next>2</next>), первая фраза которой будет доступна только после старта задания то есть наличия условия <has_info>zat_b106_sich_quest_begin</has_info> - Следующие фразы будут доступны также на выбор (<next>3</next> и <next>4</next>) Фраза 4 будет доступна сразу же после взятия квеста- она будет являться закрывающей диалог (акшион <action>dialogs.break_dialog</action>). Генерируется она путем наличия условия <dont_has_info>zat_b106_sich_quest_restr_2</dont_has_info> Эта фраза сообщает о том что ГГ еще не выполнил задание. - Фраза 3 которая является веткой завершения диалога будет доступна только при наличии условия <has_info>zat_b106_sich_quest_restr_2</has_info> (этот инфопоршень мы получим в процессе выполнения квеста) при этом фраза 4 будет заблокирована. - в треьей фразе будет происходить выдача условия <give_info>zat_b106_sich_quest_complete</give_info> обеспечивающего завершение квеста и полное блокирование диалога. - также отметим наличие акшионов <action>dialogs_zaton.zat_b106_sich_quest_relocate_item</action> и <action>dialogs_zaton.zat_b106_sich_quest_relocate_reward</action> отвечающих за передачу квестовых предметов и выдачу награды.
Объявим используемые инфопоршни в info_zaton.xml. Добавим в конце файла код:
Добавим наш диалог НПС (В данном случае Сычу) для этого в файл character_desc_zaton.xml в его профиль <specific_character id="zat_b30_owl_stalker_trader" team_default="1"> добавим строку диалога
С диалогами и инфопоршнями разобрались теперь добавим необходимые для выполнения квеста предметы, а также файлы связанный с ними.
В файл quest_items.ltx пропишем две секции предметов zat_b206_sich_quest_item_1 и zat_b206_sich_quest_item_2. Оба предмета являются квестовым- невозможна их продажа и выкладывание из инвентаря
- Имена секций рестикторов должны быть уникальны (как собственное имя, так и порядковое внутри алл спавна) - Они должны иметь тип 3 - Координаты точки спавна рестикторов должны задаваться рядом с тем обектом на локации который мы будем использовать. (position, level_vertex_id, game_vertex_id) - story_id = zat_restr_2_id - уникальный айди номер рестриктора на который будет выставляться квестовая метка. - shape0 - общий тип и размер зоны рестриктора- при изменении числовых значений можно как увеличить, так и уменьшить радиус активной зоны вблизи юзаемого предмета. - cfg = scripts\zaton\zat_restr_logic_2.ltx - путь к файлу логики рестриктора. Теперь пропишем логики рестрикторов. Рассмотрим только одну- вторая создается по образу первой. Создадим файл zat_restr_logic_1.ltx И пропишем в него следующий код:
Опишем что означает эта логика и по какому принципу она строиться:
- всего логика имеет три секции это sr_idle@start - она же изначально активная, [sr_idle@tutorial] по исполнению гайм туториала, [sr_idle@nil] - нулевое значение логики. - основной принцип работы это проверка наличия двух условий- это старт квеста (zat_b106_sich_quest_begin) и наличия актора в зоне рестиктора =actor_in_zone(zat_test_quest_restrictor_1) при их соблидение подается команда на старт туториала юзания предмета %=run_tutorial(zat_sich_quest_1_tutor)% - если актор находился в зоне рестиктора, но потом вышел из нее !actor_in_zone(zat_test_quest_restrictor_1) происходит выдача команды на остановку туториала %=stop_tutorial% и возвращение логики в исходное стартовое состоянии. Запуск или остановку туториала можно проследить по активации надписи юзания предмета. - соотвестсвенно в независимости от того какая секция логики активна при выдаче инфопоршня zat_b106_sich_quest_restr_1 происходит обнуление логики рестиктора. Дальнейшая работа туториалов в ней будет невозможно.
Текст активирущийся при юзании рестриктора буде прописан в ui_st_screen.xml
Основные параметры это: - <action id="use" finalize="1">xr_effects.zat_sich_quest_1</action> выполняемое действие по скрипту xr_effects.zat_sich_quest_1 - zat_sich_quest_tips - текст сообщения перед юзанием
В файл xr_effects.script пропишем скрипты исполняемые при юзании рескриптора.
Код
function zat_sich_quest_1(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"zat_test_quest_restrictor_1"}) then db.actor:give_info_portion("zat_b106_sich_quest_restr_1") give_actor(db.actor,nil,{"zat_b206_sich_quest_item_1"}) end end function zat_sich_quest_2(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"zat_test_quest_restrictor_2"}) then db.actor:give_info_portion("zat_b106_sich_quest_restr_2") give_actor(db.actor,nil,{"zat_b206_sich_quest_item_2"}) end end
-Происходит проверка наличия актора в зоне zat_test_quest_restrictor_1 и если оно истинно тогда происходит выдача инфопоршня zat_b106_sich_quest_restr_1 и спавн в рюкзак ГГ айтема zat_b206_sich_quest_item_1
С рестрикторами разобрались. Теперь пропишем остальные скриптовые функции:
В файле dialogs_zaton.script добавим следующие функции:
Код
function zat_b106_sich_give_tasks(first_speaker, second_speaker) task_manager.get_task_manager():give_task("geonezis_zat_b206_sich_example_task") end
function zat_b106_sich_quest_relocate_item(first_speaker, second_speaker) local items_table = { "zat_b206_sich_quest_item_1", "zat_b206_sich_quest_item_2", } for k,v in pairs(items_table) do if db.actor:object(v) ~= nil then dialogs.relocate_item_section_from_actor(first_speaker, second_speaker, v) end end end
function zat_b106_sich_quest_relocate_reward(first_speaker, second_speaker) dialogs.relocate_money_to_actor(first_speaker, second_speaker, 5000) end
Поясним их:
- Выдача квеста - Передача квестовых предметов неписю - Выдача ГГ награды за квест
Так и собственно в завершении осталось расписать сам квест:
- квест исполняется в три этапа- сначала мы юзаем рестриктор 1, потом после этого второй и в завершении отдаем полученные предметы заказчику. соответсвенно метки перемещаются с zat_restr_1_id на zat_restr_2_id и в завершении на Сыча zat_b30_owl_stalker_trader_id. При этом же обновляются тайтлы и дескрипшины этапов задания. Основные условия их изменения это выдача или же остутсвие двух основных инфопоршней zat_b106_sich_quest_restr_1 (получаемого при юзании первого рестриктора) и zat_b106_sich_quest_restr_2 (второго) - задание завершается при выдаче инфопоршня zat_b106_sich_quest_complete - квест будет провален если после его старта НПС заказчика стал враждебен по отношению к ГГ =is_squad_enemy_to_actor(zat_b30_owl_stalker_trader_squad) - по завершению квеста происходит повышение репутации у сталкеров %=inc_faction_goodwill_to_actor(stalker:50)%
В файле st_quests_zaton.xml пропишем тайтлы и дескрипшины квеста:
Код
<string id="zat_b206_sich_example_title0"> <text>Задание Сыча: извлеките компонент из старой антенны.</text> </string> <string id="zat_b206_sich_example_text0"> <text>Необходимо отправиться на ВНЗ Круг и извлечь деталь обьекта со старой антенны.</text> </string> <string id="zat_b206_sich_example_title1"> <text>Задание Сыча: извлеките вторую деталь со старого генератора</text> </string> <string id="zat_b206_sich_example_text1"> <text>Заберите вторую необходимую заказчику деталь.</text> </string> <string id="zat_b206_sich_example_title2"> <text>Задание Сыча: отдайте заказчику найденные детали.</text> </string> <string id="zat_b206_sich_example_text2"> <text>Передайте все старые детали и компоненты Сычу.</text> </string>
На этом урок добавления подобного класса заданий завершен.
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
Урок 32 Задача: Создание осветительно-сигнального устройства (добавление нового уникального предмета в игру).
1. Введение. Для создания осветительно-сигнального устройства (на подобии химических люминисцентных источников света из MW2) нам понадобиться прежде всего определиться с базовым объектом на основе которого это возможно сделать - тут особо неизчего выбирать классов объектов которые могут обладать худом и которые ГГ может бросить всего два: болт и граната, но класс болт не обладает возможностью излучать свет (по крайней мере реализация такой возможности потребует больших усилий). Остается класс граната - у класса возможен ХУД (тоесть держание в руках ГГ), есть возможность броска ГГ, есть возможность излучения света, и т.п., к сожалению есть и два минуса - движком закреплено за объектами этого класса эффект взрыва (сотрясение камеры во время уничтожения объекта) и остающиеся на поверхности локации волл-марки типа explosion_marks (отключить эти эффекты возможно только в движке). Но ничего страшного будем считать что в нашем предмете есть небольшой детонационный заряд который собственно приводит его в рабочее состояние разрушая пререгородку между двухкомпонентным наполнителем который смешиваясь при детонации начинает излучать свет. Теперь собственно что нужно сделать: Создать ХУД и мироую модель объекта, создать анимации для объекта и рук (возможно использование существующих), создать звуки (возможно использовать существующие), создать текстуру (или использовать существующую), создть партиклы для эфектности к стати ими можно скрыть волл-марки (или используйте существующие), создать конфигурационный файл предмета, создать иконку и текстовые параметры названия и описания.
2. Создадим модель объекта на базе гранаты РГД5 (бес претензии на подробное руководство по созданию 3D объектов, просто общие моменты). а) Импортируем в MilkShape 3D модель wpn_rgd5_hud.ogf. б) Удалим все меши оставив только скелет. в) Создадим меш - цилиндр и назначим ему материал в котором пропишем текстуру (и при необходимости проиведем корректировку наложения текстуры на меш) я использовал текстуру glas\glas_dirt и сделал цилиндр таким чтобы он приблизительно соответствовал размерам исходной гранаты для того чтобы использовать ее-же анимации при необходимости. г) Привяжем меш к базовому суставу скелета wpn_body. д) Экспортируем модель в формат *.object e) Для создания мировой медели загрузим модель созданную в MilkShape 3D в SDK и привяжем к базовому суставу шейп (опять же цилиндрический) - это физическая поверхность нашего объекта она должна быть немного больше визуальной, експортируем модель в файл wpn_palka.ogf ж) Для создания ХУД модели загрузим модель созданную в MilkShape 3D в SDK и присоединим файл с анимациями wpn_f1_hud_animation.omf експортируем модель в файл wpn_palka_hud.ogf
3. Создавать анимации, текстуры и звуки мне не потребовалось - я использовал те что есть, но вероятно вам придется создавать свои.
4. Создание партиклов. С партиклами было сложнее хотя я и выбрал Партикл-групп которая уже была в исходном файле particles.xr, но она оказалась зацикленной, а это помешело использовать ее для моих целей. Значит нужно редактировать, приступим: а) Запустите ParticleEditor из комплекта SDK (если сразу после открытия программы список партиклей не пустой очистите папку ***SDK\editors\rawdata\particles от стандартных партиклей и загрузите програму снова) б) Откройте в нем файл particles.xr (теперь можно сохранить распакованные партикли припомощи кнопки Save в директорию ***SDK\editors\rawdata\particles) в) Теперь выберем партикл - мне понравилась группа static\net_base_green, но она зацикленная. г) Для исправления необходимо клонировать группу (чтобы не поламать группу - мало ли где она используется) и партикл-еффекты которые в ней используються д) В клонированной группе редактируем партикл-эффекты, прежде всего заменяем на клонированные и ставим во всех эффектах галочку TimeLimit ниже выбираем длительность эффекта - Value. е) В клонированной группе cтавим параметр TimeLimit таким же как и Value в эффектах. Теперь все эффекты и группа в целом ограничена по времени вашем значением. ж) Сохраните файл particles.xr в корень своей gamedata.
5. Самое главное создать конфирурационный файл предмета: а) Скопируем файл w_rgd5.ltx и переименуем например в w_palka.ltx (внесем ссылку а него в weapons.ltx). б) Приступим к редактированию параметров Изменим следующие параметры: [palka] - имя базовой секции detonation_threshold_hit = 0 - хит для детонации объекта $spawn = "weapons\grenades\palka" - параметр для SDK где искать объект в списке объектов visual = dynamics\weapons\wpn_palka\wpn_palka.ogf - мировая модель inv_name = st_palka - Имя предмета inv_name_short = st_palka description = st_palka_descr - Описание предмета inv_grid_width = 2 - Координаты иконки предмета inv_grid_height = 2 - Координаты иконки предмета inv_grid_x = 14 - Координаты иконки предмета inv_grid_y = 23 - Координаты иконки предмета hud = palka_hud - имя секции настроек ХУДа предмета destroy_time = 3500 - время в мс между броском и детонацией blast = 0 - Уровень хита от взрава blast_r = 0 - Радиус взрава blast_impulse = 0 - Импульс от взрыва blast_impulse_factor = 0 - Коэфф импульса от взрыва frags = 0 - Количество осколков frags_r = 0 - Радиус разлета осколков frag_hit = 0 - Хит от попадания осколка frag_hit_impulse = 0 - Импульс от попадания осколка hit_type_blast = strike - Тип хита от взрыва (несущественно) up_throw_factor = 0 explode_particles = static\net_base_green - партиклы проигрываемые в месте взрыва light_color= 0.5,2.0,0.5 - цвет световой вспышки RGB (в данном случае кислотный зеленый свет) light_range = 40.0 - Растояние распространения света определяет яркость light_time = 300 - Время световой вспышки в сек fragment_speed = 0 - Скорость разлета фрагментов explode_duration = 300 - подолжительность взрыва и соответственно световой вспышки в сек snd_explode = device\door_stop - Звук взрыва [palka_hud]:hud_base - Имя секции настроек ХУДа предмета item_visual = dynamics\weapons\wpn_palka\wpn_palka_hud.ogf - визуал предмета в руках ГГ (ХУД модель)
6. Иконки и тексты. Создайте иконку и поместите ее в файле ui_icon_equipment.dds и также строковые параметры st_palka, st_palka_descr например в файле st_items_weapons.xml.
Урок 33 Задача: Разбор GUI (Графический интерфейс пользователя). Часть 1 - Основы: Создание окна с кнопкой закрытия и текстом в окне. Скачать Stalker_GUI_p1.pdf (609 кб) Урок 33a Задача: Разбор GUI (Графический интерфейс пользователя). Часть 2 - Создание заднего фона, поля ввода, списка и взаимодействие с ними Скачать Stalker_GUI_p2.pdf (189 кб)
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
Урок 34 Задача: Создание многоэтапного квеста на последовательный поиск предметов. Реализация на X-Ray 1.6.00.
Поставленная задача состоит в обучения принципам построения сложных многоходовых заданий на чистой игре Сталкер Зов Припяти. Будет показан процесс построения сложного диалога с ветвлением, последовательный спавн квестовых предметов через скрипт и собственно структура многоуровнего квеста. Задание следующее. Новиков просит ГГ принести для него разбросанные по локации сканеры аномалий. Квест будет построен таким образом что необходим исключительно поэтапный вариант его прохождения, то есть от одной точки к другой, без каких-либо вариантов. Получить один предмет раньше другого не будет предоставляться возможным.
Необходимые для редактирования файлы: 1. конфигурационные в (gamedata\configs\gameplay\) -character_desc_jupiter.xml -dialogs_jupiter.xml -info_jupiter.xml 2. конфигурационные в (gamedata\configs\misc\) - tm_jupiter.ltx - quest_items.ltx - death_generic.ltx 3. конфигурационные в (gamedata\configs\text\rus\) - st_dialogs_jupiter.xml - st_quests_jupiter.xml - st_items_quest.xml 4. конфигурационные в (gamedata\configs\misc\trade\) - trade_generic.ltx 5. скриптовый в (gamedata\scripts\) - dialogs_jupiter.script - ui_si.script - bind_stalker.script - new_tasks.script
Рассмотрим структуру квестовых диалогов. Для этого откроем dialogs_jupiter.xml и в самом низу добавим два диалога. Один активный при старте задания. Второй на завершение. В принципе можно было объединить их в один, но рассмотрим более легкий вариант. Однока при этом внесем разнообразие в процесс выдачи задания предоставив несколько вариантов его получения внутри диалога. Этот несколько освежит стандартные методы диалогостроения, когда все они делаются последовательными, без каких-либо вариантов.
Сразу же пропишем русскую транскрипцию в st_dialogs_jupiter.xml для того чтобы понимать о чем в диалоге идет речь :
Код
<string id="jup_b6_scientist_tech_quest_anomalies_scaner_0"> <text>Приветствую, хотел бы оказал вам максимально возможное содействие. Какого рода помощь тебе необходима?</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_1"> <text>В принципе есть одно небольшое дело, главное это твое желание работать.</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_2"> <text>Я готов.Что нужно делать?</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_3"> <text>Прекрасно. Правда придется немного побегать. Мне необходимо получить кое-какие данные.</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_4"> <text>Замеры? Необходимо будет устанавливать какие-нибудь сканеры?</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_41"> <text>Нет, устанавливать не придется. Их уже установили. Тебе же наоборот придется их собрать и доставить сюда, чтобы я смог получить с них результаты замеров.</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_401"> <text>Что за сканеры-то? Аномальная активность?</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_4011"> <text>Обыкновенные сканеры аномалий. Их показатели результатов замеров будут мне необходимы для проведения настройки моего оборудования.</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_4012"> <text>Все ясно. Придется взять научный комбез. Передавай координаты.</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_4013"> <text>Уже загрузил. Комбез это хорошая тема. Обязательно возьми. И смотри не сварись в аномалиях.</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_402"> <text>Кто их устанавливал и куда мне придется отправиться?</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_4021"> <text>Тебе то не все-равно, кто их размещал. Пару дней назад, сталкеры из Свободы - сойдет такой ответ? Не о том думаешь. Твоя задача отправиться на Затон, пробежаться по точкам и вернуться назад живым вместе со сканерами. Все ясно?</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_4022"> <text>Все. Передавай координаты.</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_4023"> <text>Уже загрузил. Комбез научный только одень. И смотри не сварись в аномалиях.</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_5"> <text>А может еще что нужно?</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_51"> <text>Нет, хотя может быть потом я подберу для тебя работку. Но сначала ты должен будешь добыть результаты измерений с установленных на Затоне сканеров аномалий.</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_52"> <text>Искать сканеры в аномалиях. Ха, веселая преспектива. Без специального научного костюма мне там долго не пролазить...</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_53"> <text>Намек понял. Вот держи ССП-99. Неплохой костюм, хотя и поношенный. Координаты сканеров я тебе загрузил.</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_531"> <text>Хотя бы кровь с костюма отмыли? По-любому с трупака какого-нибудь своего ботанического дружка сняли...</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_5311"> <text>Ой, ну давай мне не заливай..Тоже мне брезгливый нашелся. У самого-то, чай не первой свежести костюмчик..</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_5312"> <text>Проехали Кулибин. Все, я отправляюсь за замерами...</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_5313"> <text>Поосторожнее там...</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_532"> <text>Все понял, отправляюсь.</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_5321"> <text>Поосторожнее там...</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_6"> <text>Хорошо, я сделаю то что нужно. Говори с чего начинать.</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_61"> <text>Вот это деловой разговор, делового человека. Вообщем план таков. Сначала ты находишь на Затоне сканеры аномалий, установленные там нашими сподручными сталкерами. Координаты я тебе уже сбросил. Потом, я может быть посмотрю еще что для тебя..</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_611"> <text>Все ясно, Кулибин. Жди, я за твоими сканерами.</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_6111"> <text>Поосторожнее там. В аномалиях не сгинь...</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_end_0"> <text>Вот все твои сканеры.</text> </string> <string id="jup_b6_scientist_tech_quest_anomalies_scaner_end_1"> <text>Отличная работа. Немедленно начинаю работу над обработкой результатов замеров. Новую работу получишь позже. А пока гуляй.</text> </string>
Теперь разберем структуру представленных диалогов:
- Во втором диалоге нет ничего сложного: активен при наличие инфопоршня jup_novikov_quest_zaton_scanner_have_6, исчезает после выдачи jup_novikov_quest_zaton_scanner_end, имеет прекондишн actot_have_all_zaton_scaner когда в инвенторе ГГ наличие всех квестовых предметов. содержит один акшион actot_to_novikov_give_zaton_scaner на передачу предметов заказчику. - первый диалог сложнее. основная особенность это вложенная тройная разветвленность, когда можно выбрав одну из трех веток получить один и тот же результат. - внутри каждой из веток также имеет место дополнительные ответвления. - старт задания происходит по выдачи акшиона give_novikov_zaton_scaner_quest сопровождается также выдачей инфопоршня jup_novikov_quest_zaton_scanner_start - создание первого квестового предмета происходит также внутри диалога- акшион jup_b6_create_first_scaner - чисто для атмосферности происходит выдача ГГ костюма для выполнения задания при выборе одной из трех веток. это акшион jup_b6_to_actor_give_spez_outfit
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
Добавим наши диалоги НПС (В данном случае Новикову) для этого в файл character_desc_jupiter.xml в его профиль <specific_character id="jup_b6_scientist_tech" team_default="1"> добавим строки диалогов
С диалогами и инфопоршнями разобрались теперь добавим необходимые для выполнения квеста предметы.
В файл quest_items.ltx пропишем семь секций предметов zat_spec_anomaly_scanner_№. Все предметы являются квестовыми- невозможна их продажа и выкладывание из инвентаря ГГ.
В файл st_items_quest.xml пропишем дескрипцию предметов.
Код
<string id="zat_spec_anomaly_scanner_1_name"> <text>«Сканер грави-химического симбионта»</text> </string> <string id="zat_spec_anomaly_scanner_1_descr"> <text>«Специализированный сканер аномальной активности из серии 32.1351. Используется учеными для изучения процессов происходящих в грави-химическом симбионте»</text> </string> <string id="zat_spec_anomaly_scanner_2_name"> <text>«Сканер химической аномалии»</text> </string> <string id="zat_spec_anomaly_scanner_2_descr"> <text>«Специализированный сканер аномальной активности из серии 27.7724. Используется учеными для изучения процессов происходящих в химической аномалии»</text> </string> <string id="zat_spec_anomaly_scanner_3_name"> <text>«Сканер гравитационной аномалии»</text> </string> <string id="zat_spec_anomaly_scanner_3_descr"> <text>«Специализированный сканер аномальной активности из серии 78.9835. Используется учеными для изучения процессов происходящих в гравитационной аномалии»</text> </string> <string id="zat_spec_anomaly_scanner_4_name"> <text>«Сканер термальной аномалии»</text> </string> <string id="zat_spec_anomaly_scanner_4_descr"> <text>«Специализированный сканер аномальной активности из серии 47.3246. Используется учеными для изучения процессов происходящих в термальной аномалии»</text> </string> <string id="zat_spec_anomaly_scanner_5_name"> <text>«Сканер пси-статической аномалии»</text> </string> <string id="zat_spec_anomaly_scanner_5_descr"> <text>«Специализированный сканер аномальной активности из серии 06.8912. Используется учеными для изучения процессов происходящих в пси-статической аномалии»</text> </string> <string id="zat_spec_anomaly_scanner_6_name"> <text>«Сканер термального симбионта»</text> </string> <string id="zat_spec_anomaly_scanner_6_descr"> <text>«Специализированный сканер аномальной активности из серии 35.0205. Используется учеными для изучения процессов происходящих в термальном симбионте»</text> </string> <string id="zat_spec_anomaly_scanner_7_name"> <text>«Сканер электро-статической аномалии»</text> </string> <string id="zat_spec_anomaly_scanner_7_descr"> <text>«Специализированный сканер аномальной активности из серии 03.1392. Используется учеными для изучения процессов происходящих в электро-статической аномалии»</text> </string>
В файле trade_generic.ltx пропишем торговлю. также нужно добавлять индивидуально во все остальные файлы конфигов торговли. (но не обязательно)
С квестовыми предметами также разобрались, теперь необходимо разобраться со скриптами квеста. Собственно теперь мы и подходим к основной сути нашего урока, в этом этапе заключен его основной смысл.
В файле dialogs_jupiter.script добавим следующие функции:
Код
function jup_b6_create_first_scaner(first_speaker, second_speaker) alife():create("zat_spec_anomaly_scanner_1",vector():set(-436.574,-6.527,170.169),116113,16) end
function jup_b6_to_actor_give_spez_outfit(first_speaker, second_speaker) dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "scientific_outfit") end
function give_novikov_zaton_scaner_quest() task_manager.get_task_manager():give_task("geonezis_jup_spec_scaner") end
function actot_to_novikov_give_zaton_scaner(first_speaker, second_speaker) local items_table = {"zat_spec_anomaly_scanner_1","zat_spec_anomaly_scanner_2","zat_spec_anomaly_scanner_3","zat_spec_anomaly_scanner_4","zat_spec_anomaly_scann er_5","zat_spec_anomaly_scanner_6","zat_spec_anomaly_scanner_7"} for k,v in pairs(items_table) do if db.actor:object(v) ~= nil then dialogs.relocate_item_section_from_actor(first_speaker, second_speaker, v) end end end
function actot_have_all_zaton_scaner(first_speaker, second_speaker) return db.actor:object("zat_spec_anomaly_scanner_1")~=nil and db.actor:object("zat_spec_anomaly_scanner_2")~=nil and db.actor:object("zat_spec_anomaly_scanner_3")~=nil and db.actor:object("zat_spec_anomaly_scanner_4")~=nil and db.actor:object("zat_spec_anomaly_scanner_5")~=nil and db.actor:object("zat_spec_anomaly_scanner_6")~=nil and db.actor:object("zat_spec_anomaly_scanner_7")~=nil end
коротко их поясним: - спавн первого квестового предмета - передача бронекостюма ГГ - выдача задания - передача всех квестовых предметов НПС - скрипт проверки наличия в инвенторе ГГ всех необходимых предметов
Теперь создадим файл new_tasks.script и добавим в него следующий код одной основной функции task_spec()
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
Урок Продолжение 34в Задача: Завершение урока по созданию многоэтапного квеста.
Завершающий этап урока. Скрипт созданный нами в файле можно посмотреть в скачанном архиве с отработанным примером. Основная его особенность это последовательный спавн квестовых предметов. Последующий будет создаваться только после того как был найден предыдущий. Также происходит выдача инфопоршней используемых в структуре самого квеста. Еще одна особенность это установка дополнительной проверки в зависимости от локации.
Созданный нами скрипт необходимо обьявить в функции апдейта актора actor_binder:update(delta) в файле bind_stalker.script
Код
..... new_tasks.task_spec() .....
Теперь собственно перейдем к созданию самого задания. Код секции квеста ([geonezis_jup_spec_scaner]) можно просмотреть в файле tm_jupiter.ltx в архиве с отработанным примером. Основные особенности это наличие двух кондишинов один на завершение задания, второй на его провал (в случае если сквад ученых бункера станет врагами по отношению к ГГ). По завершению задания будет повышена репутация у группировки экологов, а также выдана награда. Структура квеста последовательная. Одна секция тайтлов, дескрипшинов и меток заменаяет другую при получении соответсвующих им инфопоршней. Всего 7 таких этапов. Инфопоршни используемые в задании выдаются также последовательно. Определяемыми являются те которые обновляются при спавне (jup_novikov_quest_zaton_scanner_create_№), а не при взятии предмета.
На этом урок завершен.
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
Урок 35 Задача: В уроке описаны два способа спавна объектов декора на локацию. Принципы, описанные в уроке, подходят для Зова Припяти, однако статья написана для Теней.
Предположим, Вам нужно добавить на локацию декорации- автомобили, мусор, баррикады_ ящики, катающиеся консервные банки и прочие статичные и динамичные объекты. Самый простой способ - использовать СДК. Но есть два альтернативных способа.
Спавн декораций через скрипт.
Для спавна нам понадобится секция объекта. В моём случае- вышки. Создаём файл тхт, и переименовываем его, меняя расширение на ltx. В моём случае это будет папка config\creatures и файл n_test.ltx. Регистрируем его в файле system.ltx вот так #include "creatures\n_test.ltx" Заметьте, что путь указывается относительно папки config.
В сам файл пишем следующее:
[test_obj]:identity_immunities--test_obj – имя нащей СЕКЦИИ. Не модели, что спавним. $spawn = "physics\object" class = O_INVBOX– класс. Чуть ниже об этом. remove_time = 60000 visual = physics\vishka_high.ogf– путь к модели относительно папки meshes description = "Тестовый объект"
От класса зависит многое. Дальше речь идёт о ТЧ: Так, O_INVBOX спавнит недвижимый объект. Но! Он проницаем. Вне зависимости от настроек шейпов модели. O_PHYS_S спавнит неприбитый объект, но с шейпами. Впрочем, если отредактировать кости модели и поставить им вес по 10 000 , то на ровной площадке модель будет сложно сдвинуть. Этот класс оптимален для спавна люков, моделек оружия, ящиков, прочего физически обсчитываемого мусора, который будет разлетаться от взрывов , аки в Crysis`е. SCRPTCAR используется для спавна авто, на которых можно ездить.
Если есть секция, то можно писать функцию. В моём случае: function n_spawn() –имя функции local obj local a = vector()-- Задаем тип переменной local dir = db.actor:direction() a.x = 241.230957-- координата X a.y = 23.297560-- высота Y a.z = 124.653923-- координата Z obj = alife():create("test_obj", a, 525991,145)– собственно спавн. Имя секции в кавычках. end
О том, как снимать координаты, так же информации много. Функцию можно вставить в диалог или забить на выполнение при получении определённого инфопоршня.
Скорее всего в Зове Припяти классы и их параметры изменены. Помогут эксперименты и знание английского. Смотрим, например, файл dynamic_objects.ltx, где прописаны стандартные классы, секции спавна дверей, взрывающихся баллонов и прочего.
Спавн через all.spawn.
Об этом файле и работе с ним много уже написано. Приведу лишь секцию, которая намертво пришивает объект к точке.
[881123513249] ;–номер секции. Должен быть уникальным ; cse_abstract properties section_name = physic_object name = esc_test_object_3 ;уникальное имя position = -18.547161,-1.374819,-27.618841; координаты direction = 0, 0, 0 id = 65535 version = 118 script_version = 6 ; cse_alife_object properties game_vertex_id = 83;гейм вертекс level_vertex_id = 258824; левел вертекс object_flags = 0xffffff7a custom_data = <
[collide] ignore_static END ; cse_visual properties visual_name = physics\vishka_high.ogf; путь к нашей модельке. ; cse_ph_skeleton properties skeleton_name = ; cse_alife_object_physic properties physic_type = 0x3 mass = 10;масса модели fixed_bones = link-- самое интересное и важное.
Fixed_bones - параметр, отвечающий за «пришитую» к локации кость. Link—имя рутовой кости, которая есть во всех РОДНЫХ моделях декораций от GSC(не нпс, авто,мутанты и пр.). Если модель не родная, то пробуем, например bone01 (Максовский формат) или же просто конвертируем модель в формат object c помощью конвертера товарища bardac, а затем смотрим имя кости в actor editor.
Урок 36 Задача: Создание новой модели сталкера/мутанта используя готовый скелет с анимациями и трехмерную модель (жесткая привязка к скелету) Файл с заданием
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014