Общая идея работы рудных жил такая: когда игрок ручками нажимает на модель жилы (Activator), в свою очередь, она GetLinkedRef().Activate(GetPlayer()) связанную линком невидимую фурнитуру. На фурнитуре MineOreFurnitureScript. Там есть событие OnActivate (строка 80), срабатывающее при этом и проверка isFurnitureInUse() (85). Если проверка говорит, что нет, не используется, регистрируются анимации, в т.ч. на основании которой будет происходить добавление предметов в инвентарь (61). Это нормальная работа.
Но, если при первой активации фурнитуры (80) проверка покажет, что она уже используется, что, в общем-то, неудивительно, т.к. Activate() и заставляет игрока это делать (использовать фурнитуру), то в стадии busy проверка isRegisteredForEvents (115) будет отрицательна, и все закончится ничем - игрок бесконечно проигрывает анимации добычи, OnAnimationEvent (54) не срабатывает, т.к. не зарегистрировано, предметы не добавляются (61), самостоятельного выхода (148) из этого состояния нет (MineOreScript не дает на это команду (116)).
Весь вопрос в том, будет ли фурнитура считаться занятой в момент активации - в большинстве случаев нет, но иногда, как показывает практика, это случается (у меня тоже).
Может, дело в чем-то другом. Но скрипт кривой в любом случае.
gangrena1972, DarkVetal, не могу гарантировать, но уверен, что с большой вероятностью виноват MineOreFurnitureScript, в частности, проверка isFurnitureInUse() в неправильном месте в неправильное время. И этот баг периодически возникает в ванильном скайриме, инфа сотка.
Скрипт сохраняется без ошибок, свойства выставил, но в игре звук не работает все же..
Если имя переменной совпадает с названием любого типа переменных, компилятор выдаст ошибку "cannot name a variable or property the same as a known type or script".
Для скрипта ActiveMagicEffect это должно быть что-то вроде:
- сделать бэкапы MineOreFurnitureScript.psc и MineOreFurnitureScript.pex - заменить строку 85 MineOreFurnitureScript.psc на это:
Код
if akActionRef == Game.GetPlayer()
- скомпилировать - положить свежий MineOreFurnitureScript.pex в .bsa своего мода - вернуть бэкапы на место
Нужно учесть, что новая версия будет применяться для жил, копии которых еще не были созданы в мире (т.е. до первой встречи с ними). Я только не уверен, это правило действует на весь скрипт в целом (переменные + текст), или только для объявленных переменных.
Wertys, он и не будет работать, т.к. маг. эффект (и его скрипт) будет запускаться только на актерах. Нужно это делать все так же через алиас с onHit().
Код
Spell Property MySpell Auto
EVENT OnHit(... IF akSource == MySpell If !GetRef().IsLocked() GetRef().Lock(GetPlayer().GetActorValue("Alteration")) Notification("Заклинание создало замок!") else Notification("Замок уже есть!") endif ENDIF ENDEVENT
Изменение репутации для пользователя Multigone
MultigoneOffline
Сообщение №879
| Тема: Вопросы по скриптам Papyrus
написано: 6 апреля 2018, 14:02
| Отредактировано: Multigone - 6 апреля 2018, 14:15
Wertys, тебе нужно создать новый алиас с условиями...
Код
(S) (GetIsObjectType) (Container) (== 1) AND (S) (GetLocked) (== 0)
...потому что в старый попадают только запертые предметы (я так думаю).
Скрипт:
Код
Spell Property MySpell Auto
EVENT OnHit(... IF akSource == MySpell GetRef().Lock(iInt(GetPlayer().GetActorValue("Alteration") AS Int, 1, 100)) Notification("Заклинание создало замок!") ENDIF ENDEVENT
Int FUNCTION iInt(Int A, Int B = 1, Int C = 0) ; Ограничение А внутри интервала В - С. IF B > C IF A >= B RETURN B ELSEIF A < C RETURN C ENDIF ELSEIF A <= B RETURN B ELSEIF A > C RETURN C ENDIF RETURN A ENDFUNCTION
1) тип заклинаний Power (можно использовать раз в день) и Lesser Power (неограниченно) не использует ману при колдовании. 2) тип эффекта для призыва существа нужно поставить Summon Creature, дальше в строке Effect Item 1 выбрать базового актера, который будет призываться. Там все просто, посмотри ванильные заклинания призыва. Пользуйся (ПКМ на форме) -> Use Info, чтобы посмотреть связанные формы с этой.
miyo, нужно написать в том Topic Info, которое отвечает за покупку, в поле End следующее:
Код
(GetOwningQuest() as ИмяТвоегоКвестовогоСкрипта).BuyAnimal(akSpeaker)
... скомпилировать, нажав ОК.
Если цена за покупку никогда не меняется, глобальная не нужна; соответственно редактируется текст топика и скрипт квеста.
Actor AnimalTrainer
Это просто переменная (аргумент) функции BuyAnimal, ее тип Actor и имя AnimalTrainer. В топике происходит вызов этой функции:
Код
(GetOwningQuest() as AnimalTrainerSystemScript).BuyAnimal(akSpeaker) (Целевой_скрипт).Выполнить_функцию(Указываем_все_аргументы)
В данном случае AnimalTrainer'ом указывается akSpeaker. В скриптах типа TopicInfo akSpeaker'ом всегда является говорящий актер. akSpeakerRef - то же самое, но как референс.
В условиях эффекта (НЕ в окне Spell - Effect Item конструктора заклинаний):
Если у заклинателя (перк или навык или случай). (S) (HasPerk) (SomePerk) (==) (1.0) OR (S) (GetActorValue) (SkillName) (>=) (75.0) OR (S) (GetRandomPercent) (>=) (33.0)
Если у заклинателя (перк и (навык или случай)). (S) (HasPerk) (SomePerk) (==) (1.0) AND (S) (GetActorValue) (SkillName) (>=) (75.0) OR (S) (GetRandomPercent) (>=) (33.0)
Если у заклинателя (перк или (навык и случай)). (S) (HasPerk) (SomePerk) (==) (1.0) OR (S) (GetActorValue) (SkillName) (>=) (75.0) AND (S) (HasPerk) (SomePerk) (==) (1.0) OR (S) (GetRandomPercent) (>=) (33.0)
Эквивалентно ((перк или навык) и (перк или случай)).
asdklghl, не совсем понял. Заклинание можно бросить независимо от выполнения или невыполнения условий, указанных в его эффектах или в списке конструктора заклинаний. При этом будет поглощена мана и полетит снаряд, если он есть. При невыполнении условий эффект не накладывается на цель. В случае архетипа SummonCreature игрок является и источником, и целью. Таким образом, если условия не выполняются, существо не должно быть призвано.
Узнать референс призванного существа напрямую невозможно, только с помощью Find(), но это не лучший вариант.
Большинство условий продублированы в СК и в папирусе, но делать сложные проверки лучше все-таки вторым.
Код
summoned1 .kill(); вот эта строчка должна убивать призванное существо, но НЕ РАБОТАЕТ
summoned1 объявлена как внутренняя переменная, ее начальное значение none, далее оно нигде не изменяется, поэтому none.kill() убьет никого.
Actor FUNCTION MyFun(Actor xCaster, ActorBase xCreatureBase, MiscObject xMarkerItem = none, Float fRadius = 500.0, Int iAttempts = 10) Actor xSomething WHILE iAttempts > 0 xSomething = Game.FindRandomActorFromRef(xCaster, fRadius) IF xSomething && xSomething != xCaster && xSomething.GetActorBase() == xCreatureBase && !xSomething.GetItemCount(xMarkerItem) xSomething.AddItem(xMarkerItem) RETURN xSomething ENDIF iAttempts -= 1 ENDWHILE ENDFUNCTION
Пример вызова:
Код
ActorBase Property SummonAtronachFire Auto MiscObject Property xDetector Auto ; Создать пустой неиграбельный предмет, служит для отметки существа, что оно найдено.
Actor xSummoned
EVENT OnEffectStart(Actor xT, Actor xC) Utility.Wait(1.0) ; Ждем, пока будет кого искать. xSummoned = MyFun(xT, SummonAtronachFire, xDetector) Utility.Wait(5.0) xSummoned.Kill() ENDEVENT
Legolasbl4, верни все Entry перка в исходное состояние. В том, в котором множитель 0.5, укажи Value = Value * X, где Х - твое значение. В настройках мода выставь 50%. Вместо 50% получишь свое значение (100 * X)%.
Aksyonov, попробуй поменять призываемого актера на НПС, например, Лидию, или любого, кто гарантированно имеет возможность диалога. Убедись, что в расе твоего призываемого существа есть флаг Allow PC Dialogue.
Нарада, у торговцев для продажи есть спец. сундук, у каждого свой, указывается в одной из его faction во вкладке Vendor, одноразовое добавление в долгосрочной перспективе ни к чему не приведет, поскольку сундук каждые несколько дней перезагружает свой лут.
Я бы делал так: где-нибудь создал постоянный апдейт с небольшим периодом, добавлял в этот сундук 1 неигровой проверочный предмет и остальные основные предметы. Добавление должно происходить только в случае, если сундук не содержит проверочного предмета (т.е. произошло обновление содержимого). Поскольку неигровой предмет не может быть куплен. А может, я бы сделал через постоянно перезапускаемый квест с алиасом этого сундука, в котором указаны добавляемые предметы. Не знаю, что лучше.
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
Кто поможет увеличить мешок с золотом в 1.7 раза. Модель - Plants\CoinBagLarge.nif В нифскопе общее увеличение всей модели ничего не дает, увеличение одной из костей дает визуальный результат, но коллизии остаются в прежнем размере. Нужно, чтобы прям весь мешок целиком.
Myprism, размер души определяется уровнем актера - см. "SoulActorLevel" в Settings, исключение - люди (великая душа). Нормальный захват можно сделать только написав новый скрипт взамен использования архетипа TrapSoul, который вешается на те же маг. эффекты. Для заполненных камней нужно создать новые формы, имеющие душу изначально - чтобы при выкидывании заполненного камня в мир он не опустошался. Еще у ванильных камней скриптом нельзя абсолютно никак определить уровень содержащейся в нем души, если она не соотвествует размеру камня - напр., великий камень (маленькая душа) считается пустым - но если создать в СК новую форму для каждой возможной комбинации, то уровень души в камне определять будет можно. Еще, оружие с чарами ванильного захвата работает только на игроке, тогда как новый скрипт позволяет захватывать души любому актеру.
В целом, хочу сказать, что такой мод я для себя делал, там много мелких нюансов (например, нужно предотвратить наложение на одну цель нескольких эффектов захвата от разных источников - от заклинания, посохов, чар оружия) и все довольно сложно.
Myprism, если принять уровни душ от мелкой до великой как 1-5, то объемы душ будут соответственно 1/2/4/8/12, исходя из даваемой ими энергии для чар, т.е., к примеру, для заполнения великого камня требуются 12 крохотных душ (если делать возможность постепенного заполнения). Вообще, себе я сделал настройку (максимально допустимая разница в уровнях души и камня при захвате). Еще, звезда Азуры должна всегда заполняться первой, а в ванили она выбирается случайно из общего кол-ва подходящих камней. Это тоже исправляется. Все же в архетипах эффектов есть "Soul Trap", я только не помню, работает ли оно без скрипта (по идее, должно работать без визуального сопровождения).
Мод конкретно на захват готов на 100%, только было лень выкладывать его сюда взамен старой версии (см. в файлах), но там еще куча других идей, реализованных полностью или частично, например, заклинание расщепления камня на осколки / сбора камня из них / объединение душ в разных камнях в один большего размера / разделение заполненного камня на несколько меньшего размера.
Я могу предоставить ядро захвата, только все равно его нужно будет корректировать в соотв. с твоими идеями, и заниматься этим нужно будет мне, т.к. там никто ничего не поймет. И сам скрипт очень плотно связан с .есп форм-листами и всем остальным. И он использует СКСЕ.
Изменение репутации для пользователя Multigone
MultigoneOffline
Сообщение №897
| Тема: Вопросы по скриптам Papyrus
написано: 4 января 2020, 14:51
| Отредактировано: Multigone - 21 апреля 2020, 20:18
Scriptname _TESTTEST56 extends ActiveMagicEffect ; на любое заклинание.
SoulGem Property DA01SoulGemAzurasStar Auto ; Автозаполнить SoulGem Property MyAzuraFilled Auto ; В СК создать изначально заполненную звезду азуры, указать ее здесь.
EVENT OnEffectStart(Actor xT, Actor xC) Utility.Wait(Utility.RandomFloat(0.0, 0.2)) Int iC1 = xT.GetItemCount(DA01SoulGemAzurasStar) Int iC2 = xT.GetItemCount(MyAzuraFilled) xT.RemoveItem(DA01SoulGemAzurasStar, iC1, true) xT.RemoveItem(MyAzuraFilled, iC2, true) xT.AddItem(MyAzuraFilled, iC1 + iC2, true) ENDEVENT
Изменение репутации для пользователя Multigone
MultigoneOffline
Сообщение №898
| Тема: Вопросы по скриптам Papyrus
написано: 5 января 2020, 10:17
| Отредактировано: Multigone - 21 апреля 2020, 20:16
Myprism, не совсем понял, причем тут модные персонажи, автолевелинг и модификаторы уровня. 1) Уровень души определяется только уровнем актера-цели. 2) Profit
Способ определения уровня души не должен (по моему мнению) содержать конкретных цифр, а брать данные из настроек, давая совместимость с др. модами, например, глобальными, где система прокачки отличается от ванильной. Параболическая функция определена для конкретных 6 точек (был использован онлайн калькулятор для вычисления функции?), но можно ли ее использовать, если точки неизвестны? В противном случае проще принять график зависимости как ломаную, и вычислять промежуточные значения на каждом отрезке линейно.
По поводу остатка - ну, дело хозяйское. В таком случае я бы ограничил макс. остаток, скажем, не больше размера обычной души. Недостаток: 2 одинаковых актера могут дать души разных размеров, поскольку к душе первого из них будет добавлен остаток. Получится "захвачена обычная душа" и "захвачена крохотная душа" и игрок такой О_о.
По поводу звезды: из соображений баланса себе я принял, что черная не может захватывать белые души, т.к. в противном случае она в разы предпочтительнее обычной. То же относится и к камням (плюс, маленькая душа в черном камне - такое себе).