Difference between revisions of "Bethesda Tutorial Basic Quest Scripting/ru"

imported>Vitamant
imported>Cyrius
 
(13 intermediate revisions by one other user not shown)
Line 1: Line 1:
{{PageTitle|Квестовое скриптописание}}
{{PageTitle|Квестовое скриптописание}}


{{RussianPage|t}}
{{RussianPage|e}}


{{Tutorial Index/ru
{{Tutorial Index/ru
Line 14: Line 14:
Эта глава посвящена использованию скриптов для продвижения квеста в зависимости от действий игрока. Ранее ты узнал, как использовать скрипты в диалогах. Теперь научишься присоединять их к персонажам и игровым объектам.
Эта глава посвящена использованию скриптов для продвижения квеста в зависимости от действий игрока. Ранее ты узнал, как использовать скрипты в диалогах. Теперь научишься присоединять их к персонажам и игровым объектам.
<br><br>Ты узнаешь:
<br><br>Ты узнаешь:
* Основы структуры скриптов и их присоединение к объектам в Creation Engine
* Основы структуры скриптов и их присоединение к объектам в Creation Engine.
* Как взаимодействовать с событиями при помощи нового скриптового языка
* Как взаимодействовать с событиями при помощи нового скриптового языка.


(Еще проще о скриптах ты можешь прочесть в статье {{ulink|Bethesda_Tutorial_Papyrus_Hello_World/ru|"Hello, World"}}.)
(Еще проще о скриптах ты можешь прочесть в статье {{ulink|Bethesda_Tutorial_Papyrus_Hello_World|"Hello, World"}}.)


=Papyrus=
=Papyrus=
Скриптовый язык, используемый Creation Kit зовется Papyrus (да-да, тот самый папирус, который использовался в качестве бумаги в древнем Египте). Скрипты, написанные на Пупирусе - это обычные текстовые файлы, которые во время выполнения транслируются в байт-код.  
Скриптовый язык, используемый Creation Kit зовется Papyrus (да-да, тот самый папирус, который использовался в качестве бумаги в древнем Египте). Скрипты, написанные на Папирусе - это обычные текстовые файлы, которые компилируются в байт-код.  


{{NewFeature|Новая система похожа на старую TESScript, но требует несколько иного образа мышления. Ты больше не можешь напрямую манипулировать объектами игрового мира; поток твоего скрипта может быть прервана посередине; куча синтаксического сахара, вроде всеми любимых скобок. В общем новый язык стал больше походить на [http://lua.org Lua] или, скажем, [http://python.org Python]. Если ты хорошо ориентируешься в TESScript, то ознакомься с {{ulink|Differences_from_Previous_Scripting|руководством по переходу}}.}}
{{NewFeature|Новая система похожа на старую TESScript, но требует несколько иного образа мышления. Теперь ты не можешь напрямую манипулировать объектами игрового мира; поток твоего скрипта может быть прерван посередине; куча синтаксического сахара, вроде всеми любимых скобок. В общем новый язык стал больше походить на [http://lua.org Lua] или, скажем, [http://python.org Python]. Если ты хорошо ориентируешься в TESScript, то ознакомься с {{ulink|Differences_from_Previous_Scripting|руководством по переходу}}.}}


Перво наперво, ты напишешь скрипт, который будет срабатывать при убийстве вора и соответствующим образом обновлять текущую стадию квеста.
Перво наперво, ты напишешь скрипт, который будет срабатывать при убийстве вора и соответствующим образом обновлять текущую стадию квеста.
Line 31: Line 31:
[[Image:ActorWindowScriptsArea.png|600px]]
[[Image:ActorWindowScriptsArea.png|600px]]


Кликни по кнопке "Add". Редактор немного подумает, после чего отобразит список всех возможных скриптов, которые можно прицепить к этому персонажу. Ты создаешь новый. Дважды щелкни по пункту "[New Script]" в верхней части списка.  
Кликни по кнопке "Add". Редактор немного подумает, после чего отобразит список всех возможных скриптов, которые можно прицепить к этому персонажу. Ты создашь новый. Дважды щелкни по пункту "[New Script]" в верхней части списка.  


[[Image:AddScriptWindow.png]]
[[Image:AddScriptWindow.png]]


Появится еще одно окошко, в котором ты можешь указать имя скрипта. Пиши: "GSQThiefScript" и щелкай по "OK".
Появится еще одно окошко, в котором ты можешь указать имя скрипта. Напиши: "GSQThiefScript" и щелкни по "OK".


[[Image:AddNewScriptWindow.png]]
[[Image:AddNewScriptWindow.png]]
Line 43: Line 43:
[[Image:ScriptAdded.png]]
[[Image:ScriptAdded.png]]


=Properties=
--Правка от Cyrius--
{{Inuse/ru}}
При добавлении скрипта может выпадать такая ошибка -
Double-click on the script name to bring up the Properties Window for this script. On their own, scripts don't know about any objects in the game other than the one to which they're attached. We use properties to hook objects together so they can affect each other. In our example, we want to set GSQ01 to stage 20 when the thief is killed, so we need to tell the script which quest we care about.  
[[file:Troble.png]]
Для ее решения нужно открыть Steam - Инструменты - Creation Kit - Свойства - Локальные файлы.
Нажмите на "Проверить целостность кэша"
Если проверка найдет ошибки - исправит их автоматом и проблема будет решена.
Должно помочь.
 
=Свойства=
Дважды кликни по имени скрипта, чтобы открыть его окно свойств (Properties Window). Сами по себе скрипты "не знают" о прочих объектах в игровом мире, за исключением тех, к которым присоединены. Чтобы поведать скрипту о других объектах, используются свойства. В нашем примере, нужно задать квесту GSQ01 стадию 20, когда вор будет убит, следовательно нужно "рассказать" скрипту, с каким именно квестом он должен взаимодействовать.  


[[File:EmptyPropertiesWindow.png]]
[[File:EmptyPropertiesWindow.png]]


Press the "Add Property" button at the bottom left of this window. This is where we create the property. In the Type field, either choose "Quest" from the pulldown, or type in the word "Quest". Put "TutorialQuest" in the Name field, and leave everything else blank.  
Нажми на кнопку "Add Property" в нижней-левой части окна. Появится окно создания нового свойства. В выпадающем списке Type, укажи тип объекта: "Quest". В качестве имени укажи "TutorialQuest". Все остальные поля оставь пустыми.


[[File:AddScriptPropertyWindow.png]]
[[File:AddScriptPropertyWindow.png]]


We've now told the script that it should care about something called "TutorialQuest," but it doesn't know which quest that is. Click on the property we just made in the list, and click "Edit Value" on the right side of the window. A new pulldown menu will appear, listing all the quests in the game. Choose "GSQ01" from this menu, and hit OK.  
Ты только что сказал скрипту, что ему должен быть известен некий квест, который он будет узнавать по имени "TutorialQuest", но нигде не указал идентификатор этого квеста. Никаких проблем! Щелкни по свойству в списке слева, затем по кнопке "Edit Value" справа и выбери из списка "GSQ01" (как обычно можно набрать часть имени на клавиатуре для быстрого поиска). Затем нажми ОК.


[[File:PropertyWindowFilled.png]]
[[File:PropertyWindowFilled.png]]


=Writing the Script=
=Написание скрипта=
Now that we've added this property, we should add some actual script to do something with it! Right-click on the script name and select "Edit Source" to bring up the script editor.  
Теперь, когда ты добавил свойство, нужно написать сам скрипт, чтобы он его как-то использовал. ПКМ по имени скрипта и из менюшки выбери "Edit Source", чтобы перейти в редактор скриптов.  


[[File:ScriptWindowWithPropertyAdded.png]]
[[File:ScriptWindowWithPropertyAdded.png]]


The top line (<code>Scriptname GSQThiefScript extends ObjectReference</code>) is boilerplate that the editor made for us when we created the script. A few lines below that is the textual version of the property we made.  
Верхняя линия (<code>Scriptname GSQThiefScript extends ObjectReference</code>) создается редактором автоматически при добавлении скрипта. Парой строчек ниже расположено свойство, которое ты только что объявил.


At the bottom of the text, copy and paste the following snippet of code.  
Скопируй нижеследующий фрагмент кода и вставь после уже введенного текста.


<source lang="papyrus">
<source lang="papyrus">
Line 73: Line 80:
</source>
</source>


Once again, ignore the <code>SetObjectiveDisplayed(20)</code>
Опять же, не обращай внимания на строчку <code>SetObjectiveDisplayed(20)</code>


If you're familiar enough with programming or scripting that what you just pasted made sense to you, feel free to skip ahead to the "Scripting the Amulet" section. For everyone else, we'll go through line by line.  
Если с программированием или скриптами ты на короткой ноге и тебе все ясно, как день, можешь пропустить этот отрывок и переходить к разделу "Скрипт для амулета". Если же нет, разберем этот код построчно.


* <code>Event OnDeath(Actor killer)</code>
* <code>Event OnDeath(Actor killer)</code>
** This line declares that the script will respond to the actor dying. When the actor dies, the game will start executing the code from this point. The game will put whoever killed the actor into the "killer" variable, but that part doesn't matter to us.  
** Эта линия говорит, что скрипт будет реагировать на смерть персонажа. Когда он умрет, игра запустит выполнение скрипта с этой строчки. Игра поместит ссылку на убийцу в переменную "killer", но мы не будем усложнять себе жизнь излишними проверками и не станем её использовать.
* <code> TutorialQuest.SetStage(20)</code>
* <code> TutorialQuest.SetStage(20)</code>
** Just like when we called <code>SetStage</code> on the owning quest in the dialogue tutorial, this will set stage 20 on the quest that we set with the TutorialQuest property.  
** Точно также, как и в случае с диалогом просто вызываем <code>SetStage</code>, устанавливая стадию квеста на 20, посредством связи, установленной  свойством TutorialQuest.
** We indent it for readability.  
** Отступы сделаны для лучшей читабельности.  
* <code>EndEvent</code>
* <code>EndEvent</code>
** This signifies the end of our handling of the death event.  
** Конец обработки события.  


Select "Save" from the file menu (or press Ctrl-S) and the editor will attempt to compile your script. An output window will pop up -- if your script is syntactically correct, it will look like this:  
Из меню "File" выбери пункт "Save" (или нажми Ctrl+S). Редактор сохранит и скомпилирует скрипт. Всплывет окно вывода. Если код написан верно, оно будет выглядеть вот так:


[[File:CompilerOutputGood.png]]
[[File:CompilerOutputGood.png]]


If you see anything else in there, you typed something wrong. Try again!  
Если окно вывода не появилось, пустое или содержит сообщения об ошибках - попробуй еще раз!


Once you're done, close the script windows and the actor window, and save your plugin. Now it's time to script the amulet itself.
Как только все нормально скомпилируется, закрой окно скриптов, окно персонажа и сохрани плагин. Пришло время заняться непосредственно амулетом.


=Scripting the Amulet=
=Скрипт для амулета=
Open up the GSQAmulet item we created in [[Bethesda_Tutorial_Creating_an_Item|the last tutorial]]. In the armor window, the scripts area is on the far right.  
Открой настройки амулета GSQAmulet, который ты создал в [[Bethesda_Tutorial_Creating_an_Item|предыдущей главе]]. В открывшемся окне Armor секция скриптов находится в нижнем-правом углу.


[[Image:ArmorWindowScriptArea.png|600px]]
[[Image:ArmorWindowScriptArea.png|600px]]


Create a new script just like we did before, and call it GSQAmuletScript. Add a Quest property to it, but to see a nifty trick, call it "GSQ01" instead of "TutorialQuest" this time.  
Создай новый скрипт, как делал это прежде. Назови его GSQAmuletScript. Добавь свойство типа Quest, как и раньше, но на этот раз назови его "GSQ01", вместо "TutorialQuest", чтобы увидеть...


[[File:AutofilledProperty.png]]
[[File:AutofilledProperty.png]]


It automatically set the value of the property for you, since you gave the property a name that matches an existing ID. If you're declaring a lot of properties, this can save you a bunch of time.  
...как значение свойству будет задано автоматически, так как имя свойства полностью совпало с ID существующего квеста. Если тебе придется объявлять множество свойств, это может сэкономить немного времени.


Open up the script, and we're going to add an event to it. The amulet can't die (obviously), but we do want to know when the player picks it up. Our event script will look like this:  
Открой скрипт. И приступим к созданию нового события. Амулет не может умереть (по крайней мере не так, как вор), да нам это и не нужно. А нужно нам обработать событие, когда амулет попадет в руки игроку. Подобное событие будет выглядеть так:


<source lang="papyrus">
<source lang="papyrus">
Line 115: Line 122:
</source>
</source>


Ignore it once again. It will be explained in the section about objectives.
Да, да, снова эта непонятная функция. Не волнуйся, в следующей главе ты, наконец, узнаешь, что она делает.


There a few things to note in this script:
Итак, разбираем скрипт:
* The parameters in the declaration (<code>newContainer</code> and <code>oldContainer</code>) will get filled in by the game when it tells this script to handle the event.  
* Параметры в объявлении (<code>newContainer</code> и <code>oldContainer</code>) будут заданы игрой, когда произойдет данное событие.
* Because the OnContainerChanged event will fire whenever this object changes hands, we need to make sure we only set the stage when it's the player taking it, hence the <code>if</code>/<code>endif</code> block.  
* Поскольку событие OnContainerChanged вызывается всякий раз, когда объект меняет владельца (н.п. кладется в сундук), необходимо проверить, что это именно игрок взял амулет. Для этого мы используем блок условий <code>if</code>/<code>endif</code> (если..., то...).
* <code>Game.GetPlayer()</code> is a convenient way to get a reference to the player without needing to set a property, and <code>newContainer</code> was filled by the engine when this event fired, so we can do a comparison in the second line to make sure the item is moving into the player.  
* Функция <code>Game.GetPlayer()</code> вернет ссылку на игрока. Объявлять его в качестве свойства нет необходимости, а в параметре <code>newContainer</code> будет ссылка на новый контейнер, в котором содержится предмет. Соответственно, если обе ссылки равны, значит новым контейнером стал инвентарь игрока.  
* The way this script is written, SetStage will be called every time the player picks up the amulet. This doesn't matter because each quest stage can only happen once - calling SetStage(30) has no effect after the first time.
* И, если условие выполняется, мы задаем новую стадию квеста - 30. Если ты внимателен и хоть что-нибудь из этого понял, то можешь догадаться, что стадия квеста будет задаваться всякий раз, когда игрок получает амулет. Никогда так не делай в настоящих проектах. Событие, происходящее один раз, должно происходить один раз. Даже если у игрока есть возможность выложить квестовый предмет или вовсе его потерять, нужно продумать все подобные варианты, так что бы задание новой стадии не привело к невозможности завершить квест (н.п. повторная его выдача, когда квестодатель уже мертв и не может получить свое имущество) или его зацикливанию. Но в нашем примере это не имеет значения, так как дальнейшее развитие сюжета предопределено - ты отдашь Бенду амулет и больше его никогда не получишь.


This script is also good to go, then. Close the script and armor windows, and save your plugin.  
Скрипт написан. Сохрани его, закрой окно Armor и сохрани плагин.


You can now play through the quest from start to finish, checking the console with [[ShowQuestVars|SQV]] to see its stage changing.  
Теперь квест можно начать, выполнить и закончить. Используй консольную команду {{ulink|ShowQuestVars|SQV}} чтобы увидеть, как изменяются стадии задания.


Players can't use the console, though, so we'll learn how to give them better feedback about the quest in the next chapter.  
Но, в отличии от нас, игроки не будут пользоваться консолью, да и эти цифры им ничего не скажут, поэтому в следующей главе мы узнаем, как организовать более дружелюбный вывод подобной информации.


{{ProTip|The scripts for Skyrim are just text files that live in your data directory before they get compiled into bytecode. This means that if you've got a favorite text editor, you can use it to work on scripts. We've included setups for both [[Sublime Text Setup|Sublime Text]] and [[Notepad++ Setup|Notepad++]] that provide syntax highlighting, some basic autocompletion, and compilation shortcuts. If you're going to get heavily into scripting, these tools can make your life a lot easier.}}
{{ProTip|Скрипты в Skyrim - это просто текстовые файлы хранящиеся в каталоге data перед компиляцией в байт-код. Это позволяет использовать для их редактирования любые текстовые редакторы, которые вам нравятся. Ты можешь прочитать про настройку {{ulink|Sublime Text Setup|Sublime Text}} и {{ulink|Notepad++ Setup|Notepad++}}, которые позволяют включить подсветку синтаксиса, поддерживают некоторые функции автозавершения и горячие кнопки для компиляции. При написании больших сложных скриптов, эти инструменты существенно облегчат тебя жизнь!}}


{{Tutorial_Bottom_Bar/ru
{{Tutorial_Bottom_Bar/ru
|Prev=Bethesda_Tutorial_Creating_an_Itemru
|Prev=Bethesda_Tutorial_Creating_an_Item/ru
|Next=Bethesda_Tutorial_Quest_Objectives/ru
|Next=Bethesda_Tutorial_Quest_Objectives/ru
}}
}}
Anonymous user