×
Menu

TES CS - Script magic

Примечание.
Скрипты.
Взято с Фуллрест(С) Larkin(С)
http://www.fullrest.ru/forum/topic/18520-openmw-ili-mechty-inogda-sbyvayutsya/page-94#entry967388
Насколько я знаю скрипты запускаются в каждом кадре не в алфавитном порядке а в порядке их создания в редакторе (в порядке их внутренних ID). При этом вроде нет разницы глобальный\локальный скрипт.
startscript не передает управление в другой скрипт (это не вызов функции) а дает указание что скрипт должен начать исполнятся со следующего кадра.
stopscript предотвращает запуск скрипта и снимает цель на которую скрипт запущен. Важный момент, startscript не меняет цель если цель уже есть, даже если попытаться перенаправить его на другую цель. Чтобы это правильно работало, нужно перед вызовом startscript FOO вызвать stopsript FOO. stopsript очистит цель и startscript сможет принять новую цель.
Я обнаружил это, когда клепал плагин про отображение урона.
 
Все скрипты, как и диалоги начинают писаться с низу!
Т.е. самое первое тригерное условие скрипта, должно находится в низу оного, а последующие Return отсекают его  от повторного выполнения.
Это оптимизирует скрипт и предотвращает повторное срабатывание.
Условия требующие постоянного мониторинга, должны находится выше.
А оптимизаторы:
;************************************************************
if ( MenuMode == 1 )
    return
endif
;************************************************************
If ( framecounter < 10 )
    set framecounter to ( framecounter + 1 )
    Return
Endif
set framecounter to 0
 
Хотя скрипт и пишется с конца, но читается Игрой, от своего начала! 
Тоже самое и с диалогами!
 

Идлы анимации и скрипты.
 
Или собираем мульти-скелет!
Сей способ способен существенно разнообразить кол-во, практически любых предметов, без необходимости создавать новые ИДЕ, или модели.
*Все на что можно повесить скрипт.
 
Примечание.
С использованием МВСЕ 2.0 можно применить niSwitсhNode, это позволит обойтись без создания анимаций в 3д МАХ.
Т.е. вложенные объекты будут статичны.
А скрипт, будет лишь переключать отображаемый объект.
Однако, могут быть некоторые сложности:
- состояние объектов не сохраняется игрой.
- неизвестно придельно допустимое кол-во вложенных объектов.
 
Вариант 1.
 
1.     создать в максе объект. Создать его копии и, внести в них некоторые изменения придающие им уникальности.
2.     Прописать анимацию через НотеТрек. Не важно сколько ключей, но, наверное можно рекомендовать 3.
3.     В самих объектах анимация не нужна, они просто должны быть в некотором кол-ве.
4.     Кол-во анимационных групп, ограничено кол-вом записей оных в движке.
5.     Теперь самое забавное! Применить к объектам контроллер невидимости, согласно Нотам в Треке.
6.     В каждую группу анимации виден только один объект. Это лучше делать в 5.1 максе.
7.     Учитывая, что на объектах нет кейфрейм контроллера, то подойдет экспорт официальным модулем.
8.     Все экспорт и полировка в нифскопе!
 
Вариант 2.
 
На примере обычного скелета с костями и прочим.
 
1.     скелет помещаем в позу Х.
Завершение оной позы означит ключами Ноте Трека «loop Start, Loop Stop и STOP» в одном фрейме!
Старт — может находится  в любом ином фрейме, но лучше не сильно отстоящем от финальной позы.
Фиксируем ключи всех анимированных костей в финальном фрейме!
2.     Создаем позу Y!
Все тоже самое, пара ключей входа и смены позиции, Петля и Завершение всей анимации в одном фрейме.
Если конечно не нужно, что бы костлявый нервно шевелился в своем положении!
*впрочем если он изображает из себя "древнего узника", на сквозняке, то это будет оправдано...
3.     И так далее, создаем энное кол-во поз и всем прописываем значения в Ноте Треке.
4.     Экспорт Нифтулз модулем!
5.     Контроллер невидимости НЕ нужен.
6.     Оптимизация и очистка нифскопом.
 
Завершив настройки моделей переходим в Тес Кс!
 
Теперь, все что остается, это создать целевой объект и повесить на него примерно такой скрипт.
 
begin AAA0000_animCorpseBIG
 
; рандомная анимация скелетов...  увеличено кол-во групп анимаций.
; в данном случае, одно "тело" содержит более 15 вложение! Значит один скелет, может оказаться в 15 позах\видах\положениях.
;*****************************************************************
short RandomPF ;случайна переменная.
short Doonce ;фиксатор.
;**************************************
DontSaveObject ;не писать в сохранение.
;*****************************************************************
if ( menumode == 1 )     ;не выполнять под меню. Дополнительная оптимизация, сокращающая нагрузку на Игру, по идее.
return
endif
;*****************************************************************
;if ( onActivate == 1 ) ;проверка активации. Скрипт работает и без этого.
; activate
; return
;endif
 
If ( doonce == 1 ) ; Собственно блокирует дальнейшее изменение позы тела после первичного изменения.
return                 ;стек находится выше всех прочих условий, отсекая RETURN-ом их исполнение.    
endif
;***************************************************************
if ( RandomPF == 1 ) ;генератор случайных чисел определяет в случайном порядке случайную группу анимации.
PlayGroup IDLE, 1   ;собственно вот.
set Doonce to 1 ;а это заблокирует дальнейшее исполнение скрипта. См выше.
elseif ( RandomPF == 2 )
PlayGroup IDLE2, 1
set Doonce to 1
elseif ( RandomPF == 3 )
PlayGroup IDLE3, 1
set Doonce to 1
elseif ( RandomPF == 4 )
PlayGroup IDLE4, 1
set Doonce to 1
elseif ( RandomPF == 5 )
PlayGroup IDLE5, 1
set Doonce to 1
elseif ( RandomPF == 6 )
PlayGroup IDLE6, 1
set Doonce to 1
elseif ( RandomPF == 7 )
PlayGroup IDLE7, 1
set Doonce to 1
elseif ( RandomPF == 8 )
PlayGroup IDLE8, 1
set Doonce to 1
elseif ( RandomPF == 9 )
PlayGroup IDLE9, 1
set Doonce to 1
elseif ( RandomPF == 10 )
PlayGroup DEATH1, 1
set Doonce to 1
elseif ( RandomPF == 11 )
PlayGroup IDLEHH, 1
set Doonce to 1
elseif ( RandomPF == 12 )
PlayGroup IDLE2W, 1
set Doonce to 1
elseif ( RandomPF == 13 )
PlayGroup IDLE2C, 1
set Doonce to 1
elseif ( RandomPF == 14 )
PlayGroup IDLE1h, 1
set Doonce to 1
elseif ( RandomPF >= 15 ) ;кроме идолов использованы записи анимаций кончин и заклинаний.
PlayGroup IDLESpell, 1
set Doonce to 1
return
endif
endif
;***************************************************************
if ( GetDistance Player <= 3072 ) ; это начало скрипта! Т.е. Они читаются снизу вверх, а также, это позволяет отсекать
set RandomPF to Random 16 ; едино разовые части от повторного выполнения. Рандом, всегда на 1 больше!
Return
endif
 
end
 
Но надо заметить МВ ДИКО не любит анимированные контейнеры и часто начинает выделывать невероятные «выкрутасы».
Улетая в Краш на ровном месте!
Но, это целая отдельная, исполненная «темной мистики» тема.
Поэтому, с контейнерами надо быть весьма острожным!
Впрочем, использование «мульти-скелета» имеющего всего одну модель на все останки, кажется работает относительно стабильно.
 

Примечание.
Можно думать, что создание таким образом разнообразных растений, ящиков, активаторов, дверей и светильников вполне реально!
*При этом - работает даже с переносными светильниками!
*В руках, как кажется, работает только базовая анимация Нулевого Идола. При выкладывании в мир, флаг, также очищается. Т.е. нулевой идол.
*Но это легко поправить изменив скрипт.
 
Примечание.
Двери, активаторы, светильники - работают через Хниф файл.
*проверено.
Предметы, оружие, броня, бодипарты, книги, ингредиенты, ремонтные и пр. объекты, а также СТАТИКИ.
НЕ понимают Хниф, работая только через Ниф файл.
*попытки подклеить разного рода Текстовые Экстрадаты в Нифы предметов, не дали результата, увы.
*проверено.
 
Отчего продвинутые "технологии" анимирования, остаются в пролете, увы.
Но если, это безобразие, будет когда-нибудь поправлено, получится создавать огромное кол-во новых объектов, без необходимости создания новых Иде!
Рандомные строения, деревья, драг-камни, шкуры животных... Наверное, это было бы весьма занятно!

Мульти-Скелет в действии!

А этот скрипт вешается на статичный светильник, типа Костра.
И проигрывает анимацию в зависимости от погоды!
 
Begin AAA000_faerToWeater
;*******************************************
Short framecounter
;*******************************************
DontSaveObject
;*******************************************
if ( MenuMode == 1 )
return
endif
;*******************************************
If ( framecounter < 15 ) ;оптимизатор скрипта, дабы не частил с выполнением, говорят это разгружает процессор. Думается, что и в скрипт Скелета.
set framecounter to ( framecounter + 1 )     ;можно добавить этот стек.
Return
Endif
set framecounter to 0
;*******************************************
if ( GetInterior == 1 ) ;Обязательна проверка в помещении! Иначе будет ерунда.
PlayGroup IDLE 1
return
endif
;*******************************************
if ( GetInterior  == 0 ) ;если модель вне помещения, то идет опрос на тип погоды.
if (GetCurrentWeather == 0 )
PlayGroup IDLE 1
elseif (GetCurrentWeather == 1 )
PlayGroup IDLE2 1
elseif (GetCurrentWeather == 2 )
PlayGroup IDLE3 1
elseif (GetCurrentWeather == 3 )
PlayGroup IDLE4 1
elseif (GetCurrentWeather == 4 )
PlayGroup IDLE5 1
elseif (GetCurrentWeather == 5 )
PlayGroup IDLE6 1
elseif (GetCurrentWeather == 6 )
PlayGroup IDLE7 1
elseif (GetCurrentWeather == 7 )
PlayGroup IDLE8 1
elseif (GetCurrentWeather > 7 ) ;версия под М+Т-Б, поэтому снегопад и буран не имеют особой анимации.
PlayGroup IDLE 5
return
endif
Endif
end

МультиКостер - в действии!
*в данном случае, работает через тестовый активатор.