Модератор форума: 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? Пиши не в ЛС, а в эту тему.
Dsion  Offline  Сообщение №2761 написано: 4 ноября 2019, 15:58



yakor77, повесить оба скрипта на один объект легко, но 95%, что это не даст желаемого эффекта... Вручную исправить один из скриптов, подглядывая в другие, тоже можно. А так, чтоб склеить... автоматически... Не думаю... Ну я, конечно, не большой авторитет. Но я последние лет 5 активно изучаю программирование, использовал штук 10 разных языков и лично я не представляю, как такое можно провернуть.

yakor77  Offline  Сообщение №2762 написано: 5 ноября 2019, 05:59 | Отредактировано: Multigone - 21 апреля 2020, 20:24



28
Цитата Dsion

yakor77, повесить оба скрипта на один объект легко, но 95%, что это не даст желаемого эффекта... Вручную исправить один из скриптов, подглядывая в другие, тоже можно. А так, чтоб склеить... автоматически... Не думаю... Ну я, конечно, не большой авторитет. Но я последние лет 5 активно изучаю программирование, использовал штук 10 разных языков и лично я не представляю, как такое можно провернуть.

Спасибо за ответ. Дело в том, что этот скрипт - единственный и уникальный, с таким именем другого быть не может. И он - глобальный, действует на все ванильные манекены сразу. Поэтому - только склейка. И, видимо, всё-таки - ручная. Я читал разные форумы, баг с головой - тоже глобальный и фундаментальный, такое происходит не только с манекенами. А, например, при смене тел NPC. Предлагается лечить через Ctri-F4 в Криэйшн Кайт. Есть другой мод, замечательный по богатству функционала. На 100 манекенов. Там проблем с головой нет. Но там надо вручную заморачиваться с установкой каждого отдельного манекена. А мне лениво делать это 100 раз. И хотелось бы в другом моде, где уже есть большой зал манекенов, одним скриптом, поменять все ванильные деревяшки - на живые и со сменой расы. Так что, без данного скрипта, для этой задачи - никак не обойтись. Видимо, всё же придется разбираться в логике автора, и пытаться сделать ручную склейку...

С уважением.
Маг Иридий.
Myprism  Offline  Сообщение №2763 написано: 6 ноября 2019, 17:17 | Отредактировано: Myprism - 6 ноября 2019, 17:18


Физик


yakor77, автоматически скрипты не склеиваются. Точно так же, как автоматически объединять можно только самые примитивные моды. Задача ваша решается написанием нового скрипта для манекенов под тем же названием. Чтобы это сделать, вы должны разобрать детально, что делают эти скрипты и написать свой с нужным вам функционалом. Менять позы - без проблем. Живые манекены? - Это самое лёгкое. Они же сделаны как живые персонажи. Заморозить манекен уже потруднее. Расы меняются легко, а вот пол - фигушки, скриптом не делается.

Бага с головой, который исправляют Ctri-F4 в Скайриме нет. А есть непонимание, как в Скайриме работают головы. Персонажа можно создать в редакторе. Но эти изменения игра не примет. Игре нужна сохранённая модель головы с применением соответствующих морфов и полноты. Вот только с этой моделью (и текстурами к ней) игра и будет работать. Чтобы приготовить такую модель и текстуры для игры, нужно нажать Ctri-F4. Сделано это для оптимизации производительности. Движок игры не успевает синтезировать головы со всеми морфами и раскрасками налету, поэтому всё должно быть приготовлено заранее.

А проблем с головой у вас не будет, если вы сделаете её не как голову с мимикой и соответствующими морфами, а как шлем имеющий форму головы. Она вообще может быть просто продолжением тела. Т.е. одна единственная модель - тело. Включает все части и голову в том числе, которые просто привязаны к соответствующим костям. И не будет ни шва на шее, ни сохранения заготовки по Ctri-F4. Но это уже не для темы по скриптам.

yakor77  Offline  Сообщение №2764 написано: 7 ноября 2019, 10:30



28
Здравствуйте, Физик!

Большое спасибо за подробный, развернутый ответ.
Мне хотелось получить результат минимальными усилиями. Вы пишете, что это невозможно, и нужен новый скрипт. Возможно, я когда-нибудь этим и займусь. Но сейчас на это у меня нет ни свободного времени, ни особого желания.
Плагин, который придает такой богатый функционал манекенам, меня вполне устраивает. Ладно, фиг с ней, с головой, для музея всё равно они практически у всех фигур будут под шлемами. Не критично. Делать голову, как шлем, или часть тела - это получить её статичной болванкой, и в этом, по сути, нет разницы, между уже имеющейся деревянной головой, и новой, возможной. Вся фишка была - как раз в мимике. А проблема в том, что игра не запоминает сделанные изменения. То есть, голову можно сделать живой, но при следующем посещении локации, она вновь сбрасывается на деревянную. Рекомендация автора пекса (выйти по дефаулту, и пересохраниться на чистый сэйв) - тут не помогает.
Короче, для подвальной кузницы [1] и музеев [2, 3] я решил оставить этот богатый пекс-активатор [4], а для домов ГГ - поставить с заменой вручную "полностью живые" манекены из [5]. Там их немного. Такое решение мне представляется оптимальным по балансу нагрузки на память и процессор компьютера. Ранее был упомянут бедный на функционал, но сохраняющий голову с мимикой и меняющий расу, плагин [6].
Благодарю всех за внимание и помощь, вопрос закрыт.

Моды и плагины (убрать пробелы, а то робот ругается):
--------------------
1. Подвал кузнеца / Blacksmith's Basement by Bluntaxe h t t p : / / w w w . nexusmods . com/skyrim/users/2521167
2. Хранилище коллекционера h t t p s : / / w w w . playground . ru/files/tes_5_skyrim_hranilische_kollektsionera-70221/
3. Музей на столе / Museum on a table h t t p s : / / gamer-mods . ru/load/skyrim_le/doma_i_lokacii/museum_on_a_table/15-1-0-1542
4. MannequinActivatorSCRIPT h t t p : / / tiarum . com/wiki//MannequinActivatorSCRIPT
5. Манекены с анимацией h t t p : / / gamer-mods . ru/load/tes_v_skyrim/gejmplej_i_animacija/manekeny_s_animaciej/16-1-0-1755
6. Фикс манекенов / Mannequin Script Fix h t t p s : / / w w w . playground . ru/files/tes_5_skyrim_mannequin_script_fix-69803/

С уважением.
Маг Иридий.

С уважением.
Маг Иридий.
trorhold  Offline  Сообщение №2765 написано: 19 декабря 2019, 02:46



6
Ребят. Подскажите тутор можно на буржуйском, как сделать так что бы НПС при входе в воду раздевались.
Я не скриптописец или как они там называются, дизайн уровней на ура, а со скриптами я не дружу. Пилю мод с новым домом (да да их навалом, но у меня особенный), есть там бассейн, видел в других модах что можно сделать что бы НПС раздевались при входе в воду. 

Может кто то видел гайд по этой теме или скрипт уже кем то написаный и выложенный в открытый доступ. Помогите пожалуйста.

Myprism  Offline  Сообщение №2766 написано: 19 декабря 2019, 04:51


Физик


trorhold, есть такой мод Мелисса. Он написан очень хорошими отечественными мододелами. Там персонажка сама раздевается в бане и даже потеет! Если память мне не изменяет, то и в реках она тоже раздевается. Вот надо посмотреть, как там это устроено. Вообще, на этом моде можно учиться, как их правильно делать.

myav  Offline  Сообщение №2767 написано: 20 декабря 2019, 11:30 | Отредактировано: Multigone - 21 апреля 2020, 20:23



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

Помимо всяких безумных вариантов, самый адекватный вариант, что я пробовал:

Код
Scriptname frivolity extends activemagiceffect

actor selfactor
ActorBase MyBase

Event onInit() ; (либо Event onEffectStart, я пробовал оба варианта)
   selfactor = GetTargetActor()
   MyBase = selfactor.GetActorBase()
   Combatstyle csStyle = MyBase.GetCombatStyle()
   ; (также я пробовал Form csForm = MyBase.GetCombatStyle() as Form а потом Combatstyle csStyle = csForm as Combatstyle)
   csStyle.SetOffensiveMult(0.10)
   selfactor.StopCombat()
   MyBase.SetCombatStyle(csStyle)
   selfactor.StopCombat()
   selfactor.EvaluatePackage()
EndEvent


Вот, скажите мне - почему это не работает?
в SetCombatStyle написано что комбатстиль базы привязан к бою и поменять не получится пока бой, вот потому я и добавил StopCombat.

И меня не так волнует, почему это не работает, как волнует ==> Как можно заставить НПС не атаковать, прямо во время боя.

Хелп....  Кто-то может показать кусок кода который будет получше чем мой и сможет поменять SetOffensiveMult во время боя, чтоб дошло до мозгов НПС?

Myprism  Offline  Сообщение №2768 написано: 20 декабря 2019, 13:22


Физик


myav, я не большой специалист в скриптах. Поэтому выскажу только предположение. Мне кажется, что дело в различии актёра и базового актёра. Базовый актёр это объект, копии которого размещаются в Скайриме. А просто актёр это и есть такая копия. Изменение свойства базового актёра это изменение свойств всех его копий. Именно поэтому selfactor.StopCombat() применяется просто к актёру, а не к базовому актёру, ведь данный бой ведёт копия. Так что, не очевидно, как MyBase.SetCombatStyle(csStyle) срабатывает на данном актёре.

myav  Offline  Сообщение №2769 написано: 20 декабря 2019, 13:53 | Отредактировано: myav - 20 декабря 2019, 14:40



30
Myprism, вот потому я и запостил это тут.

Кто может помочь и подсказать, как поменять CombatStyle именно к "уже инициализированному" актеру? Если SetCombatStyle применяется к его базе а не к нему самому.

Я думал EvaulatePackage - сбрасывает ИИ и заставляет актера заново прочитать его базу. Но если эта команда не затрагивает CombatStyle, то печально.

Хелп!

Myprism  Offline  Сообщение №2770 написано: 31 декабря 2019, 20:04


Физик


Как заполняются камни душ?
Нужно знать, каким скриптом это делается. Проблема в том, что в редакторе есть только один маленький камень душ, один большой, один великий и т.д. А в результате сбора камней и их заполнения обнаруживаются РАЗНЫЕ маленькие камни с разной ценой (хотя и с одной душой), разные большие и т.д. Игра считает их разными объектами и мне нужно понять, откуда они берутся. Я сделал разный внешний вид для полных и пустых камней. Но в игре обнаруживаются полные камни душ, которые выглядят как пустые. Они всегда дешевле тех камней душ, которые выглядят как полные. Нужно понять, как игра создаёт эти камни душ и как она даёт им изображение пустых камней.

Добавлено (01 Января 2020, 16:53)
---------------------------------------------
Немножко продвинулся с камнями душ. Похоже, они неправильно заполняются душами в ванильной игре. Вместо того, чтобы поменять игроку пустой камень душ на полный, там просто камню ставится галочка полного, а остальные свойства (цена и модель) остаются от пустого.
В скрипте Scriptname Actor extends ObjectReference Hidden
есть заголовок функции bool Function TrapSoul(Actor akTarget) native которая, видимо, и осуществляет наполнение камней душ. Но где её содержание и как его править, я пока не знаю.


Dsion  Offline  Сообщение №2771 написано: 1 января 2020, 15:41



Myprism, а как ты native функцию исправишь-то..? Скайрим ведь не весь на папирусе написан. И из папируса далеко не на все механики повлиять можно. Потому и появился SKSE, который пытается расширить возможности папируса...
А так-то большая часть Скайрима на С++. Доступа к исходному коду у нас нет. То есть, можно работать только с ассемблером. Вооружившись чем-то типа OllyDbg сделать можно что-угодно, но это совсем не то, что писать скрипты на папирусе с использованием официальных стабильных API... Даже просто найти процедуру (функцию), с которой начинается заполнение камня душ - это можно день мучиться. Потому что в ассеблере никаких имен у функций и переменных нет. Остается только по коду догадываться, что там и для чего.

http://www.ollydbg.de/Pics/OllyDbg2.gif

Myprism  Offline  Сообщение №2772 написано: 1 января 2020, 16:14


Физик


Dsion, грустно :(

Добавлено (01 Января 2020, 19:42)
---------------------------------------------
А идея, как это всё-таки исправить, у меня есть :)
Заполнение камней находится в скрипте:

Код
ScriptName magicSoulTrapFXScript extends ActiveMagicEffect
;...................
Event OnEffectFinish(Actor Target, Actor Caster)
;...................
            if Caster.TrapSoul(victim) == true ; Вот, оно, заполнение.
                ; Вот если я сюда вставлю поиск и замену в инвентаре игрока дефектно
                ; образованного заполненного камня душ правильно заполненным, то всё будет правильно.
            endif
;...................
endEvent

Добавлено (02 Января 2020, 03:35)
---------------------------------------------
Dsion, наверное, только ты мне сможешь помочь. Объясню всё подробно. В игре есть два типа камней душ - пустые и полные. Это разные типы объектов с разной ценой (им можно ещё и вес сделать разный). Я сделал для них специальные прозрачные и очень красивые модели. Таким образом, у меня сразу видно, заполнен ли камень душ. Но это не работает на тех душах, которые игрок заполняет сам с помощью заклятия отбирания душ. Дело в том, что игра использует для таких камней только объекты пустых камней душ, которым назначает заполнение. Цена, вес, модель остаются пустыми, но значится наполнение. Мне нужно это исправить. Т.е. мне нужно вычленить в инвентаре игрока "неправильные" камни и заменить их правильными того же типа и заполнения. Для частично заполненных камней душ мне не трудно сделать и соответствующие объекты и даже специальные модели для них. Проблема заключается в том, чтобы вычленить в инвентаре игрока неправильно заполненные камни душ.
В качестве обработчика, куда вставлять код, годится Event OnEffectFinish(Actor Target, Actor Caster)
Вопрос в том, как выделить дефектный камень? Алгоритм возможен такой: я ставлю всем пустым камням кейворд (например) "EmtySoulGem". Тогда все камни в инвентаре игрока с таким кейвордом, но имеющие душу, являются дефектными и подлежат замене. (В SKSE есть функции определения типа камня и типа его души.) Но как быть с инвентарём игрока? Как получить доступ к нему или выделить из него массив камней душ с нужным кейвордом (или хоть один камень, который был заполнен только что). Ещё мне нужно знать число элементов в массиве для возможности его перебирания.
Ещё дело осложняется тем, что непонятно, какие именно камни душ лежат в инвентаре. В принципе, инвентарь является контейнером. Если в контейнер положить несколько штук предметов разом, то им не выделяются отдельные ID. Они будут лежать просто как несколько штук базового объекта одной строчкой. Если же их туда положить несколько раз по одному предмету (несколькими строчками), то каждому будет выделен отдельный ID и это будут раздельные предметы. При заполнении камней душ, каждый раз создаётся новый камень, который лежит в инвентаре игрока отдельной строкой, причём одинаковые по всем параметрам так созданные камни не объединяются вместе. Это создаёт проблемы при прокрутке неоправданно длинных списков. Инвентарь игрока их не объединяет. Если все эти камни выгрузить в какой-нибудь сундук, а потом забрать оттуда, то все одинаковые камни окажутся объединены в одну строку с одним числом камней в строке. Инвентарь игрока тоже объединяет одинаковые предметы, но только не для заполненных заклятием камней душ. Может быть, вот эти не объединяющиеся камни душ в инвентаре, имеют свои особенности (те, что не дают им объединяться) и эти особенности позволяют их оттуда вычленять?

Добавлено (02 Января 2020, 09:42)
---------------------------------------------
Ещё, как можно повесить скрипт на игрока? Там бы я мог отслеживать добавление объектов и если это неправильный камень душ, заменять его.

Добавлено (02 Января 2020, 13:05)
---------------------------------------------
Со скриптом на алиас игрока получился пролёт. Добавление души в камень душ не добавляет камень в инвентарь, а изменяет его там. Так что, событие OnItemAdded() не срабатывает :(

Добавлено (02 Января 2020, 16:11)
---------------------------------------------
Второй пролёт:
Int GetSoulSize()
Int GetGemSize()
Обе функции возвращают одну и ту же цифру от 1 до 5, которая соответствует размеру камня и никак не зависит от того, заполнен он игроком или нет и в какой степени. Т.е. нет даже способа определить скриптом, есть ли в камне душа :(


Dsion  Offline  Сообщение №2773 написано: 2 января 2020, 19:45



Myprism, я немного подумал еще тогда, когда ты первый раз спросил, и ничего полезного не придумал... А еще, одна неосмотрительная компания недавно наняла меня С++ программистом :) Так что я сейчас во всю прикидываюсь нормальный трудолюбивым телом и мало сил остается думать о чем-то еще.
А GetSoulSize() не работает на объектах, выброшенных в мир? Тех, кто не в контейнере.
Единственное, что приходит в голову, - так это вообще выкинуть всю систему захвата душ и написать с нуля на папирусе. Абсолютно новый спелл, который проверяет уровень цели, наличие в инвентаре пустого камня достаточного размера, удаляет пустой камень и дает заполненный. Не, бред, забудь.

Myprism  Offline  Сообщение №2774 написано: 2 января 2020, 20:33 | Отредактировано: Myprism - 2 января 2020, 20:39


Физик


Цитата Dsion

А GetSoulSize() не работает на объектах, выброшенных в мир? Тех, кто не в контейнере.

Не в контейнере, это не актуально, так как нужно это делать именно у игрока. Тут ещё обнаружилась вот какая гадость. Заполненные камни душ игра в папирусе не отличает от пустых. Чтобы вычленить камни душ из инвентаря, я применил FormList из пустых душ. Так вот, игра считает, что все заполненные игроком относятся туда же, т.е. к пустым. Т.е. она пишет, что там есть заполнение, но не позволяет его обнаруживать папирусом.

Multigone  Offline  Сообщение №2775 написано: 2 января 2020, 21:57



815
Myprism, размер души определяется уровнем актера - см. "SoulActorLevel" в Settings, исключение - люди (великая душа). Нормальный захват можно сделать только написав новый скрипт взамен использования архетипа TrapSoul, который вешается на те же маг. эффекты. Для заполненных камней нужно создать новые формы, имеющие душу изначально - чтобы при выкидывании заполненного камня в мир он не опустошался. Еще у ванильных камней скриптом нельзя абсолютно никак определить уровень содержащейся в нем души, если она не соотвествует размеру камня - напр., великий камень (маленькая душа) считается пустым - но если создать в СК новую форму для каждой возможной комбинации, то уровень души в камне определять будет можно.
Еще, оружие с чарами ванильного захвата работает только на игроке, тогда как новый скрипт позволяет захватывать души любому актеру.

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

Myprism  Offline  Сообщение №2776 написано: 3 января 2020, 04:23 | Отредактировано: Myprism - 3 января 2020, 04:24


Физик


Multigone, разные модели для заполненных и пустых камней душ я уже сделал. Очень красивые. На этом и заметил все глюки заполнения камней душ в Скайриме. Хотел сделать и специальные модели для частично заполненных душ, но склоняюсь к мысли отказаться от частичного заполнения вообще. Во-первых, мне очень не нравится, когда великий камень поганится мелкой душой крысы, во-вторых, не правильно будет, дать игроку возможность заполнить великий камень всего лишь пятью крысами (это если сделать дозаполнение). Наверное, надо сделать так, чтобы душа полностью заполняла собой самый большой из имеющихся у игрока камней, который она превосходит. Таким образом, мамонт заполнит крохотный камень, если у игрока есть только такой (всё равно душа улетает), но крыса не осквернит собой великий камень. Кстати, для звезды Азуры это не годится.
Заменять нужно только нативную функцию Bool TrapSoul(). Но она не вешается на эффекты, а вызывается скриптами, которые вешаются туда. Т.е.
нужно заменять только её.
Цитата Multigone

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


Всегда об этом мечтал! (Ещё бы спутники руды добывали :) )
Кстати, а в каком состоянии твой мод на камни душ? Может, объединим усилия?

Multigone  Offline  Сообщение №2777 написано: 3 января 2020, 15:36



815
Myprism, если принять уровни душ от мелкой до великой как 1-5, то объемы душ будут соответственно 1/2/4/8/12, исходя из даваемой ими энергии для чар, т.е., к примеру, для заполнения великого камня требуются 12 крохотных душ (если делать возможность постепенного заполнения).
Вообще, себе я сделал настройку (максимально допустимая разница в уровнях души и камня при захвате).
Еще, звезда Азуры должна всегда заполняться первой, а в ванили она выбирается случайно из общего кол-ва подходящих камней. Это тоже исправляется.
Все же в архетипах эффектов есть "Soul Trap", я только не помню, работает ли оно без скрипта (по идее, должно работать без визуального сопровождения).

Мод конкретно на захват готов на 100%, только было лень выкладывать его сюда взамен старой версии (см. в файлах), но там еще куча других идей, реализованных полностью или частично, например, заклинание расщепления камня на осколки / сбора камня из них / объединение душ в разных камнях в один большего размера / разделение заполненного камня на несколько меньшего размера.

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

Myprism  Offline  Сообщение №2778 написано: 3 января 2020, 16:57


Физик


Multigone, ну, если реализовывать все твои задумки (их много), то это можешь сделать только ты сам. Я могу тогда предоставить тебе свои модели (они разные для пустых и полных душ). Могу даже сделать тебе специальные модели для частично заполненных камней душ. Это в случае, если тебе захочется вернуться к этому моду
Цитата Multigone

если принять уровни душ от мелкой до великой как 1-5, то объемы душ будут соответственно 1/2/4/8/12, исходя из даваемой ими энергии для чар, т.е., к примеру, для заполнения великого камня требуются 12 крохотных душ

Отлично! Это как раз то, что мне нужно знать. Ещё, чего мне не хватает, это знания, как определить размер души жертвы. Жертва в скрипте определена, но её душа должна зависеть от её уровня (вроде, это так в игре?). Большинство противников, это левельные игроки, уровень которых случаен и зависит от уровня игрока.
Сейчас у меня есть желание сделать самому этот скрипт, точнее, одну единственную функцию Bool TrapSoul(). Последние идеи такие:
1. Отказаться от частичного заполнения камней душ. Т.е. камни только пустые, либо полные. Инвентарь не будет перегружаться длиннющим списком разных камней душ с разным заполнением.
2. Заполняется в первую очередь самый большой из имеющихся у игрока камней и которому данной души достаточно для полного заполнения. Таким образом, частично заполненных камней не будет, а мелкие души не будут ловиться, если у игрока нет маленьких камней. Это лучше, чем потеря великого камня на крохотную душу. Заполнение великого 12 крохотными тоже не есть хорошо. Слишком легко.
3. Хочу сделать заполнение многих мелких камней одной большой душой, если у игрока нет больших душ. Алгоритм такой: проверка возможности заполнения начинается с листа, где, самые большие камни лежат в начале. После заполнения самого большого из доступных камней величина души жертвы уменьшается на количество души в этом камне и остаток проверяется на соответствие оставшимся у игрока камням душ для дальнейшего заполнения, пока остаток не станет меньше ёмкости крохотного камня.
4. Звезду Азуры надо просто ставить на проверку заполнения самой первой. Технически легко.

yakor77  Offline  Сообщение №2779 написано: 4 января 2020, 09:58 | Отредактировано: Multigone - 22 апреля 2020, 15:14



28
Уважаемые коллеги! Возможно ли написать скрипт, который позволит перезаряжать Звезды Азуры душами, без охоты на их владельцев, или синтаксис папируса этого не допускает? Известны ли Вам примеры такого скрипта?

С уважением.
Маг Иридий.
Multigone  Offline  Сообщение №2780 написано: 4 января 2020, 14:51 | Отредактировано: Multigone - 21 апреля 2020, 20:18



815
Myprism, yakor77,


Код
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

Myprism  Offline  Сообщение №2781 написано: 4 января 2020, 19:24 | Отредактировано: Multigone - 21 апреля 2020, 20:16


Физик


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

yakor77,
1. Существуют гораздо более простые способы сломать систему добычи душ. Например, просто сделать неисчезаемый полный камень душ :) Это я ещё в устройство станка не лазил, там, скорее всего, вообще можно отключить необходимость камней душ. Но это всё совершенно неважно. Главное, что это ломает ванильную систему баланса. Вот работаешь над модом, стараясь сохранить тот баланс, что создали разработчики, а тут появляется человек, которому эта система просто не нужна.
2. Довольно глупо сравнивать эту задачу с задачей решённой Григорием Перельманом.
3. Вы лжёте, утверждая, сто я сказал, что это невозможно. Перечитайте моё сообщение. Там первым пунктом утверждается обратное. А вот глупость содеянного мне по-прежнему очевидна.
4. 0 255 модах. Вы их что, объединять не умеете? :)

Multigone  Offline  Сообщение №2782 написано: 5 января 2020, 10:17 | Отредактировано: Multigone - 21 апреля 2020, 20:16



815
Myprism, это надо квест делать, ради, по сути, читерного предмета.

yakor77, еще проще, не требует вообще ничего.


Код
Scriptname _TESTTEST57 Extends ReferenceAlias ; На алиас игрока

SoulGem Property DA01SoulGemAzurasStar Auto ; Автозаполнить, в СК у этой формы снять флаг Reusable и указать Soul = Grand.

EVENT OnItemRemoved(Form xF, Int iN, ObjectReference xR, ObjectReference xD)
    IF xF == DA01SoulGemAzurasStar && !xD && !xR
        GetActorReference().AddItem(DA01SoulGemAzurasStar, iN, true)
    ENDIF
ENDEVENT

Myprism  Offline  Сообщение №2783 написано: 7 января 2020, 12:26 | Отредактировано: Myprism - 7 января 2020, 17:13


Физик


Multigone, Дело со скриптом хорошо пошло. Уткнулся как раз в то, о чём ты предупреждал - наложение сразу нескольких эффектов.
Зависимость заполнения камней от уровня убиваемой неписи аппроксимировал полиномом. Достаточно гладкий получился. Звёзды сделал с дозаполнением душами до верха. Разумеется, звёзды заполняются в первую очередь. Раз игрок звезду с собой таскает, значит, именно ей и хочет работать.
Прочие камни душ сделал с полным заполнением каждого камня, но если нет больших, то заполняются несколько мелких, если нет мелких, то души копятся (только если в инвентаре у игрока есть хоть один пустой камень), пока не заполнят самый маленький из имеющихся камней. Куча разных камней (а то и одинаковых, но не объединившихся) в инвентаре игрока ушла в прошлое.
В качестве потребителя душ поставил не заклинателя, а ГГ. В этом случае компаньон тоже может заполнять души в инвентаре ГГ.
И вот тут уткнулся в то, что на персонаже могут быть сразу 2 одинаковых заклинания. Если быстро стрелять по мамонтам, то выбиваются две великие души из каждого мамонта :) А подруга с зачарованным мечом выбивает из саблезубов двойное количество камней душ, причём такое, какое при моём алгоритме заполнения невозможно, например 3 крохотных (должно получиться 1 маленький и 1 крохотный). Выходит, что при смерти персонажа завершаются сразу несколько заклятий (два, как минимум) и выполняются скрипты обоих. Как ты это разрулил? Мне пока не приходят в голову достаточно красивые решения. Самое простое - прекращать предыдущее заклятие, накладывая новое, но тогда новое с коротким временем (от меча) может заменять длинное от лука, что не есть хорошо. Можно не накладывать новое, пока не закончилось старое. Это приемлемо, когда непись валит один человек, но не очень хорошо, когда двое и зачарованное оружие только у одного из них.

Добавлено (07 Января 2020, 20:11)
---------------------------------------------
Ну, как первый блин, работает такая конструкция:
Код
ScriptName magicSoulTrapFXScript extends ActiveMagicEffect

Event OnEffectStart(Actor Target, Actor Caster)
While target.HasMagicEffect(Self.GetBaseObject())
    Dispel()
endWhile
.............................
По крайней мере, удвоения камней нет, если валить неписей совместно с напарницей и оба зачарованным на отъём душ оружием. Вроде, адекватно получается. Можно чего-нибудь лучше придумать?

Multigone  Offline  Сообщение №2784 написано: 7 января 2020, 20:09 | Отредактировано: Multigone - 7 января 2020, 20:16



815
Myprism, кхм.

Цитата Myprism

Можно не накладывать новое, пока не закончилось старое. Это приемлемо

Это неприемлимо :D

yakor77  Offline  Сообщение №2785 написано: 7 января 2020, 22:30 | Отредактировано: yakor77 - 7 января 2020, 23:50



28
Коллега Multigone, в тему Вашей дискуссии о заполнении камней душ. Я в этой задаче увидел разные подходы - и в смысле оптимизационной задачи линейного программирования (транспортная задача, задача о раскрое), и тн "многостанковые задачи", но... предпочитаю излишне не заморачиваться. В ТРИЗ есть такой приём "избыточного действия": сделать с избытком, а потом убрать лишнее. Предлагаю рассмотреть такое решение. Камни душ, по сути, те же деньги, а деньги можно взять в кредит. При убийстве жертвы зачарованным на захват души оружием, ГГ+ всеми его спутниками с таким оружием, под эту душу, автоматически, через аддитем, создается ближайший по объему и качеству камень душ, от мелкого до великого и чёрного, и помещается в рюкзак убившего, соответственно ГГ или спутника. Назовём это "кредитным камнем душ" (ККД), который выдает "банк Каирна Душ". (Если кому интересно, идею банка можно развить, навесив на Валерику, маму Сераны, функции банкира этого банка, а саму Серану - сделать агентом банка, чтобы каждый раз самому в Каирн или Волкихар не мотаться. Или филиалы открыть по всем городам, и тавернам. тут простор для фантазии.) Доступ ГГ к этим камням заблокирован: "хоть видит око, да зуб неймет". Если у ГГ имеется в рюкзаке набор пустых камней душ, он, на ближайшем привале, в спокойной обстановке, может провести эквивалентный обмен, соотв. заклинанием. Пустые камни душ, по суммарной ёмкости, удаляются, а погашенные таким образом кредиты ККД - активируются в доступе. Если в рюкзаке суммарного объема камней недостаточно, оставшиеся ККД остаются неактивированными, до следующей сделки. Для упорядочивания списка так же используем "жадный алгоритм" задачи о рюкзаке (она же задача директора, она же задача одного станка). То есть, ранжировка от великого до мелкого. Можно не заморачиваться и блокировкой, и с торговлей, сразу делать ККД активными, автоматически удалять всё, что есть пустого из камней в рюкзаке, но остаток, если он не погашен, повесить на ГГ, как кредитный долг. При добыче любым способом пустых камней душ, они автоматически удаляются, по своей стоимости (их объему), в счет погашения кредита. Если развивать квестовую идею банка, можно ввести и проценты за крелит. Чтобы до бесконечности не раздувать кредитный пузырь, ввести кредитный лимит, и завязать его повышение на уровень игрока. Ввести прокачку навыка, через посещения Каирна, и добросовестность уплаты долга и процентов, с понижением процентной ставки и повышения лимита. (И тп, это на любителя, но лично я, как читер, не любитель квестовых заморочек. По сути, я давно пользуюсь такой кредитной системой, просто имея в рюкзаке заведомо большой запас пустых камней каждого сорта, с поправкой на частотность.) Как Вам такое решение? Его главное преимущество - ни одна убитая душа попусту не пропадает, экономится время и вычресурс на расчете имеющихся емкостей.

С уважением.
Маг Иридий.
Myprism  Offline  Сообщение №2786 написано: 8 января 2020, 05:49 | Отредактировано: Myprism - 8 января 2020, 06:39


Физик


Цитата Multigone

Зависимость заполнения камней от уровня убиваемой неписи аппроксимировал полиномом.

Мы можем посмотреть уровень души каждого персонажа, но только ванильных, а есть ещё и модовые. Кроме того, уровень встречающихся игроку персонажей зависит от уровня игрока. Во-первых, это реализуется уровневыми персонажами, во-вторых в игре могут быть и другие модификаторы уровня, которых мы и не знаем. Уровень жертвы всегда можно посмотреть
Код
Target.GetLevel()
Но уровень энергии в камне душ нелинейно зависит от уровня жертвы:
уровень НПС - заряд камня душ
до 4             - 250
до 16           - 500
до 28           - 1000
до 38           - 2000
свыше 38     - 3000
Вот эти цифры, это то, что мы знаем точно. Но ведь нужно определять количество души во всех персонажах, в том числе и у персонажей с уровнями 1, 2, 3 или 32. Я просто провёл через точки ( уровни 0, 4, 16, 28, 38) параболу четвёртой степени и получил все промежуточные уровни душ. Конкретно у меня: 3,37*x - 0,25*x*x + 0,0086*x*x*x - 0,000075*x*x*x*x. Таким образом, я получаю величину пропорциональную заряду камней душ, а именно: 0, 10, 20, 40, 80 для персонажей уровней 0, 4, 16, 28, 38. Ну и эта функция даёт мне также все промежуточные значения.
Большое спасибо за подробное объяснение работы заклинаний. В этом я слаб.

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

To all, Как думаете, должна ли чёрная звезда заполняться обычными душами? Из игровых диалогов следует, что - нет. Но из многочисленных обзоров следует, что заполняется. Так же из обзоров следует, что простыми душами заполняются и чёрные камни, если у игрока нет пустых обычных камней (это я уже запретил).

yakor77  Offline  Сообщение №2787 написано: 8 января 2020, 06:08



28
Myprism, похоже на мой концепт, но от моего отличается. У меня предлагается под каждую захваченную душу автоматически создавать свой, ближайший по объему, камень. Даже если у игрока нет ни одного пустого камня. Чтобы не было соблазна раздувать кредитный пузырь, вводится лимит, зависящий от уровня игрока. Пока долг не погасишь, выбрав весь лимит - нового кредита не получишь. Можно ввести два банка, или две кредитных линии, - белый и черный, для соотв. цвета камней. Короче, тема богатая, можно поиграться с банковской практикой. Так же в Рифтене могут ошиваться ростовщики душ, упыри из вампиров, которые дадут кредит, но под людоедский 1% в день. А выколачивать уплату из Каирна может заявляться вышибала, какая-нибудь бабайка. Есть моды, которые зачарованнные предметы разочаровывают в плавильне обратно, дополнительно получая камешки. Есть моды, которые позволяют, в той же плавильне, переплавлять одни камни в другие, за деньги. Так что можно предусмотреть возможность погасить долг обычными деньгами. Тут простор для фантазии. Но, главное, мой метод обходит трудности классических оптимизационных задач линейного программирования, с ограниченными рсурсами. Ресурс Каирна бесконечен, в этом главная фишка!

С уважением.
Маг Иридий.
Multigone  Offline  Сообщение №2788 написано: 8 января 2020, 11:04 | Отредактировано: Multigone - 8 января 2020, 11:16



815
Myprism, не совсем понял, причем тут модные персонажи, автолевелинг и модификаторы уровня.
1) Уровень души определяется только уровнем актера-цели.
2) Profit

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

По поводу остатка - ну, дело хозяйское. В таком случае я бы ограничил макс. остаток, скажем, не больше размера обычной души. Недостаток: 2 одинаковых актера могут дать души разных размеров, поскольку к душе первого из них будет добавлен остаток. Получится "захвачена обычная душа" и "захвачена крохотная душа" и игрок такой О_о.

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

yakor77, это надо квест делать.

Myprism  Offline  Сообщение №2789 написано: 8 января 2020, 12:40


Физик


Multigone, уровень персонажа читается в игре. Но это не даёт ответа, сколько у него души, если он только не имеет уровень 4, 16, 28, 38. А мне нужно определять для всех. Ты совершенно правильно предложил аппроксимировать ломаной. Такой вариант тоже годится. Я не принял его для себя из-за перфекционизма :) Во-первых, мне хотелось иметь гладкую функцию, во-вторых хотелось избежать некрасивых неравенств определяющих интервалы, на которых проводится линейная интерполяция и определения коэффициентов для четырёх интерполирующих прямых. На самом деле, первым вариантом у меня была линейная интерполяция до уровня 24 и обычная парабола выше. Текущие Коэффициенты определил программой Origin. Это очень продвинутая рисовалка для научных графиков и я пользовался ею ещё очень давно и она позволяет проводить полиномы через набор точек.

У меня есть только один аргумент в пользу захвата чёрной звездой обычных душ: я уже сделал модели для её частичного заполнения :)

Multigone  Offline  Сообщение №2790 написано: 8 января 2020, 14:05 | Отредактировано: Multigone - 8 января 2020, 14:13



815
Myprism, ну, гладкости функции игрок не оценит, а вот совместимость - да. И для ломаной нет нужды делать несколько неравенств, там должно быть примерно такое:

Код
aiLevels[] ; Массив 1 -  уровни из Settings (первый эл. = 0)
aiEnergy[] ; Массив 2 - энергия камней (первый эл. = 0)
iActor ; Уровень актера
iSoul ; Уровень души 0-4, как определять, уже известно

iTemp = iMin(iSoul, 3)
fActorFactSoulEnergy =
= ( iActor - aiLevels [iTemp] ) AS Float  /  ( aiLevels[iTemp + 1] - aiLevels [iTemp] ) * ( aiEnergy[iSoul + 1] - aiEnergy [iSoul] ) + aiEnergy[iSoul]

Int FUNCTION iMin(Int A, Int B = 0)
    IF A < B
        RETURN A
    ENDIF
    RETURN B
ENDFUNCTION


Здесь принимается, что для актеров с уровнем выше iGrandSoulActorLevel, расчет энергии души проводится по прямой, проходящей через отрезок iGreaterSoulActorLevel -- iGrandSoulActorLevel.

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





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