SoC. Создание квестов (базовый уровень) — различия между версиями — S.T.A.L.K.E.R. Inside Wiki

SoC. Создание квестов (базовый уровень) — различия между версиями

Материал из S.T.A.L.K.E.R. Inside Wiki

Перейти к: навигация, поиск
м (category)
Строка 8: Строка 8:
 
- старайтесь почаще тестировать внесенные изменения - так проще понять, в чем вы ошиблись (если активно работать пару часов без остановки, не разу не протестировав внесенные изменения, то потом будет очень сложно понять - почему же, черт возьми, игра вылетает при попытке поговорить с Сидоровичем?)
 
- старайтесь почаще тестировать внесенные изменения - так проще понять, в чем вы ошиблись (если активно работать пару часов без остановки, не разу не протестировав внесенные изменения, то потом будет очень сложно понять - почему же, черт возьми, игра вылетает при попытке поговорить с Сидоровичем?)
 
- перед началом работы создайте новую папку gamedata, а свои моды спрячьте подальше: работать с "чистой" версией игры не в пример удобнее и проще; особенно противопоказан Repair Mod, который с новыми диалогами часто конфликтует. О том, как создать диалоги и квесты, исключающие возможность конфликта с другими подобными модами, см. часть 4.
 
- перед началом работы создайте новую папку gamedata, а свои моды спрячьте подальше: работать с "чистой" версией игры не в пример удобнее и проще; особенно противопоказан Repair Mod, который с новыми диалогами часто конфликтует. О том, как создать диалоги и квесты, исключающие возможность конфликта с другими подобными модами, см. часть 4.
 +
  
 
==Создание базового диалога==
 
==Создание базового диалога==
Строка 13: Строка 14:
 
Начнем создание квеста с написания небольшого линейного диалога.
 
Начнем создание квеста с написания небольшого линейного диалога.
  
Открываем файл gamedata\config\gameplay\character_desc_escape.xml и проводим такие манипуляции:
+
Открываем файл '''gamedata\config\gameplay\character_desc_escape.xml''' и проводим такие манипуляции:
  
- находим строку "<actor_dialog>escape_trader_done_blockpost_box</actor_dialog>"
+
- находим строку '''<actor_dialog>escape_trader_done_blockpost_box</actor_dialog>'''
- добавляем после нее новую - "<actor_dialog>escape_trader_oops</actor_dialog>"
+
- добавляем после нее новую - '''<actor_dialog>escape_trader_oops</actor_dialog>'''
 
- сохраняем изменения
 
- сохраняем изменения
  
Мы добавили к Диалогу с Сидоровичем новую ветку, вернее, только ссылку на неё. Сама внутренняя структура ветки хранится в файле gamedata\config\gameplay\dialogs_escape.xml, который мы открываем и производим:
+
Мы добавили к Диалогу с Сидоровичем новую ветку, вернее, только ссылку на неё. Сама внутренняя структура ветки хранится в файле '''gamedata\config\gameplay\dialogs_escape.xml''', который мы открываем и производим:
  
- находим в любом месте файла промежуток между </dialog> и <dialog id="...">
+
- находим в любом месте файла промежуток между '''</dialog>''' и '''<dialog id="...">'''
 
- засовываем туда такую конструкцию:
 
- засовываем туда такую конструкцию:
  
<xml> <dialog id="escape_trader_oops">
+
<xml>
 +
<dialog id="escape_trader_oops">
 
         <precondition>escape_dialog.trader_alredy_give_job</precondition>
 
         <precondition>escape_dialog.trader_alredy_give_job</precondition>
 
         <has_info>tutorial_end</has_info>
 
         <has_info>tutorial_end</has_info>
Строка 49: Строка 51:
 
- сохраняем изменения
 
- сохраняем изменения
  
Теперь у нас прописана структура новой ветки диалога. Осталось сделать еще одну вещь - прописать строки, которые будут отображаться вместо "escape_trader_oops_...".
+
Теперь у нас прописана структура новой ветки диалога. Осталось сделать еще одну вещь - прописать строки, которые будут отображаться вместо '''escape_trader_oops_...'''.
  
Для этого откроем файл gamedata\config\text\rus\stable_dialogs_escape.xml и сделаем следующее:
+
Для этого откроем файл '''gamedata\config\text\rus\stable_dialogs_escape.xml''' и сделаем следующее:
  
- находим любой удобный промежуток между </string> и <string id="...">
+
- находим любой удобный промежуток между '''</string>''' и '''<string id="...">'''
 
- прописываем туда следующие строки:
 
- прописываем туда следующие строки:
  
Строка 81: Строка 83:
 
==Создание базового квеста==
 
==Создание базового квеста==
  
Активацию квеста в диалог прикрепить достаточно просто. Проводим с файлом gamedata\config\gameplay\ dialogs_escape.xml следующие манипуляции:
+
Активацию квеста в диалог прикрепить достаточно просто. Проводим с файлом '''gamedata\config\gameplay\dialogs_escape.xml''' следующие манипуляции:
  
- добавляем содержимое фразы <phrase id="2"> следующим:
+
- добавляем содержимое фразы '''<phrase id="2">''' следующим:
  
 
<xml>  
 
<xml>  
Строка 97: Строка 99:
 
Теперь после фразы Меченого "Да сбегаю я сейчас, сбегаю..." Сидорович таки всучивает нам квест "Принеси водку". Но не спешите тестировать изменения. Мы добавили в диалог упоминание о квесте, хотя он еще не создан.
 
Теперь после фразы Меченого "Да сбегаю я сейчас, сбегаю..." Сидорович таки всучивает нам квест "Принеси водку". Но не спешите тестировать изменения. Мы добавили в диалог упоминание о квесте, хотя он еще не создан.
  
Исправим это недоразумение. Откройте файл gamedata\config\gameplay\tasks_escape.xml и в начале файла создайте такую конструкцию:
+
Исправим это недоразумение. Откройте файл '''gamedata\config\gameplay\tasks_escape.xml''' и в начале файла создайте такую конструкцию:
  
 
<xml>
 
<xml>
Строка 125: Строка 127:
 
К этому файлу мы еще вернемся, т.к. в этом варианте многое проставлялось не иначе как от балды. Я еще подумаю, как заставить задание "Вернуться с водкой обратно" появиться в PDA, а то оно что-то не желает явить себя народу... впрочем, ладно, главное, что все работает и не вылетает. А исправление столь мелких багов - дело десятое. Продолжим.
 
К этому файлу мы еще вернемся, т.к. в этом варианте многое проставлялось не иначе как от балды. Я еще подумаю, как заставить задание "Вернуться с водкой обратно" появиться в PDA, а то оно что-то не желает явить себя народу... впрочем, ладно, главное, что все работает и не вылетает. А исправление столь мелких багов - дело десятое. Продолжим.
  
Откроем файл gamedata\config\gameplay\info_l01escape.xml и зарегистрируем до того отсутствовавшие в игре типы условий (они нам еще пригодятся для завершения работы над квестом):
+
Откроем файл '''gamedata\config\gameplay\info_l01escape.xml''' и зарегистрируем до того отсутствовавшие в игре типы условий (они нам еще пригодятся для завершения работы над квестом):
  
- после строки <game_information_portions> прописываем:
+
- после строки '''<game_information_portions>''' прописываем:
  
 
<xml>
 
<xml>
Строка 143: Строка 145:
 
Теперь займемся одной небольшой, но нужной вещью - прописыванием экранных подсказок, которые высвечиваются при получении/выполнении этапа/завершении задания.
 
Теперь займемся одной небольшой, но нужной вещью - прописыванием экранных подсказок, которые высвечиваются при получении/выполнении этапа/завершении задания.
  
Для этого откроем файл gamedata\config\text\rus\string_table_tasks_escape.xml и пропишем там:
+
Для этого откроем файл '''gamedata\config\text\rus\string_table_tasks_escape.xml''' и пропишем там:
  
 
<xml>
 
<xml>
Строка 188: Строка 190:
 
'''8.''' Ну тебя в пень... ( конец, переход к списку веток Сидоровича )
 
'''8.''' Ну тебя в пень... ( конец, переход к списку веток Сидоровича )
  
А вот так это будет выглядеть в файле gamedata\config\gameplay\dialogs_escape.xml:
+
А вот так это будет выглядеть в файле '''gamedata\config\gameplay\dialogs_escape.xml''':
  
 
<xml>
 
<xml>
Строка 243: Строка 245:
 
</xml>
 
</xml>
  
Теперь добавим в игру скрипты "передача денег" и "передача водки". Откройте файл gamedata\scripts\escape_dialog.script и перед разделителем "Trader" добавьте туда следующие строки:
+
Теперь добавим в игру скрипты "передача денег" и "передача водки". Откройте файл '''gamedata\scripts\escape_dialog.script''' и перед разделителем '''Trader''' добавьте туда следующие строки:
  
<pre>
+
<lua>
 
function transfer_deneg(first_speaker, second_speaker)
 
function transfer_deneg(first_speaker, second_speaker)
 
     dialogs.relocate_money(second_speaker, 4000, "in")
 
     dialogs.relocate_money(second_speaker, 4000, "in")
Строка 257: Строка 259:
 
     return stalker:object ("vodka") ~= nil
 
     return stalker:object ("vodka") ~= nil
 
end
 
end
</pre>
+
</lua>
  
 
Готово. Запускайте игру и любуйтесь.
 
Готово. Запускайте игру и любуйтесь.
Строка 268: Строка 270:
 
Из-за чего наш мод не может работать вместе с аналогичными ему модами? Да потому, что файлы dialogs_escape.xml и некоторые другие у них пересекаются. Поэтому выделим их отдельно от основных диалогов:
 
Из-за чего наш мод не может работать вместе с аналогичными ему модами? Да потому, что файлы dialogs_escape.xml и некоторые другие у них пересекаются. Поэтому выделим их отдельно от основных диалогов:
  
Вместо dialogs_escape.xml мы будем испольховать новый - dialogs_new.xml
+
Вместо '''dialogs_escape.xml''' мы будем испольховать новый - '''dialogs_new.xml'''.
Вместо stable_dialogs_escape.xml мы будем использовать файл stable_dialogs_new.xml (важно! не знаю почему, но он должен лежать в text\..., а не в text\rus\...)
+
Вместо '''stable_dialogs_escape.xml''' мы будем использовать файл '''stable_dialogs_new.xml''' (важно! не знаю почему, но он должен лежать в '''text\...''', а не в '''text\rus\...)'''.
  
 
Соответственно, весь реализованный нами новый контент перекидываем в пустые файлы (соблюдая форматирование), подчистив за собой на старом месте.
 
Соответственно, весь реализованный нами новый контент перекидываем в пустые файлы (соблюдая форматирование), подчистив за собой на старом месте.
Строка 277: Строка 279:
 
Остальные файлы относятся уже к квестовой части и ни с чем пересекаться не могут - где вы видели другие моды с новыми квестами? Я - нет.
 
Остальные файлы относятся уже к квестовой части и ни с чем пересекаться не могут - где вы видели другие моды с новыми квестами? Я - нет.
  
Откройте файл gamedata\config\localization.ltx и зарегистрируйте там stable_dialogs_escape.ltx.
+
Откройте файл '''gamedata\config\localization.ltx''' и зарегистрируйте там '''stable_dialogs_escape.ltx'''.
Потом откройте файл gamedata\config\system.ltx и в разделе "Dialogs" в конце строки (после dialogs_aes) пропишите dialogs_new (без ".ltx"!).
+
Потом откройте файл '''gamedata\config\system.ltx''' и в разделе '''Dialogs''' в конце строки (после '''dialogs_aes''') пропишите '''dialogs_new''' (без '''.ltx'''!).
  
 
Все. Теперь ваши диалоги будут подгружаться из сторонних файлов.
 
Все. Теперь ваши диалоги будут подгружаться из сторонних файлов.
Строка 314: Строка 316:
 
[[Участник:BAC9-FLCL|BAC9-FLCL]]
 
[[Участник:BAC9-FLCL|BAC9-FLCL]]
  
[[Категория:Скрипты]]
+
[[Категория:Конфигурационные файлы]]

Версия 12:04, 17 января 2011

Вступление

Перед изучением этого урока советую освоить находящийся несколько выше урок "Создание диалогов".

Небольшие правила, следуя которым, можно сберечь себе много нервов:

- всегда сохраняйте резервные копии модифицируемых файлов - старайтесь почаще тестировать внесенные изменения - так проще понять, в чем вы ошиблись (если активно работать пару часов без остановки, не разу не протестировав внесенные изменения, то потом будет очень сложно понять - почему же, черт возьми, игра вылетает при попытке поговорить с Сидоровичем?) - перед началом работы создайте новую папку gamedata, а свои моды спрячьте подальше: работать с "чистой" версией игры не в пример удобнее и проще; особенно противопоказан Repair Mod, который с новыми диалогами часто конфликтует. О том, как создать диалоги и квесты, исключающие возможность конфликта с другими подобными модами, см. часть 4.


Создание базового диалога

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

Открываем файл gamedata\config\gameplay\character_desc_escape.xml и проводим такие манипуляции:

- находим строку <actor_dialog>escape_trader_done_blockpost_box</actor_dialog> - добавляем после нее новую - <actor_dialog>escape_trader_oops</actor_dialog> - сохраняем изменения

Мы добавили к Диалогу с Сидоровичем новую ветку, вернее, только ссылку на неё. Сама внутренняя структура ветки хранится в файле gamedata\config\gameplay\dialogs_escape.xml, который мы открываем и производим:

- находим в любом месте файла промежуток между </dialog> и <dialog id="..."> - засовываем туда такую конструкцию:

 
 <dialog id="escape_trader_oops">
        <precondition>escape_dialog.trader_alredy_give_job</precondition>
        <has_info>tutorial_end</has_info>
        <phrase_list>
<phrase id="0">
<text>escape_trader_oops_0</text>
<next>1</next>
</phrase>
<phrase id="1">
<text>escape_trader_oops_1</text>
<next>2</next>
</phrase>
<phrase id="2">
<text>escape_trader_oops_2</text>
<next>1</next>
</phrase>
<phrase id="3">
<text>escape_trader_oops_3</text>
</phrase>
</phrase_list>
</dialog>
 

- сохраняем изменения

Теперь у нас прописана структура новой ветки диалога. Осталось сделать еще одну вещь - прописать строки, которые будут отображаться вместо escape_trader_oops_....

Для этого откроем файл gamedata\config\text\rus\stable_dialogs_escape.xml и сделаем следующее:

- находим любой удобный промежуток между </string> и <string id="..."> - прописываем туда следующие строки:

 
<string id="escape_trader_oops_0">
		<text>Сидрыч, давай поговорим о... водке.</text>
	</string>
	<string id="escape_trader_oops_1">
		<text> водке? Да какая водка? Нет её у меня, кончилась. Вроде у Волка на чердаке была, что-то он
однажды об этом упоминал... Принеси, а?</text>
 
	</string>
	<string id="escape_trader_oops_2">
		<text>Да сбегаю я сейчас, сбегаю... алкоголик, блин.</text>
	</string>
	<string id="escape_trader_oops_3">
		<text>Беги, беги... сил уж нет ждать.</text>
	</string>
 

- сохраняем изменения

Всё. Диалог готов. Можно грузить игру и смотреть, работает ли новая ветка. А теперь будем прикреплять к этому безобразию квест ""Принеси водки Сидоровичу".


Создание базового квеста

Активацию квеста в диалог прикрепить достаточно просто. Проводим с файлом gamedata\config\gameplay\dialogs_escape.xml следующие манипуляции:

- добавляем содержимое фразы <phrase id="2"> следующим:

 
<phrase id="2">
<text>escape_trader_oops_2</text>
<give_info>kvest_vodka_started</give_info>
<next>3</next>
                     </phrase>
 

- сохраняем изменения

Теперь после фразы Меченого "Да сбегаю я сейчас, сбегаю..." Сидорович таки всучивает нам квест "Принеси водку". Но не спешите тестировать изменения. Мы добавили в диалог упоминание о квесте, хотя он еще не создан.

Исправим это недоразумение. Откройте файл gamedata\config\gameplay\tasks_escape.xml и в начале файла создайте такую конструкцию:

 
<game_task id="esc_test_vodka_task">
        	<title>Принести водки</title> <!-- заголовок квеста -->
        	<objective>
            		<text>Принести водки Сидоровичу</text>
            		<icon>ui_iconsTotal_find_item</icon>
            		<infoportion_complete>test_quest_vodka_otdana</infoportion_complete>        	</objective>
        	<objective>
            		<text>Вернуться с водкой обратно</text> 
            		<map_location_type hint="esc_dinamit_to_volk">green_location</map_location_type> 
            		<object_story_id>Escape_novice_lager_volk</object_story_id>
            		<infoportion_complete>test_quest_vodka_otdana</infoportion_complete>
        	</objective>
        	<objective>
            		<text>Найти водку на чердаке</text>
            		<map_location_type hint="escape_trader">blue_location</map_location_type>
            		<object_story_id>Escape_Trader</object_story_id>
            		<infoportion_complete>test_quest_vodka_otdana</infoportion_complete>
        	</objective>
</game_task>
 

Мы прописали данные о квесте: название, иконку, строки заданий, расположение маркеров и т.д.

К этому файлу мы еще вернемся, т.к. в этом варианте многое проставлялось не иначе как от балды. Я еще подумаю, как заставить задание "Вернуться с водкой обратно" появиться в PDA, а то оно что-то не желает явить себя народу... впрочем, ладно, главное, что все работает и не вылетает. А исправление столь мелких багов - дело десятое. Продолжим.

Откроем файл gamedata\config\gameplay\info_l01escape.xml и зарегистрируем до того отсутствовавшие в игре типы условий (они нам еще пригодятся для завершения работы над квестом):

- после строки <game_information_portions> прописываем:

 
<info_portion id="test_quest_vodka_otdana"></info_portion>
 
<info_portion id="kvest_vodka_started">
<task>esc_test_vodka_task</task>
</info_portion>
 
<info_portion id="otkazalsya_prinesty_vodku"></info_portion>
 

С прописыванием условий - всё.

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

Для этого откроем файл gamedata\config\text\rus\string_table_tasks_escape.xml и пропишем там:

 
    <string id="esc_test_prinesti_vodku">
        <text>Принести бутылку водки</text>
    </string>
    <string id="esc_test_prinesti_vodku_1">
        <text>Найти водку на чердаке у Волка</text>
    </string>
    <string id="esc_test_prinesti_vodku_2">
        <text>Принести водку Сидоровичу</text>
    </string>
 

Теперь можно тестировать, что получилось. Сверяем результаты:

- по окончанию разговора про водку у вас появляется новое задание - в задании маркером отмечен Волк (ближайший к чердаку маркер, потому и отмечен) - при получении задания на экране высвечивается уведомление

Можно приступать к третьей стадии. Что мы забыли? Правильно - возможность выполнить квест.


Реализация возможности выполнить квест

На самом деле - все просто. Все условия и т.д. уже нами созданы, осталось только применить их в диалоге. Давайте несколько изменим его структуру, сделаем его ветвистым и функциональным:

0. Сидрыч, давай поговорим о... водке. ( переход к 1)

1. О водке? Да какая водка? Нет её у меня, кончилась. Вроде у Волка на чердаке была, что-то он однажды об этом упоминал... Принеси, а? ( выбор - переход к 2, 4, 5; изначально доступен только 2 вариант )

2. Да сбегаю я сейчас, сбегаю... алкоголик, блин. ( получение квеста, переход к 3, после этого перестает быть доступен )

3. Беги, беги... сил уж нет ждать. ( конец, переход к списку веток Сидоровича )

4. Вот она, твоя бутылка водки. Ну, вернее, не твоя, а Волка... ( появляется только при наличии водки в инвентаре, при выборе водка передается Сидоровичу, квест выполняется, идет переход к 7 )

5. Извини, Сидрыч, я пока еще не раздобыл, терпи... ( появляется только если взять квест, переход к 6 )

6. А ну марш отсюда! Без бутылки пришел... ууу, вражина... ( переход к 8 )

7. Теперь моя будет, Меченый! Ты так Волку и передай. Спасибо, выручил... держи награду. ( выдача награды, переход к 8 )

8. Ну тебя в пень... ( конец, переход к списку веток Сидоровича )

А вот так это будет выглядеть в файле gamedata\config\gameplay\dialogs_escape.xml:

 
<dialog id="escape_trader_oops">
        <precondition>escape_dialog.trader_alredy_give_job</precondition>
        <has_info>tutorial_end</has_info>
        <phrase_list>
                     <phrase id="0">
                             	<text>escape_trader_oops_0</text>
                              	<next>1</next>
                     </phrase>
                     <phrase id="1">
                               	<text>escape_trader_oops_1</text>
                                <next>2</next>
				<next>4</next>
				<next>5</next>
                     </phrase>
                     <phrase id="2">
				<dont_has_info>kvest_vodka_started</dont_has_info>
                                <text>escape_trader_oops_2</text>
				<give_info>kvest_vodka_started</give_info>
                                <next>3</next>
                     </phrase>
                     <phrase id="3">
                                <text>escape_trader_oops_3</text>
				<action>dialogs.break_dialog</action>
                     </phrase>
		     <phrase id="4">
                             	<text>escape_trader_oops_4</text>
				<precondition>escape_dialog.have_a_vodka</precondition>
				<action>escape_dialog.otday_vodku</action>
                              	<next>7</next>
		     </phrase>
		     <phrase id="5">
				<has_info>kvest_vodka_started</has_info>
                             	<text>escape_trader_oops_5</text>
                              	<next>6</next>
		     </phrase>
		     <phrase id="6">
                             	<text>escape_trader_oops_6</text>
                              	<next>8</next>
		     </phrase>
		     <phrase id="7">
                             	<text>escape_trader_oops_7</text>
				<give_info>test_quest_vodka_otdana</give_info>
				<action>escape_dialog.transfer_deneg</action>
                              	<next>8</next>
		     </phrase>
		     <phrase id="8">
                             	<text>escape_trader_oops_8</text>
		     </phrase>
        </phrase_list>
    </dialog>
 

Теперь добавим в игру скрипты "передача денег" и "передача водки". Откройте файл gamedata\scripts\escape_dialog.script и перед разделителем Trader добавьте туда следующие строки:

 
function transfer_deneg(first_speaker, second_speaker)
    dialogs.relocate_money(second_speaker, 4000, "in")
end
 
function otday_vodku (npc, actor)
    dialogs.relocate_item_section(npc, "vodka", "out")
end
 
function have_a_vodka (stalker, player)
    return stalker:object ("vodka") ~= nil
end
 

Готово. Запускайте игру и любуйтесь.

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


Реализация совместимости

Из-за чего наш мод не может работать вместе с аналогичными ему модами? Да потому, что файлы dialogs_escape.xml и некоторые другие у них пересекаются. Поэтому выделим их отдельно от основных диалогов:

Вместо dialogs_escape.xml мы будем испольховать новый - dialogs_new.xml. Вместо stable_dialogs_escape.xml мы будем использовать файл stable_dialogs_new.xml (важно! не знаю почему, но он должен лежать в text\..., а не в text\rus\...).

Соответственно, весь реализованный нами новый контент перекидываем в пустые файлы (соблюдая форматирование), подчистив за собой на старом месте.

Единственное, что останется сделать после установки того же Repair Mod'а - заново добавить ветку диалога Сидоровичу в файле character_desc_escape.xml. Остальное в новом варианте нашего мода переписывать не придется - для диалогов отведено три файла.

Остальные файлы относятся уже к квестовой части и ни с чем пересекаться не могут - где вы видели другие моды с новыми квестами? Я - нет.

Откройте файл gamedata\config\localization.ltx и зарегистрируйте там stable_dialogs_escape.ltx. Потом откройте файл gamedata\config\system.ltx и в разделе Dialogs в конце строки (после dialogs_aes) пропишите dialogs_new (без .ltx!).

Все. Теперь ваши диалоги будут подгружаться из сторонних файлов.


Отдельное спасибо:

XiaNi - за страшный и непричесанный, но работающий пример квеста, на основе которого я и освоил принципы квестостроения =)

Keha – за урок по созданию новых диалогов

Дополнения

1. Если изменить шапку нашего диалога в файле dialogs_escape.xml со старого варианта на такой, то ветка исчезнет после выполнения задания:

 
<dialog id="escape_trader_oops">
        <precondition>escape_dialog.trader_alredy_give_job</precondition>
        <has_info>tutorial_end</has_info>
<dont_has_info>test_quest_vodka_otdana</dont_has_info>
          <phrase_list>
 

...

Не тестировал. Дело за вами =)

Фух, вроде всё... Всем спасибо, занавес =)

Авторы

Статья создана: BAC9-FLCL

Другие места
LANGUAGE