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

SoC. Логіка NPC. Частина 4


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

Діалоги

У цьому моді буде лише один діалог, і досить простий, тому почнемо з нього. Створюємо файл config\gameplay\dialogs_need_help.xml . Щоб не поратися з ідентифікаторами текстів, спробуємо обійтися без них. Почнемо з простої тестової версії:

 
<?xml  version = "1.0"  encoding = "windows-1251"   
standalone = " yes" ?> <game_dialogs >
     < dialog  id = " 
        actor_will_need_help " > <precondition > actor_need_help.i_am_friend < 
        / 
            precondition  > "0" > 
                <text > Дружище, чи зможеш доглянути за мною, якщо стріляти почнуть? Промідольчику, там, вколоти чи
перев'язку зробити, якщо... </text >
                 <next > 1 </next >
             </phrase >
             <phrase  id = "1" > 
                <text > Немає проблем, звичайно допоможу. </text >
             </phrase >
         </phrase_list >
     </dialog >
 </game_dialogs >
 

Додаємо рядок з ідентифікатором цього діалогу до config\gameplay\character_dialogs.xml :

 
<actor_dialog > actor_will_need_help </actor_dialog >
 

Дописуємо ім'я файлу діалогу в config\system.ltx у розділі dialogs . Залишилося створити функцію i_am_friend . Наш скрипт з моделлю поведінки буде називатися scripts\actor_need_help.script , заодно пропишемо там і діалогові функції.

 
function i_am_friend ( actor,npc ) 
  return npc:relation ( actor ) ==game_object.friend
 end
 

При першому тестуванні я замінив game_object.friend на game_object.neutral , щоб не шукати друзів по всій карті.

Тестуємо, що у нас вийшло...

Діалог працює, але замість тексту - набір значків, виявилося, я написав текст у кодуванні CP866 (DOS) , потрібно поміняти її на CP1251 . Так, тепер текст гаразд.

Вибраний підхід до створення діалогу виявився вдалим.

Зверніть увагу, що замість ідентифікатора тексту можна вписати сам текст. Це ускладнить локалізацію, але зменшить час створення діалогів.

Тепер нам знадобляться функції перевірки наявності аптечок у NPC, перевірки активації схеми поведінки, активації/деактивації схеми поведінки. Додаємо їх у наш скрипт-файл.

Перший варіант скрипту я не наводитиму, щоб не збільшувати і так велику статтю. Остаточний варіант дивіться наприкінці статті. Далі по тексту йде найпростіший варіант.

Тепер у нас має бути два варіанти початкової фрази для активної та неактивної схеми. Прийде експериментувати.

Ось перший перевірений варіант:

 
<?xml  version = "1.0"  encoding = "windows-1251"   
standalone = " yes" ?> <game_dialogs >
     < dialog  id = " 
        actor_will_need_help " > <precondition > actor_need_help.i_am_friend < 
        / 
            precondition  > "0" > 
                <next > 1 </next >
                 <next > 2 </next >
             </phrase >
             <phrase  id = "1" > 
                <text > Дружище, зможеш доглянути мене, якщо стріляти почнуть? Промідольчику, там, вколоти чиперев'язку зробити , 
якщо що... < / text >
                 <precondition > actor_need_help.scheme_is_not_active </precondition >
                 <next > 11 < / 
                next > 12 < / next 
            > <text > Немає проблем, звичайно, допоможу. Вибач , друг , аптечок зовсім не залишилося . _ _ _ _ _ _ _ _ _ _ _ _ _ </text > <precondition > actor_need_help.npc_havent_medkit </precondition > </phrase > <phrase id = "2" > <text > Дякую, друже, тепер я сам впораюся. </text > <precondition > actor_need_help.scheme_is_active </precondition > <next > 21 </next > </phrase > <phrase id = "21" > <text > Та нема за що, ти мені допоміг, я - тобі. </text > <action > actor_need_help.deactivate_scheme </action > </phrase > </phrase_list > </dialog > </game_dialogs >
             
                
                
                
            
             
                
                
            
             
                
                
                
            
             
                
                
            
        
    

 

Під час першого запуску гра вилетіла без повідомлень про помилки. Я уважно переглянув усі файли і виявилося, що у скриптах замість коментаря - (два мінуси) я поставив просто мінус (рекомендую користуватися компілятором з www.lua.org для перевірки коректності скриптів). Після виправлення помилки гра почалася, але діалог так і не з'явився. Невелика дискусія на форумі (дякую ZEN та Arhet) показала, що доведеться зробити два діалоги.

Крім того, при тестах перших варіантів з'ясувалося, що завжди вибирається варіант діалогу з проханням про допомогу. Тобто, схема поведінки не активується.

Як виявилося, як параметри функції передаються не об'єкти ГГ і NPC, а об'єкти персонажа, що говорить в даний момент, і його співрозмовника. Тобто, якщо фраза належить NPC, перший параметр буде об'єктом для NPC, а чи не для ГГ. Тому я змінив назви параметрів та переписав функції.

Отже, усі проблеми вирішено. Файл діалогу набув наступного вигляду ( config\gameplay\dialogs_need_help.xml ):

 
<?xml  version = "1.0"  encoding = "windows-1251"  standalone = "yes"  ?> 
< game_dialogs >
     <dialog  id =
         " actor_will_need_help " > <precondition > actor_need_help.i_am_friend </precondition 
        > < . /precondition >
         <phrase_list >
             <phrase  id = "0" > 
                <text > Дружище, чи зможеш доглянути за мною, якщо стріляти почнуть? Промідольчику, там, вколоти чи
перев'язку зробити, якщо... </text 
                > < next > 11 < /next >
                 <next > 12 < / next >
             < / phrase >
             < phrase  id = "11" 
                > <text > Немає проблем, звичайно, допоможу. Вибач , друже , аптечок зовсім не залишилося . _ _ _ _ _ _ _ _ _ _ _ _ _ </text > </phrase > </phrase_list > < / dialog > < dialog id = "actor_will_not_need_help" > < precondition > actor_need_help.i_am_friend </precondition > < precondition > actor_need_help.scheme_is_active < / = "0" > <text > Дякую, друже, тепер я сам впораюся. </text > <next > 21 </next > </phrase > <phrase id = "21" > <text > Та нема за що, ти мені допоміг, я - тобі. </text > <action > actor_need_help.deactivate_scheme </action > </phrase > </phrase_list > </dialog > </game_dialogs >
                
                
            
             
                
                
            
        
    
     
        
        
        
             
                
                
            
             
                
                
            
        
    

 

Функції, що підтримують роботу діалогу, тепер виглядають так (файл scripts\actor_need_help.script ):

 
function i_am_friend ( talker,target ) 
  return target:relation ( talker ) ==game_object.friend
 end
 
-- За основу цієї функції взято функцію dialogs.actor_have_medkit 
function npc_have_medkit ( talker, target ) 
  return talker:object ( "medkit" ) ~= nil  or 
       talker:object ( "medkit_army" ) ~= nil  or 
       talker:object ( "medkit ) ~= nil 
end 
function npc_havent_medkit ( talker, target ) 
  return  not npc_have_medkit ( talker, target ) 
end
 
-- Оскільки модель поведінки ще не написана, вставимо заглушки 
local scheme_status= { } 
function scheme_is_active ( talker,target ) 
  return scheme_status [ target:id ( ) ] == true --  порівнюємо з true, щоб функція не повертала nil 
end 
function ( talker , target ) 
  return  not scheme_is_active ( talker , target ) 
end 
function activate_scheme ( talker , target ) scheme_status 
  [ talker : id ( ) ] = true 
end 
function deactivate_scheme ( talker , target ) 
  scheme_status [ talker : - привласнюємо nil, щоб звільнити пам'ять, зайняту цим елементом масиву end 

 

І до файлу config\gameplay\character_dialogs.xml додані рядки:

 
<actor_dialog > actor_will_need_help </actor_dialog >
 <actor_dialog > actor_will_not_need_help </actor_dialog >
 

В результаті вийшов діючий діалог, але NPC виглядає просто як ходяча аптечка. В остаточному варіанті я додав деякі «людські» реакції. Та й сама модель поведінки поки що відсутня - замість неї стоять заглушки. Виправимо це.


   
Цитата