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

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


The Red Sun


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


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


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

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

Красное солнце
Есть вопросы по скриптам Papyrus? Пиши не в ЛС, а в эту тему.
anton  Offline  Сообщение №1321 написано: 16 декабря 2014, 21:46



362
Никто не знает как ГГ, привязанного командой "SetVehicle()", заставить вращаться ?
А то по вертикали углы камеры наклоняют и тело ГГ, а повороты по горизонтали - нет (камера то вращается, но поворота тела ГГ не происходит).

Или может какая то команда, позволяющая определить направление, куда смотрит камера ГГ (куда показывает курсор) ?

Мой Блог
NdeB  Offline  Сообщение №1322 написано: 1 января 2015, 15:57 | Отредактировано: NdeB - 1 января 2015, 15:58



2
Хм... не совсем уверен что обращаюсь по адресу но надеюсь сможете указать направление в котором мне следует копать. Нужно "перехватить"  смерть гг. Т.е при наступлении у гг 0% жизни не начиналась загрузка а действо выбраненное мной.

Myprism  Offline  Сообщение №1323 написано: 1 января 2015, 19:11


Физик


NdeB, посмотри скрипт, установленный на огненном атронахе. Посмотри моё сообщение двумя выше. Там использовано событие onDying. С ним у меня возникают проблемы. Если уровень персонажа высок, скрипт не работает.  Но в папирусе есть и другое событие - onDeath. С ним (убрав проверки на здоровье) у меня всё работает отлично. Просто не понимаю, зачем там эти заморочки с проверками на здоровье в случае использования onDying. Умерла так умерла :)

Hecktor  Offline  Сообщение №1324 написано: 2 января 2015, 16:35


Sεrpεñτ Rιdεr


803
Подскажите, пожалуйста, какая функция вызывает крафт алхимии? Никак не могу найти ничего подобного.
Смотрел по всему Creation Kit, не могу понять как на CraftingAlchemyWorkbench (Алхимическая лаборатория) подвешен вывод меню крафта.
Смотрел даже Frostfall с его ступкой и пестиком - на объект так же не повешено никаких скриптов.
Откуда тогда происходит вызов?

sansuli  Offline  Сообщение №1325 написано: 10 января 2015, 09:51


The Red Sun


193
На сколько я знаю крафты происходят не через подвешанные скрипты, эт надо смотреть какие то привязки в CreationKide, я забыл уже, уже как больше года я не увлекаюсь Skyrim :-)

Красное солнце
Есть вопросы по скриптам Papyrus? Пиши не в ЛС, а в эту тему.
Hecktor  Offline  Сообщение №1326 написано: 10 января 2015, 12:33


Sεrpεñτ Rιdεr


803
sansuli, да я, собственно, разобрался. Написал такой скрипт:

Код
Event OnEquipped(Actor akActor)
   If(!Player.IsInCombat() && !Player.IsOnMount())
     Game.DisablePlayerControls()
     Game.EnablePlayerControls()
     Player.PlaceAtMe(AlchemyWorkbench)
     AlchemyWorkbench.Activate(Player)
   endif
EndEvent


И подвесил его на собственноручно сделанные ступку и пестик.
Пришлось также сделать невидимую алхимическую лабу в отдельной локации, чтобы её активировать через скрипты, телепортируя к игроку.
Вот только анимацию я не делал. Просто открывается меню крафта алхимии, чего я и пытался добиться (научиться делать).

Dsion  Offline  Сообщение №1327 написано: 10 января 2015, 12:51 | Отредактировано: Dsion - 10 января 2015, 12:54



Цитата Hecktor

sansuli, да я, собственно, разобрался. Написал такой скрипт:


Ммм... Ты серьезно ошибся... Смотри внимательно. Функция PlaceAtMe создает новый ObjectReference (новый объект в мире). Она НЕ телепортирует что-то к игроку. То есть, у тебя каждый раз создается новый объект и не удаляется. (Ну если ты не повесил на лабораторию удаляющий скрипт).

В любом случае, телепортировать к игроку ничего не нужно. И даже не обязательно ставить новую лабораторию в какой-то локации. Можно использовать любую лабораторию из любой локации и удаленно её активировать:


Код
ObjectReference Property ArcadiasWorkbench Auto

Event OnEquipped(Actor akActor)   
     If (!akActor.IsInCombat() && !akActor.IsOnMount())   
       ArcadiasWorkbench.Activate(akActor)   
     EndIf   
EndEvent

Hecktor  Offline  Сообщение №1328 написано: 10 января 2015, 13:05


Sεrpεñτ Rιdεr


803
Цитата Dsion

Можно использовать любую лабораторию из любой локации и удаленно её активировать


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

Dsion  Offline  Сообщение №1329 написано: 10 января 2015, 13:18



Может, тот мод работает не совсем так...

Наверное, он создает лабораторию командой PlaceAtMe только один первый раз. А потом уже перемещает к игроку. Но если создавать новую каждый раз, её надо же обязательно удалять (Disable, Delete).

Может, там что-то такого типа?

Код
Actor Property PlayerRef Auto
Furniture Property CraftingAlchemyWorkbench Auto
ObjectReference MyBench

Event OnInit()
     MyBench = PlayerRef.PlaceAtMe(CraftingAlchemyWorkbench)
EndEvent

Event OnEquipped(Actor akActor)
     MyBench.MoveTo(akActor)
     MyBench.Activate(akActor)
EndEvent

Hecktor  Offline  Сообщение №1330 написано: 10 января 2015, 13:25


Sεrpεñτ Rιdεr


803
Dsion, сейчас посмотрел, у него в скрипте только PlaceAtMe. Никаких MoveTo, Disable и Delete нету.
Но ты прав, пожалуй надо удалять лишнее. Об этом я не подумал. Спасибо. Поэкспериментирую ещё.

Dsion  Offline  Сообщение №1331 написано: 10 января 2015, 14:03



Ну сам смотри, удачи...
PlaceAtMe - это создание нового объекта в мире (нужно удалять).
MoveTo - это перемещение объекта. Но лабораторию нельзя будет перемещать, если она создана в CK. Нужно создавать через PlaceAtMe.

Лично у меня нету проблем и с активацией лаборатории из другой локации... Но у меня и SkyUI нету.

Hecktor  Offline  Сообщение №1332 написано: 10 января 2015, 14:43


Sεrpεñτ Rιdεr


803
Пока тема ожила, хочу задать ещё один вопрос.
У меня есть две пирамидки (Брат и Сестра). Сестра телепортирует игрока к Брату, где бы мы его не положили.
Скрипт написал такой:
Код
Scriptname CSPyramidSisterScript extends ObjectReference

Message Property CSPyramidSisterActivation Auto

ImageSpaceModifier Property CSFadeIn Auto
ImageSpaceModifier Property CSFadeOut Auto
Sound Property MAGIllusionNightEyeOn Auto

MiscObject Property CSPyramidBrother Auto
ObjectReference Property CSPyramidBrotherLocation Auto

Event OnEquipped(Actor akActionRef)
   if (Game.GetPlayer().GetItemCount(CSPyramidBrother) == 0) ; Если Брата нет в инвентаре, то:
     int CSResponce = CSPyramidSisterActivation.Show() ; Выдаём месседж с выбором Да и Нет
     if (CSResponce == 0) ; Если выбираем Да, то:
       Game.DisablePlayerControls()
       Game.EnablePlayerControls()
       MAGIllusionNightEyeOn.Play(akActionRef)
       CSFadeIn.Apply(2)
       Utility.Wait(2)
       Game.GetPlayer().MoveTo(CSPyramidBrotherLocation) ; Переносим игрока к Брату
       CSFadeIn.PopTo(CSFadeOut, 1)
       Utility.Wait(2)
       CSFadeOut.Remove()
     endif
   else ; Если Брат в инвентаре, то:
     Debug.MessageBox("Вы не сможете активировать Сестру, пока Брат находится у вас.")
   endif
EndEvent


Собственно, вопрос такой. Я хочу подвесить сюда автосохранение.
Но если просто написать Game.RequestAutoSave() перед телепортацией, то при загрузке этого сейва скрипт продолжить работу и нас телепортирует.
Хотелось бы сделать так, чтобы процесс телепортации обрубался, как при быстром перемещении. Как это можно реализовать?
Пытался найти дефолтный скрипт на быстрое перемещение, но так и не нашёл. Может, кто подскажет, как он называется?

Dsion  Offline  Сообщение №1333 написано: 10 января 2015, 15:29 | Отредактировано: Dsion - 10 января 2015, 15:33



Наверное, много вариантов...
Можно, например, попробовать вот так:

Код
Actor Property PlayerRef Auto
Bool Property Teleport Auto

Function ...
      ...
      Teleport = True
      RequestAutoSave()
      Utility.Wait(1.0)
      If (Teleport == True)
        PlayerRef.MoveTo(...)
      EndIf
      ...
EndFunction

---------------------------------------------------------
А это на игрока:
---------------------------------------------------------

ОсновнойСкрипт Property Основной Auto

Event OnPlayerLoadGame()
      Основной.Teleport = False
EndEvent

По идее, если игрок загрузит игру, флаг Teleport сбросится и телепортация не произойдет. Теоретически :)


Или попробовать использовать часы реального времени:

Код
Function ...
      ...
      Float Time1 = GetCurrentRealTime()
      RequestAutoSave()
      Float Time2 = GetCurrentRealTime()
      If (Math.Abs(Time2 - Time1) < 1.0)
          PlayerRef.MoveTo(...)
      EndIf
      ...
EndFunction

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


Если честно, я оба варианта не проверял :) Но суть в том, что нужно найти что-то, что не откатывается после загрузки сэйва.

Hecktor  Offline  Сообщение №1334 написано: 10 января 2015, 15:46


Sεrpεñτ Rιdεr


803
Хм... Dsion, спасибо за наводку. Честно говоря, до использования часов времени я бы никогда, наверное, не догадался.
Радует, что вариантов может быть много.

TheTrickster  Offline  Сообщение №1335 написано: 13 января 2015, 09:31



5
Подскажите пожалст,  после какого события квест перестает отвечать положительно на запрос IsRunning() ?
Тоесть даже если завершили все обжективы, и сквест переходит в статус Комплитед, он всеравно отвечает на этот запрос положительно.

Dsion  Offline  Сообщение №1336 написано: 13 января 2015, 14:42



Цитата TheTrickster

Подскажите пожалст, после какого события квест перестает отвечать положительно на запрос IsRunning() ?Тоесть даже если завершили все обжективы, и сквест переходит в статус Комплитед, он всеравно отвечает на этот запрос положительно.


После Stop(), конечно.

TheTrickster  Offline  Сообщение №1337 написано: 13 января 2015, 20:35



5
Цитата Dsion

После Stop(), конечно.


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

Dsion  Offline  Сообщение №1338 написано: 13 января 2015, 20:39



У ванильных тех, что я посмотрел, у всего Stop() в последней стадии.

TheTrickster  Offline  Сообщение №1339 написано: 14 января 2015, 15:38



5
Спасибо!!  значит тож буду стопать руками))
Может еще с парой вопросов поможете - второй день бьюсь.
1 - есть возможность скриптом выяснить ворованый итем или нет, например есть ли ворованый итем у меня в инвентаре.
2 - Хочу повесить вещам в инвентаре НПС какой-нибудь оунершип, чтобы при лутании трупа вещи с него считались ворованными.
        SetFactionOwner на сам труп не работает, сам труп вроде принадлежит фркации, но предупреждения о воровстве ни при наведении курсора на сам труп ни при взятии вещей из его контейнера не происходит. Пытался Прост при добавлении вещи создавать объект этой вещи перед собой, назначать ей фракцию и активировать, тогда в инвентарь добавлялась копия вещи с нужным мне признаком воровства, но с нее слетали улучшения (типа "легендарный") да и боюсь попортить какие-нить квестовые вещи таким способом.

Dsion  Offline  Сообщение №1340 написано: 14 января 2015, 18:56



Лично у меня вообще никаких идей...
Чтоб не слетали всякие улучшения, нужно работать только со существующим референсом. То есть, никакого создания новых референсов.

Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)

Вот этот ивент, по идее, должен выдавать не только базовый объект (Form), а и конкретный референс. Но нифига. Если игрок что-то берет, то akItemReference = None и ничего с ним не сделать. Возможно, это потому, что у предметов в инвентаре и нету собственного Id... Если они не квестовые или что-то такое.

И как проверить, если ли в инвентаре краденый предмет, тоже без понятия. Даже в Conditions нету.

Добавлено (14 Января 2015, 21:56)
---------------------------------------------
Варианты есть, конечно, но они кривые и абсолютно не юзаемые...


Myprism  Offline  Сообщение №1341 написано: 16 января 2015, 14:42


Физик


Можно ли с помощью скриптов заменить ArmorAddon у некоторой брони?
Хочется сделать шлем, у которого бы поднималось забрало. Модель сделал, забрало там можно крутить вокруг точки подвеса. Стал искать, как народ поступает в таком случае. Нашёл 2 мода. В одном есть две модели (открытая и закрытая), но никаких признаков их смены. В другом заменяется целиком шлем и делается это через скрипт, который висит на алиасе игрока в пустом самозапускающемся квесте!
На всякий случай, скрипт такой:

- Во-первых, мне кажется слишком мудрёной такая реализация :)
- Во-вторых, это получается, что для каждого открывающегося шлема мне надо вешать отдельный скрипт на игрока.
- В третьих, на спутнике, как я понимаю, это работать не будет, так как там нет квестов, которые бы вешали этот скрипт на алиас спутника.
- В четвёртых, скрипт переодевает не улучшенную броню и я не вижу способов её улучшать и зачаровывать.
Как можно открывать забрало шлема?

anton  Offline  Сообщение №1342 написано: 16 января 2015, 18:19 | Отредактировано: anton - 16 января 2015, 18:22



362
Myprism, можно сделать через магический эффект ;)
(как в "Анимированных драконьих крыльях", и тогда скрипты вообще не нужны)

Мой Блог
Февраль  Offline  Сообщение №1343 написано: 16 января 2015, 20:46



17
Не разбираюсь в расширеных скриптах совсем не подскажите как поменять в моде "Автонаводка / Lock-On" смену цели не на "клавиша"+"мышь влево вправо", а просто "Мышь влево вправо"?

Myprism  Offline  Сообщение №1344 написано: 23 января 2015, 02:09


Физик


anton, но ведь магический эффект нужно чем то подвесить? А тогда получаются 2 варианта - либо зачарованием, либо тем же скриптом. Но зачарование мешает игроку зачаровывать этот предмет самому, так что остаётся скрипт.

Dsion, наверное, вопрос к тебе. У меня в моде есть кольца переодевания персонажей. Переодевают скриптом. Всё работает хорошо, кроме одного, при новой загрузке игры и сейва действия колец нет. Чтобы скрипт заработал, надо снять и снова одеть кольцо. Кольцо может быть как на ГГ, так и на другом персонаже. Ну, в общем то понятно, надо в скрипте отслеживать момент новой загрузки игры. Так вот вопрос, какие именно события тут правильнее всего отслеживать?

Dsion  Offline  Сообщение №1345 написано: 23 января 2015, 09:21 | Отредактировано: Dsion - 23 января 2015, 09:36



Если просто отслеживать загрузку игры, то на алиас игрока можно добавить Event OnPlayerLoadGame() и он будет срабатывать при загрузке игры.

Но, возможно, лучше отслеживать ивент OnLoad() на самом NPC. Потому что в момент загрузки модельки они часто надевают свой стандартный Outfit. Это от разных факторов зависит, которые я все так и не понял. А OnLoad() - это ивент загрузки модели конкретного объекта.

Можно, к примеру, снять всю одежду с кого-то на площади Вайтрана, надеть что-то другое. А потом просто перезайти в Вайтран и NPC снова окажется в стандартном Outfit.

Еще можно переодевать NPC командой SetOutfit(), но у этого способа столько недостатков, что аж описывать страшно.

Myprism  Offline  Сообщение №1346 написано: 23 января 2015, 11:45


Физик


Dsion, если снять с кого-то всю одежду из его Outfit, то он восстановит себе всю Outfit, но только после удаления последней шмотки. Это сделает движок. Если хоть что-нибудь оставить, то восстановления не происходит. По крайней мере до респавна.

Я как раз пользуюсь GetOutfit() и SetOutfit(). С SKSE и командой akActor.QueueNiNodeUpdate() работает нормально, но только на уникальных актёрах (akActor.GetActorBase().GetOutfit()). На не уникальных у меня ничего не получается.

Делаю я это скриптом на кольце, т.е. мне надо отслеживать загрузку не актёра, а кольца. Но в команде OnLoad() мне нужен актёр (чтобы отслеживать его одёжку и переодевать). Как получить его при загрузке кольца, которое на него одето?

@perture  Offline  Сообщение №1347 написано: 23 января 2015, 12:25


$cience innov@tor


Myprism, посмотри как в мистической броне сделано, может пригодится. Там вроде на всех неписях нормально работает и без затрагивания аутфита.

"Не спорьте с идиотами! Вы опуститесь до их уровня, а там они вас задавят своим опытом!" ©
Dsion  Offline  Сообщение №1348 написано: 23 января 2015, 12:28



Цитата Myprism

Но в команде OnLoad() мне нужен актёр


Если переодевать через SetOutfit(), то не должно быть никаких проблем после загрузки игры... Тогда не знаю.
А если переодевать вручную, то, наверное, нужны Алиасы, в которых будут все владельцы колец. Но тогда количество колец будет ограничено.

Myprism  Offline  Сообщение №1349 написано: 23 января 2015, 13:07


Физик


Цитата Dsion

Если переодевать через SetOutfit(), то не должно быть никаких проблем после загрузки игры...

А, Outfit там у меня не главное. Я одновременно меняю тело.

@perture, спасибо, посмотрю.

@perture  Offline  Сообщение №1350 написано: 23 января 2015, 14:31


$cience innov@tor


Цитата Myprism

@perture, спасибо, посмотрю.


Если что - спрашивай, попробую вспомнить, что там к чему в скриптах.

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





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