• Прежде, чем задать вопрос, пожалуйста, убедитесь, что такой вопрос не задавался раньше. Старайтесь описать суть вопроса как можно подробней. • Прежде, чем опубликовать ответ на вопрос, пожалуйста, убедитесь, что обладаете необходимыми для этого знаниями. Старайтесь cформулировать суть ответа как можно лаконичней. • При желании ответить в приватном порядке, пожалуйста, воспользуйтесь ЛС. • При желании поблагодарить ответившего, пожалуйста, воспользуйтесь кнопкой "+" полезного сообщения.
Сообщения, не относящиеся к вопросам по скриптам Papyrus, ответам на них или уточнениям, являются оффтопом и могут быть удалены.
Красное солнце Есть вопросы по скриптам Papyrus? Пиши не в ЛС, а в эту тему.
Изменение репутации для пользователя Holtof55
Holtof55Offline
Сообщение №1351
написано: 24 января 2015, 08:32
| Отредактировано: Holtof55 - 24 января 2015, 08:34
Делаю мод, нужна помощь в скриптонаписании. Я сам програмирование не понимаю, поэтому отсылать меня к литературе безполезно, для меня это чуть понятней чем марсианский язык. В общем задача простая, для тех кто соображает Вот абсолютно рабочий код:
Код
Event OnEffectStart(Actor akTarget, Actor akCaster) if(akTarget) akTarget.AllowPCDialogue(true) endif endEvent
Но дело все в том, что этот AllowPCDialogue(true) ставится навечно, а мне надо на время, либо(что предпочтительней), код на удаление этого AllowPCDialogue(true) Для тех кто знает, это секундное дело, напишите плиз
Изменение репутации для пользователя Dsion
DsionOffline
Сообщение №1352
написано: 24 января 2015, 09:47
| Отредактировано: Dsion - 24 января 2015, 09:45
OnEffectStart срабатывает, когда эффект на кого-то накладывается и устанавливает для NPCAllowPCDialogue - Да
А OnEffectFinish срабатывает, когда эффект заканчивает действие и устанавливает AllowPCDialogue - Нет
Тут-то весь и вопрос, а как мы это время поймем, если оно не задано? Когда должен сработать финишь эффекта? Или это надо указать в Duration?
Скрипт скомпилировался, пойду пробовать в игре Спасибо!
Все в игре работает, СПАСИБО ОГРОМНОЕ!..мне может еще кое что понадобится, в частности простой код на следование за игроком, и после какого-то действия код должен удалится(перестать работать), могу обратится?
Изменение репутации для пользователя Dsion
DsionOffline
Сообщение №1354
написано: 24 января 2015, 11:23
| Отредактировано: Dsion - 24 января 2015, 11:23
Это уж тебе точно виднее Если это заклинание (Spell), то будет висеть столько, сколько длительность действия заклинания. Если зачарование, то эффект пропадет, когда предмет снимется итп.
Можно, конечно:
Код
Event OnEffectStart(Actor akTarget, Actor akCaster) akTarget.AllowPCDialogue(true) Utility.Wait(60) akTarget.AllowPCDialogue(false) EndEvent
Но это не круто...
Изменение репутации для пользователя Holtof55
Holtof55Offline
Сообщение №1355
написано: 24 января 2015, 11:30
| Отредактировано: Holtof55 - 24 января 2015, 11:34
Так, теперь новая задача. Нужен скрипт магического эффекта который снимет с Драугров, Фалмеров, и Дремор их экипировку,, включая одежду и доспехи, а после окончания эффекта, оденет обратно. Кто-то может такой скрипт соорудить? Зачем мне это нужно? Ну, вот ...надо...
To all: Как обнулить действие скрипта, который сохранён в сейве игрока? У меня в моде есть кольца со скриптом на них. Мне нужно выложить обновление мода, в котором этот скрипт изменён. Но те игроки, которые не ставят мод заново, а обновляют его, столкнутся с проблемой, что на тех кольцах, которые у них уже есть, будет работать старый скрипт. Я проверяю так: у меня есть сохранение со старым кольцом. Я изменил кольцо, в старом сохранении изменения не работают. Но стоит подобрать то же самое кольцо, но которого не существовало в сохранении, то оно работает как надо. Сама игра кольца не различает и складывает их в инвентаре в одну позицию - кольцо 2 шт. В редакторе это тоже одно и то же кольцо, но вот сохранённый и не сохранённый экземпляры работают по-разному Конечно, я могу объяснять игрокам, что им следует заменить кольца, но правильнее было бы избавить игрока от этой проблемы Да, смена имени скрипта не помогает.
Holtof55, экипировка персонажей содержится в списке одежды Outfit персонажа. Его можно менять заклинаниями или скриптами. Если заменить на специально сделанный пустой Outfit, то все шмотки переходят в инвентарь персонажа, но он может их оставить одетыми на себя. Так что надо ещё и оттуда всё забирать. Потом всё возвращать. Хлопот много, а стоит ли того задача? Помимо этого учти, что одёжка персонажей (у драугров точно) и не одёжка вовсе, а просто их тело. Чтобы раздеть такого персонажа ему надо сделать новое голое тело, которого в игре нет.
Сам скрипт должен обновляться. Ивенты и функции должны срабатывать уже новые. Но вот OnInit(), если изменен, заново уже не вызовется. А с чего бы ему вызываться? И значение уже заполненных Property не изменится. Можно было с самого-самого начала проектировать мод с учетом возможности обновления...
anton, удалить - не проблема. Игрок сам выкинет или продаст.
Dsion, там всего два события - equip и unequip, но вот свойство одно добавлено. Обработка старых свойств сохранилась, а вот новое работает только у нового экземпляра кольца. Предвидеть обновления невозможно, особенно такие. Теперь кольцо у меня не занимает слота, не имеет ArmorAddon и рисуется как ArtObject. Это даёт ему вид ещё и от первого лица. Вообще, если предвидятся обновления, то и мод не надо выкладывать, пока эти обновления не будут сделаны
Я когда-то таки придумал систему, позволяющую (теоретически) избежать проблем при обновлении. Но тогда уже особо не делал моды и так её и не проверил. Там смысл в полном отсутствии OnInit() где-либо и отсутствии Property в том виде, в котором мы к ним привыкли.
Изменение репутации для пользователя Multigone
MultigoneOffline
Сообщение №1362
написано: 29 января 2015, 18:20
| Отредактировано: Multigone - 29 января 2015, 19:20
Кто-нибудь знает, как измерить угол Х поверхности, на которой стоит игрок, с учетом направления его взгляда по оси Z?
Myprism, по поводу события OnDying (возможно, и OnDeath тоже?) - при завершении маг. эффекта с архетипом SummonCreature по времени это событие должно срабатывать (возможно, и под действием Banish тоже). Вот почему нужна проверка уровня здоровья, т.к. в ванильной игре взрыв должен происходить только при гибели атронаха от действий источников, снижающих AV Health.
Но простого условия Target.GetAV("Health") <= 0.0 недостаточно, т.к. при добивании в ближнем бою с помощью KillMove это условие не сработает (атронах погибнет с уровнем здоровья больше нуля). Конечно, ванильные атронахи не имеют анимаций добивания их игроком, речь о призванных существах с наличием таких анимаций (призванный огненный взрывающийся питомец, например). Поэтому нужно использовать:
EVENT OnDying(Actor myKiller) IF Target.GetAV("Health") <= 0.0 || Target.IsInKillMove() ; Погибает. ELSE ; Изгоняется или истекает время.
Это к слову о том, зачем там проверка уровня здоровья.
По поводу шлемов: разве нельзя вместо периодической проверки "оружие взято в руки" отслеживать анимацию Draw \ Sheatle с помощью RegisterForAnimationEvent(ObjectReference akSender, string asEventName)?
Во-вторых, необязательно для каждого шлема создавать отдельный скрипт. Достаточно одного скрипта на алиасе игрока и 2х FormList (можно вообще одного) с открытыми и закрытыми версиями. При экипировании к-л. открытой формы из первого листа находится его позиция Х и устанавливается соответствующая закрытая форма из второго. Можно и наоборот.
Dsion, дай угадаю: отсутствие Property подразумевает присутствие FormList (тоже Property, но уже одно-единственное)? Все равно, Property нужны для обмена переменными между скриптами, верно? Как минимум - текстовыми переменными и переменными форм, а числовые можно передавать через глобальные.
Multigone, я просто написал новый скрипт, в котором у события EVENT onDeath(actor myKiller) нет никаких проверок. Ведь мне не нужно обрабатывать смерть призванных атронахов. Всё работает как нужно.
Насчёт шлемов: @perture сделал анимацию забрала и она хорошо работает не только для вида от третьего лица, но даже от первого. Забрало поднимается и опускается закрывая лицо.
Изменение репутации для пользователя Multigone
MultigoneOffline
Сообщение №1364
написано: 30 января 2015, 00:05
| Отредактировано: Multigone - 30 января 2015, 00:06
Multigone, ты ответил совершенно понятно. Твой ответ рассеял мои сомнения по поводу этого скрипта и всё мне объяснил. Я же ведь до этого не был уверен что меняю его правильно. Спасибо!
А это RegisterForAnimationEvent(ObjectReference akSender, string asEventName) я пока использовать не умею
Myprism, Это я знаю, проблема в том, что я незнаю, как примерно должен выглядеть скрипт! Изначально у него стоит бандитская фракция (которая по моему вообще не враждует с игроком) и нейтральное отношение!
W@nTeD, я не гожусь в учителя скриптописания. На этот язык нет нормального описания как, скажем, на Паскаль, поэтому я всё делаю там методом тыка и по ванильным образцам. Вот фрагмент кода из моего квеста, который меняет и фракцию и отношение к игроку:
Это строки из квеста и тут используются Алиасы (псевдонимы) персонажа. Вот полный код моего заклинания развода:
Scriptname aaDivorce extends ActiveMagicEffect
Faction Property PlayerMarriageFaction Auto Quest Property RelationshipMarriage auto Quest Property RelationshipMarriageFIN auto Quest Property RelationshipMarriageBreakUp auto ReferenceAlias Property Alias_LoveInterest Auto Quest Property DialogueFollower Auto
Event OnEffectStart(Actor akTarget, Actor akCaster) akCaster.RemoveFromFaction(PlayerMarriageFaction) RelationshipMarriage.Reset() RelationshipMarriageFIN.Reset() RelationshipMarriage.SetStage(10) Alias_LoveInterest.ForceRefTo(akTarget) RelationshipMarriageBreakUp.SetStage(0) RelationshipMarriageBreakUp.SetStage(200) (DialogueFollower as DialogueFollowerScript).pFollowerAlias.Clear() (DialogueFollower as DialogueFollowerScript).pFollowerAlias.ForceRefTo(akTarget) (DialogueFollower as DialogueFollowerScript).DismissFollower() EndEvent
Вроде, этого должно хватить, чтобы сварганить своё заклинание
Добавлено (01 Февраля 2015, 11:27) ---------------------------------------------
Цитата @perture
Действие кольца можно периодически освежать с помощью RegisterForSingleUpdate. Освежаться будет как при загрузке сейва так и при переходе между локациями. Да и во всех прочих случаях.
Похоже, это то, что нужно. В руководстве нашёл вот такой пример:
; This is within the "empty" state Event OnInit() ; This event will run once, when the script is initialized RegisterForSingleUpdate(2.0) EndEvent
Event OnUpdate() if (myQuest.GetStage() == 10) Debug.Trace("Got what we needed, so stop polling!") UnregisterForUpdate() GotoState("active") ; Switch to a state that doesn't use OnUpdate() endif EndEvent
State active Event OnUpdate() ; Do nothing in here. Empty event will be thrown out by the compiler. EndEvent EndState
Я понял это так: Событие OnUpdate этого скрипта назначается как событие обновления этого объекта и это обновление происходит каждые 2 секунды до тех пор, пока не выполнится условие. После этого назначение снимается. Дальше событие OnUpdate переключается в рамки State active, где оно ничего не делает. Возникает вопрос, зачем нужно UnregisterForUpdate(), если потом переходит переключение в пустой Event OnUpdate? Вопрос возникает потому, что мне нужно поставить это для кольца, которое одевается и снимается. Т.е. мне надо правильно начать процесс и правильно его закончить.
1. Может мне использовать RegisterForUpdate при одевании кольца вместо RegisterForSingleUpdate? Тогда не нужно указывать интервала обновления. 2. При снимании кольца, видимо, надо выполнить UnregisterForUpdate()? 3. Нужно ли оставлять пустой State active и переключать в него в моём случае?
Myprism, RegisterForSingleUpdate используется в скриптах расширяющих ActiveMagicEffect Script, Alias Script и Form Script. Эта функция регистрирует однократное обновление события, и рекомендуется использовать его, а не RegisterForUpdate везде где возможно. Смысл в том, что если в какой-то непредвиденной ситуации не отработает UnregisterForUpdate, то получим зависший цикл. Интервал обновления указывается в обеих функциях.
При снимании кольца надо выполнить Unregister.
State active вообще не понятен в данном случае. Я бы сделал как то так
Код
ScriptName MyScript Extends ActiveMagicEffect
Event OnEffectStart(Actor akTarget, Actor akCaster) Тело скрипта RegisterForSingleUpdate(1.0) EndEvent
Event OnUpdate() Тело скрипта RegisterForSingleUpdate(1.0) EndEvent
Event OnEffectFinish(Actor akTarget, Actor akCaster) UnregisterForUpdate() EndEvent
В диалоге есть поле для скрипта "End:". Можно просто всписать туда akSpeaker.StartCombat(Game.GetPlayer()) Тогда NPC договорит свою фразу и набросится на игрока. Но не станет врагом игрока перманентно.
Если NPC должен стать врагом навсегда, можно всписать такое: akSpeaker.SetRelationshipRank(Game.GetPlayer(), -4) NPC станет врагом игрока. Но будет ли он на игрока набрасываться - зависит от характеристики Aggression. Если Aggression == 0, то не будет. Если Aggression == 1, будет набрасываться на врагов. Если Aggression == 2, то (тут я не уверен) будет набрасываться на всех не-союзников.
Aggression можно задвать в настройках Actor'а или изменять в том же скрипте: akSpeaker.SetActorValue("Aggression", 1)
остальное переноси в другой скрипт, который будет висеть на маг. эффекте, добавляемом спеллом RingVisibility. Ну а там по вышеприведенному примеру. В событии OnUpdate() будет осуществляться проверка экипировки, и если что-то слетело, то поправляться. И при каждой проверке будет регистрироваться следующая разовая проверка.
Spell Property RingVisibility auto ; Видимость кольца как Арт-объекта Outfit Property kOutfitEmpty Auto ; Пустой оутфит Outfit kOutfit ; Сохранённый оутфит Armor Property NewSkin Auto ; Новое тело Armor OldSkin ; Старое тело Actor Owner ; Владелец кольца
? в OnUpdate я проверяю только не слетел ли скин и оутфит. Компилятор не ругается и в игре работает. Конечно, для уверенности надо тестировать долго (до респавна) и с чистого сохранения, это будет позже.
Multigone, не спорю, я в скриптописании не силен, однако в таком контексте лог выводит следующее:
Код
[02/02/2015 - 08:34:18AM] Error: Unable to call RegisterForSingleUpdate - no native object bound to the script object, or object is of incorrect type stack: [Item 5 in container (00000014)].aaa.RegisterForSingleUpdate() - "<native>" Line ? [Item 5 in container (00000014)].aaa.OnEquipped() - "aaa.psc" Line 5
Скрипт чисто для лога. Скомпилировался без ошибок.