Сповіщення
Очистити все

SoC. Створення нових гілок діалогів


Ранг:
Майстер
Роль:
Гість
Записи:
752
Приєднався:
7 місяців тому
 

Створення нових гілок діалогів.

Теорія:

(Якщо десь чогось наплутав виправляйте, багато писав інтуїтивно)

1) Списки гілок діалогів містяться у файлах виду gamedata/config/gameplay/character_desc_*.xml

Це наприклад:
character_desc_zombied.xml
character_desc_stalker.xml
character_desc_garbage.xml і т.д.

Файли character_desc_*.xml можна порівняти зі стволом дерева діалогів. Вони перераховується назви гілок діалогів, що прикріплюються до НПС.

Наприклад, ось список гілок діалогів із Сидоровичем, взятий із файлу character_desc_escape.xml

		<start_dialog>escape_trader_start_dialog</start_dialog>
		<actor_dialog>escape_trader_talk_info</actor_dialog>
		<actor_dialog>escape_trader_jobs</actor_dialog>
		<actor_dialog>tm_trader_dialog</actor_dialog>
		<actor_dialog>tm_trader_reward</actor_dialog>
		<actor_dialog>escape_trader_done_blockpost_box</actor_dialog>

У свою чергу, кожна гілка діалогу також може розгалужуватися.

2) Розгалуження гілок прописується вже у інших файлах. Наприклад, розгалуження гілок діалогу з Сидоровичем міститься у файлі gamedata/config/gameplay/dialogs_escape.xml Візьмемо звідти, наприклад, розгалуження гілки escape_trader_jobs

(розгалуження гілок зазвичай дуже велике, тому я наведу лише частину):

<dialog  id = "escape_trader_talk_info" > 
        <precondition > escape_dialog.trader_has_talk_info_wr< / precondition >
         <has_info > tutorial_end </has_info 
        > < phrase_list > <
             phrase id  = " 
                1 " > <text > escape_trader_ /next > <next > 99 </next > <next > 9995 </next > </phrase >
                
                
	      
            
 
            <phrase  id = "0" > 
                <text > escape_trader_talk_info_0 </text >
                 <next > 1 </next >
             </phrase >
         </phrase_list >
 </dialog >

Тут <precondition>…</precondition> – це скриптова перевірка виконання умови. Гілка з'явиться у діалозі, тільки якщо умова виконується. Конкретно <precondition>escape_dialog.trader_has_talk_info_wr</precondition> з гілки escape_trader_talk_info є звернення до функції trader_has_talk_info_wr , що знаходиться у файлі-скрипті gamedata/scripts/escape_dialog.script .

Функція виглядає так:

function trader_has_talk_info_wr ( trader, actor ) 
	return  true 
end

<precondition>escape_dialog.trader_has_talk_info_wr</precondition> в принципі виконується завжди, тому що функція завжди повертає істbну і <dialog id="escape_trader_talk_info"> пропускається у списку реплік. Але для конкретної гілки може бути кілька попередніхумов і інших умов.

Далі.
<has_info>tutorial_end</has_info> - це також своєрідна перевірка умов. В даному випадку перевірка на те, чи закінчена стадія tutorial'у чи ні. Т. е. Гілка буде допущена до списку реплік, якщо стадія tutorial'а закінчена. детальніше про це наприкінці цієї статті. При закінченні tutorial'а видається інфопорція tutorial_end , яка є стрижнем цієї перевірки.

А далі йдуть конкретні фрази, що містять посилання на фрази, що випливають.

Фраза:

<phrase  id = "0" > 
                <text > escape_trader_talk_info_0 </text >
                 <next > 1 </next >
 </phrase >

це основа гілки escape_trader_talk_info . Взагалі, в будь-якій основній гілці будь-якого діалогу фраза <phrase id="0"> буде основою, з якої далі все витікатиме.

<next>1</next> - це посилання на фразу <phrase id="1"> :

       <phrase  id = "1" > 
                <text > escape_trader_talk_info_1 </text >
                 <next > 100 </next >
                 <next > 99 </next >
	     <next > 9995 </next >
         </phrase >

У свою чергу <next>100</next> , <next>99</next> , <next>9995</next> - це посилання на фрази гілочки, що ростуть із фрази <phrase id="1"> .

3) Текст кожної фрази міститься вже четвертому файлі. Для діалогу з Сидоровичем тексти лежать у файлі gamedata/config/text/ukr/stable_dialogs_escape.xml

	<string  id = "escape_trader_talk_info_0" > 
		<text> Є кілька запитань . </text >
	 </string >
	 <string  id = "escape_trader_talk_info_1" > 
		<text > Запитуй, тільки ж я всього не знаю. Сам розумієш, сиджу тут цілими днями, а життя - воно все там, зовні, у Зоні. Можу розповісти про Зону взагалі, а трохи можу про найближче околиці, де сам ходив. </text >
	 </string >

Ці рядки містять тексти для фраз <phrase id="0"> та <phrase id="1">

Разом діалоги розкладені по 4 або більше файлах.

До речі, шлях по гілках може бути зацикленим, якщо того вимагає діалог. Наприклад так:

<phrase  id = "0" > 
            <text > </text >
             <next > 1 </next >
             <next > 2 </next >
  </phrase >
 <phrase  id = "1" > 
            <text > </ text >
             <next > 11 </next >
             <next > 12 </next >
  </phrase >
 <phrase  id = "11" > 
            <text > </text >
             <next > 1 </next >   - Це повернення до фразі 1. (зациклювання)  
             <next > 111 </next >
  </phrase >

Практика:

Додамо в діалог із Сидоровичем гілку свого власного виготовлення. Наприклад:

Мічений: Сідрич, а чому це в тебе зелені чоловічки, що по столу бігають, такі худі?
Сидорович: Чого?!!
Ти їх зовсім, зовсім не годуєш?
Сидорович: Наступного разу, як підеш у зону, бери замість водяри побільше антирада. Бо мало що таким перегаром дихаєш, уже до зелених чоловічків долікувався... Жартівник.

Для цього:

1) У файлі gamedata/config/gameplay/character_desc_escape.xml в кінці списку гілок для trader_а суємо свою гілку з довільною назвою. (наприклад <actor_dialog>escape_trader_letat_gusi</actor_dialog>)

Тобто у нас вийде так

<specific_character  id = "escape_trader" no_random = "1" >
		<start_dialog > escape_trader_start_dialog </start_dialog >
		 <actor_dialog > escape_trader_talk_info < /actor_dialog >
		 <actor_dialog > escape_trader_jobs < /actor_dialog > <
		 actor_dialog > tm_trader_dialog < /actor_dialog > < actor_dialog > escape_trader_done_blockpost_box </actor_dialog > < actor_dialog > escape_trader_letat_gusi </actor_dialog > </specific_character > 
		…
		
		
                        
	

Записуємо зміни і з файлом character_desc_escape.xml вже все.

2) Тепер беремо файл gamedata/config/gameplay/dialogs_escape.xml

Діалогу:

Мічений: Сідрич, а чому це в тебе зелені чоловічки, що по столу бігають, такі худі?
Сидорович: Чого?!!
Ти їх зовсім, зовсім не годуєш?
Сидорович: Наступного разу, як підеш у зону, бери замість водяри побільше антирада. Бо мало що таким перегаром дихаєш, уже до зелених чоловічків долікувався... Жартівник.

який ми хочемо реалізувати, відповідатиме така структура:

<phrase  id = "0" > 
            <text > escape_trader_letat_gusi_0 </text >
             <next > 1 </next >
 </phrase >
 <phrase  id = "1" > 
            <text > escape_trader_letat_gusi_1 </text >
             <next > 2 </ next >
  </phrase >
 <phrase  id = "2" > 
            <text > escape_trader_letat_gusi_2 </text >
             <next > 3 </next >
 </phrase >
 <phrase  id = "3" > 
            <text > escape_trader_letat_gusi_3 </text >
 </phrase >

Умови наявності гілки в діалозі можна взяти з гілки Т. е. беремо умови

<precondition>escape_dialog.trader_has_talk_info_wr</precondition>

і

<has_info>tutorial_end</has_info>

(Можна було звичайно прописати в скрипті ще одна умова для гілки, щоб вона з'явилася тільки один раз, а потім більше не виникала. Але про це якось пізніше допишу.)

У результаті вийшла така структура:

<dialog  id = "escape_trader_letat_gusi" > 
        <precondition > escape_dialog.trader_has_talk_info_wr < / precondition >
         <has_info > tutorial_end </has_info
         > < phrase_list > < phrase
                    id =  " 0 " > 
                             < text > escape_trader /next > </phrase > <phrase id = "1" > <text > escape_trader_letat_gusi_1 </text > <next > 2 </next > </phrase > <phrase id = "2" > <text > escape_trader_letat_gusi_2 </text > <next > 3 </next > </phrase > <phrase id = "3" > <text > escape_trader_letat_gusi_3 </text > </phrase > </phrase_list > </dialog >
                              
                    
                      
                               
                                
                     
                      
                                
                                
                     
                      
                                  
                      
        
  

Її потрібно вставити в будь-якому місці між dialog id_шниками інших гілок у файлі dialogs_escape.xml .

Головне не промахнуться і засунути саме між, а не всередину одного з id

Все, що знаходиться між тегами <dialog id=""> і </dialog> це внутрішності конкретного dialog id

Тобто пхати наш

<dialog id="escape_trader_letat_gusi">
</dialog>

треба

<dialog id="">
</dialog>
тут
<dialog id="">
</dialog>

але

<dialog id="">
НЕ тут
</dialog>

Після збереження внесених змін із файлом dialogs_escape.xml все.

3) Тепер вбиваємо самі текстовички у файлі gamedata/config/text/ukr/stable_dialogs_escape.xml

Тобто нам треба у файлі stable_dialogs_escape.xml вставити таку конструкцію:

	<string  id = "escape_trader_letat_gusi_0" > 
		<text > Сідріч а чому це в тебе зелені чоловічки, що по столу бігають, такі худі? </text >
	 </string >
	 <string  id = "escape_trader_letat_gusi_1" > 
		<text > Чого?!! </text >
	 </string >
	 <string  id = "escape_trader_letat_gusi_2" > 
		<text > Ти їх зовсім, зовсім не годуєш? </text >
	 </string >
	 <string  id = "escape_trader_letat_gusi_3" > 
		<text > Наступного разу, як підеш у зону, бери замість водяри побільше антирада. А то мало що таким перегаром дихаєш, уже до зелених чоловічків долікувався... Жартівник. </text >
	 </string >

в будь-якому місці між існуючими string id

      <string id="">
	</string>
              сюди
	<string id="">
	</string>

Але не всередину одного з string id

      <string id="***">
               не сюди
	</string>

Після збереження змін у нас все готове. Можна вантажити гру та дивитися що вийшло.

Практичний приклад не працює з другим патчем – вирішення проблеми

Принаймні з другим патчем несумісна умова

<precondition>escape_dialog.trader_has_talk_info_wr</precondition>

Використання цієї умови призведе до вильоту

оскільки з другим патчем з файлу escape_dialog.script було видалено функцію:

function trader_has_talk_info_wr ( trader, actor )  
   return  true  
end

можна або вставити цю функцію назад в escape_dialog.scrip t

або використовувати інші більш відповідні умови, наприклад:

<precondition>escape_dialog.trader_alredy_give_job</precondition>

Доповнення від XiaNi

З приводу <precondition> у даному прикладі.. він тут реально взагалі не потрібен тим більше, що повертає завжди одне й те саме... тут уже чи реально треба використовувати функцію яка хоч щось перевіряє потрібне для діалогу... а так... діалог і так буде активним якщо усунути <precondition> (в даному випадку це 100%)

<has_info> і <dont_has_info> це умови на присутність і відповідно відсутність у гравця "інформації" яка, насправді, лише прапорець, що користувач чув про щось або бачив щось який видається: 1. умовами "логіки" прописаною об'єктами чи неписами. 2. скриптами 3. діалогами через наприклад "<give_info>tutorial_end</give_info>"

В принципі <has_info> відповідає скриптовому аналогу функції has_alife_info , наприклад <has_info>tutorial_end</has_info> можна замінити на <precondition>escape_dialog.check_tutor_end</precondition> і дописати в escape_dialog.script рядки :

 
function check_tutor_end ( actor, npc ) 
if 	has_alife_info ( "tutorial_end" ) 
	then 
	 return  true 
        else 
         return  false 
	end 
end
 

в якій ми перевіряємо, чи є інформація tutorial_end у гравця.


   
Цитата