Перейти к содержанию

Проблемы с таймером


Рекомендуемые сообщения

Ниже приведен скрипт, управляющий действиями Аэдра Магнуса: после того, как игрок вступает с ним в бой, Магнус пытается сначала поразить игрока с помощью заклинаний; затем, по истечении 10 секунд, если игрок все еще жив, Магнус должен применить более действенные средства для его уничтожения, для чего его интеллект (и, следовательно, магия) обнуляется.

Необходимость такого управления его действиями - обусловлена тем, что у Магнуса есть "Мантия Вечности", которая, помимо всего прочего, увеличивает его интеллект на 9000 и восстанавливает магию 100 (эффект постоянный) - понятно, что умнейший из Аэдра не должен тупо обстреливать заклинаниями игрока, если видит, что это бесполезно.

Ошибка заключается в том, что таймер принимает какое-то фиксированное значение до 1 (часто - 0,2000 или 0,9400), и дальше не растет (проверял через sv), так что команды на таймере равном 10 не выполняются (хотя, если приравнять таймер 10 с помощью консоли, все выполняется).

В сходном скрипте, управляющем другими Аэдра, также имеется обнуление магии, но там оно вызывается при условии драки с игроком и если один из Аэдра уже уничтожен (GetTarget и GetDeadCount), и там оно работает (хотя те Аэдра имеют сходные мантии) - значит, ошибка связана с таймером.

 

begin MagnusScript

 

float timer

short combatOnce

short Easing

short noLore

short trigger

 

if ( MenuMode == 1 ); ошибка вызывается не этим (таймер глючит и при отсутствии этих строк)

return

endif

 

If ( GetJournalIndex "1_1_1_1" >= 10 ); загрузка после заданного события

 

enable

 

else

disable

 

endif

 

if ( timer >= 10 )

if ( Easing == 0 )

ModFlee 50; устрашение живучестью игрока

SetIntelligence 0; обнуление магии

set Easing to 1

set timer to 0

endif

endif

 

if ( combatOnce == 1 )

if ( timer < 10 ); ошибка не вызывается этим (есть и при отсутствии этого условия)

set combatOnce to 0

set timer to ( timer + GetSecondsPassed )

endif

endif

 

if ( GetTarget, Player == 1 )

if ( combatOnce == 0 )

if ( trigger == 0 )

set combatOnce to 1; запуск ослабления

set trigger to 1; однократность ослабления

endif

endif

endif

 

if ( onDeath == 1 )

PlaySoundVP "endboom2" 1.0, 0.5

StreamMusic "Explore\WIexplore11 - WindPrayer.mp3"

endif

 

end MagnusScript

Ссылка на комментарий
Поделиться на другие сайты

Ну, по этому скрипту:

 

If ( GetJournalIndex "1_1_1_1" >= 10 ); загрузка после заданного события
enable
else
disable
endif

нельзя заставлять объект появлятся или исчезать кадый фрейм. Для этого используют функцию GetDisabled:

GetDisabled == 0
disable
endif
GetDisabled == 1
enale
endif

Далее. Вижу что локальная переменная trigger уже в втором фрейме установится в 1, но не вижу где она установиться в 0. Пока этого не будет, скрипт будет выполнятся лишь 2 фрейма.

 

Кроме того я не вижу в скрипте того отправного момента, когда начнется отсчет времени. Обычно какие-то важные сюжетны потасовки начинаются после диалога.

 

А вообще, можно было сделать проще:

if ( combatOnce == 1 ) ; на 1 выставляем в момент, когда драка началась
set timer to ( timer + GetSecondsPassed )
if ( timer >= 10 )
if ( GetTarget, Player == 1 ) ;можно использовать и другие типа Player->GetHealth > 0
ModFlee 50; ИМХО лишнее
SetIntelligence 0
set combatOnce to 2
endif
endif
endif

 

этого достаточно чтобы отсчитать от начала драки 10 сек. и проверить жив ли игрок

если жив - выполнить нужные действия.

Впрочем можно даже не проверять жив игрок или нет. Потомучто в случае смерти вылезет меню конца игры.

Возможно стоит подумать над тем, чтобы условием ослабления была достаточно близакая дистанция между игроком и монстром.

А то вдруг игрок тупо спасется бегством. а через 10 сек получит ослабленного бегом противника. :D Хотя тут по ситуации.

 

onDeath наверное лучше заменить на GetDeadCount >= 0 ибо она более корректна

Изменено пользователем TJ
Ссылка на комментарий
Поделиться на другие сайты

Переменная trigger - всего лишь устанавливала ОДНОКРАТНОСТЬ обнуления магии: как только GetDetected = 1, и если trigger и combatOnce равны нулям - то оба устанавливаются в 1 - поскольку trigger дальше не изменяется, то этим обеспечивается однократность обнуления.

Проблема оказалась в том, что блоки if-endif на условие таймера должны идти сразу после запуска таймера (timer + GetSecondsPassed) - после такого исправления все стало работать (хотя странно, почему ошибка оказалась в этом: в скриптах, управляющих стихийными бедствиями, я использовал сходные конструкции, и они почти никогда не дают сбоев).

Насчет загрузки Магнуса при условии GetJournalIndex - это обычный способ заставить NPC, активатор и т. п. появляться при появлении некоторой записи в журнале - такая конструкция есть в Wizards Islands, и с ней никогда не было ошибок. Эта конструкция весьма стабильна: если есть искомая запись в журнале, то даже установив Магнусу Disable через консоль, он тут же появится снова.

Начало битвы с Магнусом - действительно начинается из диалога, когда наивный игрок спешит проинформировать его о своей победе в битве с правителем Аэдра Монотеархом Анурром.

Может ли игрок спастись бегством, а затем атаковать ослабленного Магнуса - нет, потому что Мантия Вечности дает ее владельцу постоянную 100-кратную левитацию; и если Магнус игрока и не испепелит на расстоянии (достаточно 2 секунды, даже если здоровье игрока равно 10000), то одного удара его посоха достаточно для уничтожения не то что игрока, но кого бы то ни было (вот почему нужно обнуление магии - чтобы игрок не успел сбежать).

Магнус в моем плагине, будучи самым умным и коварным из всех Аэдра, предает Анурра, направляя к нему воскресшего Падомая (понятно в чьем теле...), а под конец решает расправиться и с ним. Поэтому ModFlee нужно - было бы странно, если бы коварный и осторожный Магнус был бы безрассудно храбрым.

 

begin MagnusScript

 

float timer

short combatOnce

short NoFlee

short NoIdle

short NoIntruder

short noLore

short NoThief

short trigger

 

if ( MenuMode == 1 )

return

endif

 

If ( GetJournalIndex "1_1_1_1" >= 10 )

 

enable

 

else

disable

 

endif

 

if ( combatOnce == 1 )

set timer to ( timer + GetSecondsPassed )

 

if ( timer >= 10 )

ModFlee 50

SetIntelligence 0

set combatOnce to 0

set timer to 0

endif

endif

 

if ( GetTarget, Player == 1 )

if ( combatOnce == 0 )

if ( trigger == 0 )

set combatOnce to 1

set trigger to 1

endif

endif

endif

 

if ( onDeath == 1 )

PlaySoundVP "endboom2" 1.0, 0.5

StreamMusic "Explore\WIexplore11 - WindPrayer.mp3"

endif

 

end MagnusScript

Ссылка на комментарий
Поделиться на другие сайты

  • 5 месяцев спустя...

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...