Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Теоретическая часть.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
450.05 Кб
Скачать

Урок 6. Реализация квеста на выполнение определенного действия через логику рестриктора, работа с туториалом. Последовательность в выполнении на несколько этапов.

Предположим нам необходимо реализовать квест следующего типа: ГГ будет выдано задание на извлечение определенного предмета из физического обьекта на локации. Пусть будет такой вариант: Сыч дает Дягтереву задание на изьятие из старой антенны и генератора на ВНЗ Круг различных деталей. Для осуществления подобных заданий необходимо использовать рестрикторы. Данный тип квестов в корне отличается от простых, когда по заданным меткам необходимо было просто подобрать заспавненные ранее предметы. 

Необходимые для редактирования файлы: 

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 в самом низу добавим диалог: 

Code

<dialog id="zat_b106_stalker_sich_test_quest_dialog">                              <dont_has_info>zat_b106_sich_quest_complete</dont_has_info>                           <phrase_list>                     <phrase id="0">                        <text>zat_b106_stalker_sich_test_quest_dialog_0</text>                                  <next>1</next>                        <next>2</next>                     </phrase>                     <phrase id="1">           <dont_has_info>zat_b106_sich_quest_begin</dont_has_info>                        <text>zat_b106_stalker_sich_test_quest_dialog_1</text>                                     <next>11</next>                        <next>12</next>                               </phrase>                     <phrase id="12">                        <text>zat_b106_stalker_sich_test_quest_dialog_12</text>                        <action>dialogs.break_dialog</action>                              </phrase>                              <phrase id="11">                        <text>zat_b106_stalker_sich_test_quest_dialog_11</text>                        <next>111</next>                               </phrase>                             <phrase id="111">                         <text>zat_b106_stalker_sich_test_quest_dialog_112</text>            <action>dialogs_zaton.zat_b106_sich_give_tasks</action>                         <give_info>zat_b106_sich_quest_begin</give_info>                               </phrase>                              <phrase id="2">            <has_info>zat_b106_sich_quest_begin</has_info>                         <text>zat_b106_stalker_sich_test_quest_dialog_2</text>                                      <next>3</next>                      <next>4</next>                     </phrase>                     <phrase id="4">                         <dont_has_info>zat_b106_sich_quest_restr_2</dont_has_info>                         <text>zat_b106_stalker_sich_test_quest_dialog_4</text>                         <action>dialogs.break_dialog</action>                               </phrase>                                 <phrase id="3">            <has_info>zat_b106_sich_quest_restr_2</has_info>                         <text>zat_b106_stalker_sich_test_quest_dialog_3</text>                         <give_info>zat_b106_sich_quest_complete</give_info>                                               <next>331</next>                               </phrase>                     <phrase id="331">                                      <text>zat_b106_stalker_sich_test_quest_dialog_331</text>                                   <next>332</next>                                               </phrase>                     <phrase id="332">                                      <text>zat_b106_stalker_sich_test_quest_dialog_332</text>                         <action>dialogs_zaton.zat_b106_sich_quest_relocate_item</action>                                               <next>333</next>                               </phrase>                     <phrase id="333">                         <text>zat_b106_stalker_sich_test_quest_dialog_333</text>            <action>dialogs_zaton.zat_b106_sich_quest_relocate_reward</action>                         <next>334</next>                               </phrase>                     <phrase id="334">                         <text>zat_b106_stalker_sich_test_quest_dialog_334</text>                                              </phrase>                                   </phrase_list>          </dialog> 

Чтобы понимать о чем в диалогах идет речь сразу пропишем русскую транскрипцию фраз в файле st_dialogs_zaton.xml 

Code

<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. Добавим в конце файла код: 

Code

<info_portion id="zat_b106_sich_quest_complete"></info_portion>  <info_portion id="zat_b106_sich_quest_begin"></info_portion>  <info_portion id="zat_b106_sich_quest_restr_1"></info_portion>  <info_portion id="zat_b106_sich_quest_restr_2"></info_portion> 

Добавим наш диалог НПС (В данном случае Сычу) для этого в файл character_desc_zaton.xmlв его профиль<specific_character id="zat_b30_owl_stalker_trader" team_default="1"> добавим строку диалога 

Code

....  <actor_dialog>zat_b106_stalker_sich_test_quest_dialog</actor_dialog>  .... 

С диалогами и инфопоршнями разобрались теперь добавим необходимые для выполнения квеста предметы, а также файлы связанный с ними.  В файл quest_items.ltx пропишем две секции предметов zat_b206_sich_quest_item_1 и zat_b206_sich_quest_item_2. Оба предмета являются квестовыми- невозможна их продажа и выкладывание из инвентаря 

Code

[zat_b206_sich_quest_item_1]:device_pda  $spawn     = "quest_items\zat_b206_sich_quest_item_1"  visual    = dynamics\equipments\quest\materials_textolite.ogf  description   = st_zat_b206_sich_quest_item_1_descr  inv_name   = st_zat_b206_sich_quest_item_1_name  inv_name_short                       = st_zat_b206_sich_quest_item_1_name  inv_weight   = 0.1  can_trade   = false  quest_item                     = true  inv_grid_width                = 1  inv_grid_height                = 1  inv_grid_x   = 2  inv_grid_y   = 19  [zat_b206_sich_quest_item_2]:device_pda  $spawn     = "quest_items\zat_b206_sich_quest_item_2"  visual    = dynamics\equipments\quest\materials_wire.ogf  description   = st_zat_b206_sich_quest_item_2_descr  inv_name   = st_zat_b206_sich_quest_item_2_name  inv_name_short                    = st_zat_b206_sich_quest_item_2_name  inv_weight   = 0.1  can_trade   = false  quest_item                     = true  inv_grid_width                = 1  inv_grid_height                = 1  inv_grid_x   = 14  inv_grid_y   = 19 

В файл death_generic.ltx пропишем: (в данном случае также необязательно так как генерации в инвентаре НПС нет) 

Code

....  zat_b206_sich_quest_item_1 = true  zat_b206_sich_quest_item_2 = true  .... 

В файл ui_si.script таблица info_table добавим (для спавна, в принципе работать будет и без внесения в этот файл): 

Code

....  "zat_b206_sich_quest_item_1",  "zat_b206_sich_quest_item_2",  .... 

В файл st_items_quest.xml пропишем дескрипцию предметов. 

Code

<string id="st_zat_b206_sich_quest_item_1_name">          <text>Первая деталь</text>  </string>  <string id="st_zat_b206_sich_quest_item_1_descr">          <text>Одна из основных деталей общей схемы в исседовательской антенне.</text>  </string>  <string id="st_zat_b206_sich_quest_item_2_name">          <text>Вторая деталь</text>  </string>  <string id="st_zat_b206_sich_quest_item_2_descr">          <text>Одна из компановочных составляющих старого генератора.</text>  </string> 

С квестовыми предметами разобрались, теперь же добавим рестрикторы используемые в квесте.  - Прежде всего создадим сами рестрикторы добавив в файл alife_zaton.ltx распакованного программой ACDC all.spawn 

Code

[zaton_1865120]  ; cse_abstract properties  section_name = space_restrictor  name = zat_test_quest_restrictor_1  position = -432.537384048828,11.5833719020996,-46.925877601563  direction = 0,0.841602981090546,0  ; cse_alife_object properties  game_vertex_id = 51  distance = 0  level_vertex_id = 131423  object_flags = 0xffffff3e  custom_data = <<END  [story_object]  story_id = zat_restr_1_id  [logic]  cfg = scripts\zaton\zat_restr_logic_1.ltx  END  ; cse_shape properties  shapes = shape0  shape0:type = box  shape0:axis_x = 4,0,0  shape0:axis_y = 0,3.13100147247314,0  shape0:axis_z = 0,0,2  shape0:offset = 0,0,0  ; cse_alife_space_restrictor properties  restrictor_type = 3  [zaton_1865121]  ; cse_abstract properties  section_name = space_restrictor  name = zat_test_quest_restrictor_2  position = -391.867065048828,10.9986919020996,-15.951530601563  direction = 0,0.841602981090546,0  ; cse_alife_object properties  game_vertex_id = 51  distance = 0  level_vertex_id = 190168  object_flags = 0xffffff3e  custom_data = <<END  [story_object]  story_id = zat_restr_2_id  [logic]  cfg = scripts\zaton\zat_restr_logic_2.ltx  END  ; cse_shape properties  shapes = shape0  shape0:type = box  shape0:axis_x = 4,0,0  shape0:axis_y = 0,3.13100147247314,0  shape0:axis_z = 0,0,2  shape0:offset = 0,0,0  ; cse_alife_space_restrictor properties  restrictor_type = 3 

- Имена секций рестикторов должны быть уникальны (как собственное имя, так и порядковое внутри алл спавна)  - Они должны иметь тип 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 И пропишем в него следующий код: 

Code

[logic]  active = sr_idle@start  [sr_idle@start]  on_info  = {+zat_b106_sich_quest_begin =actor_in_zone(zat_test_quest_restrictor_1)} sr_idle@tutorial %=run_tutorial(zat_sich_quest_1_tutor)%  on_info2 = {+zat_b106_sich_quest_restr_1} sr_idle@nil  [sr_idle@tutorial]  on_info   = {+zat_b106_sich_quest_begin !actor_in_zone(zat_test_quest_restrictor_1)} sr_idle@start %=stop_tutorial%  on_info2 = {+zat_b106_sich_quest_restr_1} sr_idle@nil  on_info3 = {!has_active_tutorial} sr_idle@start  [sr_idle@nil] 

Опишем что означает эта логика и по какому принципу она строиться:  - всего логика имеет три секции это 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 

Code

<string id="zat_sich_quest_tips">              <text>Извлечь деталь</text>  </string> 

Сам туториал пропишем в файле game_tutorials.xml 

Code

<zat_sich_quest_1_tutor>  <global_wnd/>  <item>  <disabled_key>quit</disabled_key>  <length_sec/>  <action id="use" finalize="1">xr_effects.zat_sich_quest_1</action>  <guard_key>use</guard_key>  <grab_input>0</grab_input>  <main_wnd>  <auto_static start_time="0" length_sec="5000" x="512" y="660" width="300" height="60" alignment="c" stretch="1"la_cyclic="1" la_texture="1" la_alpha="1">  <text font="graffiti22" r="225" g="225" b="250" a="255" align="c">zat_sich_quest_tips</text>  </auto_static>  </main_wnd>  </item>  </zat_sich_quest_1_tutor> 

Основные параметры это:  - <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 пропишем скрипты исполняемые при юзании рескриптора. 

Code

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 добавим следующие функции: 

Code

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 

Поясним их:  - Выдача квеста  - Передача квестовых предметов неписю  - Выдача ГГ награды за квест 

Так и собственно в завершении осталось расписать сам квест:  В файл tm_zaton.ltx добавим код: 

Code

[geonezis_zat_b206_sich_example_task]  icon = ui_inGame2_Zamanchiviy_biznes  prior = 1  storyline = false  title = {+zat_b106_sich_quest_restr_2} zat_b206_sich_example_title2, {+zat_b106_sich_quest_restr_1 -zat_b106_sich_quest_restr_2} zat_b206_sich_example_title1, {-zat_b106_sich_quest_restr_1} zat_b206_sich_example_title0  descr = {+zat_b106_sich_quest_restr_2} zat_b206_sich_example_text2, {+zat_b106_sich_quest_restr_1 -zat_b106_sich_quest_restr_2} zat_b206_sich_example_text1, {-zat_b106_sich_quest_restr_1} zat_b206_sich_example_text0  target = {+zat_b106_sich_quest_restr_2} zat_b30_owl_stalker_trader_id, {+zat_b106_sich_quest_restr_1 -zat_b106_sich_quest_restr_2} zat_restr_2_id, {-zat_b106_sich_quest_restr_1} zat_restr_1_id     condlist_0 = {+zat_b106_sich_quest_complete} complete  condlist_1 = {+zat_b106_sich_quest_begin =is_squad_enemy_to_actor(zat_b30_owl_stalker_trader_squad)} fail  on_complete = %=inc_faction_goodwill_to_actor(stalker:50)%    

Пояснения:  - квест исполняется в три этапа- сначала мы юзаем рестриктор 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 пропишем тайтлы и дескрипшины квеста: 

Code

<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> 

На этом урок добавления подобного класса заданий завершен. 

Урок 7. Создание квеста с добавлением дополнительных внутри этапных заданий. Особенности - отсутствие диалогов, использование рестрикторов, добавление квестовых предметов отдельного класса, работа с туториалами.

Поставленная задача в данном уроке будет заключаться в обучении основным принципам создания среднего по сложности квеста в игре Сталкер Зов Припяти без использования каких-либо диалогов. Выдача задания будет осуществляться автоматически, в данном случае зададим ее при старте игры. Также будет показан прием добавления во внутреннею структуру основного задания нескольких дополнительных подквестов и объяснение применение рестриторов на всех поставленных этапах. 

Само задание следующее: При старте ГГ на ПДА придет сообщение о необходимости установки схронов. Осуществляется выдача квеста. Необходимо забрать утерянные рюкзаки и заложить их в трех указанных точках. После этого задание автоматически завершается. Выдача награды не предусмотрена. 

Необходимые для редактирования файлы:  1. конфигурационные в (gamedata\configs\gameplay\-character_desc_jupiter.xml  -info_zaton.xml  2. конфигурационные в (gamedata\configs\misc\- tm_jupiter.ltx  - quest_items.ltx  - devices.ltx  - death_generic.ltx  3. конфигурационные в (gamedata\configs\text\rus\- st_quests_zaton.xml  - st_items_quest.xml  - ui_st_screen.xml  4. конфигурационные в (gamedata\configs\misc\trade\- trade_generic.ltx  5. конфигурационные в (gamedata\configs\ui\- game_tutorials.xml  6. конфигурационные в (gamedata\configs\scripts\zaton\- файлы логик рестрикторов  7. скриптовый в (gamedata\scripts\- ui_si.script  - bind_stalker.script  - new_tasks.script  - xr_effects.script  8. all.spawn. (gamedata\spawns\- alife_zaton.ltx 

На первоначальном этапе определимся с квестовыми предметами. Всего их шесть. Три будут отвечать за айтем рюкзака до его закладки. Они будут являться потомками основного родительского класса device_pda. Другие три будут определены другим классом, им будет соответствовать установленная логика и они отвечают за рюкзаки после установки схрона. Пропишем секции их конфигов в файле quest_items.ltx (Здесь и далее буду приводить конфиг только одной секции, остальные задаются аналогично только с изменением числовых значений в имени). 

Code

[zat_example_taynik_1_item]:device_pda  $spawn     = "quest_items\zat_example_taynik_1_item"  description   = zat_example_taynik_item_descr  inv_name   = zat_example_taynik_item_name  visual    = dynamics\devices\dev_rukzak\dev_rukzak.ogf  inv_weight   = 2  story_id    = zat_example_taynik_1_item  can_trade   = false  quest_item       = true  inv_grid_width  = 2  inv_grid_height  = 2  inv_grid_x      = 0  inv_grid_y      = 38  ..........  [zat_example_taynik_1]:default_inventory_box  custom_data         = scripts\zaton\inventory_boxs\zat_example_taynik_1.ltx  .......... 

Первый конфиг не содержит в себе прикрепленного файла в дополнительной секции и определяется как простой квестовый предмет, второй же содержит прикрепленный конфиг с логикой его zat_example_taynik_1.ltx  Для определении секции zat_example_taynik_1 необходимо определить родительский класс default_inventory_box в файле devices.ltx 

Code

[default_inventory_box]  GroupControlSection    = spawn_group  discovery_dependency    =  $spawn    = "devices\default_inventory_box"  class   = O_INVBOX  cform   = skeleton  visual   = dynamics\devices\dev_rukzak\dev_rukzak.ogf  script_binding          = bind_physic_object.init  radius                  = 3  inv_grid_width  = 2  inv_grid_height  = 2  inv_grid_x  = 0  inv_grid_y  = 38  cost   = 3500  can_take  = true  inv_weight  = 1.14  description  =               inv_name  =               inv_name_short  = 

В этой секции указываются основные параметры такие как основной класс, форма, визуал.  Кроме того определим его основную логику в конфигурационном файле zat_example_taynik_1.ltx 

Code

logic]  active = ph_idle@nothing  [ph_idle@nothing]  nonscript_usable = true  tips = st_taynik_check_descr 

Здесь указывается активная секция это ph_idle@nothing, а также ее содержание.  Тайник после установки можно использовать, т.е. возможно его наполнение различными предметами, также при наведении на него будет активна надпись из секции st_taynik_check_descr…

Зарегистрируем конфиги первой секции предмета тайник zat_example_taynik_..._item.  В файле death_generic.ltx пропишем код 

Code

.....  zat_example_taynik_1_item = true  zat_example_taynik_2_item = true  zat_example_taynik_3_item = true 

В файле ui_si.script добавим 

Code

"zat_example_taynik_1_item",  "zat_example_taynik_2_item",  "zat_example_taynik_3_item", 

Обозначим секции, логику и работу рестрикторов необходимых для выполнения внутренних подквестов.  В файле alife_zaton.ltx обозначим три секции 

Code

[zaton_999999011]  ; cse_abstract properties  section_name = space_restrictor  name = zat_test_quest_restrictor_1  position = 210.996811,15.980440,480.381104  direction = 0,0.841602981090546,0  ; cse_alife_object properties  game_vertex_id = 6  distance = 0  level_vertex_id = 1323235  object_flags = 0xffffff3e  custom_data = <<END  [story_object]             story_id = zat_restr_1_id  [logic]  cfg = scripts\zaton\zat_restr_logic_1.ltx  END  ; cse_shape properties  shapes = shape0             shape0:type = box             shape0:axis_x = 4,0,0             shape0:axis_y = 0,3.13100147247314,0             shape0:axis_z = 0,0,2             shape0:offset = 0,0,0 

В секции указываются координаты и тип рестрикторов, их идентификатор, имя, тип и размер шейпа.  В файле логики zat_restr_logic_1.ltx пропишем: 

Code

[logic]             active = sr_idle@start             [sr_idle@start]             on_info  = {+zat_test_quest_rest_main_come =actor_in_zone(zat_test_quest_restrictor_1) =actor_has_item(zat_example_taynik_1_item)} sr_idle@tutorial %=run_tutorial(zat_test_quest_1_tutor)%             on_info2 = {+zat_test_quest_restr_1} sr_idle@nil             [sr_idle@tutorial]             on_info   = {+zat_test_quest_rest_main_come !actor_in_zone(zat_test_quest_restrictor_1)} sr_idle@start %=stop_tutorial%             on_info2 = {+zat_test_quest_restr_1} sr_idle@nil             on_info3 = {!has_active_tutorial} sr_idle@start             [sr_idle@nil]            

Отметим особенности:  Активная секция sr_idle@start переход на вторую происходит по достижению трех условий  - наличие инфопоршня активности второго этапа основного задания (zat_test_quest_rest_main_come)  - актор находиться в зоне действия рестриктора  - наличие в его инвентаре zat_example_taynik_1_item  При выполнении всех этих условий выполняется работа рестриктора определяемая в туториале zat_test_quest_1_tutor  При получении инфопоршня zat_test_quest_restr_1 происходит переход в третью нулевую секцию логики рестриктора sr_idle@nil  При выхода актора из зоны рестриктора его работа прекращается и логика переключается во второе состояние sr_idle@tutorial из которого она может снова перейти в первое или в третье.  Объявим в файле game_tutorials.xml туторы выполняемые в работе рестрикторов 

Code

<zat_test_quest_1_tutor>                         <global_wnd/>                            <item>                                <disabled_key>quit</disabled_key>                                <length_sec/>                                <action id="use" finalize="1">xr_effects.zat_test_quest_1</action>                                <guard_key>use</guard_key>                                <grab_input>0</grab_input>                                    <main_wnd>                                    <auto_static start_time="0" length_sec="5000" x="512" y="660" width="300" height="60" alignment="c" stretch="1"la_cyclic="1" la_texture="1" la_alpha="1">                                    <text font="graffiti22" r="225" g="225" b="250" a="255" align="c">zat_test_quest_tips</text>                                    </auto_static>                                    </main_wnd>                            </item>                        </zat_test_quest_1_tutor> 

Основные параметры это функция скрипта обработчика действия xr_effects.zat_test_quest_1 и активная надпись из секции zat_test_quest_tips В файле xr_effects.scripts определим функции 

Code

function zat_test_quest_1(actor, npc)                        if xr_conditions.actor_in_zone(actor, npc, {"zat_test_quest_restrictor_1"})                           then                                 remove_item(actor, npc, {"zat_example_taynik_1_item"})                              alife():create("zat_example_taynik_1",vector():set(210.996811,15.980440,480.381104),1323235,6)                  db.actor:give_info_portion("zat_test_quest_restr_1")                           end           end 

Опишем ее:  - если выполнено условие нахождение актора в зоне рестриктора zat_test_quest_restrictor_1  то происходит удаление из инвентаря ГГ айтема первого конфига тайника zat_example_taynik_1_item, создается по заданным координатам второй zat_example_taynik_1 и выдается инфопоршень zat_test_quest_restr_1 

Выдача задания будет происходит при старте ГГ одновременно с квестами основного сюжета. Для этого добавим инфопоршень выдачи и сам квест в секцию логики [sr_idle] оригинального рестриктор zat_b101_logic.ltx 

Code

=give_task(geonezis_zat_test_example_task) +zat_test_quest_begin 

Выдача подквестов будет осуществлять в логике другого рестриктора zat_restr_logic_main.ltx Его секция прописывается в all.spawn по аналогии с предыдущими. Сама логика имеет следующий вид: 

Code

[logic]        active = sr_idle@start        [sr_idle@start]  on_info = {+zat_test_quest_begin -zat_test_quest_rest_main_come =actor_in_zone(zat_test_quest_restrictor_main)} %=give_task(geonezis_zat_test_example_task_1) =give_task(geonezis_zat_test_example_task_2) =give_task(geonezis_zat_test_example_task_3) +zat_test_quest_rest_main_come%  on_info2 = {+zat_test_quest_rest_main_come} sr_idle@nil  [sr_idle@nil] 

В активной секции при попадании актора в зону рестриктора происходит выдача внутренних подквестов и переход логики в нулевое состояние. 

Определим сам квест с подзаданиями: 

Code

[geonezis_zat_test_example_task]       icon = ui_inGame2_Osobiy_zakaz       prior = 1       storyline = false       title = {+zat_test_quest_rest_main_come} zat_test_example_title1, {-zat_test_quest_rest_main_come} zat_test_example_title0       descr = {+zat_test_quest_rest_main_come} zat_test_example_text1, {-zat_test_quest_rest_main_come} zat_test_example_text0       target ={+zat_test_quest_rest_main_come} nil, {-zat_test_quest_rest_main_come} zat_restr_main_id          condlist_0 = {+zat_test_quest_complete} complete       on_complete = %=inc_faction_goodwill_to_actor(stalker:50)% 

Подквесты: 

Code

[geonezis_zat_test_example_task_1]  icon = ui_inGame2_Osobiy_zakaz  prior = 1  storyline = false  title =  zat_test_example_1_title      descr =  zat_test_example_123_text      target = zat_restr_1_id  condlist_0 = {+zat_test_quest_restr_1} complete  on_complete = %=inc_faction_goodwill_to_actor(stalker:50)% 

Code

[geonezis_zat_test_example_task_2]  icon = ui_inGame2_Osobiy_zakaz  prior = 1  storyline = false  title =  zat_test_example_2_title      descr =  zat_test_example_123_text      target = zat_restr_1_id  condlist_0 = {+zat_test_quest_restr_2} complete  on_complete = %=inc_faction_goodwill_to_actor(stalker:50)% 

Code

[geonezis_zat_test_example_task_3]  icon = ui_inGame2_Osobiy_zakaz  prior = 1  storyline = false  title =  zat_test_example_3_title      descr =  zat_test_example_123_text      target = zat_restr_1_id  condlist_0 = {+zat_test_quest_restr_3} complete  on_complete = %=inc_faction_goodwill_to_actor(stalker:50)% 

Особенности:  - При старте задания необходимо посетить зону основного рестриктора, устанавливается тагет на zat_restr_main_id. В момент посещения активируются подквесты, выдается инфопоршень zat_test_quest_rest_main_come, задание обновляется, его тагет уходит в nill. после взятия всех квестовых айтемов- необходимо завершение всех трех подквестов для получения инфопоршня zat_test_quest_complete  Скриптовая функция которая отвечает за создание трех основных квестовых предметов и выдачу завершающего основное задание инфопоршня прописывается в файл new_tasks.script, и объявляется в апдейте актора файла bind_stalker.script 

Code

new_tasks.task_spec() 

сама функция 

Code

--/Квест Example  function task_spec()  local level_name=level.name()       if level_name=="zaton" then          if has_alife_info("zat_test_quest_begin") and not has_alife_info("zat_test_quest_spawn_items") then                     alife():create("zat_example_taynik_1_item",vector():set(248.498016,14.915686,484.567932),1391296,6)             alife():create("zat_example_taynik_2_item",vector():set(247.778076,14.872326,484.085999),1390040,6)             alife():create("zat_example_taynik_3_item",vector():set(247.055069,14.796996,483.116058),1388814,6)          news_manager.send_tip(db.actor, "Чтобы выполнить тестовое задание необходимо установить все тайники. Подбери рюкзаки оставленные сталкерами", nil, nil, 14000)          db.actor:give_info_portion("zat_test_quest_spawn_items")                        end       if has_alife_info("zat_test_quest_restr_1") and has_alife_info("zat_test_quest_restr_2") and has_alife_info("zat_test_quest_restr_3") and           not has_alife_info("zat_test_quest_complete") then          db.actor:give_info_portion("zat_test_quest_complete")       end       end  end 

Описание:  При нахождении ГГ на локации Затон и наличии инфопоршня zat_test_quest_begin создаются квестовые айтемы и отправляется мессадж на пда ГГ.  При завершении всех трех подквестов выдается инфопоршень zat_test_quest_complete завершения основного. 

Все инфопоршни необходимые нам пропишем в файле info_zaton.xml 

Code

.....  <info_portion id="zat_test_quest_restr_1"></info_portion>  <info_portion id="zat_test_quest_restr_2"></info_portion>  <info_portion id="zat_test_quest_restr_3"></info_portion>     <info_portion id="zat_test_quest_spawn_items"></info_portion>  <info_portion id="zat_test_quest_begin"></info_portion>  <info_portion id="zat_test_quest_complete"></info_portion>  <info_portion id="zat_test_quest_rest_main_come"></info_portion>  ..... 

Всю текстовую транскрипцию определим в xml-файлах.  На этом урок завершен. 

Урок 8. Создание квеста с добавлением дополнительных внутриэтапных заданий. Особенности- отсутствие диалогов, использование физических объектов класса physic_destroyable_object в качестве квестовых предметов.

В данном уроке речь пойдет о реализации задания подобного тому что было рассмотрено в предыдущем уроке. В отличие от него теперь добавление внутри этапных заданий будет завязано не на применение рестрикторов, а на использование физических объектов специального класса. Задание этих объектов будет осуществлено как в моде SGM (автор GeJorge) Также особенностью будет добавление класса метки объекта (также по аналогии с SGM) что позволит отказаться от применения рестрикторов в определенных моментах. Выдача задания осуществляется при старте игры. Диалогов нет. 

Само задание:  ГГ на ПДА приходит сообщение о необходимости обыска трех точек с установленными там объектами. Необходимо выяснить что это за объекты и вернуться в стартовую точку. После этого задание автоматически завершается. Выдача награды не предусмотрена. 

Необходимые для редактирования файлы: 

1. конфигурационные в (gamedata\configs\gameplay\)  -info_zaton.xml  2. конфигурационные в (gamedata\configs\misc\)  - tm_zaton.ltx  - quest_items.ltx  3. конфигурационные в (gamedata\configs\text\rus\)  - st_quests_zaton.xml  - ui_st_screen.xml  4. конфигурационные в (gamedata\configs\models\)  - dynamic_objects.ltx  5. конфигурационные в (gamedata\configs\scripts\zaton\)  - файлы логик рестрикторов и объектов  6. скриптовый в (gamedata\scripts\)  - bind_stalker.script  - new_tasks.script  7. all.spawn. (gamedata\spawns\)  - alife_zaton.ltx  8. физическая модель в (gamedata\meshes\dynamics\box\)  - konteyner.ogf 

Некоторые этапы добавления изменений будут приведены с сокращением, ввиду их схожести с аналогичными в других уроках. Акцент будет сделан на впервые вносимые изменения и аспекты. 

Изначально создадим новые классы квестовых предметов.  Класс родительского предмета метка будет соответствовать стандартному квестовому device_pda, но будет иметь визуал нулевого значения. поэтому при написания квестов и установки тагета в них можно будет воспользоваться именно этим приемом, а не добавлением цели на айдишнике отдельного рестриктора. пропишем в quest_items.ltx секцию 

Code

[quest_spot]:device_pda  $spawn  = "devices\quest_spot"  visual    = dynamics\scene_objects\part\part_none.ogf  can_take = false 

сами добавленные метки имеют следующие секции. как видим они являются потомками родительского класса quest_spot. также указывается айди метки по которому будет прописываться таргет story_id. 

Code

[zat_test_stalker_container_1_spot]:quest_spot  story_id = zat_test_stalker_container_1_spot  [zat_test_stalker_container_2_spot]:quest_spot  story_id = zat_test_stalker_container_2_spot  [zat_test_stalker_container_3_spot]:quest_spot  story_id = zat_test_stalker_container_3_spot 

Новый физический объект используемый нами в квесте объявим в файле dynamic_objects.ltx Он будет иметь свой уникальный класс наследуемый от основного physic_destroyable_object Секции конфигов будут следующими: 

Code

[box_quest_item]:physic_destroyable_object  $spawn                      = "dynamic_objects\box\box_quest_item"  visual              = dynamics\box\konteyner.ogf  [zat_test_stalker_container_1]:box_quest_item  custom_data       = scripts\zaton\inventory_boxs\zat_test_stalker_container_1.ltx  [zat_test_stalker_container_2]:box_quest_item  custom_data       = scripts\zaton\inventory_boxs\zat_test_stalker_container_2.ltx  [zat_test_stalker_container_3]:box_quest_item  custom_data       = scripts\zaton\inventory_boxs\zat_test_stalker_container_3.ltx 

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

Логика добавленных предметов будет задаваться в файлах zat_test_stalker_container_....ltx следующим образом: 

Code

[logic]  active = ph_idle@retranslator_take  [ph_idle@retranslator_take]  nonscript_usable = false  tips = st_take_the_quest_item  on_use = ph_idle@retranslator_heavy %+zat_test_quest_item_1_used%  on_info = {+zat_test_quest_complete} sr_idle@nil  [ph_idle@retranslator_heavy]  nonscript_usable = false  tips = st_quest_item_is_used  on_info = {+zat_test_quest_complete} sr_idle@nil  [sr_idle@nil] 

- активная секция логики ph_idle@retranslator_take  - первоначальная активная надпись считывается из секции st_take_the_quest_item  - при юзании предмета произойдет выдача инфопорции zat_test_quest_item_1_used и переход во вторую секцию логикиph_idle@retranslator_heavy  - при этом изменяется активная надпись на st_quest_item_is_used  - при получении инфопорции zat_test_quest_complete логика обнуляется. 

Теперь необходимо создать основной рестриктор на обход которого будет завязана основа квеста.  Сам рестриктор создаем в all.spawn по аналоги с предыдущими уроками.  Логика рестриктора из файла zat_restr_logic_main.ltx имеет следующий вид: 

Code

[logic]      active = sr_idle@start      [sr_idle@start]  on_info = {+zat_test_quest_begin -zat_test_quest_rest_main_come =actor_in_zone(zat_test_quest_restrictor_main)} %=give_task(geonezis_zat_test_example_task_1) =give_task(geonezis_zat_test_example_task_2) =give_task(geonezis_zat_test_example_task_3) +zat_test_quest_rest_main_come%  on_info2 = {+zat_test_quest_rest_main_come} sr_idle@wait  [sr_idle@wait]  on_info = {+zat_test_quest_all_item_used -zat_test_quest_complete =actor_in_zone(zat_test_quest_restrictor_main)} %+zat_test_quest_complete%  on_info2 = {+zat_test_quest_complete} sr_idle@nil  [sr_idle@nil] 

разберем ее:  - имеет три секции первая активная, во вторую переходит по совокупности полученных условий при обновлении квеста. - при этом происходит выдача трех подзаданий.  - для перехода в нулевую секцию необходимо завершение задания. 

Выдача задания будет происходит при старте ГГ одновременно с квестами основного сюжета. Для этого добавим инфопоршень выдачи и сам квест в секцию логики [sr_idle] оригинального рестриктор zat_b101_logic.ltx 

Code

=give_task(geonezis_zat_test_example_task) +zat_test_quest_begin    

Определим сам квест с подзаданиями:  основной квест: 

Code

[geonezis_zat_test_example_task]     icon = ui_inGame2_Osobiy_zakaz     prior = 1     storyline = false     title = {+zat_test_quest_all_item_used} zat_test_example_title2, {+zat_test_quest_rest_main_come -zat_test_quest_all_item_used} zat_test_example_title1, {-zat_test_quest_rest_main_come} zat_test_example_title0     descr = {+zat_test_quest_all_item_used} zat_test_example_text2, {+zat_test_quest_rest_main_come -zat_test_quest_all_item_used} zat_test_example_text1, {-zat_test_quest_rest_main_come} zat_test_example_text0     target = {+zat_test_quest_all_item_used} zat_restr_main_id, {+zat_test_quest_rest_main_come -zat_test_quest_all_item_used} nil, {-zat_test_quest_rest_main_come} zat_restr_main_id        condlist_0 = {+zat_test_quest_complete} complete     on_complete = %=inc_faction_goodwill_to_actor(stalker:50)% 

внутренние подквесты: 

Code

[geonezis_zat_test_example_task_1]  icon = ui_inGame2_Osobiy_zakaz     prior = 1  storyline = false  title =  zat_test_example_1_title0     descr =  zat_test_example_1_text0     target = zat_test_stalker_container_1_spot  condlist_0 = {+zat_test_quest_item_1_used} complete 

Code

[geonezis_zat_test_example_task_2]  icon = ui_inGame2_Osobiy_zakaz     prior = 1  storyline = false  title =  zat_test_example_2_title0     descr =  zat_test_example_2_text0     target = zat_test_stalker_container_2_spot  condlist_0 = {+zat_test_quest_item_2_used} complete 

Code

[geonezis_zat_test_example_task_3]  icon = ui_inGame2_Osobiy_zakaz     prior = 1  storyline = false  title =  zat_test_example_3_title0     descr =  zat_test_example_3_text0     target = zat_test_stalker_container_3_spot  condlist_0 = {+zat_test_quest_item_3_used} complete 

Особенности:  - При старте задания необходимо посетить зону основного рестриктора, устанавливается тагет на zat_restr_main_id. В момент посещения активируются подквесты, выдается инфопоршень zat_test_quest_rest_main_come, задание обновляется, его тагет уходит в nil. после юзания всех квестовых айтемов созданных в начале объектов проиходит завершение всех трех подквестов, основной квест обновляется снова. чтобы завершить его необходимо снова посетить точку основного рестриктора.  Скриптовая функция которая отвечает за создание трех основных квестовых предметов и выдачу завершающего основное задание инфопоршня прописывается в файл new_tasks.script, и объявляется в апдейте актора файла bind_stalker.script 

Code

new_tasks.task_spec()    

сама функция 

Code

--/Квест Example  function task_spec()  local level_name=level.name()      if level_name=="zaton" then         if has_alife_info("zat_test_quest_begin") and not has_alife_info("zat_test_quest_spawn_items") then                     alife():create("zat_test_stalker_container_1_spot",vector():set(210.996811,15.980440,480.381104),1323235,6)            alife():create("zat_test_stalker_container_2_spot",vector():set(267.914307,17.374102,483.001709),1424536,6)            alife():create("zat_test_stalker_container_3_spot",vector():set(305.260254,18.979174,532.515625),1484018,287)                 news_manager.send_tip(db.actor, "Для начала займи указанную точку", nil, nil, 14000)            db.actor:give_info_portion("zat_test_quest_spawn_items")                      end         if has_alife_info("zat_test_quest_rest_main_come") and not has_alife_info("zat_test_quest_spawn_items_2") then                   alife():create("zat_test_stalker_container_1",vector():set(210.996811,15.980440,480.381104),1323235,6)            alife():create("zat_test_stalker_container_2",vector():set(267.914307,17.374102,483.001709),1424536,6)            alife():create("zat_test_stalker_container_3",vector():set(305.260254,18.979174,532.515625),1484018,287)                    news_manager.send_tip(db.actor, "Чтобы выполнить тестовое задание необходимо исследовать все контейнеры.", nil, nil, 14000)            db.actor:give_info_portion("zat_test_quest_spawn_items_2")                      end      if has_alife_info("zat_test_quest_item_1_used") and has_alife_info("zat_test_quest_item_2_used") and has_alife_info("zat_test_quest_item_3_used") and         not has_alife_info("zat_test_quest_all_item_used") then         db.actor:give_info_portion("zat_test_quest_all_item_used")      end      end  end 

описание:  - первоначально по выдаче задания происходит создания меток дополнительных подквестов.  - при выдачи самих подквестов происходит создание самих предметов необходимых для их выполнения.  - при наличии трех инфопорций полученных от юзания всех предметов выдается общий инфопоршень на обновление основного задания. 

Все инфопоршни необходимые нам пропишем в файле info_zaton.xml. Всю текстовую транскрипцию определим в xml-файлах.  На этом урок завершен.