-
Пара советов по использованию поиска.
Поиск
Показаны результаты для тегов 'скрипт'.
Найдено: 7 результатов
-
Вы спросите, зачем нужна эта статья? Разве нельзя использовать скриптовые заклинания?Конечно можно, но у них есть некоторые ограничения. Например, вы хотите сделать комбинацию из нижеследующего: «Тихо» нанести повреждения NPC, то есть не видя никаких магических эффектов. Сделать игрока невидимым так, чтобы не было видно руку, колдующую заклинание. Какое-то заклинание считается враждебным, только стражник видит, как я его колдую. Колдовать заклинание аля Morrowind, которое может не сработать, или нанести случайное кол-во повреждений оружием. Колдовать заклинание, которое наносит огненное повреждение инеевым атронахам, а огненным атронахам наносит повреждение холодом. Узнать, кто колдовал заклинание на меня или на другого актера. Теперь все это можно сделать! Нижеследующее основано на том, что заклинания-способности колдуются сразу же, как только добавляются в список заклинаний, а также они не вызывают никаких визуальных изменений на колдующем или его цели. А необходимые визуальные эффекты вы можете добавить через PlayMagicShaderEffect или PlayMagicVisualEffects и т.д. Вот простейший пример, как создать простейшее «тихое» заклинание, наносящее 10 ед. повреждений мгновенно на избранную цель. Шаг 1 – создайте заклинание типа Способность, скажем "SilentDm10" с эффектом: "Понижение здоровья 10" и скриптовым эффектом: "StopSilentDm10" . Шаг 2 – создайте следующей скрипт для магических эффектов "StopSilentDm10" : scn StopSilectDm10 short doOnce Begin ScriptEffectUpdate if doOnce Dispel SilentDm10 endif set doOnce to 1 End Begin ScriptEffectFinish RemoveSpell SilentDm10 End Шаг 3 – используйте это заклинание в каком либо другом скрипте: ; target – ссылка на актера (или игрока) target.AddSpell SilentDm10 Примечание: добавление способности игроку вызовет появление сообщения, и заклинание не будет «тихим». Поэтому я бы изменил имя заклинания на что-нибудь более подходящее, например, "Отравление" . Вы не увидите больше одного сообщения "Добавлено Отравление" , если у всех ваших заклинаний-способностей будет одно имя. Настоящие программируемые заклинания более полезны. По сути, они являются комбинацией внутриигровых функций и нескольких обычных заклинаний. Вот простой пример. Он позволяет вам нанести цели случайные повреждения от X до X+Y: scn WildDamageSpell ; это внутриигровая функция на объекте 'FIGWildDamageSpell' ref target short baseDamage short wildDamage short isPlayerHostile short dam Begin OnActivate ; обнаруживаем цель set target to GetActionRef if target.IsActor == 0 || target.GetDead == 1 Return endif ; считаем кол-во повреждений set dam to baseDamage+wildDamage*0.01*GetRandomPercent ; если заклинание враждебное – простая проверка, только для игрока if dam > 0 && isPlayerHostile > 0 if target.IsGuard == 0 target.Startcombat player endif SendTrespassAlarm player player.ModCrimeGold 35 endif ; добавляем какой-нибудь нетипичный графический эффект (не обязательно!) if dam > 0 target.PME DTCT 1 endif ; наносит повреждения – здесь они ограничены от 0 до 31 ; dam <= 0 ничего не делает, dam > 31 дает 31 if dam >= 16 target.AddSpell SilentDm16 ; тот же SilentDm10, что и в предыдущем пример, но дает 16 повреждений set dam to (dam)-16 endif if dam >= 8 target.AddSpell SilentDm08 ; дает 8 повреждений, и так далее... set dam to (dam)-8 endif if dam >= 4 target.AddSpell SilentDm04 set dam to (dam)-4 endif if dam >= 2 target.AddSpell SilentDm02 set dam to (dam)-2 endif if dam >= 1 target.AddSpell SilentDm01 endif End Чтобы колдовать это заклинание: ; target – ссылка на актера, предполагается, что заклинание колдует игрок set FIGWildDamageSpell.baseDamage to 10 set FIGWildDamageSpell.wildDamage to 20 set FIGWildDamageSpell.isPlayerHostile to 1 FIGWildDamageSpell.Activate target 1 Продвинутые эффекты: Здесь все ограничено вашей смекалкой и воображением. Вот несколько вещей, которое можно сделать: 1) Заклинания-таймеры: Поскольку внутриигровые функции могут использовать блок GameMode, небольшая модификация скрипта позволит запускать его каждую секунду (или каждый кадр) в течение любого времени. 2) Эффекты для касания/цели/области: Поскольку внутри игровые функции могут вызываться где угодно, можно создать обычное заклинание с нужным набором целей, а потом в скриптовом эффекте вызывать нужную функцию на целях. 3) Заклинания с центром на игроке: Можно использовать заклинания, кастующиеся с активатора на игрока, а использование внутриигровых функцию дает вам полный контроль над ними. 4) Отслеживание колдующего: Добавьте ref-переменную в скрипт функции под названием 'caster' и устанавливайте ее перед вызовом функции. (можно также задать переменные для целей.) 5) Симулирование сопротивления, цены заклинания: Все это можно запрограммировать с помощью условий! 6) NPC колдуют заклинания: Заставить актера X немедленно колдовать заклинание на цель Y просто. Заставить его колдовать, когда это бы сделал RAI, может быть потруднее. Можно попробовать самому симулировать AI (AAI), с помощью постоянного заклинания. Постоянные заклинания: Самое смешное, что заклинания-способности не годятся для наложения постоянных эффектов – даже для игрока! Дело в том, что при смене ячейки заклинание удаляется и накладывается снова, то есть все переменные в скриптовом эффекте сбрасываются. Конечно, для игрока не все так страшно, поскольку для него можно использовать глобальные переменные в блоке ScriptEffectUpdate. Еще хуже то, что добавление способности добавляет ее всем актерам этого типа в игре. (Вот почему в примере заклинание удаляется после 1 фрейма.) Конечно, это хорошо, если вам надо, чтобы заклинание наложилось на всех актеров и исполнялось, только когда рядом игрок. Данная статья взята с неработающего ныне сайта tiarum wiki. Статья является переводом данной статьи http://cs.elderscrolls.com/index.php?title=Programmable_Spell_Effects за авторством GuidoBot. Переводчик Gwathlobal (OSFM team).
-
Думаю, вы все любите монстров, да? Даже если нет, этот урок пригодится любому начинающему скриптологу. В этом уроке я расскажу вам о том, как привязать скрипт к существу. Мы создадим скелета, который будет возвращаться к жизни после смерти (хотя он и так ... мертв). Также мы добавим эффект пламени и звук грома. Итак, начнем. Запустите СS. В окне "Object Window" выберите "Аctors" -> "Undead". Выберите любой скелет из списка, например, "CreatureSkeleton1Archer", и щелкните на нем правой кнопкой. Выберите "Edit". Измените ID скелета с "CreatureSkeleton1Archer" на "AааBloodSkeleton" (три буквы "а" нужны, чтобы наш скелет всегда находился в начале таблицы). Когда появится сообщение о создании новой формы (ID_Form), нажмите "Yes". Теперь приступим к написанию скрипта. Нажмите "Gameplay" -> "Edit scripts…". Сначала создадим новый скрипт, нажав "Script" -> "New". Убедитесь, что тип скрипта - "Object". Для начала назовем наш скрипт: scn AaaBloodSkeletonsScript Для того, чтобы после смерти скелета запускался нужный нам программный код, выберем тип блока OnDeath: begin OnDeath end В общем виде это будет выглядеть так: Scn AaaBloodSkeletonsScript begin OnDeath end Теперь нужно сделать так, чтобы после смерти скелета появлялось пламя. Для этого добавим соответствующую функцию: PlayMagicShaderVisuals effectSummonMythicDawn 5 Эта строка вызывает эффект магического пламени. Ваш скрипт теперь должен иметь такой вид: scn AaaBloodSkeletonsScript begin OnDeath PlayMagicShaderVisuals effectSummonMythicDawn 5 end Теперь добавим немного звуковых эффектов, подключив в скрипт следующую строку: PlaySound AMBThunder Функция PlaySound, используя звуковой эффект AMBThunder, вызовет звук грома. Скрипт в общем виде: scn AaaBloodSkeletonsScript begin OnDeath PlayMagicShaderVisuals effectSummonMythicDawn 5 PlaySound AMBThunder end Теперь мы просто воскресим наш скелет, добавив функцию: Resurrect 1 Все. Скрипт написан: scn AaaBloodSkeletonsScript ; название скрипта begin OnDeath PlayMagicShaderVisuals effectSummonMythicDawn 5 ; вызов пламени после смерти PlaySound AMBThunder ; проигрываем звук грома Resurrect 1 ; оживляем скелет end Примечание: Старайтесь не перегружать ваш скрипт лишними функциями, если они не нужны. Сохраните (скомпилируйте) написанный скрипт, нажав на иконку в виде маленькой дискетки. Теперь в окне "Object Window" выберите "Аctors" -> "Undead". Найдите там наш скелет "AbloodSkeleton". Щелкните на нем правой кнопкой мыши и нажмите "Edit". В графе "Script" в ниспадающем списке отыщите и подключите созданный вами новый скрипт - "АaaBloodSkeletonsScript". Все. Теперь вам остается только разместить скелет в какой-нибудь локации, создать плагин, подключить его в "лаунчере", запустить игру, отыскать его в игровом мире и убить... Но есть и другие способы включения созданного вами скелета в игру. Задержите мышку над ID нашего скелета до тех пор, пока не появится всплывающее окно с шестнадцатиричным кодом (например, "aaabloodskeleton" (00006708)). Запомните этот код (цифровой, тот, что между скобок) и в игре наберите в консоли: player.placeatme XXX где XXX - шестнадцатиричный код скелета. Создайте скрипт на кольце\амулете\на_чем_угодно, при экипировке которого будет вызываться наш скелет. Я бы порекомендовал первый способ, потому что иначе вам придется писать скрипт для кольца. Как бы там ни было, но если созданное существо нужно вам не для обучения, а для плагина, то использование консоли для его вызова не имеет смысла. Данная статья взята с неработающего ныне сайта tiarum wiki. Статья является переводом данной статьи http://cs.elderscrolls.com/index.php?title=Scripting_Tutorial:_My_First_Creature_Script за авторством jackmix69. Переводчик Platinum (OSFM team).
-
Введение Руководство Мой первый скрипт хорошо для первого ознакомления со скриптами, но он не раскрывает в полном объеме всех возможностей скриптового языка Oblivion. Это прекрасное введение для тех, кто никогда раньше не имел дела с программированием или скриптами, но модмейкерам будет полезен и более углубленный учебник для дальнейшего изучения этого замечательного ресурса. Этот учебник должен послужить более полным введением в скрипты для Oblivion, чем "Мой первый скрипт", и рассчитан на то, что читатель уже знаком с этим руководством. Если вы не поняли его основные принципы, то данный учебник может оказаться для вас слишком сложным. Но если с "Моим первым скриптом" у вас все в порядке, тогда начинаем! Информация о написании скриптов в Oblivion Что такое скрипт? Скрипты – это базовые кусочки кода, написанные на специальном скриптовом языке (далее - скрипты TES). Эти маленькие "программы" будут работать во время игры и могут выполнять определенные вещи, действительно много вещей: события на триггерах, контроль времени и места, исчезновение предметов и существ, появление или движение, выдача сообщений игроку, изменение параметров и даже изменение погоды – возможности просто невероятны. Скриптовый язык TES уникален, но он не может быть использован вне TES Construction Set. Как скриптовый язык он имеет некоторые ограничения, в отличие от "настоящих" языков программирования, например C++: Область применения скриптов TES ограничена; не надо ждать, что можно запрограммировать что-то, так или иначе не включенное в игру. Это совсем не означает, что вы не сможете достичь новых и необычных результатов! Но вы не сможете использовать скрипты TES, например, для программирования текстового процессора. Скрипты TES не похожи на SDK (комплект разработки программного обеспечения – сокр. с англ. software development kit), который действительно позволяет работать и изменять исходные коды игры. Вот почему вы не сможете использовать скрипты TES, например, для добавления новых погодных эффектов. Они прописаны в другом месте и нужно обладать дополнительными знаниями, чтобы сделать это. Данный язык интерпретируемый, а не компилируемый – коду для работы нужна отдельная программа (в данном случае Oblivion.exe), в отличие от компилированного кода, который может работать сам по себе, как .exe-приложение. TES скрипты не зависят от регистра. Это означает, что команда "player.getpos z" будет работать точно так же, как и "Player.GetPos z" или "PlAyEr.GeTpOs Z", или любой другой возможный вариант. Многие (как и автор) используют второй вариант, т.к. он наиболее понятен; множество других людей используют первый вариант, т.к. проще писать, используя один регистр. Единственно регистр имеет значение, когда вы хотите напечатать сообщение, выводимое на экран: но даже там все зависит от языка и от цели сообщения, регистр может быть любой. Что могут скрипты? Скрипты в Oblivion – способ, с помощью которого игра динамически реагирует на то, что делает игрок в игровом мире. Вы можете использовать скрипты для создания комплексных квестов. Вы можете использовать скрипты для создания особых предметов, которые будут выполнять действия, невозможные для обычного зачарования. Вы можете использовать скрипты для создания ловушек. Вы можете использовать скрипты для изменения поведения NPC или существ. Помните создание персонажа в Oblivion? Оно контролируется множеством скриптов. Выполнение квестов? Они также управляются скриптами. Так что если коротко ответить на этот вопрос: много. Чего не могут скрипты Скриптовый язык TES ограничен в своих возможностях – в нем большое количество функций, которые вы можете использовать, но иногда возможные варианты использования будут не все, которых бы вам хотелись. В большинстве случаев опытные скриптологи смогут найти специфику для очевидных ограничений, но не стоит ожидать чуда. Многие вещи запрограммированы и скрипты на них влияния не оказывают, а если и оказывают, то лишь косвенно. Учебник скриптов: до написания кода Если вы новичок в скриптах и в программировании разбираетесь лишь в общих чертах, даже если уже ознакомились с учебником "Мой первый скрипт", углубленное скриптонаписание с использованием скриптов TES может немного напугать. Вот почему здесь представлен развернутый учебник, который постепенно подведет вас к созданию более сложного скрипта. По мере изучения вы получите объяснения основных элементов скриптового языка. Вам встретятся разнообразные пояснения, но ключевые инструкции и важная информация будут выделены жирным шрифтом. Начинаем! Начинаем мы с открытия редактора скриптов: Запустите TES Construction Set, откройте Oblivion.esm, затем выберите Edit Scripts в меню Gameplay, чтобы открыть окно редактирования скриптов. Окно редактирования скриптов Открыть окно редактора скриптов можно несколькими способами: выбрав Gameplay –> Edit Scripts; нажатием на кнопку редактора скриптов (карандаш) в правом верхнем углу панели инструментов; или в меню Object или NPC, активировав кнопку [...], расположенную за редактируемым полем с названием скрипта. Давайте посмотрим на кнопки, расположенные на панели инструментов, слева направо: Открыть - позволяет выбрать скрипт для редактирования. Сохранить - проверяет текущий скрипт и компилирует его или выдает сообщения об ошибках. Примечание: в это время реального сохранения плагина на диск не происходит. При написании больших скриптов после сохранения скрипта вы должны периодически использовать команду "сохранить плагин" в главном окне TES CS, на случай "падения" конструктора. Также если при редактировании скрипта вы вдруг нажмете "сохранить плагин", изменения в скрипте при этом сохранены НЕ будут. Сначала вы должны сохранить вручную сам скрипт. Также, если просто закрыть скриптовое окно, это не значит, что скрипт сохранится. Вы должны позаботиться о его сохранении сами. Стрелки Вперед и Назад открывают следующий или предыдущий скрипт соответственно (в алфавитном порядке). Если вы присвоите своим скриптам общее обозначение в начале их названий, то это облегчит переход между скриптами и их поиск в вашем проекте. Например, мой псевдоним - Grundulum, и он стоит в начале каждого моего скрипта "GR_ShortReferencetoProject_", а последующие две или три буквы образуют аббревиатуру для конкретного мода; это заставит все скрипты, над которыми вы работаете, расположиться аккуратно и по порядку. Скомпилировать все – перекомпилирует все скрипты (для чего это нужно? Ни я, ни GhanBuriGhan не знаем). Это также добавит каждый скрипт из Oblivion в ваш мод - таким образом вы получите двухмегабайтный esp-файл, конфликтующий практически со всем, с чем только можно. Используйте эту кнопку осторожно. Удалить – удаляет скрипт, И, наконец, кнопка "Стрелка вниз" закрывает скриптовое окно. В правом верхнем углу панели инструментов можно найти ниспадающий список под названием Тип Скрипта. Данный блок позволяет выбрать один из трех типов скриптов, под который подпадает ваш скрипт: Объект Квест Магический Эффект. Подробнее об этом позже, но в рамках введения - Объектные скрипты – это скрипты, привязанные к объектам игрового мира (также, как и к предметам или NPC), Квестовые скрипты – скрипты, контролирующие выполнение квестов (как генерация персонажа), и Магические скрипты – скрипты, контролирующие все особые магические эффекты (в особенности, cкриптовые эффекты). Что мы хотим? Перед тем, как мы приступим к написанию нашего учебного скрипта, мы сначала должны решить, что мы хотим, чтобы он делал! Для этого учебника мы собираемся создать: Шкаф с Загадкой: шкаф загадывает загадку и открывается только в случае правильного ответа. Если игрок отвечает неправильно – срабатывает ловушка и ранит игрока, а шкаф остается закрытым. Это довольно сложное задание, но мы будем выполнять его шаг за шагом и в конце станет очевидно, что не все так страшно. Написание скрипта После открытия скриптового окна, нажмите Script -> New... Вы должны заметить, что Тип Скрипта – "Объект", что нам как раз и нужно. Нажмите в главном окне, которое из серого теперь стало белым. Здесь вы будете писать скрипт. Учебник скриптов: первые строки Называем скрипт Сначала мы должны назвать скрипт. Каждый скрипт должен начинаться с его названия. В окне редактора, пожалуйста, напечатайте ScriptName RiddleChestScript Отметьте, что ни пробелов, ни подчеркиваний в названии нет. Название скрипта должно состоять из одного слова, так что использовать пробелы нельзя. Также Oblivion игнорирует подчеркивание в алфавитном списке скриптов; вы можете использовать подчеркивание, чтобы сделать название более понятным для себя, но вы не увидите его, когда позже откроете скрипт. (Дополнительная информация: Oblivion допускает так называемый эффект наложения в скриптах TES, когда вы заменяете полное имя команды его сокращенной версией. Для примера: "ScriptName" становится "scn", или "ForceActorValue" становится "ForceAV". Мы не будем использовать эффект наложения в данном учебнике, но не удивляйтесь, если увидите подобное в других скриптах.) Помните, что скрипты TES не чувствительны к регистру; вы могли бы написать "scriptname" или "ScriptnamE", как угодно Попробуйте сохранить свой скрипт, используя кнопку «Сохранить» на панели задач. Ничего очевидного не случится, но если вы нажмете на кнопку «Открыть», то сможете увидеть название вашего скрипта в перечне скриптов Oblivion. Нажмите на «X» в верхнем правом углу окна выбора скриптов, чтобы закрыть его и вернуться в окно редактирования. RiddleChestScript сейчас самый короткий скрипт в Oblivion, но он ничего не делает. Давайте это исправим. Команды "Begin" и "End" Команды "Begin" и "End" определяют начало и конец блоков скрипта – отдельных участков кода, которые будут выполняться при определенных условиях. Например, "Begin GameMode" определят начало выдачи текстового блока, который будет запускаться в каждом фрейме до тех пор, пока игрок не откроет меню. Для наших целей нам нужен тип-блок "OnActivate": он запустится только тогда, когда наш шкаф будет активирован (утомительно отвечать на загадку в каждом фрейме или всякий раз, как NPC умрет, обе этих вариации возможны с использованием других вариантов типов блоков Begin!). Нажмите два раза Enter, чтобы переместить курсор вниз, и отредактируйте свой скрипт, чтобы он выглядел вот так: ScriptName RiddleChestScript Begin OnActivate ; Здесь мы напечатаем, что случится, когда шкаф будет открыт End Опять нажмите "Сохранить". Скрипт все еще ничего не делает, но, по крайней мере, теперь мы определили условия, при которых он будет работать. Также здесь нужно отметить пару вещей. Первое - мы закрыли текущий блок перед тем, как начали новый – это не так важно, когда в скрипте один блок, но как только скрипт станет более сложным, нам понадобятся составные блоки. Выражаясь в более технических терминах – блоки Begin/End не вкладываемые. Вторая вещь, которую надо отметить, это точка с запятой ";" на линии 4. Точка с запятой отмечает остальную часть строки как комментарий. Все напечатанное после точки с запятой на этой строке при компилировании скрипта будет проигнорировано. Комментарии используются, чтобы объяснить код, это поможет вам и другим быстро понять, что происходит в скрипте на определенных строках. Если вы хотите написать более чем одну строку с комментарием, то точку с запятой нужно ставить в начале каждой строки. Выдача текстового сообщения и получение ответа от игрока. Теперь нужно, чтобы наш шкаф с ловушкой загадывал игроку загадку. Для этого используется функция "MessageBox", которая должна быть вам знакома: в " Моем первом скрипте" использовалась родственная команда "Message". "MessageBox" позволяет вывести на экран небольшое количество текста и также отобразить несколько вариантов ответов, из которых может выбрать игрок. К сожалению, в Oblivion (как до него и в Morrowind), нет возможности печатать ответ на загадку, так что нам придется предоставить несколько вариантов ответов. Строка кода для этого: MessageBox "Безголосый, но плачет. Бескрылый, но парит. Беззубый, но кусает. Безротый, но бормочет. Что это?", "Летучая мышь", "Старуха", "Ветер", "Привидение" Первая строка (текст между первой парой кавычек) – текст, действительно отображаемый в окне сообщения; остальной текст, разделенный запятыми, сообщает игре, чтобы она сделала "кнопки" по одному выражению для каждой. Но как нам сделать, чтобы загадка задавалась только при первой попытке открыть шкаф, а не постоянно? Теперь мы переходим к центральной теме: использование одноразовых условий и переменных состояния. Самая распространенная из проблем, с которой сталкиваются начинающие в написании скриптов для Oblivion, берет свои корни в непонимании того, как на самом деле выполняются и, соответственно, должны быть оформлены скрипты. Так что обратим внимание на эту важную деталь. Как выполняются объектные скрипты Каждый скрипт, привязанный к объекту или NPC (объектный скрипт), выполняется в каждом фрейме отображения игры на экране, пока активна ячейка с объектом (во внутренних ячейках скрипты активны только в ячейке, в которой находится игрок; снаружи – в ячейке, в которой находится игрок и во всех активных смежных ячейках). Так что каждый отдельный скрипт (а не его отдельная строчка) выполняется 10-60 раз в секунду или столько раз, насколько быстро на вашем компьютере идет игра! Легче всего представить каждый локальный скрипт завернутым в большую циклическую спираль: до тех пор пока (объект в активной ячейке) [код скрипта] завершение Вот почему представленный ниже скрипт будет плеваться непрерывным потоком сообщений (если приложен к объекту или NPC в той же ячейке, где и игрок). Проверьте сами, если хотите: ScriptName HorribleMessageScript Begin GameMode MessageBox “Тысячи бесполезных сообщений!” End Этот пример сравнительно безобидный, но представьте себе что случится, если бы вы использовали линию кода, которая добавляет предмет в инвентарь игрока или устанавливает возле него монстра, и т.п.! Вот почему конструкции с использованием "Do Once" так существенны и часто используются при написании скриптов для Oblivion. Так что давайте продолжим написание нашего учебного скрипта - нам нужно применить переменную, чтобы наше сообщение выдавалось только один раз. Измените свой скрипт как указано ниже: ScriptName RiddleChestScript Short controlvar Begin OnActivate If ( controlvar == 0 ) MessageBox "Безголосый, но плачет. Бескрылый, но парит. Беззубый, но кусает. Безротый, но бормочет. Что это?", "Летучая мышь", "Старуха", "Ветер", "Привидение" Set controlvar to 1 EndIf End и опять сохраните скрипт. Заметьте, что команда "MessageBox" должна быть написана на одной строке! Не прерывайте и не переносите ее! И еще, напоследок нужно отметить несколько вещей. Команда "If" используется для проверки условия – всякий раз, когда выражение в круглых скобках будет истинным, будут выполняться последующие строки кода, вплоть до команды "EndIf". "==" – проверяет, эквивалентно ли левое выражение (в нашем случае это переменная "controlvar") выражению с правой стороны (в нашем случае "0"). Если вы забудете поставить "EndIf" после команды "If", редактор будет выдавать сообщение об ошибке, когда вы попытаетесь сохранить скрипт. "Short controlvar" указывает новую переменную, которую мы назвали "controlvar". Сейчас вам достаточно знать, что данная переменная будет содержать целые (целые положительные или отрицательные числа). Переменная - это "метка-заполнитель", которая может принимать различные значения. Команда "Set" для вас тоже новая, но достаточно простая – она устанавливает значение нашей переменной с 0 на 1 (все переменные начинают с нулевого значения). Это в сочетании с командой "If ( controlvar == 0 )" обеспечивает одноразовое условие – в следующем фрейме скрипт будет выполняться после того, как переменной будет присвоено значение 1, условие "If" будет неверно и текстовое сообщение больше выдаваться не будет. Учебник скриптов: первый тест Сохранение и подготовка модификации. Наш скрипт уже способен работать, так что давайте его проверим: Сохраните скрипт и закройте окно редактора скриптов. Посмотрите в окно объектов и проследуйте по директориям WorldObjects > Container > Clutter пока не найдете объект с Editor ID: CupboardFoodLower. Теперь или щелчком с зажатой правой кнопкой мыши выберите Edit, или просто щелкните два раза по объекту, чтобы открыть его свойства. Затем в ниспадающем списке скриптов выберите только что сделанный нами RiddleChestScript. Нажмите ОК, сохраните мод и выйдите из TES CS. Примечание: обратите внимание на то, что мы только что сделали. Редактирование объекта без присвоения ему нового id - опасное занятие! Никогда так не делайте, если вы не уверены в том, что вы делаете! Скрипт в игрe Теперь используйте "Файлы данных", чтобы активировать мод, запустить игру и загрузить сохранение. Когда игра загрузится, активируйте консоль (обычно это кнопка «~» (тильда), слева от клавиши «1» на основной клавиатуре) и в консоли напечатайте: player.coc "AleswellInn" и нажмите Enter. Вы появитесь в Алесвельской таверне, где вас сразу поприветствует группа невидимых людей. Это не имеет отношения к моду, просто данная ячейка использовалась автором для тестирования (она находится сверху в списке интерьеров, поэтому ее очень легко находить). Щелкайте, пока не сможете двигаться, и подойдите к шкафу слева от вас. При активировании шкафа должно появляться окно сообщений, как на картинке ниже. Нажатие на один из вариантов ответа закроет окно и, если попытаться активировать шкаф опять, ничего больше произойти не должно – это хорошо, т.к. значит, что наша проверка состояния работает, как мы и хотели. (Шкаф не открывается потому, что мы еще не включили в скрипт команду Activate, мы сделаем это позже.) Выключите Oblivion и загрузите свою модификацию в TES CS. Бедным людям из Алесвельской таверны придется дождаться следующего раза, чтобы вернуть свою видимость, но такова жизнь NPC в видеоигре. Учебник скриптов: выбор игрока, ошибки и исправления. Выбор игроком варианта ответа Теперь нужно, чтобы скрипт вычислял, какой вариант ответа выбирает игрок и, соответственно, реагировал на правильный и неправильные ответы. Функция для проверки выбранного ответа "GetButtonPressed". Данная функция устанавливает число в зависимости от того, на какую кнопку щелкнуть мышкой. Устанавливает "0" для первой кнопки ("Летучая мышь" в нашем примере) и 1, 2, 3, и т.п. для следующих кнопок, в порядке, указанном в команде MessageBox. Пока ответ не выбран, функция устанавливает 1, об этом нам тоже следует позаботиться. Функция "Activate" заставит наш шкаф открыться; фактически, эта функция просто инициирует стандартное действие, которое должно выполняться, когда вы "используете" объект со скриптом: дверь откроется, NPC начнет диалог и т.п. Следующие изменения в скрипте также демонстрируют, как можно использовать управляющую переменную, чтобы заставить Oblivion обрабатывать функции одну после другой, хотя законченный скрипт обрабатывается каждый фрейм игры: просто увеличьте управляющую переменную и проверьте его в серии операторов If–ElseIf. Это очень безопасный способ скриптонаписания для Oblivion. Это может быть не всегда нужно, но безопасно. Пожалуйста, измените свой скрипт, как указано ниже: ScriptName RiddleChestScript Short controlvar Short button Begin OnActivate If ( controlvar == 0 ) MessageBox "Безголосый, но плачет. Бескрылый, но парит. Беззубый, но кусает. Безротый, но бормочет. Что это?", "Летучая мышь", "Старуха", "Ветер", "Привидение" Set controlvar to 1 ElseIf ( controlvar > 1 ) Activate EndIf End Begin GameMode If ( controlvar == 1 ) Set button to GetButtonPressed If ( button == -1 ) Return ElseIf ( button == 2) MessageBox "Правильный ответ." Activate Set controlvar to 2 Else MessageBox "Неправильный ответ." Set controlvar to -1 EndIf EndIf End Обратите внимание на новый блок - "GameMode", который начинается с "If (controlvar == 1)". Мы устанавливаем "controlvar" в 1 как только шкаф будет активирован. Но "OnActivate" только запускает скрипт в том фрейме, в котором объект будет активирован. Поэтому нам необходимо использовать блок "GameMode", чтобы продолжить проверку выбора игрока, и далее проверка будет выполняться в каждом фрейме. Теперь проверим нажатие кнопок. А сделаем мы это с помощью присвоения новой переменной "button" величины, возвращаемой "GetButtonPressed". Скрипт работает, даже когда игра останавливается в ожидании вашего решения. Сначала мы проверим ситуацию, когда ни одна кнопка не была нажата – в этом случае команда "return" сообщает игровому движку остановить выполнение скрипта в текущем фрейме. Правильный ответ - "Ветер"; он соответствует кнопке номер два – при нажатии этой кнопки нам нужно известить игрока, что он дал правильный ответ, и позволить функции "Activate" открыть шкаф обычным способом. Все значения, соответствующие остальным кнопкам, означают, что игрок выбрал неправильный ответ, так что здесь мы можем использовать команду "Else". В этом случае мы сообщим игроку, что он глупый и шкаф не будет активирован. Теперь посмотрите на небольшое дополнение в верхней части скрипта: Begin OnActivate If ( controlvar == 0 ) MessageBox "Безголосый, но плачет. Бескрылый, но парит. Беззубый, но кусает. Безротый, но бормочет. Что это?", "Летучая мышь", "Старуха", "Ветер", "Привидение" Set controlvar to 1 ElseIf ( controlvar > 1 ) Activate EndIf End Это означает, что если шкаф будет активирован в будущем, он откроется только если "controlvar" будет больше 1. Вспомним последний абзац: если игрок дает неправильный ответ на загадку, "controlvar" получает значение -1, так что он никогда больше не сможет открыть шкаф. Но если ответ правильный, controlvar получает значение 2, и в дальнейшем игрок сможет открывать шкаф сколько угодно. Сохраните и запустите свой плагин, проверьте написанное выше. Первые ошибки и исправления Если вы тестировали плагин, то должны были обратить внимание, что все пошло не совсем так, как было запланировано. Выбор неправильного ответа не запирал шкаф навсегда, а если игрок выбирал правильный вариант, то инвентарь и сообщение о правильном ответе отображались одновременно. Сообщение должно быть закрыто перед тем, как можно будет сделать что-то еще, но оно прикрыто инвентарем! Давайте попробуем следующее (измените соответствующую секцию скрипта, чтобы он стал таким): If ( controlvar == 1 ) Set button to GetButtonPressed If ( button == -1 ) Return ElseIf ( button == 2) MessageBox "Правильный ответ." Set controlvar to 2 Else MessageBox "Неправильный ответ." Set controlvar to -1 EndIf ElseIf ( controlvar == 2 ) Activate EndIf Видите, как мы переместили команду "Activate" в секцию, которая проверяет "controlvar == 2"? Это обеспечивает четкую последовательность событий, предотвращая одновременное открытие двух блоков, а как было упомянуто выше, четкая последовательность может быть очень важна при написании скриптов для Oblivion – всегда старайтесь избегать делать слишком много вещей сразу! Сохраните, запустите и проверьте скрипт. Замечательно! Теперь инвентарь открывается как надо, но что это? Мы не можем его закрыть! Посмотрите выше: переменной "controlvar" была присвоена 2, и она и далее остается с таким значением, поскольку мы ее больше не изменяем. Следовательно, игра теперь получает непрерывные команды "Activate" всякий раз, как выполняется скрипт (в каждом фрейме)! Вот почему мы не можем закрыть инвентарь – он мгновенно открывается снова. Поэтому измените следующую часть скрипта вот так: ElseIf ( controlvar == 2 ) Activate Set controlvar to 3 EndIf Заново протестируйте мод: теперь все работает так, как мы хотели. Надеюсь, вас не смутило вышеуказанное отклонение в процессе отладки, но это очень важная вещь – вам постоянно придется продумывать свои скрипты и испытывать различные способы, чтобы добиться успеха. Что мы пропустили? Ловушку, конечно! Учебник скриптов: добавляем ловушку. Если игрок неправильно ответит на загадку, наш шкаф наложит на него проклятье. Сначала выберите заклинание, которым хотите поразить игрока: щелчок на значок "+" рядом с Magic, еще раз нажмите на "+" рядом со вкладкой Spell, наконец, выберите подпункт "Заклинание". Выбор здесь довольной большой, но для наших целей мы используем заклинание Mg05FingerSpell15. Выбрав это болезненное наказание, нужно применить его к игроку, когда он даст неправильный ответ. Отредактируйте скрипт следующим образом: Else MessageBox "Неправильный ответ." Cast Mg05FingerSpell15 Player Set controlvar to -1 EndIf Отметьте, что мы использовали функцию "Cast". (Дополнительная информация: для работы функции "Cast" необходим объект вызова. Мы не включили его в наш скрипт, потому что это объектный скрипт, и он будет привязан к игровому объекту. Следовательно, функция будет действовать относительно данного объекта.) Теперь ваш скрипт должен выглядеть так: ScriptName RiddleChestScript Short controlvar Short button Begin OnActivate If ( controlvar == 0 ) MessageBox "Безголосый, но плачет. Бескрылый, но парит. Беззубый, но кусает. Безротый, но бормочет. Что это?", "Летучая мышь", "Старуха", "Ветер", "Привидение" Set controlvar to 1 ElseIf ( controlvar > 1 ) Activate EndIf End Begin GameMode If ( controlvar == 1 ) Set button to GetButtonPressed If ( button == -1 ) Return ElseIf ( button == 2) MessageBox "Правильный ответ." Set controlvar to 2 Else MessageBox "Неправильный ответ." Cast Mg05FingerSpell15 Player Set controlvar to -1 EndIf ElseIf ( controlvar == 2 ) Activate Set controlvar to 3 EndIf End Вот и все, ваш скрипт готов. Поздравляем! Если хотите, можете поэкспериментировать со скриптом, используя другие функции. Как узнать больше. После прочтения этого учебника вы можете спросить себя, как продолжить изучение написания скриптов? Хороший способ – это просмотр примеров из учебника или скриптов игры (как написанные Bethesda, так и из модов). Попробуйте найти скрипт, схожий с тем, что вы хотите создать, скопируйте его и измените под ваши нужды. Почитайте общую информацию по функциям и описания функций, которые могут понадобиться вам для осуществления задуманного. Классификация функций в функциональные типы должна помочь вам в поиске нужного. И, наконец, официальные форумы - отличное место для поиска информации (используйте функцию поиска) или для получения помощи по конкретной проблеме. А остальное – практика, практика и еще раз практика. Заключительные строки Читатели, которые обратили внимание на функцию "If", должны были заметить, что ставить круглые скобки вокруг условий не обязательно. Я включил их в данный учебник, поскольку мне кажется, что это упорядочивает и упрощает понимание скрипта. И, наконец, хочу объявить огромную благодарность GhanBuriGhan`y за его фантастическое "Руководство по скриптам Morrowind для чайников" (Morrowind Scripting for Dummies), в котором содержится прототип этого учебника. Я не смог с ним связаться, чтобы получить разрешение на его использование; но если у него есть какие-либо вопросы насчет данного руководства, то он вправе убрать его из WIKI или же отредактировать его. Данная статья взята с неработающего ныне сайта tiarum wiki. Статья является переводом данной статьи http://cs.elderscrolls.com/index.php?title=Scripting_Tutorial:_My_First_Script за авторством Grundulum. Переводчик Eugene (OSFM team).
-
Это руководство поможет вам создать новое заклинание, используя комбинацию из стандартного и собственного, созданного вами эффекта. Откройте программу TES Construction Set. Когда она загрузится, идите по пути File -> Data и в открывшемся окошке щелкните два раза на "Oblivion.esm", чтобы загрузить мастер-файл Oбливиона. Добавление стандартного эффекта После процесса загрузки мы можем приступить к созданию нашего заклинания. Итак, активируйте окно Object Window. Нас интересует категория Magic. Разверните ее, нажав на плюс "+". Там вы увидите несколько подкатегорий, но нам нужно создать заклинание (Spell). Щелкнув левой кнопкой мыши (далее ЛКМ), выделите слово "Spell". В таблице справа вы должны увидеть множество заклинаний, используемых в игре. Щелкните правой кнопкой мыши (далее ПКМ) где-нибудь на этой таблице (неважно где) и выберите "New" в появившемся меню. Должно открыться новое диалоговое окно - "Spell". В нем: ID: ID нашего заклинания, используемое внутри Construction Set. Введите "MyFirstSpell" в это поле. Name: Настоящее имя заклинания, которое будет отображаться в игре. Введите - "My First Spell". Type: Показывает, к какому типу относится это заклинание. Выберите "Spell". На этой стадии создания заклинания таблица справа должна быть пуста. При использовании такого заклинания оно не будет производить никаких эффектов, поэтому мы сейчас добавим туда один из стандартных эффектов. Щелкните ПКМ на поле "Effects" и в появившемся меню выберете "New". Появится новое диалоговое окно - "Effect Item". Здесь: Effect: Показывает какой магический эффект будет применяться в заклинании. Выберите "Shield" (Щит). Range: Показывает, как будет применяться эффект. Выберете "Self" ("на себя"). Area: Радиус действия заклинания. В данном случае у нас нет возможности изменять это поле, т.к. этот эффект заклинания кастуется "на себя". Duration: Показывает продолжительность действия заклинания. Введите число 30. Magnitude: Показывает силу примененного заклинания. Введите число 300. Щелкните "ОК", чтобы добавить этот эффект. P.S. Вы, наверное, заметили, что значения в поле "Auto-Calculated Costs" справа автоматически изменяются. Если вам не нравятся эти значения, вы можете убрать галочку в переключателе "Auto-Calculate" в предыдущем окне. Позже мы попытаемся это сделать. Создание скрипта для заклинания Сейчас, когда мы добавили стандартный эффект, давайте добавим еще один собственный. Но, прежде всего, мы должны написать для него скрипт. Выберите Gameplay -> Edit Scripts в главном меню. Появится диалоговое окошко "Script Edit", в которое мы пока ничего не можем ввести. Выберите Script -> New из меню этого окна. Теперь мы можем создавать наш скрипт. Выберите тип вашего скрипта "Magic Effect" из ниспадающего меню "Script Type". Это очень важно! Если вы не сделаете этого, мы не сможем добавить скрипт в заклинание. Давайте назовем наш скрипт "MyFirstSpellScript" и добавим переменную для последующего использования. Итак: scriptname MyFirstSpellScript short updateCount Скрипты для заклинаний (магических эффектов) отличаются от обычных скриптов для объектов. Они "понимают" только три специальных скриптовых блока, в то время как обычные скрипты используют намного больше. Так что же это за скриптовые блоки? С удовольствием вам отвечу. Скриптовый блок - это блок Begin...End с указанным конкретным типом блока, который запускается в определенной ситуации и представляет собой условие. Скрипты для заклинаний имеют следующие типы блоков: ScriptEffectStart - этот блок запускается один раз во время начала кастования заклинания. ScriptEffectUpdate - этот блок будет проигрываться в каждом игровом фрейме в течение действия заклинания. ScriptEffectFinish - этот блок запускается один раз по окончании действия заклинания. Теперь давайте добавим блоки в наш скрипт. Begin ScriptEffectStart RemoveAllItems End Замечательный эффект. ( RemoveAllItems - убрать все вещи ) Begin ScriptEffectUpdate set updateCount to updateCount + 1 End Все, что мы делаем, это добавляем 1 в нашу переменную. Это позволит нам узнать, сколько раз запускался этот блок. Конечно, гораздо интереснее использовать здесь что-нибудь типа добавления или убавления здоровья или что-нибудь еще. Begin ScriptEffectFinish Message "Spell is finished. ScriptEffectUpdate was run %. 0f times", updateCount End Функция "Message" выведет на экран текстовое сообщение, в котором будет показано, сколько раз был запущен блок ScriptEffectUpdate. Скрипт полностью: scriptname MyFirstSpellScript short updateCount Begin ScriptEffectStart RemoveAllItems End Begin ScriptEffectUpdate set updateCount to updateCount + 1 End Begin ScriptEffectFinish Message "Spell is finished. ScriptEffectUpdate was run %. 0f times", updateCount End Выберите Script -> Save ( или щелкните на кнопке с дискеткой ) и закройте это окно. Добавление собственного эффекта Возвращаемся обратно в окно Spell, щелкаем ПКМ в поле "Effects" и выбираем "New" в появившемся меню, как мы делали это раньше. На этот раз выберите "Script Effect" в ниспадающем меню "Effect". Это позволит нам добавить скрипт, который мы только что написали. Effect: Выберите "Script Effect". Range: Выберите "Target". Area: Введите какое-нибудь значение, например, 100. Duration: Поставьте небольшое значение 5 или 10, чтобы мы долго не ждали, когда закончится дейтвие заклинание. Script Effect Info: Script: В ниспадающем меню выберите наш скрипт "MyFirstSpellScript". (Если вы нажмете на кнопку "...", то откроется окно редактирования скриптов.) Effect Name: Имя эффекта. Задайте здесь какое-нибудь имя, например "I see London, I see France". School: Навыками какой магической школы вы должны обладать, чтобы использовать этот эффект. Visual Effect: Какой визуальный эффект будет использоваться. Выберите "Frenzy" ("Бешенство"). Effect is Hostile: Если вы поставите здесь галочку, то людям не будет нравиться, если вы скастуете на них это заклинание. В данном случае ставить галочку мы не будем. Жмите "ОК". Заключительные шаги Убедитесь, что в переключателе "Auto-Calculate" не стоит галочка. Иначе вы не сможете скастовать это заклинание. ( Я так думаю, что магии не хватит на такое заклинание. От себя хочу добавить, что неплохо было бы поставить "Spell Level" на "Novice" и уменьшить "Spell Cost" до приемлемых значений.) Нажмите "ОК". Заклинание добавилось в список заклинаний в окне Object Window. Нахождение FormID Перед тем, как тестировать заклинание, нам необходимо знать его FormID, т.к. мы не можем использовать просто "MyFirstSpell". Идите в верхнюю часть списка заклинаний и найдите колонку "Count". Слева от нее вы найдете скрытую колонку FormID (две рядом стоящие линии). Щелкните по левой границе колонки "Count" и, держа зажатой ЛКМ, растяните колонку FormID. Теперь в списке найдите наше заклинание и перепишите куда-нибудь его FormID. Оно должно выглядеть примерно так: "01000CE8" (но не обязательно). Тестирование. Сохраните ваш мод. Это очень важно! Выберите File -> Save в Главном меню, введите любое желаемое имя вашего мода, например, MyMod и нажмите "ОК". Запустите Oblivion. В "лаунчере" выберете "Data Files" и отметьте файлы "Oblivion.esm" и наш файл плагина ("MyMod.esp"). Нажмите "ОК", а затем "Play". Начните новую игру или загрузите сохраненную. Имейте ввиду, что наш собственный эффект лучше работает, если вы выберете несколько целей. Откройте консоль нажатием кнопки "~" и введите следующее: player.addspell <formId> где <formId> - FormID нашего заклинания. ( Вы же его запомнили, не так ли?) Это будет выглядеть примерно так: player.addspell 01000ce8 Если все пройдет гладко, то появится сообщение о том, что нам добавлено заклинание "My First Spell". Выберите это заклинание из списка заклинаний своего игрока и скастуйте его! Вы получите временную защиту и по прошествии нескольких секунд появится сообщение, которое проинформирует, сколько раз был запущен блок ScriptEffectUpdate. Если же заклинание не добавилось, то это значит, что игра не распознала ваш FormID. Попробуйте изменять вторую цифру в FormID. Например, 02000ce8, 03000ce8 и т.д. пока не получится. Вы, вероятно, загрузили в игру не только мастер-файл и созданный вами мод, но и другие моды. ( От себя хочу добавить, что первые две цифры означают, каким по счету был загружен в игру наш мод в шестнадцатиричном формате. Обычно они сортируются по дате создания. Например, если наш мод загружается десятым, то переводим его в шестнадцатиричный код - 0А и в консоли пишем: player.addspell 0А000ce8 ). Удачи в создании заклинаний! Данная статья взята с неработающего ныне сайта tiarum wiki. Статья является переводом данной статьи http://cs.elderscrolls.com/index.php?title=Scripting_Tutorial:_My_First_Spell за авторством Mrflippy. Переводчик Vitalka (OSFM team).
-
Надеемся, вы уже знаете, как запустить редактор TES CS и что там делать, так что перейдём непосредственно к скриптам. В панели инструментов наверху найдите кнопку с карандашом (крайняя справа) – эта кнопка открывает редактор скриптов. Нажали? Значит, вы уже видите этот самый редактор. В нём сейчас пусто и основное его поле, где вам предстоит набирать будущий текст скрипта, имеет серый цвет. Теперь перейдём к скриптам. Для начала можете посмотреть, как они вообще выглядят. Для этого нажмите на красную стрелку “вправо” и перед вами откроется первый в списке скрипт - AbandonedMineTrap02Script. Судя по названию, он отвечает за работу какой-то ловушки в заброшенной шахте. Всегда старайтесь давать своим скриптам понятные названия! В этом скрипте есть все основные элементы скрипта: В самой первой строке пишется название скрипта: ScriptName AbandonedMineTrap02Script – эта строка обязательна, в ней пишется имя скрипта. Чуть ниже идёт объявление переменных: short triggered – создание короткой целочисленной переменной. В скрипте может не быть вообще переменных, а может быть несколько десятков и разных типов. Далее идут рабочие блоки: Begin [тип блока] …. End Именно в этих блоках и будет описываться работа скрипта. А теперь создадим свой собственный, самый первый скрипт! В Object Window (окне объектов конструктора) отыщите отмычки. Вы найдете их в списке Items → Misc Item. Вместо отмычки подойдет любой обычный предмет - яблоко или что-нибудь подобное. Сделайте двойной щелчок на предмете. Откроется диалоговое окно со свойствами предмета. Там, где написано "Script: NONE", кликните на кнопку с тремя точками, находящуюся справа. Это откроет редактор скриптов. Выберите Script → New, чтобы создать новый скрипт. Скопируйте приведенный ниже программный код комбинацией клавиш Ctrl + C и вставьте его в окно редактора с помощью комбинации Ctrl + V: ScriptName HelloWorld Begin OnAdd Message "Hello World!", 10 End Информация о данном скрипте: • Первая строка – это имя скрипта (Scriptname). Убедитесь, что оно уникально. В противном случае вам придётся его изменить, т.к. редактор не позволит скомпилировать скрипт. • "Begin OnAdd" означает, что код внутри данного блока будет исполняться всякий раз, когда вы подберете нужный предмет. "OnAdd" – это тип данного блока. Команда “end” закрывает секцию скрипта, которая связана с “OnAdd”. У вас может быть несколько отдельных блоков begin/end, имеющие одинаковые или различные типы блоков (blocktype). • Между begin и end находится исполняемый программный код. В нашем случае это всего лишь одна функция – Message, которая выведет на экран сообщение "Hello World!". • И последнее – временной контроль за строкой сообщения. В данном случае она имеет параметр «10», который означает, что строка будет отображаться на экране в течение 10 сек. (Прим. К сожалению, изменение времени отображения не работает, поэтому нет смысла указывать второй параметр.) Сохраните скрипт и закройте Редактор скриптов. Вернитесь к свойствам предмета, "HelloWorld" должно появиться как опция в ниспадающем списке скриптов. (Возможно, вам нужно будет закрыть окно свойств объекта и снова открыть его, чтобы скрипт "HelloWorld" появился в ниспадающем списке.) Щелкните ОК, чтобы сохранить изменения, и закройте окно. На панели инструментов выберите File -> Save; в окне сохранения введите имя файла HelloWorld (это будет ваш первый *.esp файл плагина - HelloWorld.esp !). Откройте Oblivion_Launcher и щелкните Data Files. Двойным щелчком мыши подключите свой HelloWorld.esp, щелкните OK и закройте окно. Теперь все должно работать! Запустите игру, бросьте отмычку (или предмет, который вы использовали) на землю и подберите ее. При этом должно появиться сообщение "Hello World!". И с этим первым результатом добро пожаловать в увлекательный мир скриптинга! Данная статья взята с неработающего ныне сайта tiarum wiki. Автором является OSFM team, а сама статья является переводом данной статьи http://cs.elderscrolls.com/index.php?title=Scripting_Tutorial:_My_First_Script.
-
В этом уроке будет рассказано, как создать Spell Tome (или проще говоря, книгу, после прочтения которой игроку будет добавлено заклинание). Вам нужно создать книгу, вставить в нее какой-нибудь текст, и добавить скрипт, который будет добавлять игроку заклинание. Если вы ничего не знаете о скриптинге, или вы новичок в TES CS, я надеюсь, что вы сначала почитаете другие обучающие материалы, а затем вернетесь, когда изучите основы. Мой первый скрипт – это прекрасный обучающий материал для изучения азов скриптинга. Начало Откройте TES CS и загрузите Oblivion.esm (и какой-нибудь существующий файл .esp, если вы хотите добавить книгу, обучающую заклинанию, в него). Если вы планируете создать новый плагин, тогда перейдите в главное меню (File>Save) и сразу сохраните его, назвав, например, SpellTomeTutorial. Это позволит вам избежать возможных проблем с падением редактора при попытке создания нового файла плагина позже, когда вы проделаете большой объем работы и захотите её сохранить. Создание тома (книги) Откройте Object Window (Окно объектов) и раскройте категории 'Items' > 'Book' > 'Clutter' и выберите 'Book'. Теперь выберите одну из книг в списке (например, 'Book1CheapGuideAnvil'), правый клик на ней и в появившемся меню выберите edit (редактировать). Измените ID на что-то вроде 'aaaSpellTome' (таким образом, ее будет легко найти вверху списка книг. Прим. Если используется расширитель редактора CSE, то добавлять ааа в начало ID нет необходимости, т.к. все записи, добавляемые вашим модом, будут и так на самом верху в своих категориях, к тому же выделены цветом.) и измените name (название) на такое, которое вам нравиться. Также, пока вы еще здесь, очистите весь текст в окне справа, и убедитесь, что у книги нет зачарования (Enchanting), обучения (Teaches) или скрипта (на данный момент). Жмите OK, и когда у вас спросят, желаете ли создать новый объект, выбирайте yes (да). Заклинание Вы не сможете создать книгу, обучающую заклинанию, без самого заклинания. В этот момент вы можете выбрать, использовать уже существующее в игре заклинание, или создать новое. Я не буду здесь рассказывать, как создать новое заклинание, но вы можете почитать об этом, например, здесь. Неважно, какой вариант вы выберете, главное то, что вам нужен будет ID заклинания. В этом обучающем материале я буду использовать существующее заклинание 'StandardFrostDamageTarget1Novice'. Скрипт Нам нужно создать скрипт, который мы прикрепим к нашей книге, и благодаря которому игроку будет добавляться заклинание. Вернемся к главному меню, перейдем Gameplay>Edit Scripts… Идем вперед, открываем окно для написания скриптов и создаем новый скрипт (Script>New). Наберите в окошке текст, который вы видите ниже, и нажмите Save (Сохранить). Далее я объясню, как это работает. scn aaaSpellTomeScript short doonce short buttonpressed int button begin onActivate if doonce == 0 MessageBox "Вы желаете изучить заклинание Снежный заряд?", "Да", "Нет, возможно позднее" set doonce to 1 set buttonpressed to 1 else Message "Вы уже получили все знания, которые содержатся в этой книге" endif end begin GameMode if buttonpressed == 1 set button to GetButtonPressed if button == 1 set doonce to 0 set buttonpressed to 0 Message "Хорошо, возможно вы пожелаете учиться позднее" elseif button == 0 set buttonpressed to 0 Player.AddSpell StandardFrostDamageTarget1Novice Message "Используй эти знания мудро" endif endif end Как работает скрипт Первая часть скрипта содержит его название и объявляет переменные. scn aaaSpellTomeScript ;название скрипта short doonce ;переменная, для того, чтобы скрипт сработал только один раз short buttonpressed ;помогает знать, нажал или нет игрок на кнопку int button ;здесь будем запоминать какая кнопка была нажата Блок OnActivate исполняется каждый раз, когда вы открываете (активируете) книгу, и спрашивает вас, не желаете ли изучить заклинание, если вы его еще не изучили. begin onActivate if doonce == 0 ;если указан 0, значит игрок еще не знает заклинание, предлагаем его выучить MessageBox "Вы желаете изучить заклинание Снежный заряд?", "Да", "Нет, возможно позднее" set doonce to 1 ;ставим 1, чтобы более не спрашивать игрока set buttonpressed to 1 ;указываем скрипту, что игрок что-то выбрал else ;иначе - говорим игроку, что он уже знает это заклинание. Message "Вы уже получили все знания, которые содержатся в этой книге" endif end Блок GameMode исполняется каждый фрейм игры, проверяет, была ли нажата кнопка, и срабатывает, если это так. begin GameMode if buttonpressed == 1 set button to GetButtonPressed ;смотрим, какая кнопка была нажат if button == 1 ;если игрок решил отказаться от изучения set doonce to 0 ;говорим скрипту, что мы должны позже спросить игрока вновь set buttonpressed to 0 ;указываем, что игрок пока что ничего не выбрал Message "Хорошо, возможно вы пожелаете учиться позднее" ;подтверждаем выбор игрока elseif button == 0 ;если игрок выбрал вариант "Да", то есть хочет выучить заклинание set buttonpressed to 0 ;говорим скрипту, что хотим закончить проверку нажатий кнопок ;добавляем заклинание игроку (не забудьте изменить EditorID на свое заклинание) Player.AddSpell StandardFrostDamageTarget1Novice Message "Используй эти знания мудро" ; подтверждаем выбор игрока endif endif end Собираем все вместе Теперь всё, что нам осталось сделать, это собрать сделанное ранее в кучу. Давайте этим и займемся. Откройте окно редактирования своей книги, выберите в раскрывающемся списке script название своего скрипта (он должен быть в самом вверху). Если вы не можете его найти, перейдите вновь к редактированию своего скрипта и убедитесь, что вы установили тип скрипта как 'object', и сохраните свой скрипт (при этом не должно появится никаких ошибок). В этот моменты вы также можете добавить текст в книгу, чтобы описать, что именно дает книга, или просто что-то сказать игроку, который будет это читать. Имейте ввиду, что читать текст игрок будет только после того, как решит, учиться заклинанию или нет. Нажмите OK в окне и сохраните свой мод. Тестирование Прежде всего, вам нужно убедиться, что вы сохранили свой плагин, после чего вам нужно узнать FormID вашей новой книги заклинаний. Как только вы сделаете это, запустите OblivionLauncher и выберите «Файлы данных». Убедитесь, что ваш плагин отмечен и закройте окно. Как только вы окажетесь в игре, открывайте консоль (кнопка ~ (тильда)) и набирайте следующее: player.addItem [YOURFORMID] 1 замените [YOURFORMID] на Form ID книги, который вы нашли ранее. Откройте книгу и посмотрите на результат. Очень важное отступление от переводчика Есть пара важных моментов, на которых вы, наверняка, споткнетесь, если вы еще не являетесь хорошими знатоками редактора (а если вы таковыми являетесь, зачем вы это читаете?). Как узнать Form ID книги и что это вообще такое? Смотрим на картинку: Справа от столбца Editor ID идет на самом деле не столбец Count, как может показаться на первый взгляд. Вы можете видеть там рядом две полоски. Растяните их и увидите, что это скрытый еще один столбец - Form ID. Если вы поспешили записать его для вашей книги и уже готовы мчаться в игру проверять свой мод, я вас еще немного задержу. Посмотрите внимательно на рисунок. Если я зайду в игру и попробую для тестового вызова ввести в консоли что-то вроде этого: player.addItem 01000ED3 1 То, скорее всего, у меня ничего не выйдет. И я сейчас объясню почему. Form ID состоит из восьми цифр в шестнадцатиричной системе исчисления. Первые две это порядковый номер мода. Так как у меня в редакторе загружен мастер-файл Обливиона и мой мод, то первые две цифры предметов из моего мода будут показываться как 01. 00 – это предметы из мастер-файла, можете на рисунке и в редакторе в этом убедиться. Однако и это еще не всё. Дело в том, что у вас наверняка стоит Золотое издание Обливиона. А если так, то уже установлены официальные моды. А порядковые номера модов предметам раздаются в момент загрузки их в игру. То есть вот эта запись player.addItem 01000ED3 1 говорит игре – дай мне такой-то предмет из первого загруженного мода (01). Однако, у меня в Золотом издании мой мод стоит после всех официальных. И он получается аж двенадцатым esp-файлом. И чтобы вызвать предмет из него, мне нужно указать в порядковом номере цифру 12. Это будет выглядеть вот так: player.addItem 0С000ED3 1 С – это 12 в шестнадцатиричной системе исчисления. Конечно же, есть еще вариант сортировки модов при загрузке с помощью сторонних программ (например, OBMM). В этом случае вы можете принудительно поставить свой мод первым в загрузке и протестировать его не задумываясь обо всех этих цифрах. Кстати, то, что первые две цифры задают порядковый номер модов – одна из причин, почему мы не можем загрузить в игру более 255 модов. Две шестнадцатиричные цифры, выделеные для нумерации, в сумме могут давать всего лишь 256 комбинаций. Одна из них уже занята мастер-файлом (00). Остается 255. Проблемы Блок GameMode не выполняется, когда открыто какое-нибудь меню. Поэтому некоторые сообщения могут приходить немного с опозданием, когда вы закроете книгу и выйдете из инвентаря. Лучше (и проще) всего было бы давать игроку заклинание автоматически при активации книги (так как блок OnActivate не выполняется в меню), как бы то ни было, я хотел показать, как использовать MessageBox в данном контексте. Скрипт не учитывает, есть ли у игрока уже заклинание или нет. Это можно изменить, используя вместо переменной 'doonce', проверку на наличие у игрока заклинания. Книга Еще одна проблема – вы не сможете книгу взять или прочитать (кроме тестов, когда вы добавляете книгу в инвентарь через консоль). Если вы хотите, чтобы книгу можно было брать, открывать и читать, нужно просто добавить Activate после OnActivate: begin onActivate Activate if doonce == 0 MessageBox "Вы желаете изучить заклинание Снежный заряд?", "Да", "Нет, возможно позднее" set doonce to 1 set buttonpressed to 1 else Message "Вы уже получили все знания, которые содержатся в этой книге" endif end Теперь вы сможете читать книгу. Решение Мы можем решить эти проблемы, немного изменив и упростив наш скрипт: scn aaaSpellTomeScript short doonce begin onActivate Activate if doonce == 0 Player.AddSpell StandardFrostDamageTarget1Novice Message "Используй эти знания мудро" set doonce to 1 endif end Как видите скрипт стал проще, мы убрали несколько переменных, полностью выкинули второй блок. В этом варианте у нас не будут спрашивать, хотим мы изучить заклинание или не хотим. При первой активации этой книги мы автоматически выучим новое заклинание (при этом сможем сделать это лишь один раз) и сможем брать и читать книгу. Дополнение от авторов сайта На самом деле, данный скрипт, а именно его расширенная версия, не учитывает тот момент, что если книга взята, а заклинание не изучено, чтобы снова появился диалог с предложение изучить заклинание, книгу нужно выбросить из инвентаря и снова активировать. Решить проблему поможет дополнительный блок OnEquip: begin OnEquip player if doonce == 0 MessageBox "Вы желаете изучить заклинание Снежный заряд?", "Да", "Нет, возможно позднее" set doonce to 1 set buttonpressed to 1 else Message "Вы уже получили все знания, которые содержатся в этой книге" endif end И раз уж мы затронули эту тему, то нельзя не вспомнить про официальный DLC - SpellTomes. Он так же добавляет книги с заклинаниями, который игрок может изучить при прочтении. Давайте взглянем на один из его скриптов: scn DLCTomeSCRIPTDLCTomeSpellAundaesAura2Apprentice short button short used begin OnEquip player if used == 0 MessageBox "Do you want to add 'Aundae's Aura' to your spell list?", "Yes", "No" endif end begin OnActivate Activate if isActionRef player == 1 && used == 0 MessageBox "Do you want to add 'Aundae's Aura' to your spell list?", "Yes", "No" endif end begin menumode set button to getbuttonpressed if button > -1 if button == 0 ; add the spell to the player's spellbook player.addspell DLCTomeSpellAundaesAura2Apprentice playsound SPLRestorationCast set used to 1 endif endif end Как мы видим, отличий не много. Здесь отсутствуют лишние строчки с выводом сообщений, количество кнопок уменьшено до 2-х. Это, в итоге, позволяет нам отказаться от одной дополнительной переменной в коде. Но, в целом, смысл тот же. Работать будут оба варианта. Статья взята отсюда: https://modder.ucoz.ru/load/tutorial_po_skriptingu_kniga_obuchajushhaja_zaklinaniju/3-1-0-182, автор: Игорь Лютый (Igor Ra), которая, в свою очередь, является переводом данной статьи.
-
Данная запись является переводом статьи https://www.shrine-of-kynareth.de/scripting-oddities-in-oblivion. Я собираюсь использовать эту страницу для описания странностей, с которыми я столкнулся при попытке модифицировать Oblivion. В качестве базы я использую Elder Scrolls CS Wiki и буду записывать только то поведение, которое там не описано или прямо противоречит тому, что написано. RemoveMeIR Удаление элементов с помощью RemoveMeIR от игрока оставляет *что-то* после себя. Допустим, вы удалили яблоки из инвентаря с помощью RemoveMeIR. Если посмотреть инвентарь, яблок нет. Но если вы проверите инвентарь с помощью GetItemCount, он все равно вернет 1 яблоко, которые вы можете удалить с помощью RemoveItem, после чего GetItemCount вернет 0. Я еще не проверял, происходит ли то же самое с контейнерами. ResetInterior ResetInterior работает не так, как описано в вики. В вики написано: Помечает ячейку как просроченную, поэтому в следующий раз, когда игра будет сохранена или игрок войдет в ячейку, она будет очищена, как будто прошло несколько дней. Это не так. Эта ячейка будет полностью сброшена, удалено все, что вы бросите на пол, чего обычно не происходит, если ячейка сбрасывается после ожидания нескольких дней. Поэтому это хорошая функция для ячеек типа арены (фактически, арена — единственное место, где она используется), но плохая функция для домов игрока. SetDescription SetDescription имеет необязательный третий аргумент для установки текста перков, которые вы получаете при достижении уровня 25/50/75/100. Использование команды без третьего аргумента все равно установит все 5 текстов, обычное описание навыков, а также тексты всех четырех перков. Я не нашел способа установить только обычное описание навыков, не устанавливая при этом тексты уровня мастерства. OnSoulTrap Обработчик события OnSoulTrapможет вызвать сбои при использовании украденного камня души или, возможно, к которому прикреплена другая дополнительная информация, что делает его практически непригодным для использования. Примечание: В xOBSE этот баг был иправлен. Существует вероятность того, что в этом обработчике событий есть еще не исправленные ошибки. OnScriptedSkillUp OnScriptedSkillUp ведет себя странно. Если вы установите основные уровни навыков внутри обработчика события OnScriptedSkillUp, он будет игнорировать настройки игры для необходимых улучшений навыков. Если вы установите это значение на 100, как это делают многие моды уровней, чтобы иметь возможность отображать прогресс в %, любое значение, превышающее 9, все равно будет запускать повышение уровня. Используя точно такой же код внутри обработчика события OnSkillUp работает так, как ожидалось. Один из обходных путей, который я использовал, заключался в запуске квеста, который запускался и вносил желаемые изменения, а затем снова останавливался. Кроме того, получение перка с помощью скриптового повышения навыка (например, с помощью AdvSkill) не приведет к появлению обычного сообщения о перке со значком навыка и текстом, а создаст обычное окно сообщения. GetFirstRef Третий аргумент includeInactiveRefs в функциях GetFirstRef и GetNextRef не работает. Он никогда не найдет ссылки, которые были подставлены в него. SetHarvested В вики написано: Примечание: Изменения сохраняются в сэйве. После быстрого теста это, похоже, не так. После перезагрузки игры растения вернулись в прежнее состояние. Дальше тестировать не стал, так как в любом случае для меня это было недостаточно надежно. Update3D В вики написано: Эта команда в данный момент работает некорректно при вызове на игроке. Update3D похоже, по большей части работает на игроке, с некоторыми оговорками: Его можно использовать только тогда, когда игрок находится в режиме от третьего лица. При использовании на игроке, когда он верхом, игра вылетает. Оба условия можно проверить перед использованием. Кроме того, перед использованием этой команды можно перевести камеру в вид от третьего лица. ConScribe:DeleteLinesFromLog Функция DeleteLinesFromLog из мода ConScribe оставляет пустую строку в журнале всякий раз, когда она используется (я думаю, это было в конце журнала). Хорошей идеей может быть чтение всего журнала в массив, удаление всех пустых строк и последующее перестроение его время от времени (если вы регулярно удаляете из него строки). String Variables with % Возможно, это очевидно для других,к сожалению, не для меня: Если у вас есть строковая переменная, содержащая %,его нужно ввести как %%, чтобы распечатать как %.Если вы используете эту строковую переменную для создания другой строковой переменной, вам нужно удвоить ее. Допустим: let textPart := "I have a 100%%%% chance to mess that up" let textFull : "%z, and I don't like it" textPart Для этого даже есть хорошая функция, sv_Percentify, но, конечно, я обнаружил ее только после того, как целый час задавался вопросом, почему один из моих скриптов сломался. GoToJail Спасибо Кэт за то, что она выяснила это: эта функция работает только при использовании в результирующем скрипте диалога. Если у игрока есть какие-либо предметы, оснащенные с помощью EquipItem 1 (установлен флаг отсутствия возможности снятия), это приведет к сбою игры.