SetDelete использоваться в комбинации с Disable[27], чтобы полностью удалить объект из игры. SetDelete 1 отмечает объект для удаления, SetDelete 0 снимает этот флаг. Это может быть полезно в оптимизации. Некоторые объекты симулируют свое поднятие отключением активированной копии, а затем добавлением нового объекта в инвентарь. Это оставляет невидимые объекты в игре (что съедает время процессора и память, так как скрипт на таких объектах все равно исполняется). Если копия отмечена для удаления, она полностью исчезает. Если это копия из мастер-файла, то она остается, но при этом не модели, ни скрипты не используются. Если копия была создана в игре, она исчезает навсегда.
Примечание: Использование SetDelete с любой другой функцией в одном и том же фрейме приведет к вылету.
Этот скрипт вылетит:
Begin _spell_effect
float timer
rotate y 120 ; вылет спровоцирован этим
if ( timer < 3 )
set timer to ( timer + GetSecondsPassed )
else
disable
setdelete 1
endIf
Решения этой проблемы – сначала отключение объекта, а затем используя GetDisabled и Return, безопасное его удаление:
Begin _spell_effect
DontSaveObject
float timer
if ( GetDisabled == 1 ) setdelete 1 return endIf
rotate y 120
if ( timer < 3 ) set timer to ( timer + GetSecondsPassed ) else disable endIf
Другое решение предложено Soralis, с использование локальной переменной "deletobj" как флага:
if ( deleteobj = 1 ) ;локальная переменная, установлена, когда хотите удалить
if ( deletetimer == 0 )
Disable
endif
if ( deletetimer < 10 )
set deletetimer to ( deletetimer + 1 )
endif
if ( deletetimer == 10 )
SetDelete, 1
endif
Return
endif
Также, вызывайте SetDelete только из скрипта того объекта, который хотите удалить. Object->SetDelete 1 обычно приводит к вылету. Предмет в вашем инвентаре тоже не должен удалятся, так как это приведет к неверному расчету нагрузки. Если вам действительно нужно удалить предмет из инвентаря, и вы знаете, что игрок его носит, то можно использовать команду Drop, перед отключением и удалением. Также иногда при использовании SetDelete магические эффекты вызывают проблемы (Информация с форумов / Dan_Wheeler).
Не сохранять изменений объекта
DontSaveObject
Вызывайте эту функцию, если не хотите, чтобы предмет сохранялся в сэйве. Используйте DontSaveObject на объектах, которые:
1. Могут быть включены/отключены в течение игры, например стадии постройки крепости.
2. Объекты, которые могут перемещаться, например объекты, на которых можно ездить.
Используя DontSaveObject, можно избежать раздражающего сообщения "save game data has changed" (данные сохраненной игры были изменены), когда объект в сэйве был изменен: например, подвинут или отключен/включен. Это потому, что данные об объектах хранятся в сэйве, например, был ли объект отключен/включен и т.д. (Информация с форумов / IndigoRage).
В оригинальной игре она используется в скрипте SignRotate и в следующем:
Пример:
Begin diseaseAscended
DontSaveObject
; поднявшиеся спящие по какой-то причине все заражены мором...
Чтобы NPC шел между двумя определенными точками в игровом мире, используйте AITravel.
Переменные – мировые координаты x, y, z. Их можно определить, переместив камеру к желаемой точке, или выбрав точку на сетке пути, или объект, в результате координаты будут показаны внизу окна объектов. Использование необязательного флага reset неизвестно.
Когда эта функция используется в скриптах, важно, чтобы она вызывалась только один раз. Посмотрите на следующий скрипт на NPC
Begin Travel
AiTravel, 1359, 2700, 1045
End Travel
Он не будет работать, так как скрипт постоянно добавляет NPC AITravel, и NPC застывает вместо того, чтобы идти.
Begin Travel
Short do_once
If (do_once==0)
AiTravel, 1359, 2700, 1045
Set do_once to 1
endif
End Travel
Это должно работать, NPC пойдет в нужную точку, как только скрипт станет активным, то есть при загрузке ячейки.
Проверка, завершил ли NPC свое движение
GetAIPackageDone (returns Boolean/short)
if ( GetAIPackageDone == 1 )
[делать что-то]
endif
Чтобы проверить, пришел ли NPC в нужное место, можно использовать GetAIPackageDone. Эта функция возвращает 1 в том фрейме, когда текущий пакет ИИ завершен.
Используйте это, чтобы проверить завершено ли движение. Этот скрипт показывает, как соединить несколько функций AITravel в одном скрипте, используя переменную состояния и конструкции if-elseif:
Begin TravelLoop
short state
float timer
if ( menumode == 1 ) ; если меню открыто - не исполнять
return
endif
;начало движения
if ( state == 0 )
if ( player -> GetDistance HB_adros_darani < 5000 )
set state to 5
endif
;******************* Он начинает свой путь
elseif ( state == 5 )
SetHello 0
AITravel -8144, -19409, 728 ;new co-ords point 1
set state to 10
elseif ( state == 10 )
if ( GetAIPackageDone == 1 ) ;он пришел в точку 1
set state to 40
endif
elseif ( State == 40 )
AITravel -9147, -19459, 720 ; новые координаты точки 2
set State to 50
elseif ( state == 50 )
if ( GetAIPackageDone == 1 ) ;он пришел в точку 2
set state to 60
endif
elseif ( state == 60 )
AITravel -8144, -19409, 728 ; новые координаты точки 1
set state to 70
elseif ( state == 70 )
if ( GetAIPackageDone == 1 ) ;он пришел в точку 1
set state to 80
endif
elseif ( state == 80 )
AITravel -6640, -18496, 1040 ;новые координаты точки 0
set state to 90
elseif ( state == 90 )
if ( GetAIPackageDone == 1 ) ;он пришел в точку 0
set state to 0
endif
endif
End TravelLoop
Хорошие примеры скриптов с AITravel можно найти в “lookoutscript” (Фаргот, прячущий сокровища) и CharGenWalkNPC (страж, идущий по кораблю в начале игры). Или поглядите мой плагин Traveling Merchants, что понять, что такое настоящее безумное использование AITravel J !
Если вы планирует широко использовать эту функцию, то вам следует знать о следующих проблемах: когда вы покидаете ячейку с путешествующим актером, или вы отдыхаете, скрипт никогда не выполнит условие с GetAIPackageDone, так как ваш NPC стоит все то время, когда вы не в ячейке или спите. Следующий простой код заставит скрипт снова работать (это для предыдущего скрипта)
; *************** Спасение скрипта – восстанавливает скрипт после выхода из ячейки или сна
If ( Player -> GetDistance, HB_adros_darani < 5000 )
if (GetCurrentAIPackage == -1) ; проверка бездействия
set timeout to ( timeout + GetSecondsPassed )
if ( timeout >= 3) ; ждем некоторое время.
; иногда актер бездельничает понемногу
set state to (state - 10) ; переход к следующему состоянию