Модератор форума: 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? Пиши не в ЛС, а в эту тему.
slastik  Offline  Сообщение №1441 написано: 25 февраля 2015, 21:11


Жаждущий


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

- Что это за горы стоят?
- А, это орки бегут!
valambar  Offline  Сообщение №1442 написано: 25 февраля 2015, 21:20



513
Повторю вопрос. Как вернуть состояние скрипта к начальному - в смысле, допустим, есть вариант выбора, одни варианты отправляют св следующее состояние командой GotoState "ИмяСостояния", а один из вариантов - наоборот, возвращает в начальное. Когда я ставлю команду  GotoState "Begin" (у меня обозначено начальное состояние Auto State Begin), именно эта команда не компилируется - хотя остальные отправки к следующим состояниям работают.

Dsion  Offline  Сообщение №1443 написано: 25 февраля 2015, 21:46



Дались вам вообще те состояния...

valambar  Offline  Сообщение №1444 написано: 25 февраля 2015, 21:51 | Отредактировано: valambar - 25 февраля 2015, 22:16



513
Цитата Dsion

Дались вам вообще те состояния...

Ну вообще-то для простеньких скриптов то что надо.  Только вот почему при попытке заставить их прийти обратно к началу какой-то бунт... Короче, как вернуть все к исходному состоянию самым коротким путем?

О, кажется, нашел. Если состояние вообще не объявлять, то можно в начальном событии активации указать переход в состояние, а в вариантах внутри состояния один обозначить как переход к пустому состоянию, то есть фактически к блоку вне состояний. Скрипт скомпилировался, посмотрим, будет ли он работать.

Да, работает. 

Правда, теперь возник следующий вопрос - я вот спрашивал про modactorvalue - оказывается, это не то, что мне было нужно. Эта функция "подзеленивает" навыки - то есть изменяет результирующий навык, не меняя базового. А тогда какой командой можно повысить навык, допустим, как в обучении? Setactorvalue? тогда надо как-то написать типа setactorvalue("Lockpicking") = getactorvalue("Lockpicking") + 1? Как это написать правильно?

Dsion  Offline  Сообщение №1445 написано: 25 февраля 2015, 22:27



Цитата valambar

setactorvalue("Lockpicking") = getactorvalue("Lockpicking") + 1


Можно попробовать вот так:
SomeActor.SetActorValue("magicka", SomeActor.GetBaseActorValue("magicka") + 10.0)

Получать текущее значение лучше функцией GetBaseActorValue. Потому что просто GetActorValue вернет атрибут с учетом баффов и дебаффов.

И с этим, в любом случае, надо осторожно... Наверняка что-то может пойти не так...

valambar  Offline  Сообщение №1446 написано: 25 февраля 2015, 22:49



513
Ага. Методом господина Тыка нашел скомпилировавшийся вариант
float Lockpickingvalue
Lockpickingvalue = GetPlayer().GetBaseActorValue("Lockpicking") + 1
GetPlayer().SetActorValue("Lockpicking", Lockpickingvalue)

Интересно, он будет работать как повышение навыка с объявлением, что навык повысился и вкладом в повышение уровня?

Добавлено (26 Февраля 2015, 01:45)
---------------------------------------------

Цитата Dsion

Извини. Просто Папирус - единственный язык из мне знакомых, в котором есть эти состояния. А я привык обходиться без них и не вижу в них смысла.


В Обливионе роль состояний выполняли переменные - назначаешь следующее значение переменной и соответствие функций этому значению - и скрипт работает по другому, чем при другом ее значении. Здесь фактически то же самое, но переменных не объявляешь, а отправляешь действие скрипта в разные блоки состояний. Для начинающих как раз удобно - меньше надо думать  :D Пожалуй, единственный момент Папируса, более удобный для новичков. Все остальное - я долго ахал и охал, когда узнал, что он бюрократически запрашивает проперти и отказывается признавать функцию, если она в пропертях не указана  facepalm

Добавлено (26 Февраля 2015, 01:49)
---------------------------------------------
Опять немного не то. Повышение навыка теперь не "зеленое", а "белое", но влияния на повышение уровня нет. И какой же командой повысить навык так, чтобы это работало как повышение навыка в обучении?


Dsion  Offline  Сообщение №1447 написано: 25 февраля 2015, 23:01



Посмотри в каком-то квесте что-ли... Изольда, например, когда даришь ей бивень, повышает красноречие.

Добавлено (26 Февраля 2015, 02:01)
---------------------------------------------
Квест Favor110, если что...


valambar  Offline  Сообщение №1448 написано: 25 февраля 2015, 23:07



513
Цитата Dsion

Посмотри в каком-то квесте что-ли... Изольда, например, когда даришь ей бивень, повышает красноречие.


О, точно. 
Game.IncrementSkill("Speechcraft")
А почему в этой команде про плейера не говорится? Или она только для игрока и существует?

Holtof55  Offline  Сообщение №1449 написано: 26 февраля 2015, 16:25



49
Я так и не понял как добавить случайному нпс при диалоге, пакет на сопровождение, а потом корректно его убрать.
Можно без наворотов, просто тупо должен идти за гг, а потом(через диалог же) вернутся к своим делам.....

Dsion  Offline  Сообщение №1450 написано: 26 февраля 2015, 16:34



Создать в квесте пустой алиас с пометкой Optional, повесить на алиас пакет. А потом при помощи скрипта совать туда NPC:
MyAlias.ForceRefTo(akSpeaker)
и убирать из него NPC:
MyAlias.Clear()

Пакеты на алиасах приоритетнее пакетов на самом NPC. А если NPC сразу в нескольких алиасах с пакетами, то приоритет пакетов будет зависеть от приорититов квестов.

Holtof55  Offline  Сообщение №1451 написано: 26 февраля 2015, 17:43 | Отредактировано: Holtof55 - 26 февраля 2015, 17:43



49
Dsion, Спасибо, сейчас же и испытаю

Добавлено (26 Февраля 2015, 20:43)
---------------------------------------------
Dsion, Все о'кейно! Супер, спасибо!

Еще один вопросик махонький, если позволите...какую команду надо вставить в срипт, чтобы проигралась музыка?
И играла пока идет анимация, или сцена...
Сама музыка есть, добавлена а локацию, и когда игрок туда попадает, играет, то есть формат правильный, wav


slastik  Offline  Сообщение №1452 написано: 27 февраля 2015, 08:07 | Отредактировано: slastik - 27 февраля 2015, 09:07


Жаждущий


209
Цитата Holtof55

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

В тело скрипта:
MySound. Play()
И в свойствах:
Sound Property MySound auto

Добавлено (27 Февраля 2015, 11:07)
---------------------------------------------
И снова здравствуйте.
Где те люди, которые советовали мне создать для часов анимированную модель? :)
Я сделал тестовую модель, состоящую из одной стрелки, которая делает полный оборот за 24 игровых часа (4320 секунд). Как теперь мне синхронизировать эту анимацию с игровым временем? Допустим, я привяжу скрипт, в котором через Event OnInit() задам поворот модели по оси на определенный градус относительно циферблата в зависимости от текущего времени. Это даст часам правильную стартовую позицию. Но как быть дальше? Анимация останавливается при выходе из локации и запускается с нуля при входе, анимация не реагирует на пропуск времени и сон, продолжая с того же места, хотя прошло N игровых часов. Кто-то говорил, что с такой моделью можно обойтись вообще без скриптов. Подскажите - как? :)

- Что это за горы стоят?
- А, это орки бегут!
Dsion  Offline  Сообщение №1453 написано: 27 февраля 2015, 09:36



slastik, на всякий случай, напомню, что скорость течения игрового времени зависит от глобальной переменной. В 20 раз быстрее - это значение по-умолчанию, но многие его меняют.

Кроме ивента OnInit(), на ObjectReference есть еще много других ивентов. Например, OnLoad(), который выполняется каждый раз, когда загружается моделька объекта и становится готовой для анимации.

В том скриптике, что я выкладывал, стрелка движется не плавно. Она каждые секунд 10 синхронизируется со временем и прыгает на 1...2 градуса.
Но можно сделать и иначе: одну синхронизацию со временем в момент загрузки модели, а потом запуск анимации поворота с нужной скоростью (анимации не из NIF, а при помощи функции TranslateTo). Но в этом случае, нужно еще получать значение глобальной переменной скорости времени и использовать для расчета скорости поворота стрелки.

slastik  Offline  Сообщение №1454 написано: 27 февраля 2015, 11:18


Жаждущий


209
Dsion, на счет OnLoad - хорошая идея, спасибо. Как это она мне в голову не пришла...

Добавлено (27 Февраля 2015, 14:18)
---------------------------------------------
Dsion, нет, все равно при длительном пропуске времени все идет наперекосяк. Проблема в том, что когда регистрируется SingleUpdateGameTime и ГГ, к примеру, ложится спать, то момент следующего обновления эвента проходит во время сна, соответственно следующий эвент не регистрируется и т.о. цикл сбивается. А OnLoad при пробуждении не срабатывает. Спасибо за участие, но наверно это гиблая идея.

P.S. Единственное, что приходит в голову, - это добавить еще один эвент OnActivate, чтобы гг мог вручную ресетить время, если часы сбились.


- Что это за горы стоят?
- А, это орки бегут!
Holtof55  Offline  Сообщение №1455 написано: 27 февраля 2015, 11:53



49
Здравствуйте, есть еще один момент, который мне не удается решить самостоятельно.
Я запускаю музыку через скрипт, который запускает и анимацию, в конце анимации добавляется некое событие, отмеченное keyword-ом,теперь я хочу вписать условие в скрипт, что если сработал этот keyword, то музыка должна остановится(команду на стоп я знаю) в общем нужно синхронизировать старт и стоп музыки. Со стартом проблем нет, но вот со стопом есть, я пока использую утилиту на паузу,но это не круто, надо сделать по keyword
Кто-то сможет подсказать?

lolososo  Offline  Сообщение №1456 написано: 27 февраля 2015, 12:48



36
Цитата Holtof55

Здравствуйте, есть еще один момент, который мне не удается решить самостоятельно. Я запускаю музыку через скрипт, который запускает и анимацию, в конце анимации добавляется некое событие, отмеченное keyword-ом,теперь я хочу вписать условие в скрипт, что если сработал этот keyword, то музыка должна остановится(команду на стоп я знаю) в общем нужно синхронизировать старт и стоп музыки. Со стартом проблем нет, но вот со стопом есть, я пока использую утилиту на паузу,но это не круто, надо сделать по keyword
Кто-то сможет подсказать?

Функция HasKeyword может поможет тубе

Dsion  Offline  Сообщение №1457 написано: 27 февраля 2015, 12:50



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

Могу показать еще один вариант, который чуть иначе работает...

slastik  Offline  Сообщение №1458 написано: 27 февраля 2015, 13:14


Жаждущий


209
Dsion, речь идет о пропуске времени рядом с объектом, к которому привязан скрипт. Если пропускать время в другой локации, то по возвращению вновь сработает OnLoad и все наладится, а вот если находиться рядом, когда объект уже загружен - то цикл сбивается. Это происходит когда пропуск времени или сон по длительности больше, чем время, которое задано для обновления события в скрипте. Если в этот промежуток, когда актер пропускает время или спит, должен сработать следующий Event OnUpdateGameTime - то он не сработает. В результате скрипт зависает на этапе до пропуска времени +1. В моем случае часы находятся в доме, где установлена кровать ГГ. Один из возможных выходов - вынести часы на улицу, но это уже не то :)

- Что это за горы стоят?
- А, это орки бегут!
Dsion  Offline  Сообщение №1459 написано: 27 февраля 2015, 13:23



Так говорю же: попробуй мой скриптик. Там нету такой проблемы. Сразу после сна/пропуска они синхронизируются со временем.

Добавлено (27 Февраля 2015, 16:23)
---------------------------------------------
Если игрок спит в то время, когда должно произойти обновление, то обновление все-равно произойдет, но когда он проснется.


slastik  Offline  Сообщение №1460 написано: 27 февраля 2015, 13:52 | Отредактировано: slastik - 27 февраля 2015, 13:59


Жаждущий


209
Dsion,
If (!Is3DLoaded())
Return
EndIf

Что дает это условие в твоем скрипте? Если модель уже загружена - возврат к предыдущему этапу?

И проверь при возможности свой скрипт на наличие моей проблемы. Целиком я его взять не могу. Приходится адаптировать, потому как мне недостаточно просто вращать, мне еще нужно выравнивать при загрузке относительно текущего игрового времени. Это же часы, а не просто вентилятор :)

- Что это за горы стоят?
- А, это орки бегут!
Dsion  Offline  Сообщение №1461 написано: 27 февраля 2015, 14:01



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

slastik  Offline  Сообщение №1462 написано: 27 февраля 2015, 14:05


Жаждущий


209
Dsion, пока игрок спит или пропускает время модель считается незагруженной? Возможно в этом кусочке все дело, сейчас буду снова пробовать :)

- Что это за горы стоят?
- А, это орки бегут!
Dsion  Offline  Сообщение №1463 написано: 27 февраля 2015, 14:05



Именно целиком его и стоило бы взять (для начала)... Ничего туда дописывать не нужно.
Только развернуть стрелку так, чтоб при угле Z = 0 она показывала на "12".

Holtof55  Offline  Сообщение №1464 написано: 27 февраля 2015, 14:06 | Отредактировано: Holtof55 - 27 февраля 2015, 14:07



49
Цитата lolososo

Функция HasKeyword может поможет тубе

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

Код
if(HasKeyword == ??? или HasKeyword(?????) = true? или еще как-то?
Mytrack.Remove()
endif

Dsion  Offline  Сообщение №1465 написано: 27 февраля 2015, 14:19



В момент загрузки модели, стрелка сразу синхронизируется со временем. А потом синхронизируется каждые 0.05 игрового часа и так аж до выгрузки модели. Если игрок нажмет "T" и прождет какое-то время, стрелка синхронизируется сразу после конца ожидания. Со сном, скорее всего, так же.

slastik  Offline  Сообщение №1466 написано: 27 февраля 2015, 15:44


Жаждущий


209
Dsion, с вращением стрелки вокруг оси Z проблем нет, но при попытке вращать ее вокруг оси Y возникают проблемы, стрелка произвольно поворачивается в разных направлениях, уходя за циферблат. Я нарочно подогнал модель так, чтобы она как раз была в нужном положении при установке - и стрелка, и циферблат установлены в редакторе с углами 0 относительно игровых осей. Так что ваш скриптик у меня не работает. Не знаю еще что тут можно сделать.

Но зато переделал свой скрипт по вашему принципу. Убрал к черту состояния и просто вписал все в один эвент с синхронизацией в 0,1. Теперь все работает нормально, видимо зависания скрипта происходили именно из-за наличия множества состояний.

Спасибо за науку.

- Что это за горы стоят?
- А, это орки бегут!
Dsion  Offline  Сообщение №1467 написано: 27 февраля 2015, 15:56



Да всё там нормально... :(
Стрелка должна вращаться всегда именно по оси Z. Но эту ось Z можно развернуть как угодно. Часы могут и на полу лежать (осью Z вверх), и на стене висеть (осью Z в сторону игрока перпендикулярно стене) и как угодно еще...
Ладно, сам смотри.

slastik  Offline  Сообщение №1468 написано: 27 февраля 2015, 17:13


Жаждущий


209
Цитата Dsion

Стрелка должна вращаться всегда именно по оси Z. Но эту ось Z можно развернуть как угодно.


Теперь понятно :)
Я просто думал, что под осью Z имеется в виду ось Z системы координат локации. А получается, что это ось Z самой модели. Ладно, на будущее учту, еще раз спс :)

- Что это за горы стоят?
- А, это орки бегут!
lolososo  Offline  Сообщение №1469 написано: 27 февраля 2015, 19:22 | Отредактировано: lolososo - 27 февраля 2015, 19:22



36
Цитата Holtof55

Функция HasKeyword может поможет тубеМожет и поможет, ток я еще только учусь, как мне надо ее вписать?

Код
if(HasKeyword == ??? или HasKeyword(?????) = true? или еще как-то?
    Mytrack.Remove()
endif


Код
If myItem.HasKeyword(DoomKeywordProperty)
   Debug.notification("Наш предмет имеет DoomKeywordProperty")
     EndIf


Holtof55  Offline  Сообщение №1470 написано: 28 февраля 2015, 02:10



49
lolososo, спасибо, попробую!
Еще один момент, как запустить проверку, есть ли на нпс(актере) действующий магический эффект(эффект определенный, а не абы какой)

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





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