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

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


The Red Sun


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


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


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

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

Красное солнце
Есть вопросы по скриптам Papyrus? Пиши не в ЛС, а в эту тему.
Multigone  Offline  Сообщение №1771 написано: 26 июня 2015, 16:12



832
nepewka

1) Я же закомментировал akTarget.
2) Для ванильных актеров лучше использовать алиас, для модных - можно вешать на ActorBase или на его ObjectReference. В зависимости от задачи, в общем.

Dsion  Offline  Сообщение №1772 написано: 26 июня 2015, 17:08



Мне не только DeferredKill не нравится, а вообще всё, что может вызвать проблемы при отключении мода... Хехехе.

Multigone  Offline  Сообщение №1773 написано: 27 июня 2015, 09:24



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

nepewka  Offline  Сообщение №1774 написано: 28 июня 2015, 19:32 | Отредактировано: Multigone - 27 апреля 2020, 17:05



255
Multigone, конечно дружище. Сам сколько тестов проводил, ошибки при расчете здоровья свыше 10000 имеют место быть..
Не с проста в Creatiom kit руками актеру больше 10000 не поставишь, стоит ограничение.
То есть, ну как бы в наших модах редко здоровье актера превышает 5 тысяч, но в тех где превышает придется все же пользоваться скриптом с deffered kill'ом
Добавлено (28 Июня 2015, 22:32)
---------------------------------------------
[b]Это  при попытке компилирования того скрипта от AlexTirex, эх жаль я раньше его не проверил :(

Multigone  Offline  Сообщение №1775 написано: 28 июня 2015, 21:02



832
nepewka, наверное, у тебя нет исходников скриптов. Ссылка.

nepewka  Offline  Сообщение №1776 написано: 28 июня 2015, 22:02 | Отредактировано: nepewka - 28 июня 2015, 22:03



255
разобрался, проблема была в том, что стандартный extends у Actor почему то objectreference, сменил на extends actor все заработало

Добавлено (29 Июня 2015, 01:02)
---------------------------------------------
UPD: по поводу скрипта, работает впринципе нормально. Но ещё не откажусь твой вариант увидеть :)

Кстати, как нельзья кстати оказался твой скрипт с IgnoreFriendlyHits, я заметил что заставить непися избежать от себя урона это пол беды, но вот мини атронахи, призываемые моими атронахамии, агрятся на меня просто писец с какой периодичностью, если я их хотя бы капельку задеваю, и это несмотря на совместный бой.  Такие вот дела)

Multigone  Offline  Сообщение №1777 написано: 29 июня 2015, 08:36 | Отредактировано: Multigone - 29 июня 2015, 20:21



832
nepewka,



UPD.
UPD. 2
UPD. 3

nepewka  Offline  Сообщение №1778 написано: 29 июня 2015, 09:08



255
Multigone, ох вот это понаписал)

Добавлено (29 Июня 2015, 12:08)
---------------------------------------------
не в обиду проделанной работе, скажи пожалуйста, чем этот код лучше небольшого скрипта AlexTirex с DefferedKill ??

просто код огромный и сложноватый для меня, хотелось бы понять чем в работе отличается ?

В одном из комментариев прочитал:

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

Это что же получается, если атакующий наносит слишком много урона, часть его урона просто будет пропадать вникуда?


Multigone  Offline  Сообщение №1779 написано: 29 июня 2015, 11:38 | Отредактировано: Multigone - 27 апреля 2020, 17:08



832
nepewka,

1) Можно задавать любой бонус к текущему максимуму здоровья.
2) Учитывается регенерация и лечение - они будут восполнять бонус здоровья, если актер имеет здоровье не меньше половины.
3) Если актер имеет большой максимум здоровья (величина вражеского хита не должна превышать половину максимума здоровья), то DefferedKill() можно убирать из кода (в версии AleksTirex'а DefferedKill() играет ключевую роль).

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

1) Здоровье всегда поддерживается на 50%, пока бонус здоровья больше нуля. Ничего нельзя поделать, это является условием реализации идеи.
2) Игрок не видит своего (или чужого) суммарного здоровья. Для игрока его можно выводить уведомлением по запросу или при достижении опред. порогов.

Цитата nepewka

Это что же получается, если атакующий наносит слишком много урона, часть его просто будет пропадать в никуда?

Именно. Если текущий максимум здоровья актера = 1000, то хиты величиной больше 500 будут ограничиваться числом 500. Это происходит потому, что текущее значение AV Health (как и сила / магия) не может быть отрицательным числом (наблюдал в игре, однако, сейчас ни в чем нельзя быть уверенным).

nepewka, а, еще кое-что.

У AleksTirex'а есть такое:

Код
Event OnUpdate() ; Регистрация через 1.0 с.
     if GetAV("Health") <= 0

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

Проверка: здоровье 0.678 (жив). Переход на следующий уровень здоровья не требуется, RestoreAV("Health", GetBaseAV("Health")) не выполняется.
Удар. Здоровье = 0
Проверка: здоровье 0.777 (жив).
Удар. Здоровье = 0
И т.д.

В общем, идея понятна. Чем больше интервал между обновлениями (проверками), тем с меньшим шансом (GetAV("Health") <= 0.0) вернет true.

nepewka  Offline  Сообщение №1780 написано: 29 июня 2015, 13:06 | Отредактировано: nepewka - 29 июня 2015, 13:06



255
Цитата Multigone

Именно. Если текущий максимум здоровья актера = 1000, то хиты величиной больше 500 будут ограничиваться числом 500. Это происходит потому, что текущее значение AV Health (как и сила / магия) не может быть отрицательным числом (наблюдал в игре, однако, сейчас ни в чем нельзя быть уверенным).


это актуально по отношению к вышеописанному скрипту? Или вообще по игре?
Если по игре я такого не замечал, тестил заклинания с высоким уроном 3000, 4000, 5000 по актеру со здоровьем 5000. Все нормально работало или что ты имел ввиду?

Multigone  Offline  Сообщение №1781 написано: 29 июня 2015, 16:20 | Отредактировано: Multigone - 29 июня 2015, 16:27



832
nepewka, то, что изменяемые параметры актера (магия, сила, и т.д.) не могут быть ниже 0, применимо ко всей игре. Ограничение урона - если по актеру с здоровьем 100 попадет хит величиной 5000, то здоровье актера станет не -4900, а 0.0. Поэтому уловить величину хита в 5000 невозможно, т.к. определения хита скриптом не существует, кроме как измерить разницу здоровья до хита и после него. А раз при хите 5000 изменение здоровья будет 100 - 0 = 100, то хит будет считаться равным 100. Это и есть ограничение урона, когда вместо настоящего урона в 5000 актер получает только 100.
То же самое и с лечением, если при текущем здоровье 300 из 1000 будет выпито зелье, восстанавливающее 9000 здоровья, то здоровье актера станет не 9000  + 300 = 9300, а только 1000, т.е. оставшиеся 8300 уйдут в никуда. Т.е. изменяемый параметр имеет нижний предел 0, ниже которого он не может опуститься, и верхний предел в (GetBaseAV("Параметр") + все модификаторы от заклинаний и прочего).

Цитата nepewka

интервал же вообще можно убрать, ведь так?

Можно, но пауза между последовательными проверками все равно будет иметь место. К тому же, чем чаще происходит обновление, тем больше неэффективных расчетов или проверок.

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

EVENT OnUpdate()
    RegisterForSingleUpdate(0.01)
    (Дофигища действий, которые точно не смогут выполниться за 0.01 с.)
ENDEVENT

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

Чтобы этого избежать, правильно делать так:

EVENT OnUpdate()
    (Дофигища действий)
    RegisterForSingleUpdate(0.01)
ENDEVENT

Просто к сведению.

Dsion  Offline  Сообщение №1782 написано: 29 июня 2015, 17:26



Я бы в вашу беседу вообще не влезал. Но мне просто обидно, когда я советую кому-то применить скрипт для решения его проблемы, а человек мне пишет что-то типа "Нет! Скрипты - это зло и все проблемы только от них. Не хочу скрипт!". И откуда же такое мнение взялось у общества?

nepewka, может, объяснишь, для чего тебе это всё? А мы почешем репы и придумаем нормальный вариант, который не закончится бегающими без голов неписями...

Чем не устраивает просто неуязвимость к урону?
Чем не устраивает сделать NPC Essential + регенерацию 100% хп в секунду + отключить bleedout (ползанье на коленях)
Чем не устраивает 1000 хп, 1000 регенерация и 99.99% ресист к урону?

Multigone  Offline  Сообщение №1783 написано: 29 июня 2015, 19:17 | Отредактировано: Multigone - 27 апреля 2020, 17:10



832
Dsion, хочешь сказать, что DeferredKill() позволяет НПС выжить после киллмуви и бегать с отрубленной головой? Неожиданная инфа... Ну, поскольку использование того скрипта имеет смысл при здоровье > 10000, и вряд ли какой агрессор может нанести хит 5000, DeferredKill() можно убрать... Или отключить киллмуви...

Или проверять, было ли киллмуви, если да, EndDeferredKill(), актер мертв.

Цитата Dsion

может, объяснишь, для чего тебе это всё?

Он хочет не просто неуязвимость, а настолько много здоровья, сколько нельзя установить через СК или игру. Может, сделать супербосса какого-нибудь. Я не проверял ограничение на 9999 HP, но допускаю, что оно имеет место быть.

(Далее текст про то, какие скрипты гибкие, универсальные и т.д.)

nepewka  Offline  Сообщение №1784 написано: 29 июня 2015, 20:31 | Отредактировано: nepewka - 29 июня 2015, 20:30



255
Multigone, Скажи пожалуйста в чем принципиальное отличие события OnUpdate и цикла в самом эвенте While ?

Это же впринципе одно и тоже... Ну по свойствам и схожей работе..

Я просто предпочитаю while, так как OnUpdate не хочет корректно работать в скриптах с extends ActiveMagicEffect.

Видишь ли, в событии OnEffectStart где есть actor Caster, actor Target...
Я могу задать команды, которые я люблю использовать:
1) Caster/Target.Cast
2) Caster/Target.AddSpell
3) Caster/Target.placeatme

А когда я пытаюсь задать эти команды через OnUpdate (чтобы он повторял их с нужной мне переодичностью, он ругается, мол, не знает, к кому я обращаюсь) (не компилирует)

Причем через extends Actor в скрипте Актера вроде OnUpdate нормально работает.

Может быть есть какой то способ заставить OnUpdate работать в среде ActiveMagicEffect или же придется довольствоваться While ??

Добавлено (29 Июня 2015, 23:31)
---------------------------------------------
UPD:
Multigone, Dsion насчет ваших длинных постов, отвечу чуть позже  ;)


Multigone  Offline  Сообщение №1785 написано: 29 июня 2015, 20:58 | Отредактировано: Multigone - 29 июня 2015, 20:59



832
nepewka,

1) Это разные вещи. Настолько, что даже представить нельзя.
2) Потому что Actor AkTarget - это параметр события OnEffectStart(). Параметр (переменная) любого события может использоваться там и нигде больше. Чтобы компилировал, нужно создать переменную в теле скрипта, которой присвоить значение переменной AkTarget при старте эффекта:

Actor MyAct

EVENT OnEffectStart(Actor xT, Actor xC)
    MyAct = xT
ENDEVENT

EVENT OnUpdate()
    MyAct.TrapSoul()
ENDEVENT

Почему работает в Actor (и кое-где еще) - ибо там референс (игровая копия формы СК), к которому прикреплен данный скрипт, определяется через Self:

MyAct = Self

Во всех случаях, где Self выступает в качестве объекта действия к.-л. функции, его можно не писать:

Self.GetAV("Health")
GetAV("Health")

Dsion  Offline  Сообщение №1786 написано: 29 июня 2015, 21:03



Добротный ассассин может нанести больше 10 000 урона одним единственным ударом на сложности "Адепт" или больше 5 000 на сложности "Мастер"... Или в два раза больше серией ударов за одну секунду...
Не подумайте, что я для понта пишу... Но просто это надо учитывать.

nepewka  Offline  Сообщение №1787 написано: 29 июня 2015, 21:07



255
Цитата Dsion

Добротный ассассин может нанести больше 10 000 урона одним единственным ударом на сложности "Адепт" или больше 5 000 на сложности "Мастер"... Или в два раза больше серией ударов за одну секунду... Не подумайте, что я для понта пишу... Но просто это надо учитывать.


Для таких вот "ассассинов" и нужны супербоссы с 50000 здоровья :)))

Dsion  Offline  Сообщение №1788 написано: 29 июня 2015, 21:20



Понятно. Ну и как тебе помогут эти скрипты? Они делают цель неубиваемой только тогда, когда она вступает в бой. Ассассин замочит её раньше, чем скрипт сработает. Ладно, как хотите...

nepewka  Offline  Сообщение №1789 написано: 29 июня 2015, 22:25 | Отредактировано: nepewka - 29 июня 2015, 22:25



255
Цитата Dsion

Понятно. Ну и как тебе помогут эти скрипты? Они делают цель неубиваемой только тогда, когда она вступает в бой. Ассассин замочит её раньше, чем скрипт сработает. Ладно, как хотите...


Необязательно. За работу скрипта при вступлении в бой отвечает OnCombatStateChanged, есть ещё OnLoad event делающий цель "неуязвимой", как только ты увидешь 3д модель врага.

Добавлено (30 Июня 2015, 01:25)
---------------------------------------------
UPD: Как и событие OnHit, собственно, если я всё правильно понимаю.

Я щас понимаю о чем ты, если скрипт работал бы только по CombatStateChanged он был бы уязвим для любого рода ассасинов, убивающих его до начала боя. Поэтому и нужны разношерстные события  good

Dsion  Offline  Сообщение №1790 написано: 29 июня 2015, 22:53



...не знаю, чего Multigone с тобой возится и делает для тебя длинные скрипты, если тебе впадло даже двумя словами объяснить, чего ты пытаешься добиться...
Зачем вообще вся эта хрень? Нужен неубиваемый босс - дай ему 100% сопротивление урону. Нужен трудноубиваемый босс - дай ему 99% сопротивление урону. Легко, логично, лорно, безбагово...

Даже если ты делаешь какой-то мод на замер ДПС, то все-равно можно дать 90% ресист, а потом домножить дпс на 10.

nepewka  Offline  Сообщение №1791 написано: 30 июня 2015, 00:07 | Отредактировано: nepewka - 30 июня 2015, 00:08



255
Dsion, Сам не знаю чего возится :) Не перевелись ещё добрые люди на этой земле и пока они тут, тема на этом форуме будет жить  ;)

Чего пытаюсь добиться ? Добавить интереса в "свой" собственный скайрим. Мне не нравится стандартная игра. Её враги, закланания, предметы.
Я прошел её всю и есть два выхода. Либо бросить, либо добавить интереса путем добавления нового контента, в первую очередь новых врагов.
Стандартные соперники... Не создают никакого челенджа.

Теперь обьясню почему всегда отказываюсь от банальной идеи добавления перков игроку для увеличения сложности игры.
Mod Weapon Damage 0.01
Mod Spell Magnitude 0.01

Знаешь, если бы я хотел пойти таким путем, я бы не стал делать перки, зачем? Проще зайти Creation kit > Gameplay > Settings и там изменить настройки для сложности игры.
Переделать какой нибудь Мастер, сделав так что бы игрок наносил 1/100 урона по врагу, а враг в 100 раз больше по игроку.

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

P.S. я не делаю никаких модов, я делаю интересную игру для себя.
И главное что дает Multigone, это знания для работы над игрой. За что ему большое спасибо.

Multigone  Offline  Сообщение №1792 написано: 30 июня 2015, 06:09 | Отредактировано: Multigone - 30 июня 2015, 06:11



832
Цитата Dsion

Нужен трудноубиваемый босс - дай ему 99% сопротивление урону.

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

nepewka, это мне и самому нужно. Когда вижу чью-то проблему, стараюсь ее решить, если могу это сделать (или думаю, что могу; иногда действую методом ошибок и ошибок), я пишу комментарий. Если она решена - приобретаю новые знания или лучше понимаю некоторые вещи. Такой вот эгоистичный подход.

Dsion  Offline  Сообщение №1793 написано: 30 июня 2015, 06:53 | Отредактировано: Dsion - 30 июня 2015, 06:57



Есть еще обычный флаг Essential... Можно прямо на NPC ставить или на алиас...
Если этот флаг скомбинировать с высочезной регенерацией ХП, то актор не будет ползать на коленях...

Или со скриптом такого типа:

Код
Int DeathCount = 0

Event OnEnterBleedout()

    DeathCount += 1

    If (DeathCount >= 9)
        KillEssential()
    Else
        RestoreActorValue("Health", 10000)
    EndIf

EndEvent


Типа, 9 жизней. Хехехе.

Multigone  Offline  Сообщение №1794 написано: 30 июня 2015, 08:00



832
Dsion, игрока тоже можно сделать особенным с помощью SetEssential(true)? Если да, фактически, это полноценная замена DefferedKill(), но без ее проблем.
Интересно, если особенному актеру в Class установить Bleedout Default = 0.0, или непосредственно в ActorBase Bleedout Override = 0, будет ли он бессмертен? И жаль, что это можно менять только из СК.

Цитата Dsion

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

Как вариант, сразу восстанавливать ему здоровье выше предела вхождения в Bleedout.

Забавно, что bleed out подразумевает истечение кровью, а НПС в это время усиленно лечатся.

nepewka  Offline  Сообщение №1795 написано: 30 июня 2015, 08:19



255
Multigone, кстати насчет скрипта. При загрузке локации, имеешь ввиду всё таки event OnLoad ?

А почему нельзя обойтись одним event OnHit ? 
по идее он тоже должен запускаться и "спасать" нпц так быстро, что никакой ассассин не убьёт

Multigone  Offline  Сообщение №1796 написано: 30 июня 2015, 10:06 | Отредактировано: Multigone - 30 июня 2015, 10:07



832
nepewka, OnLoad() срабатывает, когда игрок входит в локацию (или в Cell? я в этом не разбираюсь), где находится Self в текущий момент игры. Т.е. при загрузке этой локации. Загружена 3D модель объекта или нет - не имеет значения.
OnHit() срабатывает после воздействия, и когда первая строчка кода в OnHit() начнет выполняться, актер будет уже мертв.

nepewka  Offline  Сообщение №1797 написано: 30 июня 2015, 10:17



255
Multigone, Ясно..

Скажи, что не так:
Событие OnUpdate  в скрипте не выполняется до конца, если у заклинания стоит Full Duration 2sec, а если Duration поставить 0, то OnUpdate и вовсе не запускается. Я так понимаю, OnUpdate теряет актёра, как только endEvent OnEffectStart проходит, как заставить его доработать до конца?

Actor Victim 
Int Pika

EVENT OnEffectStart(Actor Target, Actor Caster) 
     Victim = Target
     RegisterForSingleUpdate(0.001)
ENDEVENT 

EVENT OnUpdate()
     If Pika == 20
     UnregisterForUpdate()
     else
     Victim.DamageAV("Health", 100)
     Pika += 1
     endif
     registerforsingleupdate(0.1)
ENDEVENT

Добавлено (30 Июня 2015, 13:17)
---------------------------------------------
UPD: вернее теряет актёра, сразу, как только MGEF спадает с цели.


Multigone  Offline  Сообщение №1798 написано: 30 июня 2015, 10:40 | Отредактировано: Multigone - 30 июня 2015, 10:44



832
nepewka, ничего не теряется, просто скрипт прекращает работу после завершения маг. эффекта. Если в момент завершения остались какие-то активные события, то они дорабатывают свои задачи, а новые события не происходят.
Сумма времени в скрипте и продолжительность маг. эффекта формально совпадают, да. Но, фактически, за 20 обновлений потратится времени больше 2 с. Интервал между последовательными обновлениями складывается из паузы (0.1) и времени на обработку кода (небольшое, но есть). Отсюда разница.
Чтобы избежать, ставь продолжительность больше 2 с или увеличивай частоту обновлений.

Ссылка.

nepewka  Offline  Сообщение №1799 написано: 30 июня 2015, 11:01 | Отредактировано: nepewka - 30 июня 2015, 11:30



255
Цитата Multigone

nepewka, ничего не теряется, просто скрипт прекращает работу после завершения маг. эффекта. Если в момент завершения остались какие-то активные события, то они дорабатывают свои задачи, а новые события не происходят. Сумма времени в скрипте и продолжительность маг. эффекта формально совпадают, да. Но, фактически, за 20 обновлений потратится времени больше 2 с. Интервал между последовательными обновлениями складывается из паузы (0.1) и времени на обработку кода (небольшое, но есть). Отсюда разница.
Чтобы избежать, ставь продолжительность больше 2 с или увеличивай частоту обновлений.


спасибо, но в таком контексте While для использования повторений будет действительно лучше для меня :)
просто потому, что независимо от MGEF будет всегда дорабатывать до конца

Frostik  Offline  Сообщение №1800 написано: 2 июля 2015, 22:04



53
Есть плагин(ы), в которых нпс выполняют очень сложные скрипты и пакеты AI.
Открываю плагин в СК - выделяю нужного нпс, но в его свойствах пусто.  unsure
Подскажите в чем ошибка. Мне нужно видеть какие скрипты прикреплены к нпс...

PS   запускаю СК обычным образом, возможно надо через skse_loader???

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





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