Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скрипты Morrowind.doc
Скачиваний:
92
Добавлен:
29.10.2018
Размер:
2.81 Mб
Скачать

Условия While

While ( condition )

; что-то делать

EndWhile

Команда while отличается от if тем, что она повторяется в течение одного фрейма, пока условие не будет выполнено. Вот хороший пример:

Short desiredAmnt

SetStrength 0

while( GetStrength < desiredAmnt ) ; переменная для совпадения

modStrength 1

endwhile

Это установит значение силы равным значению desiredAmnt за один фрейм. Следующий скрипт сделает это за неизвестное количество фреймов, потому что скрипт вызывается каждый фрейм:

if(getStrength < desiredAmnt) ; переменная для совпадения

modStrength 1

endif

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

Заметьте, что этим можно обойти некоторые функции, которые не принимают переменные как параметры.

Создание булевых операторов в скриптах tes

К сожалению, нет булевых операторов в скриптах (AND, OR, NOT, XOR, …). Потому вам придется имитировать их условиями if…endif.

Вместо AND:

if ( variable1 AND variable2 ); не существует

[делать что-то]

endif

вам придется использовать:

If ( variable1 )

If ( variable2 )

[делать что-то]

endif

endif

Для кострукции OR:

if ( variable1 OR variable2 )

[делать что-то]

endif

используйте конструкции elseif:

If ( variable1 )

[делай это]

elseif ( variable2 )

[делай то]

endif

Список функций tes Объяснение формата

В начале я буду записывать функцию и аргументы следующим образом:

[no fix] Code "string", arg_enum, var_float, [optional] (returns short)

[no fix] Указывает, что эта функция никогда не используется со стрелкой, то есть не может быть вызвана определенным объектом. Функции без этого префикса могут быть вызваны актером, объектом или теми, и другими.

Code: Имя функции

Аргументы функции: “string” указывает на строку, например ID объекта. arg_enum указывает на явное значение (не переменную). var_float указывает на переменную определенного типа (например, float). Скобки [] указывают на необязательные параметры. (returns short) или (returns float) указывают, что функция возвращает значение и обозначает его тип. Я буду использовать (returns Boolean/short), чтобы указать, что функция возвращает 1 или 0, так как в игре они имеют тип short.

Пример использования приводится курсивом и с отступом:

Code "ID", var_enum, var_float

Примеры скриптов заключены в рамку:

Begin script

[функции скрипта]

End script

С 8-ой редакции функции из Трибунала и Бладмуна находятся в соответствующих разделах руководства. Они обозначены:

для функций Трибунала

для функций Бладмуна.

Чтобы использовать эти функции нужно установить соответствующее дополнение (но не обязательно его активировать16). Бладмун и (выпуск GOTY) включает все функции и из Трибунала.

Работа с объектами Работа с вещами в инвентаре Добавление и удаление вещей из инвентаря

AddItem, "ObjectID", count_enum

RemoveItem, "ObjectID", count_enum

Actor -> AddItem, "item_ID", 1

Container -> RemoveItem, "itme_ID", 5

Эти функции достаточно просты, они добавляют и удаляют предметы из инвентаря игрока или других инвентарей, включая контейнеры. RemoveItem может удалить объект из инвентаря навсегда, и он исчезнет.

Примечание: Удаление предметов, которые отсутствуют в инвентаре, уменьшит общий вес предметов, даже если их там нет. Так что всегда проверяйте количество предметов в инвентаре, прежде чем будете их удалять. (Спасибо DinkumThinkum за эту инфу)

Не пытайтесь, чтобы предмет удалил сам себя через скрипт – это приведет к вылету (см скрипт-пример.)

Можно использовать отдельный глобальный или локальный скрипт, чтобы удалить такой предмет. Однако, если игрок имеет несколько копий одного предмета с скриптом, то RemoveItem может запороть данные на других объектах (вы это увидите в виде непонятных цифр). Экипировка или использование этого испорченного объекта может привести к вылету игры17 (DinkumThinkum, Информация с форумов)

Чтобы этого избежать:

1. Если объект не имеет скрипта, используйте GetItemCount, чтобы убедиться что игрок имеет хотя бы 1 объект.

2. Если на объекте есть скрипт, используйте GetItemCount, чтобы знать, что у игрока ровно 1 объект, или сделайте объект уникальным.

Функция Drop не имеет этого бага. Однако она может вызвать удвоение, если используется с OnPCEquip / SkipEquip, что может быть устранено добавлением и удалением любого предмета как описано для этих функций.

Использование Additem / Removeitem в диалогах: Эти функции могут принимать глобальные переменные и только в поле результатов диалога, и только если глобальная переменная не была установлена в том же диалоге (Информация с форума / Argent; Согласно нему, максимальное количество, которое ему удалось добавить, равнялось 65534 (используя переменную типа long = 2147483520)). Также убедитесь, что эта переменная не изменяется в этом же диалоге. Например, var_a равняется 3 в момент, когда ответ выбран в диалоге. Если поле результата выглядит так:

set var_a to var_a + 10 ;

AddItem gold_001, var_a

То только три дрейка будут добавлено, а нет 13. Если возникнет необходимость, то все вычисления объедините в одном ответе, добавьте оператор choice, ведущий на следующий ответ, и добавляйте уже там. Также, даже используя переменные типа long, я не смог добавлять предметов больше 32767. (Тестировалось на Морре без дополнений) (Информация с форумов / Kir)

Примечание по использованию контейнеров: Утверждалось, что только первая функция AddItem всегда работает с контейнерами, но после этого, игрок должен вручную получить доступ к сундуку (напр. добавить предмет), прежде чем AddItem будет иметь какой-то эффект (непроверенная информация с форумов). Если вы хотите добавить что-то в контейнер, который был опустошен, единственный способ, похоже, это удалить старый пустой контейнер и добавить новый вместо него (новый будет работать, пока в него что-то не положили, а затем вытащили. После этого его также нужно заменить.) К сожалению, единственный способ убедится, пуст ли контейнер – это узнать, есть ли там каждый предмет в игре (Информация с форумов / ThePal).

Пример:

Следующий скрипт обсуждался на форумах (извините, не помню, кто сделал его первым). Он должен спрашивать игрока, не желает ли он «переработать» предмет, который надет на нем, а затем заменить этот предмет «переработанным».

Begin scr_thing

short button

short OnPcEquip

short state

if ( MenuMode == 1 )

return

endif

if ( OnPCEquip == 1 ) ; когда предмет надет

set state to 1

set OnPCEquip to 0 ; делать это один раз после каждого одевания

endif

if ( state ==1 )

MessageBox "recycle?" , "yes", "no"

set state to 2

elseif ( state == 2 )

set button to GetButtonPressed

if ( button == 0 )

PlaySound "mysticism cast"

player->RemoveItem "item_a", 1 ;эта строка обрушит игру!!!

player->AddItem "item_b", 1

set state to 0

elseif ( button == 1 )

set state to 0 ; все сделано, сбрасываем в ноль

endif

endif

end

Он отлично работает без функции RemoveItem в нем, но с этой строкой игра рушится. Причина в том, что скрипт присоединен к item_a, а так как данный скрипт удалит этот предмет и должен удалить себя самого, игра вылетает. Так что эта идея должна реализовываться посредством глобального скрипта.