Если, допустим, есть квест SiskiQuest, а на нем скрипт SiskiQuestScript, а на скрипте проперти SiskiVar и функция SiskiFunc, то в любом другом скрипте можно вот так:
Код
Quest Property SiskiQuest Auto ... (SiskiQuest As SiskiQuestScript).SiskiVar = 40; (SiskiQuest As SiskiQuestScript).SiskiFunc(4040); ...
или еще вот так:
Код
SiskiQuestScript Property SiskiQuest Auto ... SiskiQuest.SiskiVar = 40; SiskiQuest.SiskiFunc(4040); ...
С объектами в мире так же, но нужно заполнять проперти конкретным референсом из конкретной локации...
PitrPokir, ну вот небольшое задание. Выполнять, конечно, не обязательно, если не хочешь, но, на мой взгляд, было бы полезно. 1. Создаешь новенький мод. 2. Создаешь в моде один единственный квест. На квесте оставляешь галочку Start Game Enabled - он будет запущен всегда. 3. Создаешь в квесте один пустой алиас. (Specific Reference, но никого не выбирать). 4. На алиасе обязательно ставишь галочку Optional. Это означает, что он может быть пустым. 5. На алиас вешаешь собственно созданный (или ванильный) пакет следования за игроком. Можно взять PlayerFollowerPackage. 6. На этом же квесте создаешь один диалог. Игрок говорит что-то типа "за мной идти хочешь ты...", а NPC отвечает "..за тобой идти хочу я...". В поле для скрипта на диалоге сначала вбиваешь ; и компилируешь. Потом к скрипту добавляешь проперти с типом ReferenceAlias и именем типа FollowerAlias, а в потом в само поле для скрипта вписываешь FollowerAlias.ForceRefTo(akSpeaker) 7. Проверяешь в игре (может понадобиться сохраниться/загрузиться, чтоб появился диалог).
Скрипт на диалоге засовывает НИП в алиас и пакет на алиасе становится приоритетнее всех пакетов на самом НИП. Когда предлагаешь пойти с тобой другому НИП, то в алиас засовывается уже другой НИП, а первый "освобождается" и идет по своим делам. Если нужно, чтоб бегало с тобой сразу много, надо много алиасов. И чуточку усложнить скрипт. Скрипт должен заполнять не конкретный алиас, а первый свободный из списка.
Ну да, оно не совсем просто, но и не сложно. Может, стоило бы еще другие варианты рассмотреть. Типа, при вытягивании духа, можно было бы этого духа сразу убивать, а потом поднимать каким-то воскрешением. Тогда бы он и без алиаса бегал за игроком. Но с алиасами - гибче
Лично я ивенты не использовал бы. Ну вот зачем выполнять кусок кода и делать какие-то проверки каждый раз, когда призрак получает урон? У тебя в перспективе будет квест и на нем много алиасов, да? Будет разумно добавить скрипт на сам квест и сделать в нем функцию типа
Код
Function CreateGhost(Actor akSource) Actor Clone = Game.GetPlayer().PlaceActorAtMe(akSource.GetActorBase()); Clone.RemoveFromAllFactions(); ... Alias[Index].ForceRefTo(Clone); EndFunction
Заданием этой функции будет получить аргументом какого-то живого НИП и создать призрака-спутника. Причем это функция должна делать вообще всё, что надо сделать... Вот в этой функции можно создать клона, удалить ему фракции, изменить характеристики итп, а потом сунуть в первый свободный алиас. А на алиас можно никаких скриптов и не вешать. А потом откуда там тебе надо (из заклинания или из диалога) просто вызываешь эту функцию на своем квесте одним из двух способов на выбор:
Код
Quest Propery MyQuest Auto
Event OnEffectStart(Actor akTarget, Actor akCaster) (MyQuest As MyQuestScript).CreateGhost(akTarget); EndEvent
или
Код
MyQuestScript Propery MyQuest Auto
Event OnEffectStart(Actor akTarget, Actor akCaster) MyQuest.CreateGhost(akTarget); EndEvent
Блин, так же сделано в DialogueFollower. И чего я распинался?
Добавлено (05 Февраля 2017, 18:34) --------------------------------------------- Там всё легко, но только два подвоха, про которые важно не забыть: 1. Проверку наличия свободного алиаса лучше делать до создания клона. А если свободного алиаса нету, то клона не создавать. 2. Не забыть сделать правильное отключение и удаление клонов. И позаботиться, чтоб они удалялись всегда-всегда-всегда. Если умрут, если закончится время действия заклинания итп. Во всех случаях надо Disable() + DeleteWhenAble() референс. Ну и не забыть очистить алиас.
Изменение репутации для пользователя Dsion
DsionOffline
Сообщение №1056
| Тема: Вопросы по скриптам Papyrus
написано: 6 февраля 2017, 18:40
| Отредактировано: Dsion - 6 февраля 2017, 18:46
Ну нельзя же вот так просто брать от фонаря название функции и пытаться её вызвать Вот тут полный список всех методов на всех типах: https://www.creationkit.com/index.php?title=Category:Script_Objects И видно, что никакого Dispel на объектах типа "Spell" нету. Dispel есть на ActiveMagicEffect, но только на нем. А еще на объектах "Actor" есть DispelSpell(Spell akSpell).
Изменение репутации для пользователя Dsion
DsionOffline
Сообщение №1057
| Тема: Вопросы по скриптам Papyrus
написано: 7 февраля 2017, 07:06
| Отредактировано: Dsion - 7 февраля 2017, 08:04
Ну в Скайриме есть базовые объекты и их референсы. В CreationKit в списках слева - это почти всё базовые объекты. А в мире базовых объектов не бывает, а только референсы. Вот есть, например, базовый объект IronSword (тип проперти для скрипта: Weapon). Он всего один, на нем указаны все характеристики и вид меча. А в мире может валяться дофига референсов этого меча (тип проперти: ObjectReference). Изменение характеристик базового объекта изменяет характеристики всех референсов. И вот представь, что ты пытаешься "снять" этот IronSword (базовый). С кого игра должна его снять? Какой именно нужно снять, если НИП держит их два сразу? Вот потому на проперти типа Weapon нету метода "снять". Ну и по аналогии: Spell - это базовый объект заклинания. С кого оно должно сниматься функцией диспел? MagicEffect - это базовые объект магического эффекта. А вот ActiveMagicEffect - это уже что-то типа референса - это настоящий уже действующий эффект на каком-то настоящем НИП в мире. И его можно Dispel.
Если твой скрипт наследует ActiveMagicEffect - это означает, что ты в любом месте можешь прописать Dispel() и это должно снять именно этот эффект с того, на кого он наложен.
Ну Self - это всегда именно тот скрипт, в котором мы написали "Self". Так что первый вариант вполне правильный. И в скрипте на магическом эффекте, теоретически, Self.Dispel() или просто Dispel() должно работать. А если не работает, то это, скорее, баг или недоработка Скайрима, а не что-то другое...
Изменение репутации для пользователя Dsion
DsionOffline
Сообщение №1059
| Тема: Вопросы по скриптам Papyrus
написано: 7 февраля 2017, 17:54
| Отредактировано: Dsion - 7 февраля 2017, 17:38
Многие не понимают один важный аспект скриптов, а я не знаю, как это описать без четырех страниц текста...
1. Все скрипты в Скайриме - это почти то же самое, что классы в С++. Создание папирусового скрипта с именем "SluttyActor" равноценно объявлению класса SluttyActor в С++.
2. Все классы(скрипты) могут быть типом переменной (или проперти), таким же как int и float. Но в С++ мы можем в любом месте создать экземпляр любого класса: SluttyActor a; , а в папирусе таким образом мы можем создать только простые переменные (int и float). Экземпляры всех остальных классов могут существовать только связанными с каким-то реальным объектом в мире игры.
3. Actor, ObjectReference, Spell итп - мы можем создавать проперти этих типов только потому, что в Data/Scripts/Source у нас лежат скрипты Actor.psc, ObjectReference.psc, Spell.psc итп.
4. Как в С++ классы могут наследовать друг друга, так и в папирусе скрипты могут наследовать друг друга. Например, класс Actor (живой объект в мире) наследует класс ObjectReference (любой объект в мире). Это означает, что любой Actor - это всегда и ObjectReference тоже. На Actor всегда можно вызвать любую функцию, которую можно вызвать на ObjectReference. Актора можно передать аргументом в функцию, которая просит ObjectReference итп. Но Actor еще и расширяет ObjectReference, добавляя новые функции. Актор - это всегда ObjectReference, но ObjectReference - не всегда Актор.
5. И самое главное. Это не совсем правильно, но так будет легче понять. Попробуйте не отделять в сознании скрипт от какой-то вазы, на которой он висит. Представьте, что скрипт - это есть ваза, а ваза - это есть скрипт. Не называйте скрипт "СкриптНаВазе", а назовите его "УлучшеннаяВаза". И с этого момента можете думать об "УлучшеннаяВаза" точно так же, как вы думаете об "Actor". А почему нет? Точно такой же класс. Точно так же, как и Actor, наследует и расширяет ObjectReference. Вы теперь можете создать проперти с типом УлучшеннаяВаза. Или написать функцию, которая будет принимать аргументом именно улучшенную вазу. Ну и еще всякое...
Multigone, если ты вдруг это всё читал... То (AAA as BBB) - это не обращение к скрипту BBB на объекте AAA... А это называется type cast или приведением типов... Мы как-бы говорим "Вот у меня есть объект типа AAA, но я точно знаю, что это объект типа BBB. Так что заглохни, компилятор, и дай мне работать с ним как с BBB.". В папирусе это безопасно, но в том же Си или С++ надо быть осторожным...
Добавлено (07 Февраля 2017, 20:54) --------------------------------------------- PitrPokir, а как получилось, что время действия не известно? Мало ты информации подогнал
Изменение репутации для пользователя Dsion
DsionOffline
Сообщение №1060
| Тема: Вопросы по скриптам Papyrus
написано: 8 февраля 2017, 05:38
| Отредактировано: Dsion - 8 февраля 2017, 05:51
PitrPokir, ну сам смотри... Лично я пока не вижу смысла вешать на игрока эффект... Через квест, на котором алиасы и основной скрипт, всегда можно узнать, сколько у игрока в подчинении призраков и их референсы. Вешать эффект на призрака (кроме abGhostAbility) тоже пока смысла не вижу... Но, может, он (смысл) и есть. Ты же не всё рассказываешь. Ладно-ладно, не моё дело.
PitrPokir, так это же важно! Лучше об этом бы и подумал! Варианта, как минимум, два: 1. Вешаем скриптик на алиас с ивентом OnDeath. Когда ивент срабатывает, скрипт сразу отключает и удаляет референс. А потом еще и очищает алиас. Таким же способом можно сделать ограничение времени действия. При создании призрака - заказ OnUpdate. А в OnUpdate - отключение, удаление, очистка. 2. Не очищаем алиас сразу после смерти. Но для функции поиска пустого алиаса алиас с мертвым НИП будет считаться пустым. Опять же, надо не забыть отключить и удалить труп.
Ну и еще дофига вариантов можно придумать. Придумать нормальную систему работы с алиасами - это же самое важное для тебя.
SanBos, так запросто. Тебе нужно изучить квест DialogueFollower полностью и диалог "идем со мной" на квесте DialogueFavorGeneric. Когда поймешь (истинно), как там всё работает, запросто запилишь пункты 1, 2 и 3. А потом можно и за пунтк 4 думать.
Ну и еще алиас на квесте DialogueFollower... Пакеты на алиасе приоритетнее пакетов на самом НИП и именно они заставляют НИП быть спутником. Ну там увидишь по ходу дела.
С озвучкой там легко всё. Когда создашь топики и топик инфо, там можно будет просто дважды клацнуть по фразе и записать звук.
Изменение репутации для пользователя Dsion
DsionOffline
Сообщение №1064
| Тема: Вопросы по скриптам Papyrus
написано: 14 февраля 2017, 14:25
| Отредактировано: Dsion - 14 февраля 2017, 14:26
Я смотрел квест, из которого она меняется. Точно название не помню, но там в нем есть слова "monitoring" и "dlc1". Каждую секунду выполняется необоснованно сложная и длинная функция, определяющая, "осел" ли игрок... Если результат определения изменяется, то и переменная изменяется, и выполняется EvaluatePackage()... Я бы эту функцию не копировал, о чем и сообщил гангрене в приват... А вот EvaluatePackage() каждую секунду действительно могло бы помочь.
Просто смотреть вперед игроку разрешено или нет? Не передвигаясь при этом.
Ну, в целом, да, можно сделать, конечно. Когда игрок заходит в триггер, нужно начать регулярное повторение функции. Либо через OnUpdate, либо через OnTrigger (если частота там подходящая). А в функции проверяем на игроке IsSneaking (скрытность) и GetAngleZ (поворот по оси Z), чтоб находился в заданном промежутке. Промежуток можно рассчитать единоразово на основе GetAngleZ самого триггера. Тогда надо будет только не забывать правильно повернуть сам триггер. Могу написать скрипт, если со всеми деталями определишься...
Да этот случай из тех, когда свой легче сделать, чем разбираться в чужом... И этот скрипт проверят игрока только в момент входа в триггер. То есть, можно войти в режиме скрытности, а потом хоть крагами бегать, хоть в барабан бить...
nnnpc, круто придумал :-D А бандитов туда можно сажать? А то некоторых бандиточек жалко убивать. Заставить сидеть в клетке - это, скорее всего, тебе нужно разбираться с алиасами квестов и пакетами... И скриптами до кучи. Думаю, для каждой клетки придется создать отдельный алиас. На каждый алиас вешается пакет сидения в клетке (один). А потом НИП, кроме телепортации, помещается в этот алиас. А за прогрузку не знаю... Ну разве что можно Disable (отключить) всех НИП во всех алиасах верхнего этажа, когда игрок на нижнем. И наоборот... Не сложно, но не факт, что будет всё нормально работать.
Изменение репутации для пользователя Dsion
DsionOffline
Сообщение №1070
| Тема: Вопросы по скриптам Papyrus
написано: 24 февраля 2017, 03:02
| Отредактировано: Dsion - 24 февраля 2017, 03:02
Multigone, я бы просто для интереса попробовал какой-то бред типа... Ну создать новый предмет с именем "Усил.", а потом делать String NewName = RefName1 + RefName2 Но у меня SKSE вообще нету.
Да... Может, кто-то что-то посоветует, но я бы сильно не расчитывал... Ну если бы, теоретически, это была лично моя проблема и мне было очень важно найти решение, то я бы поймал вылет в OllyDbg, а потом помаленьку двигался назад с брейкпоинтами и пытаясь понять, что должна делать вылетающая процедура. Но вряд ли тут кто-то этим заниматься будет. Скорее, в теме этих модов. Ну или удалять один за другим все объекты, добавленный модом в тот район...
Без SKSE можно задействовать только кнопки-цифры с 1 по 8. Да и то не очень красиво: через предмет одежды, который вызывает функцию при надевании и сразу снова снимается. А если с SKSE, то можно использовать любые кнопки, но я SKSE не использую и не собираюсь.
Добавлено (07 Апреля 2017, 16:55) --------------------------------------------- Когда-то давно еще делал мод, который позволял колдовать заклинания, рисуя "прицелом" символы в воздухе. Работало, но было не очень круто.
Mengur, а что вписал в скрипт Actor? Не покажешь? Я просто вообще ни разу не слышал, чтоб кто-то редактировал эти скрипты. Интересно!
А вообще, проблема известная. "Аура" вокруг игрока - распространенное стандартное решение. И да, скрипт магического эффекта получает событие от актора. Похожим образом, кстати, работает "обнаружение жизни".
Ну еще один кривой вариант - это добавить всем расам пассивный навык, который тоже будет накладывать магический эффект и получать события. Но перезаписывать все расы - это диковато. А больше лично я вариантов и не знаю.
Добавлено (24 Апреля 2017, 09:30) --------------------------------------------- Хотя видел еще в Default Objects поле "Every Actor Ability". Я его не проверял и не знаю, работает ли, но, судя по названию, должно добавить пассивное умение всем акторам. Но, опять же, может вызвать несовместимость с чем-то.