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

Вопросы по скриптам Papyrus
sansuli  Offline  Сообщение №1 написано: 31 Август 2012, 17:29 | Отредактировано: Multigone - 23 Апрель 2020, 17:24


The Red Sun


193
Уроки по скриптованию на языке Papyrus
Прежде чем задать вопрос просмотрите вышеуказанные уроки.
ok


Тема регламентирована.


• Прежде, чем задать вопрос, пожалуйста, убедитесь, что такой вопрос не задавался раньше. Старайтесь описать суть вопроса как можно подробней.
• Прежде, чем опубликовать ответ на вопрос, пожалуйста, убедитесь, что обладаете необходимыми для этого знаниями. Старайтесь cформулировать суть ответа как можно лаконичней.
• При желании ответить в приватном порядке, пожалуйста, воспользуйтесь ЛС.
• При желании поблагодарить ответившего, пожалуйста, воспользуйтесь кнопкой "
+" полезного сообщения.

Сообщения, не относящиеся к вопросам по скриптам Papyrus, ответам на них или уточнениям, являются оффтопом и могут быть удалены.

Красное солнце
Есть вопросы по скриптам Papyrus? Пиши не в ЛС, а в эту тему.
nodtrial  Offline  Сообщение №3031 написано: 3 Апрель 2021, 13:42 | Отредактировано: nodtrial - 3 Апрель 2021, 16:38



1
Ребята подскажите, почему может игнорировать команду GlobalVar1.SetValue(10.00) ?

Переменная объявлена в проперти, указана в пропертис в СК, флоат, не константа.
Меняется по событию OnRead, скрипт привязан к книге.

при
debug.notification("До: " + GlobalVar1.GetValue() as int)
GlobalVar1.SetValue(10.00)
debug.notification("После: " + GlobalVar1.GetValue() as int)

Оба раза выводит нули или другое базовое значение.
В консоли show GlobalVar1 тоже показывает базовое значение и до и после события.

ЗЫ: Решено!!!
Я нашёл в чем было дело - всё заработало после того как удалил мод полностью, почистил его скрипты, и запустил заново.

Dsion  Offline  Сообщение №3032 написано: 3 Апрель 2021, 16:30



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

JohnSmith  Offline  Сообщение №3033 написано: 12 Сентябрь 2021, 16:52



29
Всем привет, помогите пожалуйста с простым скриптом. Суть в следующем - скрипт вешается на предмет и при одевании проверяется какое-либо условие (например пол нпц) и выполняется что-либо. Проблема в том, что я никак не могу найти REF предмета к которому прикреплен скрипт.

Scriptname AaaScriptName extends ObjectReference

event OnEquipped(Actor akActor)

  ;ObjectReference equipment = self

  Form equipment = GetBaseObject()

  if (akActor.GetActorBase().GetSex() == 1)

    akActor.RemoveItem(equipment, 1)

    Debug.MessageBox(equipment)

  endIf

endevent


Dsion  Offline  Сообщение №3034 написано: 13 Сентябрь 2021, 14:08



Та да, есть такое. У обычных предметов, лежащих в контейнерах, референсов и нету.
Вроде, есть у тех, что также находятся в алиасе. Не уверен.
Можно сделать проперти типа Armor и сунуть туда базовый объект. Тогда можно будет его снять.

Armor Property Magic2Ring Auto;

Event OnEquipped(Actor akActor)
    akActor.UnequipItem(Magic2Ring);
EndEvent

Но если надето несколько одинаковых предметов, то и не фак, что снимется нужный.

JohnSmith  Offline  Сообщение №3035 написано: 13 Сентябрь 2021, 21:28



29
Цитата Dsion

Та да, есть такое. У обычных предметов, лежащих в контейнерах, референсов и нету.
Вроде, есть у тех, что также находятся в алиасе. Не уверен.
Можно сделать проперти типа Armor и сунуть туда базовый объект. Тогда можно будет его снять.

Armor Property Magic2Ring Auto;

Event OnEquipped(Actor akActor)
    akActor.UnequipItem(Magic2Ring);
EndEvent

Но если надето несколько одинаковых предметов, то и не фак, что снимется нужный.

Если я вас правильно понял, то мне придется под каждый предмет делать скрипт и вписывать туда Property с его рефом. У меня сотни предметов, добавляющиеся через лвл-листы всем нпц, для большинства из них не сделаны муж. версии, поэтому я решил повесить на вещи скрипт. Наверное это надо делать как-то через пустой квест.


Multigone  Offline  Сообщение №3036 написано: 15 Сентябрь 2021, 15:01



724
JohnSmith, хватит одного скрипта-шаблона, который будет повешен на все формы, и у которого проперти будет заполнено этой формой. В смысле, если для всех предметов требуется выполнить одно и то же действие (например, снять или удалить).

Lissenok  Offline  Сообщение №3037 написано: 6 Декабрь 2021, 18:51



11
Здравствуйте. Подскажите,пожалуйста, есть ли такой скрипт, чтобы в контейнер один раз в сутки добавлялись определенные предметы, но не просто обновлялись, а плюсовались. Допустим, если добавляется две единицы молока, то через неделю их было в контейнере уже 14? Спасибо.

Multigone  Offline  Сообщение №3038 написано: 14 Декабрь 2021, 17:40



724
Lissenok,

Например, такое (на контейнер, он не должен авто-обновляться вместе с локацией):

MiscObject Property MyItem Auto ; Предмет (для оружия, брони, зелий, боеприпасов вместо MiscObject использовать соотв. Weapon, Armor, Potion, Ammo)
Int Property MyCount Auto ; Кол-во

EVENT OnInit()
   RegisterForSingleUpdateGameTime(12.0)
ENDEVENT

EVENT OnUpdateGameTime()
   AddItem(MyItem, MyCount)
   RegisterForSingleUpdateGameTime(24.0)
ENDEVENT

; В данном случае скрипт впервые добавляет предметы через 12 ч. после первой инициализации референса контейнера, и далее каждые 24 ч. Чтобы предмет добавлялся в опред. промежуток времени суток / строго в опред. время суток, скрипт должен быть немного сложнее, но я не могу его сейчас написать и проверить, т.к. не установлен СК и нет исходников.

Lissenok  Offline  Сообщение №3039 написано: 25 Декабрь 2021, 13:19



11
Цитата Multigone

Lissenok,

Например, такое (на контейнер, он не должен авто-обновляться вместе с локацией):

MiscObject Property MyItem Auto ; Предмет (для оружия, брони, зелий, боеприпасов вместо MiscObject использовать соотв. Weapon, Armor, Potion, Ammo)
Int Property MyCount Auto ; Кол-во

EVENT OnInit()
   RegisterForSingleUpdateGameTime(12.0)
ENDEVENT

EVENT OnUpdateGameTime()
   AddItem(MyItem, MyCount)
   RegisterForSingleUpdateGameTime(24.0)
ENDEVENT

; В данном случае скрипт впервые добавляет предметы через 12 ч. после первой инициализации референса контейнера, и далее каждые 24 ч. Чтобы предмет добавлялся в опред. промежуток времени суток / строго в опред. время суток, скрипт должен быть немного сложнее, но я не могу его сейчас написать и проверить, т.к. не установлен СК и нет исходников.


Спасибо! Мне и не надо в определенное время, главное, что бы когда я возвращалась домой, в контейнере лежал не один предмет, а по количеству прошедших дней.



emelya8307  Offline  Сообщение №3040 написано: 16 Март 2022, 20:44



22
Здравствуйте. Подскажите, пожалуйста, как мне в моем квесте отследить событие диалога, ну например, когда Лидия говорит "Целительные чары? Ты что, из храма?". Мне нужно, чтобы после этих слов сработала функция в моем квесте. Но вроде бы ванильные скрипты диалогов править нежелательно. Как мне поймать это событие? Но необязательно этот диалог. Любой другой ванильный диалог.

Multigone  Offline  Сообщение №3041 написано: 17 Март 2022, 18:29



724
emelya8307, в некоторых случаях можно использовать SM Event Node.

emelya8307  Offline  Сообщение №3042 написано: 17 Март 2022, 20:12



22
Multigone ,  да, спасибо. Щас посмотрел SM Event Node, там есть ActorDialogueEvent, как я понял, надо создать квест который будет запускаться при событии диалога. Короче пока для меня тут много непонятного, как все работает

emelya8307  Offline  Сообщение №3043 написано: 29 Март 2022, 19:10



22
Подскажите, пожалуйста, почему у меня не срабатывает фрагмент скрипта в квесте?

Alias_Victim.GetActorRef().GetActorBase().SetEssential(False)

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

ActorBase Ref = Alias_Victim.GetActorRef().GetActorBase()

While Ref.IsEssential()

Ref.SetEssential(False)

Utility.Wait(1.5)

EndWhile

Допускю, что этот скрипт дичь полнейшая, потому что теоретического образования по программированию у меня ноль. Нужно, чтобы бессмертный актер после нападения на него игрока становился смертным. Флаг Essential стоит на актере,  не на алиасе.

Буду надеяться, что сюда кто-нибудь заглянетblush2




Multigone  Offline  Сообщение №3044 написано: 30 Март 2022, 00:49 | Отредактировано: Multigone - 30 Март 2022, 00:55



724
emelya8307, попробуй так:

Utility.Wait(0.1)
((((Alias_Victim.GetReference()) as Actor).GetBaseObject()) as ActorBase).SetEssential(false)

Также попробуй увеличить продолжительность паузы.
Твои обе версии идентичны, за исключением паузы.

emelya8307  Offline  Сообщение №3045 написано: 31 Март 2022, 20:37



22
Multigone,  Попробовал твой способ, работает примерно так же как и мой, иногда не срабатывает, хз почему.

Multigone  Offline  Сообщение №3046 написано: 1 Апрель 2022, 03:24



724
emelya8307, можно проверять поэтапно:

Actor ActorIs = (Alias_Victim.GetReference()) as Actor
ActorBase ActorBaseIs = ActorIs.GetLeveledActorBase()
Debug.MessageBox("AliasIs " + Alias_Victim)
Utility.Wait(0.01)
Debug.MessageBox("ActorIs " + ActorIs)
Utility.Wait(0.01)
Debug.MessageBox("ActorBaseIs " + ActorBaseIs)
Utility.Wait(0.01)
Debug.MessageBox("ActorBaseIsEssentialBefore " + ActorBaseIs.IsEssential())
Utility.Wait(0.01)
ActorBaseIs.SetEssential(false)
Utility.Wait(0.01)
Debug.MessageBox("ActorBaseIsEssentialAfter " + ActorBaseIs.IsEssential())
Utility.Wait(0.01)
Debug.MessageBox("ActorBasePersist " + ((Alias_Victim.GetReference()) as Actor).GetLeveledActorBase() == ActorBaseIs)

Lexo  Offline  Сообщение №3047 написано: 18 Апрель 2022, 17:42


Всепознающий мододел


223
Кто-нибудь знает, как отследить, что игрок открыл новую локацию?

Multigone  Offline  Сообщение №3048 написано: 19 Апрель 2022, 00:42



724
Lexo,

; Нужен тест.
; Требуется SKSE.
; На алиас игрока.
; Добавляет локацию в форм-лист, если ее там нет.
; С момента запуска скрипта каждая локация единожды будет определяться, как новая, когда игрок будет заходить туда.
; Возможны задержки выполнения при большом количестве посещенных локаций (в таком случае лучше использовать несколько форм-листов).

FormList Property xFLST AUTO

EVENT OnInit()
    RegisterForMenu("Loading Menu")
ENDEVENT

EVENT OnMenuClose(string menuName)
   Location xLoc = GetReference().GetCurrentLocation()
   IF xFLST.Find(xLoc) < 0
      xFLST.AddForm(xLoc)
      Debug.Notification("Открыта новая локация! " + xLoc)
   ENDIF
ENDEVENT

Lexo  Offline  Сообщение №3049 написано: 19 Апрель 2022, 09:14


Всепознающий мододел


223
Multigone, хорошая мысль. Как же я сам не додумался? Спасибо

Lexo  Offline  Сообщение №3050 написано: 20 Апрель 2022, 16:39


Всепознающий мододел


223
Использовав вашу наработку, слегка улучшил скрипт. Вроде как даже работает (во всяком случае, пока что сбоев не было):


KeyWord property KeyWord_Lockation auto
Event OnCellLoad()
   Location NewLock = GetReference().GetCurrentLocation()
   float houseCost = NewLock.GetKeywordData(KeyWord_Lockation)
 If houseCost == 0
 
  Debug.Notification("Открыта новая локация!")
  NewLock.SetKeywordData(KeyWord_Lockation, 100)
 
 elseif houseCost == 100.0
 
  Debug.Notification("Старая локация! " + houseCost)
 
 Endif
EndEvent

Multigone  Offline  Сообщение №3051 написано: 20 Апрель 2022, 19:39



724
Lexo, а, эт я не знаю, не пользовался. Насколько я понял из описания, GetKeywordData() и SetKeywordData() позволяют получить и установить значение некой float-переменной, соотнесенной с кейвордом, имеющимся у этой локации (зачем? почему? непонятно). При этом, добавлять новые кейворды к формам, насколько я знаю, в процессе игры нельзя.

Действительно, можно запоминать какую-либо информацию об этой локации, шифруя ее значением float-переменной кейворда, при условиях:
1) У каждой локации, данные которой требуется запомнить, есть один или несколько известных кейвордов (предустановленных в СК), и
2) Дефолтное значение переменной кейворда (если его можно устанавливать из СК) не совпадает с числами, которыми предполагается шифровать информацию, и
3) Другие моды не управляют значениями этих переменных.

Lexo  Offline  Сообщение №3052 написано: 20 Апрель 2022, 19:58


Всепознающий мододел


223
Multigone, я сам не понял, в чём прикол, но вот этот скрипт пока без нареканий работает. Разумеется, позже будет больше тестов - может быть что-то и выявится. Но этот почему-то работает. Так что если вдруг, можно иметь в виду...

nepewka  Offline  Сообщение №3053 написано: 21 Апрель 2022, 13:31



252
Всем привет, вопрос по скрипту в Fallout 4

Есть перк, хочу выдать его всем нпц и монстрам в игре, существует ли возможность выдать его посредством скрипта ? (напомню в Fallout 4 перки можно динамически вешать на нпц, в отличии от Skyrim )
Нужен какой-то оптимальный метод, по которому можно обратиться ко всему игровому миру и ввести скриптовую команду addperk

Multigone  Offline  Сообщение №3054 написано: 21 Апрель 2022, 18:49



724
nepewka, не знаю, что там в F4, в Скайриме это делается так (пример для Ability):

1) Создается заклинание с FF / Self / Area, на что-либо вешается скрипт с апдейтом Х сек., кастующим это заклинание игроком. На заклинании скрипт, добавляющий попавшим в зону действия целям это Ability.

2) Либо (требуется SKSE) берется локация, в которой находится игрок в текущий момент, перебираются все подряд референсы этой локации (не уверен, что временные референсы тоже учитываются, хотя, скорее всего, да). Тем из них, что являются актерами, добавляется Ability.

Ability, добавленное скриптом, имеет баг - когда актер выгружается из мира, а потом снова загружается, Ability формально остается, но актер теряет его Effects. Хотя это можно обойти.

Особенности работы скриптов в F4 можно обсудить в этой теме.

nepewka  Offline  Сообщение №3055 написано: 22 Апрель 2022, 16:50



252
Цитата Multigone

не знаю, что там в F4


Привет! Да тоже самое что и в Скайриме, тот же ведь движок скриптовый. С той лишь разницей что доработали некоторые вещи, типа выдача динамически перков любому актёру через скрипт, что было недоступно в Скайриме.


Цитата Multigone

Особенности работы скриптов в F4 можно обсудить в этой теме.


Там раздел мёртвый( а так как скрипты один в один в двух играх, думаю лучше писать сюда)


Цитата Multigone

1) Создается заклинание с FF / Self / Area, на что-либо вешается скрипт с апдейтом Х сек., кастующим это заклинание игроком. На заклинании скрипт, добавляющий попавшим в зону действия целям это Ability.


Этот вариант мне кажется проще и интереснее.

В F4 нету возможности что-либо кастовать самому, но можно это сделать через энчант на какой-нибудь вещи и потом через скрипт в MGEF повесить заклинание на игрока с селфкастом.

Нужно сделать так, чтобы это происходило автономно и с периодичностью такой, чтобы если начался бой(даже не наш если), актёры участвующие в нём получали эту Ability/Perk

Введу в курс дела:
идея заключается в том, чтобы сделать кастомный резист к тому или иному типу урона, чтобы он просчитывался через перк и мог снижаться от входящего урона.


Multigone  Offline  Сообщение №3056 написано: 22 Апрель 2022, 17:29



724
nepewka, чтобы это работало, нужно взаимодействие между скриптом и заклинанием. Каковы особенности редактора в F4, не в курсе. Поэтому, если нужно, могу расписать версию для СК Скайрима.

Lexo  Offline  Сообщение №3057 написано: 22 Апрель 2022, 18:02 | Отредактировано: Lexo - 22 Апрель 2022, 18:02


Всепознающий мододел


223
nepewka, создать заклинание-плащ с магнитудой 1000, в него вставить заклинание-концентрацию с галочками NoHitEffect, NoHitEvent и прочими, помогающими не обнаруживать его. Создать квест, в нём создать алиас, в котором будет выбран игрок. На этот алиас игрока повесить заклинание-плащ. А уже через эффект-концентрацию раздавать всем перки.

emelya8307  Offline  Сообщение №3058 написано: 24 Апрель 2022, 23:25 | Отредактировано: emelya8307 - 25 Апрель 2022, 00:23



22
Кто-нибудь знает, как отследить, что игрок открыл новую локацию?

Lexo, Это легко отслеживается через изменение статистики. На Алиас игрока или квест повешить скрипт:

Event OnInit()

  RegisterForTrackedStatsEvent() ; Для отслеживания изменения сттистики нужно сначала зарегистрироваться.

EndEvent

Event OnTrackedStatsEvent(string asStatFilter, int aiStatValue)

    if (asStatFilter == "Locations Discovered")

     Debug.Notification("Открыта новая локация.")

       ; что-то сделать

    endif

endEvent


У меня все прекрасно работало. Не надо никаких форм-листов, кейвордов, переменных, отслеживание происходит мгновенно при открытии новой локации.

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


nepewka  Offline  Сообщение №3059 написано: 24 Апрель 2022, 23:25 | Отредактировано: Multigone - 25 Апрель 2022, 00:17



252
MultigoneLexo, привет!

Цитата Multigone

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

с удовольствием рассмотрю твоё предложение)
идея отличается от того, что предложил Lexo ?


Попытаюсь ещё больше вести в курс дела того, что хочу сделать.

Дело в том, что в F4 своеобразная система работы резистов по урону, в которой не обошлось без васянства разработчиков.

Два основных вида урона в игре - физический(баллистический. обычные виды оружия) и энергетический (всякие лазерки, плазма пушки)
Формула снижения урона работает таким образом, что чем больше урон превосходит резист, тем больше будет входящий урон, вплоть до 99% и наоборот, если резист(броня) больше урона, вплоть до снижения урона в 91%.
Так должно быть в идеале и так работают игровые формулы с физическим уроном, но не работают таковым образом с энергетическим. Формулы считают только базовый энергетический урон, но при этом не считают уйму бонусов, с помощью которых этот базовый урон можно увеличить. А для физического всё считают нормально.

В следствии чего получается, что физический урон при прочих равных всегда превосходит энергетический. Доходит до абсурда, вплоть до того, что непись может иметь физ резиста больше, чем энерго, но при этом физ оружие по нему будет бить больше, чем энерго. Из-за кривости формул.

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

Как я планирую исправить данную проблему:

1) Убрать зависимость энерго резиста от движковых формул.
2) Создать свою собственную систему снижения урона через перки и кастомные Actor values (для тех кто не в курсе, одно из нововведений в F4 - возможность создавать свои собственные Actor value )
3) Сам перк будет выглядеть вот так:

Entry point: Mod typed incoming weapon damage
в кейвордах укажем, что наш урон энергетический

Ссылка на изображение 1.


4) Перк должен висеть на всех актёрах в игре, в том числе и на игроке.
Как видите на скриншоте мы можем регулировать получаемый актёром урон на число actor value его брони с нужным нам множителем, надо только поставить + или - , чтобы перк срабатывал как снижение урона.

Также мы можем создать уникальный вид урона и регулировать его через кастомные actor value в перке.
Это если будем возиться с новыми типами урона, но в таком случае придётся в предметах брони или статах неписей прописывать значение кастомного actor value

Ссылка на изображение 2.


Пока что не будем ничего создавать в плане новых типов урона, а пофиксим работу сломанного энергетическог урона.
Для этого, как вы уже поняли нам понадобится Ability на игроке, который будет вешать этот перк неписям вокруг него.

Как-то так, надеюсь теперь вам понятнее стала задача smile Спасибо за помощь!


Multigone  Offline  Сообщение №3060 написано: 25 Апрель 2022, 00:49



724
Lexo, плащ очень часто обновляется (период явно меньше 1 с). Это сделано для того, чтобы актер, попавший в радиус действия (который обычно оч. небольшой), сразу же почувствовал на себе его эффекты. Большой радиус плаща вызовет (значительное?) повышение нагрузки на игру из-за частых проверок множества актеров. Впрочем, это только мое мнение.

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

nepewka, попробуй сперва с плащом.

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





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