Модератор форума: Kris†a™  
Форум » TES V: Skyrim » Мастерская » Вопросы по скриптам Papyrus (О скриптах Papyrus (Skyrim). Скриптеры не проходите мимо!)

Вопросы по скриптам Papyrus
sansuli  Offline  Сообщение №1 написано: 31 Август 2012, 17:29 | Отредактировано: Multigone - 23 Апрель 2020, 17:24


The Red Sun


193
Уроки по скриптованию на языке Papyrus
Прежде чем задать вопрос просмотрите вышеуказанные уроки.
ok


Тема регламентирована.


• Прежде, чем задать вопрос, пожалуйста, убедитесь, что такой вопрос не задавался раньше. Старайтесь описать суть вопроса как можно подробней.
• Прежде, чем опубликовать ответ на вопрос, пожалуйста, убедитесь, что обладаете необходимыми для этого знаниями. Старайтесь cформулировать суть ответа как можно лаконичней.
• При желании ответить в приватном порядке, пожалуйста, воспользуйтесь ЛС.
• При желании поблагодарить ответившего, пожалуйста, воспользуйтесь кнопкой "
+" полезного сообщения.

Сообщения, не относящиеся к вопросам по скриптам Papyrus, ответам на них или уточнениям, являются оффтопом и могут быть удалены.

Красное солнце
Есть вопросы по скриптам Papyrus? Пиши не в ЛС, а в эту тему.
Multigone  Offline  Сообщение №2971 написано: 3 Октябрь 2020, 01:56



719
VictorCorvin,


Код
Scriptname _TESTTEST62 Extends ActiveMagicEffect

    ; нужен тест
    ; на эффект зелья (FF-Self, какая-то длительность действия)
    ; заполнить Property

HeadPart Property MyHeadPart Auto
    ; модные глаза, доступные всем расам

Spell Property MySpell_1 Auto
Spell Property MySpell_2 Auto
Spell Property MySpell_3 Auto
    ; пассивные эффекты - заклинания Ability-Constant-Self
    
HeadPart CurrentHeadPart
    
EVENT OnEffectStart(Actor xT, Actor xC)
    IF xT != Game.GetPlayer() || xT.IsOnMount()
        Dispel()
        RETURN
    ENDIF
    GoToState("Work")
    ActorBase xB = xT.GetBaseObject() AS ActorBase
    Int iC = xB.GetNumHeadParts() - 1
    WHILE iC >= 0 && xB.GetNthHeadPart(iC).GetType() != 2
        iC -= 1
    ENDWHILE
    CurrentHeadPart = xB.GetNthHeadPart(iC)
    xT.ReplaceHeadPart(CurrentHeadPart, MyHeadPart)
    xT.QueueNiNodeUpdate()
    xT.AddSpell(MySpell_1, false)
    xT.AddSpell(MySpell_2, false)
    xT.AddSpell(MySpell_3, false)
ENDEVENT

STATE Work
    EVENT OnEffectFinish(Actor xT, Actor xC)
        xT.RemoveSpell(MySpell_1)
        xT.RemoveSpell(MySpell_2)
        xT.RemoveSpell(MySpell_3)
        xT.ReplaceHeadPart(MyHeadPart, CurrentHeadPart)
        WHILE xT.IsOnMount()
            Utility.Wait(1.0)
        ENDWHILE
        xT.QueueNiNodeUpdate()
    ENDEVENT
ENDSTATE

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

mka_n  Offline  Сообщение №2972 написано: 3 Октябрь 2020, 09:25



6
Привет!
Подскажите как посчитать вещи одетые на персонажа с определенным кейвордом.
if Game.GetPlayer().WornHasKeyword(ArmorType) - эта конструкция возвращает true.
А точное кол-во как получить?

Multigone  Offline  Сообщение №2973 написано: 3 Октябрь 2020, 10:12



719
mka_n,

Без SKSE - есть Conditions (WornApparelHasKeywordCount, см. PerkMatchingSet).
Со SKSE - проверяются и считаются предметы, надетые в соотв. слоты актера (GetWornForm(int slotMask), применение см. в Armor.psc).

mka_n  Offline  Сообщение №2974 написано: 3 Октябрь 2020, 16:58 | Отредактировано: Multigone - 4 Октябрь 2020, 14:13



6
Цитата Multigone

Без SKSE - есть Conditions (WornApparelHasKeywordCount, см. PerkMatchingSet).

Спасибо. Но этот Conditions не работает по неведомой мне причине с моим кейвордом(( А если цеплять из skyrim.esm любой то отрабатывает как надо.

VictorCorvin  Offline  Сообщение №2975 написано: 3 Октябрь 2020, 18:52



8
Multigone  огромное Вам спасибо. а Вы не подскажите как можно ввести этот скрипт без Creation Kit?А то у меня это прога постоянно вылетает когда пытаюсь войти в закладку скриптов.

Multigone  Offline  Сообщение №2976 написано: 3 Октябрь 2020, 20:50



719
VictorCorvin, никак. Нужно разобраться, почему вылетает, это не нормальное поведение СК. В общем случае:

Для изменения Property ванильных скриптов (.pex), они должны быть распакованы из Skyrim - Misc.bsa в Data/Scripts (туда же скрипты из DLC).
Для просмотра текста скриптов и компиляции, их исходники (.psc) должны находиться в Data/Scripts/Source (исходники не поставляются с игрой с какой-то версии, их нужно качать отдельно, где именно - без понятия, у меня нет лиц. Скайрима).
Если подключенный мод использует SKSE, но SKSE не установлено в файлы игры, возможны вылеты из нее (насчет СК - без понятия).
В SE версии Скайрима, возможно, есть какие-то фундаментальные отличия в работе скриптов (не в курсе, вот соотв. раздел).

Тут обучение (что есть).

yakor77  Offline  Сообщение №2977 написано: 4 Октябрь 2020, 13:22 | Отредактировано: Multigone - 4 Октябрь 2020, 14:11



28
Виктор Корвин, для конвертации из pex в psc, и обратно - существуют утилиты. "Качать исходники" нет необходимости, их можно получить и самому. Лично я, давно и успешно, использую вот этот пакет. Вот его дословный текст рекламки: "Уникальная программа, которая очень поможет модермейкерам, которые работают со скриптами.
Большинство авторов пытаются скрыть написанный скрипт и просто удаляют его оставляя только компилированный файл в расширении .pex, но эта программа поможет нам вытащить из него скрипт! Как это делается?
Да просто, для начала распакуем всё из архива в папку, я назвал её: Декомпиляция, далее устанавливаем vcredist файл, берём любой .pex файл и нажимаем открыть с помощью, находим нашу папку Декомпиляция и файлик "Champollion", открываем с помощью него и он выдаёт нам текстовый файл со скриптом. Аллилуя!
Спасибо Фантому! Автор: li1nx. Ссылка.

С уважением.
Маг Иридий.
CYNIC78  Offline  Сообщение №2978 написано: 14 Октябрь 2020, 18:05 | Отредактировано: Multigone - 18 Октябрь 2020, 16:16



5
Всем привет. Я снова с вопросом по парным анимациям. С вашей помощью мои парные анимации  работают отлично в том числе и в бою, персонаж больше не застревает в положении когда не может пользоваться магией\оружием пока не зайдет в инвентарь. Если кому интересно, вот пример кода

Код
Event OnEffectStart(Actor akTarget, Actor akCaster)
    Game.DisablePlayerControls()
    akTarget.StopCombat()
    akCaster.StopCombat()
    Utility.Wait(0.5)
        ;Персонаж и НПС прячут оружие и выходят из состояния боя, запускаем анимацию
    akCaster.PlayIdleWithTarget(pa_01, akTarget)
    Utility.Wait(3.5)
        ;Даем время анимации проиграться, затем возвращаем контроль игроку над персонажем и заставляем НПЦ и персонажа обнажить оружие
    akTarget.DrawWeapon()
    akCaster.DrawWeapon()
    Game.EnablePlayerControls()
Endevent

Это работает с НПЦ, но вот с созданиями (creatures) у меня возникла проблема.

Я сделал специальные парные анимации human-wolf, зарегистрировал ивенты через FNIS  - все как обычно. В CK создал соответсвующие айдлы, все ок. Но проблема в том, что мои ивенты это не killmove, а обычные парные анимации, то есть без убийства актера. Так вот, командой playidlewithtarget мои анимации не работают на животных. В качестве теста проверил свои анимации на ивенте killmove тупо подменив своей анимацией ванильную (paired_2hwkillmovewolfa.hkx) и она сработала. Но, естественно, после проигрывания актер (волк) умирает так как это ивент killmove. То есть проблема не в анимации, но вот в чем - понять не могу. В качестве костыля я уже думал может как нибудь воскрешать каждый раз актера после анимации, но этот вариант мне не нравится. Может кто нибудь подскажет.

DOOM2004  Offline  Сообщение №2979 написано: 16 Октябрь 2020, 11:38 | Отредактировано: Multigone - 17 Октябрь 2020, 23:54



8
Всем привет. Пишу сюда т.к коммерческая ветка кажется мертва. Суть вопроса: сделал левеллисты с одеждой дня npc, они её меняют только при disable/enable. Если видится решение готов обсудить, заранее спасибо.

Нужно чтобы меняли, например при посещении ГГ ячейки или в 00:00, или после сна, уж не знаю как буде проще реализовать и чтобы не было конфликтов с другими модами.

Я упоминал о мертвой коммерческой ветки, готов заплатить за проделанную работу.

yakor77  Offline  Сообщение №2980 написано: 16 Октябрь 2020, 16:25



28
Дум2004, тогда Вам нужно писать свой собственный скрипт. В котором как раз и прописать условия, что на что менять, когда и где. Одно только помещение в левел лист, само собой, автоматически - смены одежды Вам не обеспечит. Левел лист, это как шкаф или сундук, Вы в него что-то поместили - оно там и хранится вечно. Чтобы сменить одежду - надо открыть шкаф, снять старую одежду, повесить в шкаф, достать оттуда новую одежду, надеть/одеть её, закрыть шкаф.

С уважением.
Маг Иридий.
Myprism  Offline  Сообщение №2981 написано: 17 Октябрь 2020, 08:07


Физик


DOOM2004, если вы изменили левельные списки, но персонажа уже встречали в игре, то его экипировка содержится в вашем сейве, т.е. старая. Вот поэтому вам приходится его переинициализировать, чтобы сгенерировать новую экипировку. Если вы начнёте игру заново, или встретите персонажа в первый раз, то его экипировка будет уже соответствовать новым левельным листам. Т.е. ваша проблема со старой одеждой не в моде, а в вашем сейве. Не очень представляю, как вам менять это скриптом. Ведь вам нужно переинициализировать всех персонажей, которых уже встречал пользователь вашего мода. А он этого захочет? Ведь запросто может быть, что игрок уже раздал персонажам какие-нибудь шмотки, которые он очень ценит, а ваш мод эти шмотки убьёт.

DOOM2004  Offline  Сообщение №2982 написано: 17 Октябрь 2020, 08:28



8
Звучит логично. Т.к я не знаком со скриптам думаю что писать некий фильтр не представляется возможным.

Dsion  Offline  Сообщение №2983 написано: 17 Октябрь 2020, 14:56



DOOM2004, хрень в том, что нормального (не костыльного) способа повесить скрипт на ВСЕХ НИП нет вообще. Когда об этом заходит речь, обычно единственное, что могут посоветовать, - это либо дать игроку огромную магическую ауру, которая будет вешать магический эффект на всех НИП, а на эффекте скрипт. Либо дать пассивное умение всем расам. Либо установить everynpcability в defaultobjects. Но решать проблему такими способами реально противно. Можно, но противно.
В общем, сам скрипт - не проблема. Проблема в том, как его на всех повесить.
А без скрипта мы ограничены в управлении одеждой НИП. Без скрипта они точно не сменят её "после сна", как вы хотите.
Я делал похожий мод, но он управлял не всеми НИП, а только ограниченным количеством.

Добавлено (17 Октября 2020, 15:00)
---------------------------------------------
Если без скриптов, то НИП тупо надевают свой outfit в момент загрузки модели и всё. С этим, вроде, даже баг связан. Можно взять талантик, позволяющий красть у НИП одежду, обокрасть НИП, а потом перезайти в локацию и он снова одет.


DOOM2004  Offline  Сообщение №2984 написано: 17 Октябрь 2020, 17:40 | Отредактировано: Multigone - 17 Октябрь 2020, 23:56



8
Цитата Dsion

Я делал похожий мод, но он управлял не всеми НИП, а только ограниченным количеством.

Можно и так по идее, есть лимит на количество npc?

mka_n  Offline  Сообщение №2985 написано: 21 Октябрь 2020, 10:21 | Отредактировано: Multigone - 22 Октябрь 2020, 12:00



6
Всем привет.
Подсобите ограничить "посадку" определенных трав, если не выполнены условия.
Если я правильно понял то нужно на контейнере подправить скрипт.

Получилось такое:
Код
Keyword Property isNirnroot Auto
function OnItemAdded(form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
    If akSourceContainer == Game.GetPlayer()
        if akBaseItem.HasKeyword(isNirnroot)
            Debug.MessageBox("1")
        else
            Debug.MessageBox("0")
        endif
    Endif
endfunction

Проблема что всегда Debug.MessageBox("0") , хотя кейворд на Nirnroot есть.

и можно ли на контейнере проверять стадию квеста?

debug.Notification(NN01)
int MyQuestStage = NN01.GetStage()
debug.Notification(MyQuestStage)

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

Dsion  Offline  Сообщение №2986 написано: 21 Октябрь 2020, 22:58 | Отредактировано: Dsion - 21 Октябрь 2020, 22:58



mka_n, да должно работать, по идее. Тупой вопрос: ты же заполнил проперти с кейвордом и квестом?

mka_n  Offline  Сообщение №2987 написано: 22 Октябрь 2020, 00:25



6
Dsion, да заполнил, простое debug.Notification(keyword) выдает none.

Myprism  Offline  Сообщение №2988 написано: 22 Октябрь 2020, 06:09


Физик


mka_n, не уверен, что дело в этом, но игрок у тебя контейнер, а с контейнерами в игре есть тонкость. Много объектов помещённых в контейнер разом, не имеют индивидуальных ID. Если же в контейнер поместить n объектов по одному n раз, то ID им выделится. У меня было так: сделал я колечко со скриптом и положил 6 штук. в сундук, а колечки в игре не работают. Кладу их рядом с сундуком - работают. Если кладу 6 раз по одному в тот же сундук - работают. Т.е. ID присваивается только когда экземпляр объекта в сундуке один, либо имеет историю одного объекта.

Multigone  Offline  Сообщение №2989 написано: 22 Октябрь 2020, 11:57



719
mka_n, потому что проверяемый объект уже содержит в сохранении свою, предыдущую версию (Property) скрипта. Нужно: 1) подключить мод; 2) загрузить сохранение, где локация с этим объектом еще ни разу не посещалась; 3) идти и проверять. Еще можно попробовать сделать ему Reset(), но не уверен.

Dsion  Offline  Сообщение №2990 написано: 22 Октябрь 2020, 23:43



mka_n, хм, не должно быть none. Эх, чую, что в конце окажется, что все-таки не заполнил.

mka_n  Offline  Сообщение №2991 написано: 23 Октябрь 2020, 10:25 | Отредактировано: Multigone - 23 Октябрь 2020, 13:49



6
Dsion, да нет ж -) На самом MISC

Код
function OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
    if akNewContainer == game.GetPlayer() as ObjectReference && akOldContainer == none
        if itemToAddPotion
            game.GetPlayer().AddItem(itemToAddPotion as form, ItemCount, true)
        endIf
        if (NN01.GetStageDone(200))
            if itemToAddIngredient
                ;debug.trace(self as String + " akNewContainer = " + akNewContainer as String + ", akOldContainer = " + akOldContainer as String, 0)
                game.GetPlayer().AddItem(itemToAddIngredient as form, ItemCount, true)
            endIf
        else
            Debug.MessageBox("Качество хромает, похоже я пока не умею это сажать, нужно учиться")
        endIf
        game.GetPlayer().RemoveItem(myBase as form, 999, true, none)
    endIf
endFunction

Работает(я даже проверли не забыл ли заполнить), криво конечно ,я хотел чтоб он вообще не давал его посадить. Наверно можно это де событие вызывать на самом INGR , но хз как будет это рабоать когда ты сразу стек кидешь а не по одному в грядку. Тут пишут что не всегда будет работать.

Друзья, а как вешать spell на противника при каждой физ.атаке? Что-то типа дебафа брони\резов...

Dsion  Offline  Сообщение №2992 написано: 23 Октябрь 2020, 23:16



Вроде, в перках есть entry point Apply Combat Hit Spell. Хотя я его не юзал. Еще был тип магического эффекта Enhance Weapon. Тоже не юзал.

DOOM2004  Offline  Сообщение №2993 написано: 24 Октябрь 2020, 22:01 | Отредактировано: Multigone - 25 Октябрь 2020, 00:27



8
Цитата DOOM2004

Нужно чтобы меняли, например при посещении ГГ ячейки или в 00:00, или после сна, уж не знаю как буде проще реализовать и чтобы не было конфликтов с другими модами.


1. Неписи только именные, рандомы итак переоденутся.
2. Мне видится 2 варианта:
- После сна. (Самый логичный)
- По игровому времени после 00:00
3. SKSE установлен, так же установлен мод Dynamic Outfits (Basic Version) (https://www.nexusmods.com/skyrimspecialedition/mods/20748) С ним неписи одеваются скажем так по погоде автоматически, не знаю точно как это реализовано, но кажется через заклинания.

Multigone  Offline  Сообщение №2994 написано: 25 Октябрь 2020, 00:20



719
DOOM2004, для SSE есть отдельный раздел. В скриптах LE и SE, SKSE32 и SKSE64 наверняка есть какие-то отличия (не в курсе). SE мне неинтересен, т.к. нет игры, инструментов, а значит, и возможности тестирования. Могу написать для LE, но не гарантирую работу на SE.
Во-вторых, в описании мода указано, что он влияет на большинство нпс, значит, для твоих именных в нем должны быть созданы исключения. Иначе создается конфликт, когда 2 независимых мода берут управление сменой одежды у конкретного нпс. Поэтому, либо Dynamic Outfits должен быть мастером для твоего мода (второй - патч для первого), либо вносить изменения непосредственно в Dynamic Outfits, либо отказаться от Dynamic Outfits в пользу собственного. Работать с Dynamic Outfits я не могу по вышеописанной причине.

DOOM2004  Offline  Сообщение №2995 написано: 25 Октябрь 2020, 00:35



8
Да, возможно есть отличия, мне не известно об этом. Я написал в эту ветку т.к не могу создавать темы, а в ветке SE нет подходящей. Если все же функционал окажется одинаков можно отказаться от Dynamic Outfits, возможно часть его функционала можно вписать в новый мод.

Добавлено (25 Октября 2020, 08:55)
---------------------------------------------
Вот что пишут на Nexus:

1. This process will work for almost any mod, including mods that require SKSE. The only notable exceptions are certain SKSE mods that install a DLL. In some cases, the DLL may have to be modified/recompiled. If the mod you are porting contains a SkyProc Patcher, please read "Addendum 2."

Как понимаю если нет dll все должно работать обычными методами конвертации мода le -> se


mka_n  Offline  Сообщение №2996 написано: 25 Октябрь 2020, 10:52 | Отредактировано: mka_n - 25 Октябрь 2020, 10:52



6
В papyrus есть функция аналог "entry point Apply Combat Hit Spell" ?

Multigone  Offline  Сообщение №2997 написано: 25 Октябрь 2020, 14:10 | Отредактировано: Multigone - 26 Октябрь 2020, 02:29



719
mka_n, тебе уже ответили, как накладывать заклинание при атаке - дать атакующему перк и настроить его условиями и прочим.
Отдельной функции в папирусе для этого, конечно же, нет. Есть событие OnHit(), с помощью которого определяется факт / момент атаки, RefID атакующего, его оружие и т.д. Но событие должно находиться в скрипте, запущенном на жертве. Значит, скрипт через заклинание / референс алиас должен быть повешен на нее ДО атаки. Там все сложно, тебе проще через перк.

DOOM2004,

Код
Scriptname _TESTTEST63 Extends ReferenceAlias ; Multigone

    ; На ReferenceAlias конкретного актера (актеров).
    ; Все Property должны быть изучены и настроены перед первым запуском мода.
    ; Нужно больше тестов.

Outfit Property MyDailyOutfit Auto ; Модный дневной аутфит.
Outfit Property MyPersonalOutfit Auto ; Модный ночной аутфит (если нет, оставить none).
Outfit Property MySleepOutfit Auto ; Модный аутфит для сна (если нет, оставить none).
    
Float Property pfMorningTreshold = 7.00 Auto ; Время утренней смены одежды. Допустимые значения: 1.0 < pfMorningTreshold < 11.0
Float Property pfEveningTreshold = 22.00 Auto ; Время вечерней смены одежды. Допустимые значения: 13.0 < pfEveningTreshold < 23.0

Float Property pfBlockTimeScale = 300.0 Auto
    ; Актер не может менять одежду чаще, чем раз в (pfBlockTimeScale) реал. сек. Допустимые значения: pfBlockTimeScale >= 1.0
    ; Надевание одежды для сна игнорирует это правило. Загрузка модели игнорирует это правило.

Faction Property CurrentFollowerFaction Auto ; Автозаполнение.
    ; Если заполнено: актер, находящийся в этой фракции, либо являющийся IsPlayerTeammate(), исключается из алгоритма смены одежды, пока проходит эти проверки.

GlobalVariable Property GameDaysPassed Auto ; Автозаполнение.
    
Outfit VanillaDailyOutfit ; Ваниль.
Outfit VanillaSleepOutfit

Float fMorningRandom ; Рандомайзеры (колебание значений времени смены в пределах +- 1 игр. час)
Float fEveningRandom

Int iCurrentOutfit
Int iAllowChange

EVENT OnInit()
    RegisterForSingleUpdate(3.0)
ENDEVENT

EVENT OnUpdate()
    Update()
ENDEVENT

EVENT OnUpdateGameTime()
    UpdateGameTime()
ENDEVENT

FUNCTION Update()
    ActorBase xB = (GetReference() as Actor).GetBaseObject() AS ActorBase
    VanillaDailyOutfit = xB.GetOutfit()
    VanillaSleepOutfit = xB.GetOutfit(true)
    IF MyPersonalOutfit || MySleepOutfit
        fMorningRandom = pfMorningTreshold + 1.0 - Utility.RandomFloat(0.0, 2.0)
        fEveningRandom = pfEveningTreshold + 1.0 - Utility.RandomFloat(0.0, 2.0)
        GoToState("Main")
        OnLoad()
    ELSE
        GoToState("Simple")
        OnLoad()
    ENDIF
ENDFUNCTION

FUNCTION UpdateGameTime()
ENDFUNCTION

STATE Main
    EVENT OnLoad()
        IF MySleepOutfit
            (GetReference() as Actor).SetOutfit(none, true)
        ENDIF
        iAllowChange = 1
        iCurrentOutfit = 0
        UpdateGameTime()
    ENDEVENT
    
    EVENT OnUnload()
        UnregisterForUpdate()
        UnregisterForUpdateGameTime()
    ENDEVENT

    EVENT OnSit(ObjectReference akFurniture)
        UpdateGameTime()
    ENDEVENT

    EVENT OnGetUp(ObjectReference akFurniture)
        UpdateGameTime()
    ENDEVENT
    
    FUNCTION Update()
        IF iAllowChange < 0
            iAllowChange = 1
            UpdateGameTime()
        ELSE
            iAllowChange = 1
        ENDIF
    ENDFUNCTION

    FUNCTION UpdateGameTime()
        Actor xA = GetReference() AS Actor
        Float fT = fMod(GameDaysPassed.Value) * 24.0
        IF CurrentFollowerFaction && (xA.IsInFaction(CurrentFollowerFaction) || xA.IsPlayerTeammate())
            iAllowChange = -1
            RegisterForSingleUpdate(30.0)
        ELSEIF MySleepOutfit && xA.GetSleepState() > 0
            IF iCurrentOutfit != 3
                iCurrentOutfit = 3
                iAllowChange = 0
                xA.SetOutfit(MySleepOutfit)
                IF fT < fMorningRandom || fT >= fEveningRandom
                    fMorningRandom = pfMorningTreshold + 1.0 - Utility.RandomFloat(0.0, 2.0)
                    RegisterForSingleUpdateGameTime(fMod(24.0 + fMorningRandom - fT, 24.0) + 0.1)
                ELSE
                    fEveningRandom = pfEveningTreshold + 1.0 - Utility.RandomFloat(0.0, 2.0)
                    RegisterForSingleUpdateGameTime(fMod(24.0 + fEveningRandom - fT, 24.0) + 0.1)
                ENDIF
                RegisterForSingleUpdate(pfBlockTimeScale)
            ENDIF
        ELSEIF iAllowChange < 1
            iAllowChange = -1
        ELSEIF MyPersonalOutfit && (fT < fMorningRandom || fT >= fEveningRandom)
            IF iCurrentOutfit != 2
                iCurrentOutfit = 2
                iAllowChange = 0
                xA.SetOutfit(MyPersonalOutfit)
                fMorningRandom = pfMorningTreshold + 1.0 - Utility.RandomFloat(0.0, 2.0)
                RegisterForSingleUpdateGameTime(fMod(24.0 + fMorningRandom - fT, 24.0) + 0.1)
                RegisterForSingleUpdate(pfBlockTimeScale)
            ENDIF
        ELSEIF iCurrentOutfit != 1
            iCurrentOutfit = 1
            iAllowChange = 0
            xA.SetOutfit(MyDailyOutfit)
            fEveningRandom = pfEveningTreshold + 1.0 - Utility.RandomFloat(0.0, 2.0)
            RegisterForSingleUpdateGameTime(fMod(24.0 + fEveningRandom - fT, 24.0) + 0.1)
            RegisterForSingleUpdate(pfBlockTimeScale)
        ENDIF
    ENDFUNCTION
ENDSTATE

STATE Simple
    EVENT OnLoad()
        Actor xA = GetReference() AS Actor
        IF !CurrentFollowerFaction || (!xA.IsInFaction(CurrentFollowerFaction) && !xA.IsPlayerTeammate())
            xA.SetOutfit(MyDailyOutfit)
        ENDIF
    ENDEVENT
ENDSTATE

Float FUNCTION fMod(Float A, Float B = 1.0)
    IF B
        RETURN A - Math.Floor(A / B) * B
    ENDIF
ENDFUNCTION

; Эта функция служит для остановки скрипта.
; Повторный запуск после остановки производится функцией: Update()
; Первый запуск при подключении мода происходит автомат.

FUNCTION Stop()
    GoToState("")
    UnregisterForUpdate()
    UnregisterForUpdateGameTime()
    Actor xA = GetReference() AS Actor
    xA.SetOutfit(VanillaDailyOutfit)
    xA.SetOutfit(VanillaSleepOutfit, true)
ENDFUNCTION

DOOM2004  Offline  Сообщение №2998 написано: 26 Октябрь 2020, 14:03



8
Multigone, большое спасибо. Есть 2 вопроса:
"Extends ReferenceAlias ; Multigone" Вот здесь прописывать список npc?
с Property понятно, а в настройках npc важно какой Outfit выбирать или скрипт сам npc оденет?

Multigone  Offline  Сообщение №2999 написано: 27 Октябрь 2020, 00:48



719
DOOM2004, для каждого актера создается отдельный референс алиас квеста. Квест должен быть запущен. На все алиасы цепляется этот скрипт, заполняются необходимые проперти. Скрипт будет управлять сменой указанных в проперти аутфитов согласно времени суток и использованию нпс кровати (если указан аутфит для сна). Ванильные аутфиты не играют роли (только если у нпс есть ванильный сонный аутфит, а модный для сна не указан, тогда при впадании в сон нпс будет (предположительно) менять обычный аутфит на сонный, т.к. скрипт в этом случае не управляет этим). Первая смена аутфитов сразу в момент запуска мода в игре. Остановка скриптов и возврат ванильных аутфитов с помощью функции Stop(). Если удалить мод, не отключив, возможна (нужен тест) потеря аутфитов.
Разбираться с Dynamic Outfits и распределением одежды по нпс желания никакого не имею, т.к. там работы явно не на одну неделю, куча подводных камней и долгое тестирование. Авторы таких модов пилят их долгое время, внося правки по отзывам.

frodo01  Offline  Сообщение №3000 написано: 6 Декабрь 2020, 20:09 | Отредактировано: Multigone - 7 Декабрь 2020, 21:59



5
установил мод bloodthirst что бы вампиры могли кусаться и подумал может дать им возможность заражать укусами
напечатал скрипт и начал следить за Алвой ворвался к ней домой, её хахаль накинулся на меня а у Алвы проигралась анимация укуса и потом она приобретает уже внешность вампира

Код
scriptName AAAVBloodthirstNPCInfect extends activemagiceffect

;-- Properties --------------------------------------
spell property DiseaseSanguinareVampirisNPC auto
keyword property ActorTypeNPC auto
actor property PlayerREF auto
Idle Property VampireFeedingBedRight Auto
Idle Property VampireFeedingBedrollRight Auto
idle property IdleVampireStandingFeedFront_Loose auto
idle property VampireFeedingBedRight_Loose auto
idle property VampireFeedingBedrollLeft_Loose auto
idle property VampireFeedingBedLeft_Loose auto
idle property VampireFeedingBedrollRight_Loose auto
idle property IdleVampireStandingBack auto
;-- Variables ---------------------------------------

;-- Functions ---------------------------------------
function OnEffectStart(Actor Victim, Actor akCaster)
    ;-- akCaster(вампир)
    ;-- Victim(жертва)
    if Victim != PlayerREF
        if Victim.HasKeyword(ActorTypeNPC)
            If akCaster.PlayIdle(VampireFeedingBedRight)
                Victim.DoCombatSpellApply(DiseaseSanguinareVampirisNPC, Victim as ObjectReference)
            endif
            If akCaster.PlayIdle(VampireFeedingBedrollRight)
                Victim.DoCombatSpellApply(DiseaseSanguinareVampirisNPC, Victim as ObjectReference)
            endif
            if akCaster.PlayIdleWithTarget(IdleVampireStandingFeedFront_Loose, Victim as ObjectReference)
                Victim.DoCombatSpellApply(DiseaseSanguinareVampirisNPC, Victim as ObjectReference)
            endif
            if akCaster.PlayIdle(VampireFeedingBedrollRight_Loose)
                Victim.DoCombatSpellApply(DiseaseSanguinareVampirisNPC, Victim as ObjectReference)
            endif
            if akCaster.PlayIdle(VampireFeedingBedRight_Loose)
                Victim.DoCombatSpellApply(DiseaseSanguinareVampirisNPC, Victim as ObjectReference)
            endif
            if akCaster.PlayIdle(VampireFeedingBedrollLeft_Loose)
                Victim.DoCombatSpellApply(DiseaseSanguinareVampirisNPC, Victim as ObjectReference)
            endif
            if akCaster.PlayIdle(VampireFeedingBedLeft_Loose)
                Victim.DoCombatSpellApply(DiseaseSanguinareVampirisNPC, Victim as ObjectReference)
            endif
            if akCaster.PlayIdleWithTarget(IdleVampireStandingBack, Victim as objectreference)
                Victim.DoCombatSpellApply(DiseaseSanguinareVampirisNPC, Victim as ObjectReference)
            endif
        endif
    endif
endFunction

Форум » TES V: Skyrim » Мастерская » Вопросы по скриптам Papyrus (О скриптах Papyrus (Skyrim). Скриптеры не проходите мимо!)
Поиск:





Ответ на жалобу смотрите в разделе жалоб