Модератор форума: 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? Пиши не в ЛС, а в эту тему.
AleksTirex  Offline  Сообщение №601 написано: 6 декабря 2013, 19:59


Архимаг


371
Цитата DarkVetal

Две функции RegisterForUpdate(08.00) и OnUpdate(12) выдают ошибку. Я так понял первая включает предмет в заданное время, а вторая поддерживает указанное количество часов?



http://www.creationkit.com/OnUpdate_-_Form 
Первая - команда регистрации события.
Вторая - событие.

Добавлено (06 Декабря 2013, 23:59)
---------------------------------------------
nine-dragon-art, SKSE - расширитель скриптового языка Папирус. Он добавляет свои функции/команды/события.
ScriptDragon я не пользовался, да и не вижу сейчас модов с ним, т.е. он не получил развитие.


Myprism  Offline  Сообщение №602 написано: 7 декабря 2013, 03:59


Физик


AleksTirex, Я описал только как тот триггер срабатывает в игре. Он большой, но срабатывает прежде, чем игрок туда заходит, на ещё большем расстоянии. Но я же с ним поигрался. Если его сделать маленьким и поставить на дорогу, то срабатывает как надо. Беда в том, что мне этот триггер нужен там, где у меня три нечисти патрулируют. В итоге срабатывает слишком издалека. Пошёл пробовать твой код.

Добавлено (07 Декабря 2013, 07:50)
---------------------------------------------
Всё работает! Мой триггер с твоим кодом прекрасно запускает тот (кто бы сомневался :) ). Одна проблема - мой триггер срабатывает совершенно как тот - на большом расстоянии. Мне ещё нужна проверка, что в мой триггер вошёл именно игрок. Как в активации засечь игрока?

Добавлено (07 Декабря 2013, 07:59)
---------------------------------------------
Ну вот, оказывается, иногда и своё серое вещество надо напрячь :) Всё оказалось очень просто:

Event OnTriggerEnter(ObjectReference akActionRef)
    if akActionRef == Game.GetPlayer()
          GetLinkedRef().OnTriggerEnter(akActionRef)
    endif
EndEvent


Теперь триггер работает как надо.


LordVadim  Offline  Сообщение №603 написано: 7 декабря 2013, 04:37



139
Цитата DarkVetal

Куда ее прикрутить, ведь это функция действия на время, а не выключателем. К нужному предмету? Как должен выглядеть полный скрипт? Две функции RegisterForUpdate(08.00) и OnUpdate(12) выдают ошибку. Я так понял первая включает предмет в заданное время, а вторая поддерживает указанное количество часов? Первая функция прописалась в скрипте без проблем, но не работает.


OnUpdate() - это событие, а не функция. В скобках ничего быть не должно - поэтому выдает ошибку. События называются событиями потому, что срабатывают в зависимости от наступления каких либо условий. В данном случае - по прошествии времени указанного функцией RegisterForUpdate(08.00) - если оставить как написано, то событие OnUpdate() будет вызываться каждые 8 секунд.
Куда это вставлять - зависит от того, что необходимо сделать. Например если просто надо выключить котел1 через некоторое время - то проще сделать как писал AleksTirex, поставить в скрипте Wait(время) - и повторить цикл While.

DarkVetal  Сообщение №604 написано: 7 декабря 2013, 07:53 | Отредактировано: DarkVetal - 7 декабря 2013, 07:54

AleksTirexLordVadim, газ, вода и слив работают идеально! Благодарю за помощь!
OnUpdate() - это событие, а не функция. В скобках ничего быть не должно - поэтому выдает ошибку. События называются событиями потому, что срабатывают в зависимости от наступления каких либо условий. В данном случае - по прошествии времени указанного функцией RegisterForUpdate(08.00) - если оставить как написано, то событие OnUpdate() будет вызываться каждые 8 секунд.
Куда это вставлять - зависит от того, что необходимо сделать. Например если просто надо выключить котел1 через некоторое время - то проще сделать как писал AleksTirex, поставить в скрипте Wait(время) - и повторить цикл While.
Мне надо чтобы включалось в определённое время суток. Например в 20.00 зажигаются огни, появляется стража, блокируются ворота (маркер коллизии) . А в 8.00 все опять исчезает. Да и привязывать скрипт надо уже к нужному предмету, ведь активация по времени, а не от рычага.

Я так понял игре пофигу на какой активатор вешать скрипт включения предметов, то есть если вместо рычага я повешу на триггер-активатор, то может ли любой кто зайдет в триггер вызвать действие скрипта? Или нужно подправить скрипт?
Event OnTriggerEnter(ObjectReference akActionRef)
if GetLinkedRef().IsDisabled()
GetLinkedRef().Enable()
else
GetLinkedRef().Disable()
endif
endEvent

Или добавить условие появления в нем актера:
Event OnTriggerEnter(ObjectReference akActionRef)
(akActionRef as Actor)
if GetLinkedRef().IsDisabled()
GetLinkedRef().Enable()
else
GetLinkedRef().Disable()
endif
endEvent

AleksTirex  Offline  Сообщение №605 написано: 7 декабря 2013, 11:01


Архимаг


371
Цитата DarkVetal

может ли любой кто зайдет в триггер вызвать действие скрипта? Или нужно подправить скрипт?



Скрипт поправлять не надо, ведь он по определению срабатывает только на актёров. Это прописано в самом триггер-боксе на объекте по умолчанию. Там же сменить принцип срабатывания бокса триггера.
 
Если речь идёт о срабатывании на НПС, т.е. на человека, а не на любого актёра (мышь, драугр и т.д.), тогда надо вводить условия, но уже не (akActionRef as Actor), а akActionRef.HasKeyword(ActorTypeNPC).

VALKNUT  Offline  Сообщение №606 написано: 7 декабря 2013, 11:15



AleksTirex, глянь пожалуйста мое сообщение №600

Кто к нам с чем и за чем, тот от того и того... ʘ_ʘ
<a class="link" href="http://modgames.net/load/0-0-200451-0-17" rel="nofollow" target="_blank"> border="0" alt=""/</a>
DarkVetal  Сообщение №607 написано: 7 декабря 2013, 11:23

AleksTirex, стражу я привел как пример, а если делаю без стражи, или нужно разное время срабатывания? Типа темнеет, зажигаются костры\фонари (статика и свет) во время потемнения (выставить время как в игре), или открывается проход куда-то (например войти в локацию можно с 10.00 до 20.00 часов) - убирается завал камней или неработающая дверь.
Да, нужно срабатывание триггера на любое существо (зашел в запретную зону - появилась тюремная решетка вокруг, или лазер покромсал на фарш.

AleksTirex  Offline  Сообщение №608 написано: 7 декабря 2013, 12:15


Архимаг


371
Цитата VALKNUT

а можно как-то рекурсивно добавить весь FormList и так же рекурсивно его удалить?



Можно:
 
 int iIndex = ListSpell.GetSize()
  While(iIndex > 0)
  iIndex -= 1
  akActor.RemoveSpell(ListSpell.GetAt(iIndex) as Spell)
  endWhile

 
Естественно, если надо добавлять заклинания, тогда команда AddSpell, если не заклинания, а перки, тогда AddPerk, и т.д.
Можно любое количество заклинаний так добавлять/удалять.

Добавлено (07 Декабря 2013, 16:15)
---------------------------------------------
DarkVetal, всё зависит от конкретной ситуации. Одного общего универсального решения почти нет (оно есть, но не удобное). В каждом случае желательно делать свой метод, заточенный под данную ситуацию и необходимые действия.
 
Сам принцип "универсального" метода: при попадании ГГ в локацию срабатывает событие, например, OnCellAttach(). В нём проверяется текущее время, вычисляется необходимое время ожидания до старта цикла на включение/выключение чего-либо. Потом это время выжидается событием OnUpdate() и по его срабатыванию запускается цикл на вкл/выкл. Если ГГ зашёл когда уже должен работать цикл, то вычисляется время до первой смены цикла, сам цикл запускается на это время и по его окончании запускается этот цикл уже со своими параметрами. Этим ты синхронизировал игровое время и свой цикл.
Если цикл не постоянный, а может меняться, то нужно вводить и эти расчёты тоже.

(попробуй сам написать этот скрипт по этому алгоритму, это не так сложно, как кажется)


AleksTirex  Offline  Сообщение №609 написано: 7 декабря 2013, 14:05


Архимаг


371
DarkVetal, на любой постоянный и невыключаемый объект в центре локации (например, камень или столб) вешается скрипт:
 
ObjectReference Property akObject Auto
GlobalVariable Property GameHour Auto
float fTimeStart = 20.00 ; время старта, когда фонари должны включиться
float fTimeStop = 6.00   ; время финиша, когда фонари должны выключиться
float fTimeWait

 
Event OnCellAttach()
  UnregisterforUpdateGameTime()
  if GameHour.value > fTimeStart || GameHour.value < fTimeStop
    akObject.Enable()
    if GameHour.value < fTimeStop
      fTimeWait = fTimeStop - GameHour.value
    else
      fTimeWait = fTimeStop + 24.0 - GameHour.value
    endif
  else
    akObject.Disable()
    fTimeWait = fTimeStart - GameHour.value
    endif
  endif
  RegisterForSingleUpdateGameTime(fTimeWait)
endEvent

 
Event OnCellDetach()
  akObject.Disable()
  UnregisterforUpdateGameTime()
endEvent

 
Event OnUpdateGameTime()
  if akObject.IsDisabled()
    akObject.Enable()
    fTimeWait = fTimeStop + 24.0 - GameHour.value
    RegisterForSingleUpdateGameTime(fTimeWait)
  else
    akObject.Disable()
    fTimeWait = fTimeStart - GameHour.value
    RegisterForSingleUpdateGameTime(fTimeWait)
  endif
endEvent


Где akObject назначается свой основной объект (маркер или нечто подобное), а все остальные объекты для выключения подвязываются к этому объекту через Enable Parent (все остальные фонари-лампы).
 
fTimeStart и fTimeStop - время включения и выключения фонарей. Это уже сам в скрипте поставишь нужные значения, сейчас в 20.00 включаются, а в 6.00 утра выключаются.
 
При входе в локацию (при её загрузки) проверяется время, и по результатам фонари включаются или выключаются. Там же рассчитывается время для ближайшего переключения фонарей и запускается режим ожидания до этого переключения. Когда наступит нужное время, фонари переключатся, рассчитается время для следующего переключения, и опять запустится режим ожидания. При выходе из локации все фонари выключаются и сбрасывается режим ожидания. И дальше опять при входе в локацию... и так каждый раз. Пока ГГ в той локации, режим ожидания сам будет включать и отключать фонари.

DarkVetal  Сообщение №610 написано: 7 декабря 2013, 14:33

AleksTirex, последний тупой вопрос - как назначить нужный предмет на akObject? И кроме фонарей можно же прицепить любой предмет?
И главное - это не оставит в сейвах следов? Не хотелось бы, чтобы у людей, удаливших мод, остались следы и глюки.

AleksTirex  Offline  Сообщение №611 написано: 7 декабря 2013, 17:05


Архимаг


371
Цитата DarkVetal

как назначить нужный предмет на akObject? И кроме фонарей можно же прицепить любой предмет?



Рядом со скриптом, есть кнопочка Properties, нажимаешь её, выделяешь своё свойство akObject и Edit Value, дальше как и везде - мишенью тыркаешь по своему объекту в окне мира. ОК.
 
Назначать akObject можно любой постоянный объект, а уже к нему привязывать можно хоть тысячу любых других объектов. Изначально галочек "выключен" ставить нигде не надо, скрипт сам сделает нужное действие.
 
Следов и глюков в сейвах этот скрипт не оставит.

VALKNUT  Offline  Сообщение №612 написано: 7 декабря 2013, 17:31



AleksTirex, еще подсказка нужна...

Пытаюсь изменить класс НПС, но видимо что-то не так делаю.
СК не ругается, но ни к чему это в игре не приводит..
В FormList добавлены 3 стиля, в каждой ветке диалога указываю свой индекс..

myActorBase.SetClass(myClass.GetAt(0) as Class)

Код с рекурсивной обработкой FormList отлично работает.

Благодарю!

Кто к нам с чем и за чем, тот от того и того... ʘ_ʘ
<a class="link" href="http://modgames.net/load/0-0-200451-0-17" rel="nofollow" target="_blank"> border="0" alt=""/</a>
AleksTirex  Offline  Сообщение №613 написано: 7 декабря 2013, 19:50


Архимаг


371
Цитата VALKNUT

все пытаюсь добавить скрипт - вылетает редактор, что на лестницу вешал, что на хединг маркер, одинаково вылетает при нажатии кнопки ОК (добавить новый скрипт)



После нажатия Add появится окно с выбором скриптов, выделяешь первую строку NewScript и ОК. Появится окно, там надо вписать своё название скрипта (и если нужно, поменять тип). В окне объекта появится скрипт. Далее правой кнопкой по нему Edit Source, откроется редактор скрипта. Туда и надо прописывать сам текст скрипта.
 
Если ты делаешь так и СК вылетает, то он битый, и надо его "чинить". Как именно... просто удали и установи с нуля.

AleksTirex  Offline  Сообщение №614 написано: 8 декабря 2013, 11:34


Архимаг


371
Цитата DarkVetal

первые 2 столбца скрипта идут на ура



Это не понял, что такое "2 столбца"? Это 2 скрипта на один объект или что-то другое?
 
Если надо сделать новый скрипт и добавить к объекту, то можно делать/создавать скрипт на любом объекте, потом удалить этот скрипт с этого объекта, сам же файл скрипта останется в папке, и потом этот скрипт просто назначить на свой нужный объект.

LordVadim  Offline  Сообщение №615 написано: 8 декабря 2013, 14:05



139
Цитата DarkVetal

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


Можно настроить Notepad++ на работу со скриптами Notepad++ Установка.
Я вообще не представляю как можно нормально работать со скриптами в том убожестве, что встроено в СК.

AleksTirex  Offline  Сообщение №616 написано: 8 декабря 2013, 15:30


Архимаг


371
Цитата LordVadim

Я вообще не представляю как можно нормально работать со скриптами в том убожестве, что встроено в СК.



Например я, всё пишу в строннем редакторе (Notepad++ с поддержкой языка Папирус, очень удобно, когда есть подсветка), а в родной редактор только вставляю готовый текст скрипта и компилирую.
 
*************************
 
DarkVetal, странно, я такой эффект ни разу не встречал, и даже не слышал о таком от других людей. Тебе просто "повезло", наверное. Как с этим бороться не знаю.

LordVadim  Offline  Сообщение №617 написано: 8 декабря 2013, 16:20



139
Цитата AleksTirex

а в родной редактор только вставляю готовый текст скрипта и компилирую.


А зачем? В Notepad++ ведь можно настроить и компиляцию. Я настроил F8 на сохранение и F9 на компиляцию - удобно, нажал две кнопки и все готово! В родной редактор СК вообще не заглядываю.

AleksTirex  Offline  Сообщение №618 написано: 8 декабря 2013, 16:52


Архимаг


371
Это да, так удобнее компилировать, НО, при компиляции через родной редактор меньше шансов, что забудешь инициализировать свойства, т.к. всё равно открываешь нужный объект, а там и скрипт сразу вставляешь, и свойства назначаешь. А при компиляции через нотепад всё равно надо лезть туда же и делать тоже самое.
Но это уже кто к чему привык. :)

LordVadim  Offline  Сообщение №619 написано: 9 декабря 2013, 06:08 | Отредактировано: LordVadim - 9 декабря 2013, 06:09



139
Цитата DarkVetal

Не сталкивался с таким?


А ты пути в ScriptCompile.bat менял?
И еще, для компиляции с помощью Notepad++ скрипт должен располагаться в папке: ...\Skyrim\Data\Scripts\Source

.

Добавлено (09 Декабря 2013, 10:08)
---------------------------------------------
Ко нибудь знает, где в игре настраивается параметр количества одновременно работающих источников света с тенью в одной локации? И можно ли его установить более 4?

Myprism  Offline  Сообщение №620 написано: 9 декабря 2013, 06:50


Физик


Цитата LordVadim

И можно ли его установить более 4?

Нигде и нельзя :( Вот такая грустная новость. И не только источники света с тенью, но любые источники света. В оригинальных локациях одна текстура обычно освещается только одним источником, максимум двумя. Один на локацию основной и маленькие локальные источники. Кроме того, в ванили локации имеют общее рассеянное освещение, да такое, что и без источников света всё видно :)

LordVadim  Offline  Сообщение №621 написано: 9 декабря 2013, 09:36



139
Цитата Myprism

Нигде и нельзя. Вот такая грустная новость.

 
Спасибо за ответ. Я, в принципе, так и предполагал.

DarkVetal  Сообщение №622 написано: 9 декабря 2013, 16:29

AleksTirex, компилировал твой скрипт через редактор, не загружая .ESM. Со всеми ошибками разобрался, осталась одна:
Mismatched input "endif" expecting ENDEVENT

Artem13  Offline  Сообщение №623 написано: 9 декабря 2013, 17:50 | Отредактировано: Artem13 - 9 декабря 2013, 17:52


Mercenaries. Со смертью на ты.


Цитата DarkVetal

Mismatched input "endif" expecting ENDEVENT



Выделенный endif лишний:

Event OnCellAttach()
UnregisterforUpdateGameTime()
if GameHour.value > fTimeStart || GameHour.value < fTimeStop
akObject.Enable()
if GameHour.value < fTimeStop
fTimeWait = fTimeStop - GameHour.value
else
fTimeWait = fTimeStop + 24.0 - GameHour.value
endif
else
akObject.Disable()
fTimeWait = fTimeStart - GameHour.value
endif
endif
RegisterForSingleUpdateGameTime(fTimeWait)
endEvent

<a class="link" href="http://nick-name.ru/sertificates/278209/" rel="nofollow" target="_blank"> border="0" alt=""/</a>
Да, мы бандиты и бродяги, как злословит молва,
Мы попадаем в передряги, помня эти слова.
Смотри вперед и не сдавайся ты на милость судьбе!
Предай их всех, останься верен себе. (Канцлер Ги - Кантри Бреган Д'Эрт)
DarkVetal  Сообщение №624 написано: 9 декабря 2013, 19:09 | Отредактировано: DarkVetal - 10 декабря 2013, 15:58

AleksTirex,LordVadim,Artem13 спасибо вам огромное, наконец-то всё получилось! Проблему компиляции решил так:
1. Скопировал скрипт Алекса в блокнот, добавил имя, сохранил с расширением .psc
2. Зашел в редактор, не загружая мастер-файл скомпилировал свой .psc скрипт в .pex.
3. Загрузил мастер-файл, и потом добавил скрипт нужному предмету.
-------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------
AleksTirex, в Доме теплых ветров, к лестнице привязал скрипт, akObject привязал к хединг маркеру, а к нему, через Enable Parent подключил разные предметы. Прикол в том, что предметы вкл\выкл не по времени указанному в скрипте, а в любое другое время, плюс работает это не в прямом эфире, надо выйти и войти в дом заново, тогда срабатывает (через раз и в любое время)
У тебя был скрипт без названия, поэтому я посмотрел другие твои скрипты и дописал название и то, что после него, как в других скриптах:
Scriptname aAutoFadeObject extends ObjectReference
Не знаю, правильно ли. И кроме akObject, в Properties было еще свойство: Game Hour, и на него можно что-то назначить, может без этого и не срабатывает вовремя.
P.S. Всё проверялось с помощью быстрого ожидания, но даже если за час до назначенного времени прекратить быстрое ожидание и просто ждать в игре, все равно не срабатывает.

AleksTirex  Offline  Сообщение №625 написано: 13 декабря 2013, 15:53 | Отредактировано: AleksTirex - 13 декабря 2013, 22:00


Архимаг


371
DarkVetal, вот интересно, а как скрипт узнаёт текущее время в игре, не задумался над этим?

Всем читающим эту тему: в названиях функций/команд/событий/свойств ВСЕГДА присутствует подсказка, что именно это "слово" обозначает.
Например, Game Hour в переводе на русский язык - "игровое время", т.е. "сколько сейчас времени в Скайриме". Вот это и есть то, как именно скрипт узнаёт текущее время, и если на это свойство не назначен нужный ID, то скрипт не имеет понятия, сколько времени в Скайриме, и естественно, ничего работать не будет.

Надо назначить нужный ID этому свойству.

***********
Тип скрипта правильно написал.

DarkVetal  Сообщение №626 написано: 13 декабря 2013, 16:54

AleksTirex, а разве в редакторе есть такое понятие "время", то есть в игре оно присутствует, в редакторе есть ползунок, отвечающий за перемотку времени,но это нематериальный обьект,в отличие от предметов, как же узнать его id?

AleksTirex  Offline  Сообщение №627 написано: 13 декабря 2013, 17:21 | Отредактировано: AleksTirex - 13 декабря 2013, 21:59


Архимаг


371
Цитата DarkVetal

а разве в редакторе есть такое понятие "время", то есть в игре оно присутствует, в редакторе есть ползунок, отвечающий за перемотку времени,но это нематериальный обьект,в отличие от предметов, как же узнать его id?



А как же, конечно есть.  Хоть время и не материально, но циферки то... вполне материальны. Game Hour - это глобальная переменная, которая заполняется движком, и в ней записано текущее игровое время на момент вызова этой функции.

Всем, кто читает эту тему: при заполнении свойств, сперва нажмите кнопку автозаполнения Auto-Fill, и тогда все свойства, которые называются также как и ID, сами заполнятся, а остальные свойства придётся заполнять как обычно вручную.

DarkVetal, нажми на эту кнопку, и свойство само заполнится.

DarkVetal  Сообщение №628 написано: 13 декабря 2013, 18:10 | Отредактировано: DarkVetal - 14 декабря 2013, 06:26

AleksTirex, ну голова! Я б и не допёр до такого, спасибо еще раз. Я тебе надоел уже своими тупыми вопросами.  unsure

LordVadim  Offline  Сообщение №629 написано: 13 декабря 2013, 21:51



139
Можно ли сделать НПС призраком? Но не только полупрозрачным, а чтобы сквозь него можно было пройти?

Amiball1992  Offline  Сообщение №630 написано: 13 декабря 2013, 23:23



23
LordVadim, да, поместив в список его заклинаний активный эффект. Покопайся, я не помню, как он называется (эффект).

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





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