• Прежде, чем задать вопрос, пожалуйста, убедитесь, что такой вопрос не задавался раньше. Старайтесь описать суть вопроса как можно подробней. • Прежде, чем опубликовать ответ на вопрос, пожалуйста, убедитесь, что обладаете необходимыми для этого знаниями. Старайтесь cформулировать суть ответа как можно лаконичней. • При желании ответить в приватном порядке, пожалуйста, воспользуйтесь ЛС. • При желании поблагодарить ответившего, пожалуйста, воспользуйтесь кнопкой "+" полезного сообщения.
Сообщения, не относящиеся к вопросам по скриптам Papyrus, ответам на них или уточнениям, являются оффтопом и могут быть удалены.
Красное солнце Есть вопросы по скриптам Papyrus? Пиши не в ЛС, а в эту тему.
Как только будет внятная инфа, то она будет добавлена в шапку. Примеры такому в разделах Fallout. А вообще-то, лучшим вариантом для сбора инфы был бы аналог Картотеки. Это способствовало бы развитию моддинга, поскольку уже были бы ответы на многие вопросы. Но в свое время раздел Скайрима пошел по другому пути.
Не знаю, жив ли тут кто, но у меня, как ни странно, возник вопрос... точнее 2... Предыстория: создал перк. Хочу, что бы перк работал только на тот предмет, который держал игрок в правой руке во время чтения заклинания. И тут же возникли проблемы...
1) не получается в ReferenceAlias скриптом ForceRefTo заполнить оружие из руки игрока. Читал тут комменты, и понял, что предметы инвентаря не имеют своих ID (и я убедился в этом, прописав такую штуку "ObjectReference orWeap = Caster.GetEquippedWeapon() as objectreference"). Есть ли хоть какой-то способ манипулировать конкретной ссылкой на оружие в руке игрока вне границ одного скрипта (для базовых объектов, значит, беседчики придумали Formlist, а тут "на" тебе - не понятно, что за дела)
2) даже если бы каким-то непонятным чудом получилось бы прописать реф оружия в алиас скрипта, как заставить перк принимать этот алиас? В кондишнах перепробовал все возможные функции - ничего подобного нет (точнее, есть функция IsAliasRef, но там нельзя выбрать квест [как так???]).
Unlogin, чо-то у меня тоже никаких идей. Ну до того, что можно отменять эффект перка навсегда, если игрок сменит оружие, ты, наверное, додумался. Не совсем то, но лорно. Выпустил оружие из рук - разорвал связь. До того, что можно сохранять базовый ID тоже, наверняка, додумался. Большинство ванильных орудий имеют разные базовые id для разных типов зачарования. Но это будет давать сбой, если игрок наденет оружие такого же типа с таким же зачарованием. И в случае предметов, которые ирок сам заточил/зачаровал тоже будут сбои. Я бы так не делал. Ну еще жутко неудобный вариант, когда игрок должен выбросить оружие на землю (или на какой-то алтарь), чтоб зачаровать.
Больше нифига в голову не приходит... Я бы просто отменял эффект навсегда в случае смены оружие.
Я даже когда-то читал про один баг. В какой-то там ветке есть перк, делающий надетую на игрока бронь невесомой. Так вот этот перк делает невесомой не только надетую бронь, а и точно такую же, лежащую в инвентаре.
Dsion, вот с вариантом про алтарь я как-то не подумал... можно же контейнер для этой цели использовать... ну, ладно, как зафиксировать конкретный реф оружия, возможно, разобрались. А как потом этот реф в перке использовать - пока что загадка. Или наоборот, как перк использовать только на реф.
Multigone, я так-то думал несколько сделать. Например, шанс крита. Типа, ты наделись конкретно своё оружие особенной силой, которая увеличивает шанс крита. Если короче, то хотел руны в Скайрим добавить. Что б совсем эпично было - зачаровал оружие, наточил его, руну нанёс, и это уже мега-артефакт...
Автономный троль-бот
Изменение репутации для пользователя Multigone
MultigoneOffline
Сообщение №2706
написано: 24 сентября 2018, 07:45
| Отредактировано: Multigone - 24 сентября 2018, 07:51
Unlogin, чтобы узнать референс непостоянного объекта, нужно его выбросить в мир. Далее - им заполняется алиас (optional), он считается постоянным и его референс существует внутри инвентаря. В алиасе указывается ключ. слово для перка. Таким способом можно отметить <= 128 ед. оружия на один квест. Можно сделать что-то вроде алтаря, при активации которого на него помещается оружие из правой (левой) руки. Например, для квеста со 128 алиасами (нумерация 0-127) в простейшем случае это будет выглядеть так:
Код
; На активатор алтаря
Quest Property MyQuest Auto ObjectReference Property MyAltarMarker Auto
EVENT OnActivate(ObjectReference akActionRef) GoToState("Wait") IF (akActionRef AS Actor).GetEquippedObject(1) AS Weapon Int iCount WHILE (MyQuest.GetAlias(iCount) AS ReferenceAlias).GetReference() && iCount < 128 iCount += 1 ENDWHILE IF iCount < 128 ObjectReference xRef = akActionRef.DropObject((akActionRef AS Actor).GetEquippedObject(1)) xRef.MoveTo(MyAltarMarker) (MyQuest.GetAlias(iCount) AS ReferenceAlias).ForceRefTo(xRef) ELSE Debug.MessageBox("Свободных мест нет.") ENDIF ENDIF GoToState("") ENDEVENT
STATE Wait EVENT OnActivate(ObjectReference akActionRef) ENDEVENT ENDSTATE
Всем привет, подскажите пожалуйста скрипт на одноразовый телепорт, активировал и он выключился или сам предмет исчез. И скрипт на тп лута с персонажа. Активировал и с ГГ снимается одежда, оружие и весь лут и перемещается в определенный ящик. Заранее спасибо.
Добавлено (22 Октября 2018, 17:01) --------------------------------------------- Нужен скрипт на перемещение содержимого инвентаря в ящик. То есть - ГГ активирует предмет и переноситься в определенную точку(тп при активации я уже сделал) и у него пустой инвентарь все перенеслось в определенный ящик. Помогите пожалуйста со скриптом.
Существует хорошо известный глюк использования физики - это её "бешенство". При выходе персонажа в отрытый мир (не в интерьер) волосы или плащ начинают метаться. Через некоторое время могут успокоиться, а могут и нет. Тогда персонаж становится невидимым. Так как это происходит только в открытых локациях, то можно предположить, что физика глючит из-за того, что локация не успевает прогрузиться. Но задержка появления персонажа, увы не помогает. Зато великолепно всё исправляется, если задержать появление в открытой локации только шмотки с физикой относительно появления персонажа, на коем эта шмотка надета. Например, достаточно задержать появление волос относительно персонажа на 2 секунды, чтобы проблем с ними не было совсем. На эти 2 секунды их можно заменить волосами без физики. Вопрос в том, как написать скрипт, который бы находился на одеваемой шмотке и засекал, когда персонаж меняет локацию и выходит в открытый мир. Скрипт, который делает это, вися на персонаже, я написал и он великолепно исправляет физику волос. Но мне нужен скрипт именно на шмотках. Ведь не вешать же скрипт на каждого персонажа Скайрима! Гораздо правильнее - повесить его на ограниченное число проблемных шмоток с физикой (плащи, волосы). Да, шмотки раздаются персонажам через оутфиты и левельные списки.
А условия Condition Functions не подойдут? Для определения работы скрипта? IsInteier там и подобное? Если в интерьере тогда запускать скрипт если не в интерьере тогда не запускать, я помню так делал, весьма работало неплохо.
Aksyonov, у меня нет проблемы определять, находится ли персонаж в интерьере. Вот скрипт, который я повесил на персонажа:
Код
Scriptname aa_ChangeLocation extends Actor
Armor property HairItem auto
Event OnLocationChange(Location akOldLoc, Location akNewLoc) if (Game.GetPlayer().GetCurrentLocation() == akNewLoc) && !(Game.GetPlayer().IsInInterior()) ; Если главный герой в той же локации и если она не интерьер AddItem(HairItem) ; Добавляем новые EquipItem(HairItem, true) ; Устанавливаем новые RegisterForSingleUpdate(3.0) ; Ждём 3 секунды endIf endEvent
Event OnUpdate() RemoveItem(HairItem) ; Удаляем новые волосы endEvent
И он прекрасно работает. Мне нужен скрипт для ПРЕДМЕТА. Тех же волос или плаща, находящегося в левельных списках и оутфитах очень многих персонажей. Нужно чтобы при инициализации предмета или при переходе главного героя в данную локацию, все плащи там стали Disable, а через 3 секунды - Enable. Дело в том, что многочисленные мои варианты (не привожу примера, так как никакой не работает )тут не работают. Тут есть какая-то фишка, которую я не понимаю. Вот другой пример её: создаю я кольцо со скриптом. Всё отлично работает. Дальше кладу 6 колец в сундук в интерьере - в игре кольца больше не работают. Одно кольцо, лежащее на полу - работает, 6 в сундуке - не работают. А вот если в сундук положить левельный список, в котором уже лежат 6 колец (но не 6 сразу вместе, а отдельно, 6 раз по одному) - то всё работает отлично. Тут есть какая-то фишка с тем, как Скайрим выделяет память под переменные однотипных объектов.
Добавлено (06 Декабря 2018, 08:28) --------------------------------------------- Я попробую по чётче обрисовать свою задачу. При переходе Главного Героя в некоторую локацию, она начинает загружать все свои объекты. Мне нужно, чтобы небольшая часть объектов (одежда с физикой на персонажах локации) грузилась не сразу, а спустя 3 секунды после начала загрузки локации. Внимание, задерживаться должны не персонажи с физикой (не поможет), а только некоторые их шмотки.
andrelo-1, спасибо за наводку. Очень полезные функция: string Function SetModelPath(string path, bool firstPerson, bool female) native Открывает большие возможности. Но моя проблема не в этом, а куда прикрутить её или что-то другое. Мне не удаётся подобрать для шмотки событие в котором я мог бы её менять. У меня тупо ничего не делает даже вот такой код:
Myprism, мне тоже ничего в голову не приходит... Ну можно повесить на вещи зачарование с постоянным эффектом. Тогда будет возможно отслеживать момент загрузки актора. Но это как-то не изящно. Можно дать всем расам умение с постоянным эффектом (или там где-то есть фишка, позволяющая дать умение всем акторам). Можно заставить вещь проверять состояние (загружен/не загружен) актора-носителя каждые несколько секунд. Эти варианты не только не изящны, но еще и создадут дополнительную нагрузку. В общем, одни кривые костыли... А меня от костылей уже тошнит... Я теперь либо делаю красиво, либо не делаю вообще... Если проблему нельзя исправить "по-нормальному" (средствами nifskope итп.), то я бы вообще забил...
Myprism, можно например составить список всех вещей, у которых надо отключать физику, и при смене локации просто по этому списку менять модель. Иногда будет конечно много лишней работы, особенно если в локации нет ни у кого нужных вещей. Но все же...
Друзья, вы меня утешили. Я наверное, всё же не совсем тупой, а просто задача, которую я поставил, действительно не решается. Дело в том, что у надетой шмотки совсем нет событий! Меня ввело в заблуждение то, что шмотки это как бы ObjectReference. Да, пока их не надели. И даже OnЕquipped это событие ещё не надетой шмотки. И смена слота у надетой шмотки тоже не происходит. Так что, есть только один путь - через Актора. Dsion, постоянное заклятие это не такое уж и плохое решение. Во-первых, так работает вся обувь на высоком каблуке и это проблем не вызывает. Во-вторых это открывает возможность создавать плащи (особенно актуально) и причёски с физикой, которые совсем не занимают слотов. Если шмотка привязана только к одной кости, то её можно рисовать магическим эффектом. При этом сам объект к которому привязан магический эффект не показывается, а эффект рисуется. А скелеты у плащей и причёсок с физикой обычно свои и привязаны только к одной из костей обычного скелета. Одна беда, пока занимался только телами и бронёй, совсем забыл (да и знал то не очень) магические эффекты... А вообще, когда приходится изобретать такие костыли, то это верный признак того, что путь выбран не тот. Ведь главная причина в дефекте физики. И заключается он в том, что если скелет объекта с физикой грузится одновременно со скелетом персонажа, то, похоже, объект с физикой инициализируется не на персонаже, а в центре локации и потом физика старается (иногда тщетно) это исправить. Ведь плащи и причёски всегда вытянуты к центру локации, а вероятность глюка тем больше, чем больше локация. andrelo-1, идея новая для меня, надо хорошенько её обдумать.
@perture, Точно! Там на персонажа вешается заклятие (заклятие видимости забрала). Заклятие на персонажа вешает шмотка, а уже у заклятия полно событий и доступ к чему угодно. Так же работают и высокие сапоги. Я сейчас пробую так сделать для укрощения плащей. Кстати, это ещё позволяет сделать плащи не занимающие слотов, так как их видимость может быть обеспечена заклятием. Кстати, у меня та же проблема, спустя некоторое время уже не помню, как делал ту или иную вещь А так как приходится переключаться между очень многими областями программирования, то случается это частенько :(
Цитата @perture
Сам бы таким путем и пошел.
Вынужден сам себе запрещать такие решения Достаточно посмотреть на размер DLL-ки и тот факт, что её писали на Си (я на нем не писал), чтобы понять, что времени на это уйдёт много. Для меня то это не проблема, я легко в это нырну и даже получу от этого удовольствие, но тогда модов от меня уже долго никто не увидит И так уже у меня возникло опасение, что из-за того, что я программирую в слишком большом количестве разных областей, а переключение между ними не очень лёгкое, то процесс создания модов перестаёт быть сходящимся :)
Добавлено (12 Декабря 2018, 21:17) --------------------------------------------- 1. Скажите, пожалуйста, переменные какого уровня сохраняются в скрипте при сохранении и загрузке игры? Наверное, переменные объявленные внутри функции или события не сохраняются. А те, что объявлены в скрипте вне функций и событий?
2. Есть ли способ отследить внутри скрипта extends ActiveMagicEffect событие загрузки игры? Или выхода из игры?
Изменение репутации для пользователя Dsion
DsionOffline
Сообщение №2719
написано: 12 декабря 2018, 22:08
| Отредактировано: Dsion - 12 декабря 2018, 22:08
Myprism, да, вроде, всё сохраняется... Вход/Выход/Загрузка не должны никак мешать работе скриптов... Но я бы все-равно не использовал функцию utility.wait()... Это просто воще не круто...
1. Скажите, пожалуйста, переменные какого уровня сохраняются в скрипте при сохранении и загрузке игры? Наверное, переменные объявленные внутри функции или события не сохраняются. А те, что объявлены в скрипте вне функций и событий? 2. Есть ли способ отследить внутри скрипта extends ActiveMagicEffect событие загрузки игры? Или выхода из игры?
1. Мне тоже кажется, что все переменные сохраняются. 2. OnPlayerLoadGame, если эффект висит на игроке. Выход вроде никак не отследить.
andrelo-1, Увы, эффект визит не на игроке, а на других персонажах.
Добавлено (13 Декабря 2018, 19:46) --------------------------------------------- Ещё появились вопросы. Вот объявляю я в скрипте переменную: Armor Armor31 Присваиваю ей значение: Armor31 = (NPC.GetWornForm(0x00000002) as armor) Дальше меняю свою переменную: Armor31.SetSlotMask(0x00000800) ; 41 И обнаруживаю, что соответствующая шмотка на персонаже поменяла свои слоты. Таким образом, знак присваивания означает, что присваивается указатель на объект. А как получить копию объекта?
Изменение репутации для пользователя andrelo-1
andrelo-1Offline
Сообщение №2722
написано: 13 декабря 2018, 17:08
| Отредактировано: andrelo-1 - 13 декабря 2018, 17:09
andrelo-1, а это точно? Ведь базовый объект не вызывался...
Добавлено (13 Декабря 2018, 20:28) --------------------------------------------- А ведь это объясняет непредсказуемое поведение моего скрипта...
Добавлено (16 Декабря 2018, 15:59) --------------------------------------------- Загадки папируса. (Или игры). Долго я возился над скриптом, задерживающим появление шмоток с физикой через заклятие. Большой получился, хоть и работает. Но не люблю я таких громоздких решений. Тогда отложил его и написал очень простой скрипт, который вешается прямо на шмотку:
Код
Scriptname _HDTPhysics extends ObjectReference
Event OnEquipped(Actor akActor) if (akActor != Game.GetPlayer()) ;&& !(akActor.IsInInterior()) Armor NPCItem = (Self.GetBaseObject() as armor) akActor.UnEquipItem(NPCItem) Utility.Wait(3.0) akActor.EquipItem(NPCItem) endif endEvent
Не бейте ногами за Utility.Wait(3.0). У надетой шмотки нет никаких событий кроме OnEquipped и OnUnEquipped. Не обрабатывает она и событие OnUpdate. И не ругается на событие, но код в нём никакой не работает. Но даже с этим маленьким кодом возникли непонятки. Если я брошу такую шмотку на пол в интерьере, то она прекрасно работает в соответствии со скриптом. Но если я дам эту шмотку персонажу в оутфит, а в игре заберу эту шмотку, она не работает. Т.е. не пропадает на 3 секунды при надевании. Вот есть 2 шмотки. Одну с пола подобрал, другую с трупа. В моём инвентаре они выглядят идентично. Точнее сливаются в одну с цифрой 2. Но если их выбросить на землю, а потом надеть по-отдельности на персонажа-спутника, то одна шмотка работает, другая - нет. Почему???
Работает нормально. NPC, у которых такая вещь в аутфите, перенадевают её во время загрузки локации. А если такого NPC убить, забрать вещь и надеть на спутника, тот сразу перенадевает её. И хреново, конечно, у вещи нет референс id. Ни зарегистрировать её, ни даже Self использовать нельзя.
Я сначала написал большой и сложный скрипт, который вешается на заклятие (а оно вешается на персонажа шмоткой) и отслеживает видимость персонажа главным героем. (Работает хорошо, кстати). А в процессе отладки понавешал на все события мессаджей. Вот тут и увидел, что персонаж переодевается, причём делает это только при выходе из интерьера на открытое пространство (как раз, где надо). При переходе из интерьера в интерьер переодевания нет. Принципиальное отличие твоего скрипта в том, что ты саму шмотку в свойство определил. Скорее всего в этом и причина, что у тебя скрипт работает всюду. Скорее всего, свойству референс id выделяется. Ещё, скажи, пожалуйста, зачем нужна первая задержка в 1 секунду? То, что у меня не работает, если шмотка берётся с трупа, скорее всего, связано с тем, что шмотке не выделяется референс id. Если она лежит в игре на полу - то это просто объект и референс id у него быть обязан. Такой глюк у меня был пару лет назад с кольцами. Я тогда повесил скрипт на кольцо, отладил его и всё работало великолепно, пока мне не понадобилось положить кольца в сундук. Кольца извлечённые из сундука не работали категорически. Тогда проблему удалось решить так - я положил все кольца в левельный список, но не 6 вместе, а 6 раз по одному. А этот левельный список бросил в сундук. В этот раз я попытался сделать тоже со шмоткой, положить её в отдельный левельный список, увы, в этот раз не помогло.
Добавлено (17 Декабря 2018, 06:37) --------------------------------------------- Да, а от самоопределения шмотки Armor NPCItem = (Self.GetBaseObject() as armor) ты отказался потому, что не работал Self? Дело в том, что для шмотки на земле он работает! Значит, он не работает только для шмотки из инвентаря.
Dsion, тут получается очень интересная вещь. Пока скрипт висит только на одной шмотке без референс-id, то всё работает нормально. Но если повесить на 2 разные шмотки из тех, что есть у персонажа, то обе они запускают один и тот же скрипт с ОБЩИМИ локальными переменными. Т.е. скрипты на таких шмотках не являются разными объектами, а только одним. Я усложнил скрипт и встроил туда защиту от случаев срабатывания, когда шмотка переодевается самим скриптом. В принципе, событие onEquip не вызывается в том случае, если надевание данного объекта произошло именно скриптом (или консолью). Но оно может произойти во время действия скрипта по другим причинам, например, скрипт трогает другую шмотку, которая уже вызывает переодевание нашей. Получилось так:
Код
Scriptname _DelayOnEquip extends ObjectReference
Armor Property EmptyItem = none Auto ; Замещающая шмотка int Property ItemSlot = 53 Auto ; Слот занимаемый задерживаемой шмоткой float Property Delay = 3.0 Auto ; Задержка появления, с десятичной частью
Пока шмотка с таким скриптом у персонажа одна, всё работает отлично. Но если их две, то сработает только одна, так как у них окажется одна общая переменная SenderisScript. После того, как скрипт запустится один раз, код в событии не работает второй раз пока не закончится его выполнение. Т.е. пропадать на 3 секунды будет только одна шмотка из двух. В принципе, сегодня утром я придумал, как это обойти. У меня может быть только 4 разных слота, на которых может стоять проблемная физика. Тогда в скрипте должно быть 4 разных SenderisScript для каждого номера слота и 4 фрагмента кода, работающих для четырёх условий. Получается рекурсивное использование одного скрипта. Задача зацепила меня. Не важностью для моего мода, а просто как интересная задача Но пока отложу её. Я сейчас заканчиваю большой мод и у меня там уже есть скрипт, который более-менее спасает от такой проблемы с физикой. Так что, сначала выложу, а потом вернусь к этому орешку
Изменение репутации для пользователя miyo
miyoOffline
Сообщение №2728
написано: 6 февраля 2019, 17:53
| Отредактировано: miyo - 6 февраля 2019, 17:59
Здравствуйте, сейчас делаю мод на торговца животными-спутниками и столкнулся с такой проблемой. Квестовый скрипт выглядит так:
Код
Scriptname FalmerNuadarSystemScript extends Quest
GlobalVariable Property FrostSpiderCostF Auto MiscObject Property Gold Auto Quest Property pDialogueFollower Auto
Function BuyAnimal(Actor AnimalTrainer)
Game.GetPlayer().RemoveItem(Gold, FrostSpiderCostF.value as int) AnimalTrainer.GetLinkedRef().SetActorOwner(Game.GetPlayer().GetActorBase()) ;AnimalTrainer.SetActorValue("Variable04", 1) (pDialogueFollower as DialogueFollowerScript).SetAnimal(AnimalTrainer.GetLinkedRef())
EndFunction
Когда Property были только прописаны в Source без добавления в Properties, после покупки питомца c диалогом было всё в порядке, только не снимались деньги у главного героя, а как только добавил в Properties деньги стали сниматься при покупке, но перестал активироваться диалог у купленного питомца
Изменение репутации для пользователя Dsion
DsionOffline
Сообщение №2729
написано: 6 февраля 2019, 18:21
| Отредактировано: Dsion - 6 февраля 2019, 18:32
до и после покупки питомца... Если REF Animal меняется с None на ID зверька, то скрипт нормально отрабатывает и проблема не в этом скрипте и не в проперти на нем...
Правда, там немного неправильно извлекается значение глобальной переменной и я вообще не понимаю, зачем там глобальная переменная, но черт с ним, если работает. Если у тебя несколько торговцев и они продают разных питомцев, то скрипт правильнее будет сделать один на всех... Ну, то есть, никакого упоминания конкретных торговцев и конкретных питомцев в скрипте. Можешь вешать скрипт на самих торговцев, а питомец и его цена будут задаваться в проперти.
Добавлено (06 Февраля 2019, 21:23) --------------------------------------------- С не заполненным проперти pDialogueFollower скрипт точно не мог нормально работать и делать питомца твоим спутником...
Добавлено (06 Февраля 2019, 21:29) --------------------------------------------- Если всё проходит как надо и паучара попадает в алиас квеста DialogueFollower, то вряд ли ты сможешь сказать ему "стой тут" или "идем за мной", если не менял квест DialogueFollower. Там есть ответы только для человеческих голосов и для собачьего голоса. Для паучьего - нету
Как по мне, будет намного лучше вообще забить на квест DialogueFollower и сделать свой с нуля. Там не сложно. Тогда не придется менять ванильный DialogueFollower, не придется ломать совместимость с другими модами на спутников итп.
Изменение репутации для пользователя miyo
miyoOffline
Сообщение №2730
написано: 6 февраля 2019, 20:31
| Отредактировано: Multigone - 21 апреля 2020, 20:32