MenuMode возвращает 1, если игрок открыл меню (инвентарь). Обычно эти строки помещаются в каждый скрипт, чтобы он не исполнялся, когда у игрока открыт инвентарь. Диалоги, консоль, счетчик сна, похоже, также являются меню.
If ( MenuMode == 1 )
Return
Endif
Использование MenuTest, чтобы открыть и закрыть меню
Не документировано:
[no fix] MenuTest, short_enum
MenuTest ничего не возвращает, он, когда она вызывается, она закрывает определенные типы меню, например меню игрока, NPC и контейнеров. Не работает для меню диалогов, зачарования, алхимии, создания заклинаний или починки. (Информация с форумов / JOG, Jilin).
menutest или menutest 0 чтобы закрыть меню
menutest 3 открыть меню характеристик или сфокусироваться на нем
menutest 4 открыть инвентарь или сфокусироваться на нем
menutest 5 открыть меню заклинаний или сфокусироваться на нем
menutest 6 открыть карту или сфокусироваться на ней
для menutest 3,4,5,6, это работает как клик на верхней правой кнопке меню.
Пример:
if ( OnPCEquip == 1 )
set OnPCEquip to 0
coc Balmora
MenuTest
endif
Различные функции и переменные
Прерывание выполнения скрипта
[no fix] Return
Return прерывает выполнение скрипта для данного фрейма. Весь код после него в этом фрейме не будет исполняться. В следующем фрейме скрипт будет выполняться с начала.
If ( MenuMode == 1 )
Return
Endif
Внимание: Все, что ниже return, не будет исполняться, даже если условия там будут истинны, так что будьте внимательны.
Эти функции используются для управления глобальными скриптами. Глобальные скрипты начинают выполняться с помощью функции StartScript (из локального скрипта, другого глобального или поля result в диалоге) и завершаются функцией StopScript.
Примечание: Если вы используете StopScript, что скрипт завершил сам себя, то завершение не обязательно произойдет немедленно. Скрипт исполнится до слова End, и только потом завершиться. Так что используйте return для немедленного завершения скрипта.
Стартовые скрипты Трибунала в плагине начинают выполняться каждый раз, когда игра загружается, даже если они были завершены – см раздел Советы и Трюки «Определение, загрузился ли игрок» (Информация с форумов / DinkumThinkum).
Насколько я знаю, эти функции не работают с локальными скриптами, зато можно вызываться нацеленные скрипты использую «стрелку»: ObjectID -> StartScript (см также раздел Советов и Трюков).
Функция ScriptRunning возвращает 1, если скрипт выполняется и 0 в противном случае:
if ( ScriptRunning, CharGen == 0 )
StartScript CharGen
Endif
StopScript также может использоваться для создания однократных условий:
Begin do-once_script
[…]; делать что-то
StopScript do-once_script
End
Уменьшение и увеличение яркости
[no fix] FadeIntime_float_enum
[no fix] FadeOuttime_float_enum
[no fix] FadeToalpha_enum time_float_enum
FadeTo 50 2.0 ;(Затемняет экран на 50% за 2 секунды)
FadeIn и Fadeout затемняют экран (не объект) за указанное время (в секундах). Время > 0 и <= 10.0. FadeTo затемняет только на определенный процент: 0 – полная прозрачность, 100 – чернота.
Добавление локации на карту
[no fix] ShowMap"cell ID"
ShowMap "Gnisis"
Эта функция подсвечивает указанные ячейки. ID ячейки может быть полным или частичным, то есть все ячейки, которые начинаются с данной строки будут подсвечены на карте (например ShowMap "Vivec" покажет все кантоны).
Пример: чтение это книги покажет все указанные места:
Begin bookPilgrimsPath
if ( GetJournalIndex TT_PilgrimsPath >= 100 )
Return
endif
if ( OnActivate == 1 )
Journal TT_PilgrimsPath 100
ShowMap "Gnisis"
ShowMap "Vivec"
ShowMap "Ghostgate"
ShowMap "Koal Cave Entrance"
ShowMap "Fields of Kummu"
Activate
endif
End
См также консольную команду FillMap.
Присваивание случайных значений переменным
[no fix] Random, value_enum
Set my_variable to Random, 50
Введение в скрипт некоторой неопределенности — отличная возможность, и она может быть реализована функцией Random. Random возвращает значения между 0 и установленным значением–1. Так, в примере выше, my_variable примет значение между 0 и 49.
Заметьте, что глобальная переменная типа short Random100 принимает новые случайные значения между 0 и 100 в каждом кадре в игровом скрипте, так что вы можете использовать и ее.
Примечание: Для любого вызова Random с верхней границей больше 100, вариабельность возвращаемой величины становится все меньшей, вплоть до Random, 255, при котором получаются только 0 или 1, а любые попытки вызвать функцию при 256 приводят к вылету. (Морровинд и Трибунал). Это исправлено в Bloodmoon, так что там получается более ровное распределение вероятности и в интервалах, превышающих 100. Но вылет при 256 и 512, и т.д., все еще происходит (Информация от Neko). Также было обнаружено, что иногда верхняя граница функции Random устанавливается гораздо выше, чем заданное число. Установка верхней границы в одно из следующих чисел приводит к странному результату – возвращаемое число находится около 1100: 65, 66, 68, 70, 71, 76, 77, 79, 82, 83, 84.
Проигрывание видео
[no fix] PlayBink“filename” flag_enum
Останавливает игру и проигрывает видео. Установите флаг в 1, чтобы игрок мог прервать показ нажатием escape. Видео должно быть в формате Bink и помещено в папку Datafiles/Videos. MW по умолчанию загружает видео с CD, так что я не уверен, что это реально сработает. Возможно (не проверялось), что установив "TryArchiveFirst=-1" в файле Morrowind.ini можно повлиять на это (-1 Use raw data, 0 Use Newer, 1 use Archive Only). В противном случае придется искать no-CD патч, чтобы проигрывать собственное видео.
Эти функции используются для управления списками Уровневых Предметов (Leveled Item) и Уровневых Существ (Leveled Creature) прямо во время игры. Уровневые списки представлены парами объект/уровень, где уровень — требуемый уровень игрока для появления объекта. Функции AddTo добавят нужную пару объект/уровень в указанный уровневый список, если только тот уже не содержит также названную пару. Функции RemoveFrom удалят данную пару из уровневого списка. Также, если для функции RemoveFrom указать пару с уровнем –1, тогда все пары, содержащие данный объект, будут удалены.
Примечание: Функции RemoveFrom не удаляют существующий объект из мира. Если Уровневое Существо уже посчитано как определенное животное, то удаление этого создания из Уровневого Списка не повлечет за собой мгновенное исчезновение данного создания их мира. Тем не менее, это предотвратит появление данного Уровневого Существа в следующий раз.
Пример:
Активировав предмет с этим скриптом можно запретить и разрешить существование крыс в мире, удаляя их из списка Уровневых Существ и удаляя мясо крысы из списка Уровневых Предметов.
Функция GetSquareRoot возвращает корень квадратный от заданного числа. Полезно для вычисления векторов или расстояний (помните Пифагора?).
Функции уровня воды
[no fix] GetWaterLevel(float)
[no fix] SetWaterLevelnewWaterLevel_float
[no fix] ModWaterLevelwaterLevelChange_float
Отличная возможность для жестоких ловушек… Эти функции используются для того, чтобы определить и изменить уровень воды в текущей внутренней ячейке. Когда Актер внезапно обнаруживает себя под водой, он ждет, пока у него не останется половина запаса воздуха, а затем он начинает всплывать на поверхность по прямой линии. Плавающие тела движутся, не учитывая столкновений.
Примеры:
Этот скрипт должен висеть на ручке, чтобы она поднимала или опускала уровень воды в комнате.
Begin crank
short changelevel
float direction
float waterlift
short crankturn
short currcrank
float newwaterlevel
if ( MenuMode )
return
endif
if ( OnActivate == 1 )
if ( changelevel == 0 )
if ( direction == 1 )
set direction to –1
else
set direction to 1
endif
set changelevel to 1
endif
endif
if ( changelevel == 0 )
return
endif
set crankturn to 360 * GetSecondsPassed
set crankturn to crankturn * direction
set currcrank to GetAngle X
set crankturn to currcrank + crankturn
SetAngle X crankturn
set waterlift to 120 * GetSecondsPassed
set waterlift to waterlift * direction
ModWaterLevel waterlift
set newwaterlevel to GetWaterLevel
if ( direction == 1 )
if ( newwaterlevel >= 600 )
SetWaterLevel 600
set changelevel to 0
endif
else
if ( newwaterlevel <= 0 )
SetWaterLevel 0
set changelevel to 0
endif
endif
end crank
Это модифицированный скрипт “Float”, помещенный на всех объектах с точкой вращения в центре, чтобы они плавали на поверхности, вне зависимости от уровня воды. Он также заставляет объект прекратить дергаться, если игрок стоит на нем.
Begin NewFloat
float timer
float swingTime
float startAngle
float currangle
short reset
float xvalue
float zvalue
float zoffset
float tmpoffset
float weightoffset
set startAngle to GetStartingAngle, x
if ( MenuMode == 0 )
if ( timer == 0 )
if ( reset == 0 )
set timer to Random 100
set timer to timer / 4
endif
endif
set swingTime to 1
set timer to ( timer + GetSecondsPassed )
set currangle to GetAngle X
set xvalue to 10 * GetSecondsPassed
set zvalue to 5 * GetSecondsPassed
if ( GetStandingPC )
set zoffset to –30
SetAngle X 0
else
;rotate up
if ( timer < swingTime )
set currangle to currangle + xvalue
SetAngle X currangle
set zoffset to zoffset + zvalue
;rotate down
elseif ( timer < (swingTime * 3) )
set currangle to currangle – xvalue
SetAngle X currangle
set zoffset to zoffset – zvalue
;up again
elseif (timer < (swingTime * 4 ) )
set currangle to currangle + xvalue
SetAngle X currangle
set zoffset to zoffset + zvalue
;reset timer to zero
else
set timer to 0
set reset to 1
set zoffset to 0
SetAngle, x, startangle
endif
endif
set tmpoffset to GetWaterLevel
set tmpoffset to tmpoffset + zoffset
SetPos Z tmpoffset
endif
end NewFloat
Советы и трюки
Маленькие помощники: поиск, копирование и вставка текста
Хорошая функция для начинающего скриптера – это поиск текста в главном меню TES CS. Ее можно использовать для поиска скриптов, например, для нужной функции, которую вы хотите использовать и желаете узнать примеры ее использования.
Можно также использовать любые текстовые редакторы или альтернативные редакторы, указанные ниже, чтобы писать скрипты и копировать их в/из TES CS с помощью ctrl-c / ctrl-v.
Чтобы сделать копию скрипта, который вы хотите изменить, не меняйте имя, это просто перепишет старый скрипт. Вместо этого копируйте оригинальный скрипт (ctrl-a, ctrl-c), создайте новый, вставьте старый (ctrl-v) в него, переименуйте скрипт и изменяйте в нем что угодно.
Альтернативные скриптовые редакторы
1) MentalElf создал EMACS,который поддерживает табуляцию if-блоков и поддержку цветов:
http://www.aloha.net/~frann/rsg/
EMACS доступен под лицензией gnu (ссылка на страницу MetalElf)
2) Dave Humphrey создал MWEdit,альтернативный редактор с улучшенной поддержкой скриптов (Это только бета. Я ее быстро просмотрел, и она хорошо смотрится) http://mwedit.sourceforge.net/
Касательно скриптов, Dave приводит следующие фишки:
- Цветовая кодировка слов. Можно использовать обычную белую или синюю цветовую схему или любую другую, чтобы обозначать различные типы слов. Это может быть отключено. (см тригонометрический скрипт для примера)
- Выбрать шрифт в окне скриптов.
- Новый компилятор скриптов обнаруживает большее количество ошибок.
- Три уровня сообщений о предупреждениях / ошибках, что позволяет вам отрегулировать количество сообщений от компилятора.
- Компилятор добавляет пробелы в скрипт там, где они могут потребоваться (например, в конструкциях if)
- Типы объектов в функциях проверяются более строго. Если функция требует NPC, вы получите сообщение об ошибке, если используете другой тип.
- Компилирует скрипт при сохранении (без показа сообщений об ошибках)
- Экспортирует и импортирует скрипты в текстовые файлы.
- Показывает подробную справку по скриптовым функциям.
- Все сообщения компилятора показаны внизу в отдельной части окна. Двойной щелчок, чтобы перейти к месту, указанному в сообщении.
- Показывает подробную информацию на сообщения компилятора.
- Компилятор не позволяет использовать зарезервированные слова как имена переменных (такие как as end, X, Y[44] и т.д.)
- Использование функций, которые известны как неработающие, приведет к появлению сообщения компилятора.
- Простые помощники по функциям могут быть показаны для более быстрого написания скриптов.
Используйте стиль для написания нормальных скриптов
Это ограничение довольно спорное, ибо у каждого вырабатывается свой личный стиль.
И это звучит немного заносчиво.J Однако, я думаю это может быть полезно для новичков, и вот несколько моих замечаний по поводу стиля и безопасности скриптования:
· Используйте комментарии. В коротком скрипте это может показаться бесполезным, но даже здесь вы можете захотеть указать к какому моду/квесту/объекту относится этот скрипт, какое у него предназначение и т.д. Для длинных скриптов это становится необходимым для вас самих, если вы перестали работать на несколько дней, а также для тех, кто захочет поучиться на ваших скриптах. Объясняйте свои переменные, вставляйте заголовки в главные части скрипта, комментируйте главные части кода и т.д.
Используйте переменные состояния со стилем. В общем, из-за природы скриптов «выполнения единожды за кадр», это ваш главный п