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

Ваш первый баг

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

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”? Это обеспечивает более четкую последовательность событий алгоритма, и как я уже отмечал ранее, для Морровинда это может оказаться очень важным, - старайтесь никогда не делать слишком много вещей одновременно! Ну, теперь запускайте и тестируйте новый вариант.

Здорово, теперь сундук открывается, как мы хотели, но что за такое? Курсор тормозит, и мы не можем закрыть меню инвентаря! Посмотрите, что мы запрограммировали выше - controlvar была установлена на «2», и так и осталась с этим значением, больше оно не меняется. Теперь игра непрерывно получает задание активировать сундук (функция “Activate”), это происходит каждый раз, когда выполняется скрипт, то есть каждый фрейм! Вот почему мы не можем закрыть сундук – он немедленно открывается снова. Тогда попробуем изменить следующий кусочек скрипта:

elseif ( controlvar == 2 )

Activate

Set controlvar to 3

endif

Тестируйте плагин еще раз: все работает так, как надо. Надеюсь, вас не смутила моя небольшая экскурсия по процессу отладки. Это очень важная часть обучения – вы должны постоянно прорабатывать свои скрипты и искать разные решения поставленных задач.

Чего не хватает? Конечно, ловушки!

Наложение заклинания на игрока

Наш сундук проклянет игрока, если он даст неправильный ответ.

Для начала откройте закладку “Spellmaking” в TESCS. С помощью правого клика вызовите в списке выпадающее меню и выберите “New”. Дайте заклинанию ID “Frost_Curse”, имя «Ледяное проклятие», установите его тип как “Curse” (Проклятие) и присвойте ему мощность, например, от 1 до 5 пунктов. Результат должен выглядеть так:

Теперь нам нужно наложить это проклятие на игрока. Для этого мы воспользуемся функцией “AddSpell”. Через какое-то время мы снимем проклятие, используя функцию “RemoveSpell”, и чтобы это время отмерить, нам понадобится таймер. Отредактируйте свой скрипт еще раз:

Begin my_first_script

Short controlvar

Short button

Float timer

If ( OnActivate == 1 )

If ( controlvar == 0)

MessageBox “Нету голоса - все же кричит, нету крыльев, а чем-то полощет, нет зубов - норовит укусить, нету рта, но все время бормочет. Что это?”, “Летучая мышь”, “Старуха”, “Ветер”, “Дух”

Set controlvar to 1

elseif controlvar > 1

activate

endif

endif

if (controlvar == 1)

set button to GetButtonPressed

if ( button == -1 )

return

elseif ( button == 2)

MessageBox "Ответ верный"

Activate

set controlvar to 2

else

MessageBox "Ответ неверный"

Player -> AddSpell, "Frost_Curse"

set controlvar to –1

Endif

elseif ( controlvar == 2 )

Activate

Set controlvar to 3

elseif ( controlvar == -1 )

Set timer to ( timer + GetSecondsPassed )

if timer > 10

Player -> RemoveSpell, "Frost_Curse"

set controlvar to -2

endif

endif

End

Теперь давайте с этим разберемся. Player -> AddSpell, "Frost_Curse" накладывает проклятие на игрока. Обратите внимание, мы использовали выражение “Player -> “ – это гарантирует, что эффект будет наложен именно на игрока. Если бы мы этого не сделали, по умолчанию проклят был бы не игрок, а сундук, в чем я, признаться, не вижу особого смысла…

Теперь вот этот кусок:

Float timer

Set timer to ( timer + GetSecondsPassed )

if timer > 10

…вот так вы можете создать таймер в Морровинде. Функция “GetSecondsPassed” возвращает в секундах время, прошедшее с последнего фрейма. Обычно это какие-то доли секунды (потому что скрипт прокручивается заново каждый фрейм), отсюда ясна необходимость использовать для данной переменной тип Float – тип, позволяющий содержать значения с плавающей точкой. Таким образом, наш таймер отсчитает десять секунд, и проклятие будет снято. При этом позаботимся о том, чтобы это событие случилось лишь один раз:

Player -> RemoveSpell, "Frost_Curse"

set controlvar to –2

Отлично, теперь сохраняйтесь и тестируйте свой мод. Работает отлично, не так ли? Ну, почти. Попробуйте вот что: дайте неправильный ответ, позвольте сундуку наложить на вас проклятие, и откройте меню инвентаря. Подождите. Видите, проклятие заканчивается спустя положенные десять секунд, никак вам не повредив? Ну конечно: скрипт продолжает работать и когда вы в меню, а вот заклинание работает только в игре. Мы же не хотим, чтобы игрок отделался от сундука так просто? В таком случае, нам нужно модифицировать скрипт таким образом, чтобы он приостанавливался на то время, пока игрок находится в меню. К счастью, для этого существует функция “MenuMode”, которая возвращает «1», если игрок находится в меню. Поэтому внесем в начало скрипта следующие изменения:

If ( MenuMode == 1 )

Return

Endif

Помните, команда “Return” заставляет игру приостановить скрипт на время данного фрейма.

Ну все, наконец-то мы пришли к законченной версии нашего скрипта. Мои поздравления! Если хотите, поэкспериментируйте со своим скриптом еще немного. Например, можно поместить сундук в определенную локацию в Морровинде и закрыть его. Попробуйте его открыть с помощью функции “Unlock”, модифицировав скрипт дополнением к функции “Activate”. Попробуйте озвучить момент открытия сундука, например, с помощью строки: PlaySound3D, “skillraise”. Можно также попробовать заменить функцию “AddSpell” функцией “Cast”, и т.д. Предыдущие пользователи заметили один баг – что случится, если игрок уйдет из локации с сундуком, до того, как проклятие будет снято? Как можно все исправить?

Вот окончательный скрипт:

Begin my_first_script

Short controlvar

Short button

Float timer

If ( MenuMode == 1 )

Return

Endif

If ( OnActivate == 1 )

If ( controlvar == 0 )

MessageBox “Нету голоса - все же кричит, нету крыльев, а чем-то полощет, нет зубов - норовит укусить, нету рта, но все время бормочет. Что это?”, “Летучая мышь”, “Старуха”, “Ветер”, “Дух”

Set controlvar to 1

elseif controlvar > 1

activate

endif

endif

if ( controlvar == 1 )

set button to GetButtonPressed

if ( button == -1 )

return

elseif ( button == 2 )

MessageBox "Ответ верный"

Activate

set controlvar to 2

else

MessageBox "Ответ неверный"

Player -> AddSpell, "Frost_Curse"

set controlvar to –1

Endif

elseif ( controlvar == 2 )

Activate

Set controlvar to 3

elseif ( controlvar == -1 )

Set timer to ( timer + GetSecondsPassed )

if timer > 10

Player -> RemoveSpell, "Frost_Curse"

set controlvar to -2

endif

endif

End