Модератор форума: 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? Пиши не в ЛС, а в эту тему.
sansuli  Offline  Сообщение №1051 написано: 1 июня 2014, 19:01


The Red Sun


193
Мда, привет сем, знаете как каждый игровой час изменять глобальное значение Global Variable? А именно каждый игровой час снижать значение на 1. К примеру в 8:00 GlobalVariable = 100, а в 12:00 GlobalVariable = 96.
Пробовал через скрипт функцией RegisterForUpdateGameTime(), но это не то, в игре глобал значение понижается каждый час, но если включить ожидание на любое количество времени, то глобал значение понижается на 1 еденицу, не смотря на ожидание.
Подскажите как воплотить задуманное?

Красное солнце
Есть вопросы по скриптам Papyrus? Пиши не в ЛС, а в эту тему.
Dsion  Offline  Сообщение №1052 написано: 1 июня 2014, 19:19



Цитата sansuli

Подскажите как воплотить задуманное?


Можно сохранить время начала отсчета и определять, сколько часов прошло.

часов_прошло = текущее_время - время_начала_отсчета
глобальная_переменная = 100 - часов_прошло

sansuli  Offline  Сообщение №1053 написано: 1 июня 2014, 20:17


The Red Sun


193
Ну решил проблему таким вот скриптом, более менее похоже))

GlobalVariable property MyGV auto
Float GameTime
Float TimePasset
Float XXX
Int ModGV
Import Utility

Event OnEffectStart(Actor Target, Actor Caster)
RegisterForUpdateGameTime(1)
GameTime = GetCurrentGameTime()
EndEvent

Event OnUpdateGameTime()
TimePasset = GetCurrentGameTime() - GameTime
XXX = TimePasset / 0.04
If XXX > 1 && XXX < 2
ModGV = 1
ElseIf XXX >= 2 && XXX < 3
ModGV = 2
ElseIf XXX >= 3 && XXX < 4
ModGV = 3
...
EndIf
MyGV.SetValue(MyGV.GetValue() - ModGV)
GameTime = GetCurrentGameTime()
EndEvent

Красное солнце
Есть вопросы по скриптам Papyrus? Пиши не в ЛС, а в эту тему.
Dsion  Offline  Сообщение №1054 написано: 1 июня 2014, 20:32



Ну ты пока не бог программирования :)

Посмотри еще вот эту функцию (округление вниз):
http://www.creationkit.com/Floor_-_Math

sansuli  Offline  Сообщение №1055 написано: 2 июня 2014, 07:49


The Red Sun


193
Мда, спасибо, так выглядит лучше.

GlobalVariable property MyGV auto
Float GameTime
Float TimePasset
Int ModGV
Import Utility

Event OnEffectStart(Actor Target, Actor Caster)
RegisterForUpdateGameTime(1)
GameTime = GetCurrentGameTime()
EndEvent

Event OnUpdateGameTime()
TimePasset = GetCurrentGameTime() - GameTime
ModGV = Math.Floor(TimePasset / 0.04)
;Debug.Notification(ModGV)
MyGV.SetValue(MyGV.GetValue() - ModGV)
GameTime = GetCurrentGameTime()
EndEvent

Красное солнце
Есть вопросы по скриптам Papyrus? Пиши не в ЛС, а в эту тему.
Greywolk  Offline  Сообщение №1056 написано: 2 июня 2014, 10:35



63
Здравствуйте. Возник такой вопрос. Возможно ли скриптом заменить одного NPC (конкретного) на другого NPC (конкретного)?

Dsion  Offline  Сообщение №1057 написано: 2 июня 2014, 11:40



Цитата Greywolk

Здравствуйте. Возник такой вопрос. Возможно ли скриптом заменить одного NPC (конкретного) на другого NPC (конкретного)?


А можно пример?
Кого и где заменить?

Greywolk  Offline  Сообщение №1058 написано: 2 июня 2014, 12:01 | Отредактировано: Greywolk - 2 июня 2014, 13:08



63
Например: при экипировке предмета одежды (возможна  проверка по Keyword) заменить одного NPC(компаньона) на другого.
При снятии предмета происходит обратное действие.
Второй NPC клон первого только другой расы.  Все пакеты и прочее одинаковые.
Проблема в том, что на предмете висит скрипт смены расы. И когда компаньон одевает этот предмет у него меняется раса и игра
теряет его Facegen (лицо темнеет). А так одновременно со сменой расы подменялся бы и NPC.
Если возможно скрипт повесить на NPC.

P.S. Если можно конкретный скрипт (название и персонажей я сам попробую вставить).
Я сам в скриптах мало разбираюсь.
P.P.S. Вещи можно заранее отобрать или сделать у них один общее (внешнее) хранилище.
P.P.P.S. Возможно ты прав и это действительно невозможно.

Dsion  Offline  Сообщение №1059 написано: 2 июня 2014, 12:56 | Отредактировано: Dsion - 2 июня 2014, 13:13



Умеешь же ты туманно изъясняться :-D Хотя, может, и правильно. Чтоб никто идеи не украл.

Если нужно просто, чтоб один NPC временно пропал нафиг, а на его месте появился другой - это запросто.
А вот если нужно, чтоб новый NPC делал то же самое, что делал старый (т.е. имел те же пакеты), и находился в тех же алиасах квестов, то уже сложнее. Без дополнительной информации ответить нечего :(

Добавлено (02 Июня 2014, 16:48)
---------------------------------------------
Ага, понял. Если ты сам мод делаешь и обе версии NPC-компаньона твои собственные, то можно.
Например, такой вариант:
1. Есть 2 разных ActorBase: Темный и Светлый. Без пакетов и скриптов. Они куда-то ставятся и один отключается.
2. Есть квест. В квесте алиас. На алиасе все пакеты и скрипты. В алиас засовывается Светлый Актор. Он начинает бегать за игроком, сражаться итп.
3. Происходит какое-то событие. Светлый Актор отключается (Disable). Темный перемещается на позицию Светлого, включается, засовывается в алиас. И дальше путешествует с игроком.
Такая схема позволит не добавлять одинаковые пакеты и скрипты разным версиям Актора. И в диалогах полегче проверку сделать было бы.

Добавлено (02 Июня 2014, 16:56)
---------------------------------------------
Пфф, не, фигня это всё. Как же перемещение вещей, надетых вещей итп. Усложняется всё.

В общем, я передумал. Не в курсе, как всё сделать. Перенести вещи, надеть те, что были надеты, перенести магические эффекты и еще черт-знает-что. Оно-то возможно, но...

Менять расу действительно необходимо?

sansuli  Offline  Сообщение №1060 написано: 2 июня 2014, 13:17


The Red Sun


193
Greywolk, мда, можно при экипировке отключить НПС (но сохранить чтобы вернуть обратно), создать его клона, включить, добавить ему предмет и экипировать, а потом ему изменить клону расу. Потом при снятии экипировки (т.е при окончании магического эффекта), отключаем и удаляем клона, возвращаем оригинального НПС.
Примерно скрипт выглядит так:

Actor TargetClone
Actor TargetOrigin
Armor property MyArmor1 auto
Race property AddedRace auto

Event onEffectStart(Actor Target, Actor Caster)
Float TargetPosX = Target.GetPositionX()
Float TargetPosY = Target.GetPositionY()
Float TargetPosZ = Target.GetPositionZ()
Float TargetAngX = Target.GetAngleX()
Float TargetAngY = Target.GetAngleY()
Float TargetAngZ = Target.GetAngleZ()
TargetOrigin = Target
ObjectReference Clone = TargetClone.PlaceAtMe(TargetClone.GetActorBase(), 1, false, true)
TargetClone = Clone as Actor
TargetClone.Enable()
TargetClone.SetAngle(TargetAngX, TargetAngY, TargetAngZ)
TargetClone.SetPosition(TargetPosX, TargetPosY, TargetPosZ)
TargetClone.AddItem(MyArmor1, 1, true)
TargetClone.EquipItem(MyArmor1, false, true)
TargetClone.SetRace(AddedRace)
EndEvent

Event OnEffectFinish(Actor akTarget, Actor akCaster)
Float TargetClonePosX = TargetClone.GetPositionX()
Float TargetClonePosY = TargetClone.GetPositionY()
Float TargetClonePosZ = TargetClone.GetPositionZ()
Float TargetCloneAngX = TargetClone.GetAngleX()
Float TargetCloneAngY = TargetClone.GetAngleY()
Float TargetCloneAngZ = TargetClone.GetAngleZ()
TargetClone.Disable()
TargetClone.Delete()
TargetOrigin.Enable()
TargetOrigin.SetAngle(TargetCloneAngX, TargetCloneAngY, TargetCloneAngZ)
TargetOrigin.SetPosition(TargetClonePosX, TargetClonePosY, TargetClonePosZ)
EndEvent
Ну как то так, ну ты дополнишь скрипт, по нужде.

Красное солнце
Есть вопросы по скриптам Papyrus? Пиши не в ЛС, а в эту тему.
Greywolk  Offline  Сообщение №1061 написано: 2 июня 2014, 13:25 | Отредактировано: Greywolk - 2 июня 2014, 14:15



63
Цитата Dsion

Менять расу действительно необходимо?

Да. Это забито в предмет(обувь системы HH). Ради этого такие заморочки. Если это не реально осуществить - так тому и быть.
Просто не буду использовать эти предметы ((лишить компаньонов большей части одежды(комплектов)).

Спасибо. Буду пробовать. Только как мне это "прицепить" к NPC.
P.S. Возможно ли вместо свойства myArmor использовать Keyword предмета.
Обуви много разной, а Keyword у нее один.
P.P.S. Я очень плохой скриптер.

Dsion  Offline  Сообщение №1062 написано: 2 июня 2014, 14:17



А можно ссылку на этот странный мод "обувь системы HH", который меняет расу?
Я очень надеюсь, что у него есть достаточные основания для такого... Иначе, это просто хамский код.

sansuli  Offline  Сообщение №1063 написано: 2 июня 2014, 14:38 | Отредактировано: sansuli - 2 июня 2014, 14:39


The Red Sun


193
Greywolk, nujno vybrat myarmor v svoystvah, skripta.

Красное солнце
Есть вопросы по скриптам Papyrus? Пиши не в ЛС, а в эту тему.
Greywolk  Offline  Сообщение №1064 написано: 2 июня 2014, 14:39



63
Мод называется Demonica (есть на этом сайте). Там в обувь на каблуке добавлен скрипт на смену расы (чтобы подменить скелет).
В результате персонаж приподнимается на высоту каблука.

Myprism  Offline  Сообщение №1065 написано: 6 июня 2014, 06:09 | Отредактировано: Myprism - 3 июня 2014, 04:59


Физик


Как можно скриптом добавить расе слоты брони видимые от первого лица?
Для каждой расы в редакторе можно поставить галочки напротив тех слотов брони, предметы в которых должны отображаться в виде от первого лица. Я для видимости дополнительных колец в виде от первого лица включаю там слоты 54, 55, 56, 57 для всех основных рас. От этого размер мода почти удваивается, т.е. редактор полностью переписывает свойства рас. Это же может быть источником конфликтов, если игрок поставит другой мод меняющий одну из этих рас. Если бы мне удалось включать эти дополнительные слоты в вид от первого лица скриптом, многие из этих проблем отпали бы.

Добавлено (06 Июня 2014, 10:09)
---------------------------------------------
Спецы по скриптам, помогите.
Проблема такая. У меня в моде Кольценосцы есть назгулы, которые респавнятся. Некоторым игрокам (меньшинство) они кажутся недостаточно сильными, а некоторым так страшны, что люди даже мод сносят :). Но есть те, кто готовы их один раз терпеть и убить, но их респавна не хотят. Так я подумал, что назгулов можно было бы убивать необратимо, уничтожая Кольцо Власти. В моде оно находится у Короля-Чародея и может быть выковано на специальной наковальне. Чтобы реализовать это, мне нужны ответы на 3 вопроса:
1.) Можно ли засекать попадание предмета в триггер? Скажем, бросил игрок кольцо в лаву (имеется), оно долетело до дна, оказалось в триггере и сделалось Disable, или даже уничтожилось совсем. По этому событию я хочу сделать переключаемым маркер Enable/Disable для назгулов.
2.) Как засекать создание предмета в кузнице? Нужно включать маркер по событию создания кольца игроком.
3.) Для того, чтобы засекать создание первого кольца и уничтожение последнего (игрок может выковать не одно), видимо, надо создавать глобальную переменную и отслеживать её значение?


Dsion  Offline  Сообщение №1066 написано: 6 июня 2014, 12:56 | Отредактировано: Dsion - 6 июня 2014, 12:57



1. Конечно, можно. Триггеры же для того и сделаны. Когда что-то в триггер попадает, в его скрипте срабатывает ивент OnTriggerEnter(ObjectReference akActionRef).
2. Тоже без проблем. Можно просто засекать появление предмета в мире. А можно еще сделать дополнительную проверку, появился ли он именно в инвентаре игрока и работает ли игрок в кузне в данный момент.
3. Можно глобальную переменную или обычную переменную в квесте. Но, наверное, лучше было бы создать FormList, который будет содержать список всех существующих в мире колец. Чтоб уж точно исключить добавление одного кольца дважды итп.

А ты не читал "Кольца Детей Ауле"?

Myprism  Offline  Сообщение №1067 написано: 6 июня 2014, 14:34


Физик


Dsion
1. Ага, это я легко отработаю. Надо только будет проверить, disable объект будет продолжать возбуждать триггер, или нет. Если да, то просто приподниму нижнюю грань триггера над полом.
2. А как засечь появление предмета в мире? Скрипт на предмете? А как называется событие?
3. Не понял, как тут можно использовать FormList. Наверное, просто создам глобальную переменную существования кольца и если она равна 1, то не позволять ковать новое, пока старое в лаву не бросят.

Нет, не читал.

Dsion  Offline  Сообщение №1068 написано: 6 июня 2014, 14:48



Триггерное событие, наверное, срабатывает только один раз в момент попадания кольца. Но можно, на всякий случай, проверять IsDisabled(). Или сразу Delete() кольцо...

Когда выковываешь кольцо со скриптом, у него срабатывают ивенты OnInit и OnContainerChanged. Вот только оба ивента могут срабатывать повторно для того-же кольца. Например, OnInit срабатывает еще раз, если кольцо выбросить на землю. Потому я и подумал, что может быть нужна регистрация каждого кольца в FormList. А если уже было зарегистрировано, чтоб не добавлялось. Ну это не очень-то простая тема... И это если много колец.

А если кольцо только одно, то пусть OnInit устанавливает переменную "кольцоСуществует" в true и всё... Какая разница, сколько раз оно сработает.

AleksTirex  Offline  Сообщение №1069 написано: 6 июня 2014, 16:03 | Отредактировано: AleksTirex - 6 июня 2014, 16:53


Архимаг


371
Триггер всегда/постоянно реагирует на объект, а не один раз. У триггера есть разные события; вход, выход и нахождение в нём, так вот последнее событие многократное, а первые два одноразовые. Так же есть GetTriggerObjectCount() , с помощью которого в любой момент можно узнать кол-во объектов в зоне триггера.

Для срабатывания события на объект "Кольцо" надо во вкладке Primitive в графе collision layer выставить L_TRIGGER

******************************

Узнать сам факт крафта кольца можно дефолтными методами и без применения "кувалды". Для этого есть готовый механизм в СК.

1. Делается квест с запуском по событию Craft Item.
2. В SM Event Node создаётся свой запуск (Craft Item) с параметром/условиями Event Data:Workbench  - HasKeyword - myKeyword == 1
3. Назначается свой квест.
4. В квесте создаётся скрипт:

Event OnStoryCraftItem(ObjectReference akBench, Location akLocation, Form akCreatedItem)
if akCreatedItem as MiscObject == myRihg
; делаем нужное
Stop() ; выключаем квест,  чтобы двть возможность повторного его срабатывания
endif
endEvent

5. В этом скрипте меняете глобалку или любое нужное действие, далее квест выключается для возможности повторного запуска, ведь ГГ может несколько раз крафтить кольцо.

В результате при крафте кольца запустится квест, сработает в нём скрипт, тем самым вы создали событие крафта своего кольца.

Myprism  Offline  Сообщение №1070 написано: 7 июня 2014, 11:58 | Отредактировано: Myprism - 7 июня 2014, 13:33


Физик


AleksTirexDsion,
1. У объекта ObjectReference нет события OnInit :( Вообще, я озадачен тем, что в папирусе нет штатных обработчиков возникновения и исчезновения предметов. Для создания это не критично, так как мне достаточно события получения кольца главным героем. После этого я запрещаю его повторный крафт изменив глобальную переменную. В этом случае считается, что кольцо в мире есть.
2. А вот с уничтожением дело плохо обстоит. Ведь уничтожение кольца в лаве это только один из способов. Кроме того, ГГ может снять с кольца зачарования, продать его или просто потерять. Или положить в респавнящийся сундук.

А можно ли создать глобальную переменную ObjectReference, присваивая ей ID кольца после получения его главным героем? Тогда при исчезновении кольца там будет Nill. Это и станет условием прекращения респавна назгулов?

Добавлено (07 Июня 2014, 15:58)
---------------------------------------------
AleksTirex, а разве кольцо MiscObject? Не Armor?
Следующий скрипт кольцо уничтожает:

Scriptname aaOneRingDestroy extends ObjectReference

Armor Property OneRing auto

Event OnTriggerEnter(ObjectReference akActionRef)
if (akActionRef.GetBaseObject() as Armor == OneRing)
akActionRef.Disable()
akActionRef.Delete()
endif
EndEvent

Dsion  Offline  Сообщение №1071 написано: 7 июня 2014, 12:57



Цитата Myprism

А вот с уничтожением дело плохо обстоит. Ведь уничтожение кольца в лаве это только один из способов. Кроме того, ГГ может снять с кольца зачарования, продать его или просто потерять. Или положить в респавнящийся сундук.

А можно ли создать глобальную переменную ObjectReference, присваивая ей ID кольца после получения его главным героем? Тогда при исчезновении кольца там будет Nill. Это и станет условием прекращения респавна назгулов?



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

Добавлено (07 Июня 2014, 16:57)
---------------------------------------------
Или его хватает назгул, доставляет хозяину и начинается апокалипсис :)


Myprism  Offline  Сообщение №1072 написано: 7 июня 2014, 13:30


Физик


Dsion, Я просто не вижу этого события в справочнике http://www.creationkit.com/ObjectReference_Script
Наверное, оно является более общим и поэтому не указано для ObjectReference. Сейчас буду искать соответствующее ему событие уничтожения объекта.

Изначально кольцо у меня находится у главного назгула. Дело в том, что я не сделал в этом моде ни одного квеста и там нет сюжетной линии кроме уничтожения назгулов и зачистки локаций. С кольца можно снимать зачарование (невидимость) и его можно выбрасывать и продавать. Если я его сделаю квестовым, то в лаву его тоже нельзя будет бросить :( Тогда пришлось бы делать специальный активатор для его уничтожения.
Наверное, надо сделать нахождение Кольца Власти главным героем до встречи его с назгулами.

mxac  Offline  Сообщение №1073 написано: 8 июня 2014, 10:31 | Отредактировано: mxac - 8 июня 2014, 15:53



178
Ребят, подскажите пжлст как выйти из инвертаря скриптом - например вешаем на зелье и при использовании этого зелья закрывался инвертарь...


Nikiiita  Offline  Сообщение №1074 написано: 8 июня 2014, 12:35 | Отредактировано: Nikiiita - 8 июня 2014, 12:40



2
Всем привет. Кому я могу довертеться unsure  здесь, найди меня в Vk.com. Очень надо.
VK-Никита Юсупов. Исетское, статус-холост. 15 лет.
Или пиши свой!

Юс
mxac  Offline  Сообщение №1075 написано: 11 июня 2014, 09:10 | Отредактировано: mxac - 11 июня 2014, 09:50



178
Подскажите как правильно сделать так, чтобы при экипировке свитка, он снимался и удалялся из инвертаря(куда лучше скрипт повесить - на сам свиток нельзя). Я хотел повесить скрипт на маг эффект(кстати если делать через маг эффект, нужно его запускать или нет?) свитка, с Event OnObjectEquipped(...) и проверкой что экипирован именно тот свиток что нужно.

И подскажите возможно ли скриптом выйти из инвертаря?


mxac  Offline  Сообщение №1076 написано: 11 июня 2014, 15:27



178
Блин, хотелось без квестов =) Но если через квест делать то можно и на прямую сделать - специфик референс-игрок, и на сам алиас скрипт повесить, только вот как скрипт правильно будет выглядеть?(Я уже сначала пробывал чтото, и не получалось)


mxac  Offline  Сообщение №1077 написано: 11 июня 2014, 17:43 | Отредактировано: mxac - 11 июня 2014, 17:48



178
Таак, заработало через квест, НО свиток не снимается сразу, только после выхода из меню, если екипировать несколько раз его, то скрипт и выполнится столько же раз; в квесте алиас на самого игрока, на котором проверяется екипировка... Надо наверно сделать проверку самого свитка(свиток не уникальный), чтобы скрипт выполнялся при эвенте OnEquipped, подскажите как это сделать ;)


Dsion  Offline  Сообщение №1078 написано: 11 июня 2014, 18:27



Чтоб работало OnEquipped, скрипт ведь должен либо к самому свитку цепляться, либо к алиасу, в котором какой-то конкретный из свитков.

А в предыдущей версии ты в скрипт на игроке не вставлял ничего типа Utility.Wait(x)? Эта функция не даст скрипту продолжить выполнение до закрытия меню.
Если же ничего такого нету, то, вроде, вещь должна нормально сниматься и удаляться даже если игрок в меню.

mxac  Offline  Сообщение №1079 написано: 11 июня 2014, 18:49



178
Цитата Dsion

А в предыдущей версии ты в скрипт на игроке не вставлял ничего типа Utility.Wait(x)? Эта функция не даст скрипту продолжить выполнение до закрытия меню.

Точно  facepalm Пасиба, а то Я уже пошол обходными путями... Кстати а PlaceAtMe создаёт объест под ногами или рядом "под прицелом"?


Alisa1992  Offline  Сообщение №1080 написано: 12 июня 2014, 13:34



Ребята, помогите разобраться. В квестах , что берутся в тавернах и у управляющего 
на ликвидацию бандита, великана, дракона оплата 100 септимов, как увеличить до 500 или 1000 ни как не пойму. 
    
Character --> Quest --> Bounty Quests 
По совету, цитирую: 
награда выдается функцией   
function RewardPlayer()  
Game.GetPlayer().AddItem(Gold001, RewardAmount)  
в скрипте  
где RewardAmount  
 Int Property RewardAmount = 100 Auto --> Увеличила до 1000, но при получении награды получаю 100   
{Default = 100; How much gold to reward player.}

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





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