Основы скриптинга в Skyrim или разрываем ткань Обливиона
Guten Abend, meine liebe Genossen и сегодня очередная часть "повествования" о том, как идет процесс "подгонки" Скайрима под мои нужды.
И, прежде чем продолжить, хотелось бы обратиться к новым подписчикам, которые успели появиться с момента выхода прошлой части:
Товарищи, мне не известно, насколько вам интересны мои публикации. Если вы подписались потому, что вам интересен мой контент - спасибо и добро пожаловать, я всегда рад новым "целевым" подписчикам.
Однако, иногда бывает так, что подписывается совершенно случайный человек, который "оказался рядом", увидев, к примеру, мой комментарий в совершенно стороннем посте. Если вы - один из таких, убедительная просьба - не ставьте минусов публикациям лишь по той причине, что их содержание не пересекается с вашими интересами. Поверьте, это не только нагоняет тоску, но и отбивает всякое желание дальше публиковать что-то.
А теперь мы продолжаем. Как вы уже успели заметить из моих предыдущих постов - я медленно, но, верно, делаю дом игрока на манер локации "Туманная роща".
Обливион - это не пещера, не дом и не замок. Простому смертному туда не попасть через дверь. Разорвать ткань Обливиона могут лишь те, кто познал мастерство магии.
Блин, да кому вообще интересен весь этот напыщенный пафос? В общем, господа, сегодня мы будем делать заклинание, которое будет телепортировать игрока в локацию и обратно. Причем не абы как, а с сохранением исходной точки! Откуда ушли, туда и пришли. А в этом нам поможет Папирус - скриптовый язык Скайрима.
Итак, начнем с простого. У нас уже имеется так называемый COCMarkerHeading, вот его и задействуем. Для тех, кто далек от этой темы - данный маркер обозначает место, в которое игрок будет телепортирован при использовании консольной команды "сос имялокации". К слову, в обычных помещениях используются схожие маркеры, определяющие, где окажется игрок после прохождения через дверь.
Также для для реализации данной задумки понадобится вспомогательная локация. Для чего она нужна? Чтобы не плодить мусор в основной локации, все объекты, которые задействованы в работе, отправляются в неё.
Таковая у меня уже имеется. В неё мы помещаем так называемый XMarkerHeading, и переименовываем в MGHMarkTeleport - так нам будет удобнее. Для чего он нужен? Об этом расскажу ниже. Также в этой локации можно заметить кучу суровых нордских мужичков - это NPC которые необходимы для нормального функционирования плодородной земли - каждая "грядка" ссылается на своего NPC. 30 посадочных мест - 30 немытых нордов. И, собственно, наш маркер:
Топаем в раздел Magic - Spell. Тут хранятся все имеющиеся заклинания. Создаем новое. Вписываем ID, имя, временный placeholder для описания, а также назначаем эффект.
Стоп, что? Какой эффект?
Ах, да, все заклинания устроены весьма интересным образом.
Spell - заклинание, которое появляется, собственно, в разделе заклинаний.
При чтении заклинания активируется привязанный эффект. Этот самый эффект и надо будет создать. Для этого топаем в Magic - Magic Effect и создаем новый. Видим кучу всего непонятного:
На самом деле, всё довольно понятно.
ID - собственно, ID.
Name - пока не разобрался, замещено placeholderom, потом глянем, где всплывет.
Effect Archetype - выставлено "Скрипт". Это значит, что магический эффект сам не будет делать ничего, а отдаст эту обязанность скрипту.
Casting type - "Выстрелил и забыл". И ежу понятно - один раз прочитали, скрипт активировался и всё. После этого можно читать еще раз.
Delivery - v subbotu указывает, на кого применяется результат заклинания - на цель, или же на себя.
Magic Skill - колдовство. Отвечает за сортировку - в какой вкладке будет заклинание.
Minimum Skill Level - пока не разобрался, что это и на что влияет.
Так, что дальше...
Визуальные эффекты - подглядываем в какое-нибудь готовое заклинание и повторяем. Собственно, это и есть визуальные эффект - для огненного шторма будут эффекты огня, для ледяного лед, у нас же эффекты призыва.
Звуки - они и в Африке звуки.
А теперь самое интересное - скрипт!
Добавляется он кнопочкой Add, что справа внизу.
Но, для начала, давайте разберемся с логикой работы скрипта.
Вот, собственно, и он сам. Кому надо - забирайте.
Scriptname MGHScriptTeleport extends ActiveMagicEffect
ObjectReference Property Marker Auto
ObjectReference Property Mark Auto
Cell Property TargetCell Auto
{TargetCell is name for your cell}
Event OnEffectStart(Actor Caster, Actor Target)
If Caster.GetParentCell() != TargetCell
Utility.Wait(1.0)
Mark.MoveTo(Caster)
Caster.MoveTo(Marker)
Else
Utility.Wait(1.0)
Caster.MoveTo(Mark)
EndIf
EndEvent
Что это вообще такое? Ну, если понимать что к чему, то всё довольно понятно:
Scriptname - служебная фраза, обозначает начало скрипта.
MGHScriptTeleport - имя скрипта.
extends - служебная фраза. Дословно - "Расширяет" или же "Основывается"
extends ActiveMagicEffect - основывается на "Родителе" ActiveMagicEffect
А теперь немного логики. Вот как работает скрипт:
Для начала мы объявим "свойства":
ObjectReference Property Marker Auto
ObjectReference Property Mark Auto
Cell Property TargetCell Auto
Что есть свойства? Свойства позволяют использовать один скрипт множество раз.
К примеру, я хочу сделать два заклинания - первое телепортирует в первый дом, а второе - во второй.
Тогда бы мне пришлось писать два разных скрипта:
Игрок.ТелепортироватьВ - Дом_1
Игрок.ТелепортироватьВ - Дом_2
Через свойства это можно сделать одним скриптом:
Игрок.ТелепортироватьВ - СвойствоДом
И после этого уже сделать два заклинания и каждому сослаться:
СвойствоДом = Дом_1
СвойствоДом = Дом_2
Не понятно, да? Ладно, продолжим.
Предположим, игрок стоит в Вайтране и читает скрипт первый раз, дабы перенестись в локацию.
"Стоит в Вайтране" - то есть, стоит где угодно, но не в конечной локации.
Для того, чтобы проверить это условие, впишем строку:
If Caster.GetParentCell() != TargetCell
Иными словами:
Если:
ПозицияИгрока НеРавна СвойствоЛокация - вот тут просто ссылаемся на нашу локацию, а не жестко прописываем её имя.
То:
Utility.Wait(1.0) - подождать одну секунду, дабы сперва мы увидели графический эффект от чтения заклинания.
Mark.MoveTo(Caster) - "Метка" - тот самый маркер MGHMarkTeleport, который находился ранее во вспомогательной локации и на который мы ссылаемся в свойствах, передвигается на место игрока. Всё! Метка размещена и игра помнит, где она находится!
Caster.MoveTo(Marker) - Заклинатель, то есть игрок, перемещается на место, где расположен другой маркер - COCMarkerHeading, то есть, который расположен в основной локации и при перемещении на него, игрок перемещается в локацию.
С этим всё! Но, помните строчку?
"Стоит в Вайтране" - то есть, стоит где угодно, но не в конечной локации.
Но что, если игрок оказался в конечной локации? А это значит, что он уже прочитал заклинание в первый раз и оказался в конечной локации. А теперь хочет прочитать его второй раз и отправить обратно. Туда, где расположен маркер.
Эту работу осуществляет всё та же строчка кода:
If Caster.GetParentCell() != TargetCell
А нужный код помещает под условием Иначе
Utility.Wait(1.0) - ждем секунду
Caster.MoveTo(Mark) - игрок перемещается обратно на метку, которая расположилась в месте первого чтения заклинания и ждет не дождется, когда когда мы на неё вернемся.
EndIf - конец цикла "Если/То/Иначе"
EndEvent - конец кода (события, вообще-то - это немного другое)
Всё!
Ничего не понятно, да?
Ладно, попробую рассказать это всё нормальным, человеческим языком:
Вот вам три свойства:
Маркер
Метка
Локация
Читаем заклинание первый раз:
Выполняем проверку:
Мы в Локации?
Нет! Значит, мы хотим туда попасть!
Размещаем Метку туда, где стоим, пусть дожидается нас.
Отправляемся в Локацию.
Читаем заклинание второй раз:
Выполняем проверку:
Мы в Локации:
Угууу! Значит, мы хотим попасть обратно.
Тогда просто перемещаемся на метку, которая нас уже ждет.
Ура! Разобрались!
Дело осталось за малым.
Вставляем текст нашего скрипта и компилируем.
Переходим в Свойства скрипта и начинаем связывать Свойста с нужными объектами:
Mark ссылается на Маркер, который будет ставиться нам под ноги.
Marker ссылается на Маркер, который расположен там, где мы окажемся после чтения заклинания.
TargetCell - ссылаемся на нашу локацию - AAAMGHaven. ААА - временный префикс для сортировки локации вверх списка. MGHaven - Misty Grove Haven, то бишь "Убежище в Туманной роще"
Всё! Вот теперь правда всё, честно честно!
Бежим проверять, уряяя!






