Вверх Вниз


Модератор форума: Kris†a™, Multigone  
Форум » 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? Пиши не в ЛС, а в эту тему.
yakor77  Offline Сообщение №2851 написано: 05 Апреля 2020 в 14:42 | Отредактировано: yakor77 - Воскресенье, 05 Апреля 2020, 14:46


Странник


26
По поводу раздевания перед плаванием и одеванием после. Задача давным-давно решена. Я знаю, по крайней мере, два мода, в котором она решена на автомате. Это мод (целая локация) "Подземная баня", и мод (тоже целая локация, русская локализация Вильи) "Алиса" (она может научить героя соотв. магическому заклинанию). В UI (новый интерфейс) можно поставить самораздевание и самоодевание - на горячую клавишу. То есть, можно было бы залезть в эти моды, и выдернуть оттуда текст готового скрипта. Но не, неохота возиться, не интересна сама идея. Сама идея меня не зажигает. Работает в чужих модах - и пусть работает, и не лезь.

С уважением.
Маг Иридий.
Myprism  Offline Сообщение №2852 написано: 05 Апреля 2020 в 15:47


Физик


1615
Multigone, Спасибо большое!
yakor77, обычно это делают ставя на бассейн триггер. Персонаж пересекает его границы - переодевается. Моя задача намного сложнее. Мне нужно чтобы любой персонаж (хотя бы любой из спутников) переодевался при любом плавании. И да, такие моды есть. Первый, который я давно знал, это Мелисса. Там бездна скриптов и квестов и он для меня слишком сложно устроен (всё же я не люблю скрипты, а к квестам у меня вообще отвращение :( ), всё же его механизм я понял, там это делается через магические эффекты. Есть ещё 2 - в одном ДЛЛ-ка и всего пара скриптов дез исходников - не годится, в другом через магические эффекты и довольно не сложно. Вот вместе с подсказкой Multigone, у меня уже много пищи для ума.

yakor77  Offline Сообщение №2853 написано: 06 Апреля 2020 в 15:30 | Отредактировано: Multigone - Вторник, 21 Апреля 2020, 22:28


Странник


26
Myprism, Мелиссу я тоже давно знаю, и тоже не люблю её тест-сон перед началом встречи. Вообще она сильно замороченная, капризная и ревнивая дама. Алиса - её урезанная версия. Но все они - клоны Вильи. Ладно, есть еще целый пул с раздеванием - это всё, что связано с СексЛаб, и сопутствующими модами. И есть пул модов, которые связаны с засыпанием и его анимацией, в некоторых выставляется условие спать в пижаме, или вообще нагишом. Помимо "Подземной бани", есть мод, модифицирующий поместья, и там тоже есть своя банька с раздеванием. Там же есть и туалет типа сортир, в котором можно присесть, и тоже приходится частично раздеваться. Есть мод "Магазин-ателье", его скрипт использован в Мелиссе - она застревает в магазинах готовой одежды, и быстро меряет всё, что там есть. Есть мод, раздевающий и одевающий манекены. Есть мод по быстрому собиранию лута с покойников, он тоже мгновенно их раздевает. Короче, задача имеет три части. Каузу - собственно скрипт раздевания или одевания, полного или частичного, своего или чужого, живого или мертвого, перса. Повод - тот самый триггер (граница бассейна, вход в парилку бани или в примерочную магазина, укладывание спать и просыпание, начало и завершение секса). И условие (магический эффект, или галочка в квадратике опции мода, или горячая эф-клавиша).

С уважением.
Маг Иридий.
Dsion  Offline Сообщение №2854 написано: 06 Апреля 2020 в 16:51



1285
Myprism, та чо там думать... Если мод уже привязан к SKSE, то тупо каждую секунду проверять. А если надо без SKSE, то да, через магический эффект и абилу с constanteffect:

Код
Event OnEffectStart(Actor akTarget, Actor akCaster)
    (akTarget as MyStateScript).OnSwimStart();
EndEvent

Event OnEffectFinish(Actor akTarget, Actor akCaster)
    (akTarget as MyStateScript).OnSwimStop();
EndEvent

Блин, администраторы форума уже два года кормят байками о переезде форума на новый движок, а код нормально вставить как нельзя было 5 лет назад, так и сейчас нельзя.

emelya8307  Offline Сообщение №2855 написано: 10 Апреля 2020 в 15:15 | Отредактировано: Multigone - Вторник, 21 Апреля 2020, 23:50


Странник


12
Здравствуйте! Многие сейчас пробуют играть в Скайрим без убийств, чтобы в статистике убийств были красивые нули. Но вот беда - есть некоторые заскриптованные квестовые персонажи, их не так много, которых может убить только ГГ. Приходится убивать, и в статистике появляеся убийство.
Родилась идея мода - некий алтарь, молясь перед которым ГГ мог бы "очистить свою совесть", то есть стереть из статистики вынужденное убийство.
В консоли есть для этого команда ModMiscStat "people killed" -1
А есть ли в Папирусе подобные команды? Может кто-то исследовал этот вопрос?
Например при обращении к алтарю проходит проверка на убийство персонажа, и если персонаж был из списка заскриптованных, то статистика убийства очищается, если персонаж обычный, не Protected, то нет.

Моральная сторона меня мало волнует. Все равно противников так или иначе приходится лишать жизни - будь то кастование на них бешенства, чтобы убили другие, сбрасывание их криком ФусРоДа с высоты, заманивание в ловушки, и т.д., главное, чтобы убийство не попало в статистику игрока. Чисто спортивный интерес.
Но есть некоторые персонажи, которых может убить только Главный Герой собственными руками, иначе квест будет не пройденным. Некоторые персы так заскриптованы, совершенно необоснованно, например Диджа в квесте "Туши свет!", или Энодий Папий в квестах Темного братства.
Или другой случай - Дюрневир в Каирне душ. Его убийство записывается на игрока, даже если игрок сидел курил в сторонке во время боя.
И потом этот Дюрневир оказывается жив-здоров, его можно даже призывать в Тамриэль, а убийство в статистике остается.
Поэтому и придумал такой способ с алтарем. Ну или еще как-нибудь красиво это обыграть. Чистить консолью не хочется, и оставлять так тоже.
Я в скриптах могу самое большее написать примитивный скрипт на включение выключение или на добавление предмета и всё.
Нашел функцию в скрипте Game

Function IncrementStat(string asStatName, int aiModAmount = 1) native global

Но даже воспользоваться ею правильно у меня не хватает ума. всё, что я ни пытался написать, даже не компилируется, потому что я асолютно не понимаю, что делаю. Темный лес. javascript://
Потому и спрашиваю.

Dsion, вот я написал крохотный тестовый скриптик, повешал на переключатель в Доме теплых ветров в качестве эксперимента. Скриптик работает, убирает статистику убитых существ (у меня там висело одно убийство Дюрневира)

Код
Event OnActivate (ObjectReference akActionRef)
   If GetPlayer() == akActionRef
      IncrementStat("creatures killed", -1)
      Debug.MessageBox("Твои грехи прощены")
   endif
endEvent


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

Dsion  Offline Сообщение №2856 написано: 10 Апреля 2020 в 22:43 | Отредактировано: Dsion - Пятница, 10 Апреля 2020, 22:45



1285
emelya8307, количество убитых - это ведь просто число. Никакой информации о том, кто именно убит, из него не выдоить. Если бы мне было нужно сделать именно то, что ты описал, то я бы заюзаз story manager и OnStoryKillActor.
Это позволит вызывать функцию каждый раз, когда игрок кого-то убивает. В функции проверяем, был ли убит один из "скриптовых" НИП (скорее всего, да, по формлисту). Если убит скриптовый НИП, то прибавляем единичку к какой-то переменной типа "количество_убитых_скриптовых_НИП". А алтарь потом отнимает от счетчика столько убийств, сколько указано в этой переменной. И сбрасывает переменную в ноль. Если всего убито 3, а скриптовых убито 2, то 1 останется на совести игрока.
Можно и без алтаря. Сразу отнимать 1, если убит скриптовый НИП.
Это всё, в общем-то, сделать легко, но для совсем новичка не очень легко. Я бы забил.

Если все-таки будешь делать, то первый шаг - это сделать квест, в нем скрипт с ивентом OnStoryKillActor и настроить SM (Story Manager), чтоб этот квест запускался при убийстве пофиг-кого и выводил сообщение.

emelya8307  Offline Сообщение №2857 написано: 11 Апреля 2020 в 04:00


Странник


12
Огромное спасибо за ответ. В принцепе стало понятно в общем, в каком направлении двигаться, но для моих познаний это реально трудно))) Может и забью, а может, на карантине делать нечего, и попробую что-то.
Щас на алиас Энодия Папия повешал скрипт на событие OnDeath, чтобы счетчик убийств щелкнул -1, в игре сработало, убийство не засчитали, но на каждого такого актера вешать скрипт тоже как то не очень.

Myprism  Offline Сообщение №2858 написано: 11 Апреля 2020 в 06:24


Физик


1615
emelya8307, Dsion, а может так: завести квест, сделать в нём алиасы на всех таких персонажей и уже на них повесить скрипты? Т.е. не на самих персонажей, а на их алиасы? Тогда персонаж вроде как не затронут непосредственно, а скрипт на нём висит :)

emelya8307  Offline Сообщение №2859 написано: 11 Апреля 2020 в 11:43


Странник


12
Myprism, так это и так квестовые персонажи, и они и так находятся в алиасе. и убивать их приходится по ходу квеста. Тот же Энодий появляется в игре только на время квеста "убить Энодия Папия"

Dsion  Offline Сообщение №2860 написано: 11 Апреля 2020 в 13:42



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

emelya8307  Offline Сообщение №2861 написано: 11 Апреля 2020 в 15:38


Странник


12
Я сейчас поковырялся в Creation Kit и подумал, что проще сделать esp плагин без всяких скриптов, где снять галочки Protected с алиасов этих персонажей в квестах. Попробовал на Гае Мароне, Дидже и Энодии - работает. Все же esp файл напрямую не затрагивает ваниль, мод делаю для себя, так что ну иво нафиг эти скрипты, я уже понял, что скриптер из меня никакой. Огромное спасибо за участие и помощь.

myav  Offline Сообщение №2862 написано: 13 Апреля 2020 в 10:23


Странник


30
Что-то тут вообще тихо стало...  Надеюсь что все - еще живы)

Помогите плз найти где я промазал логикой.

Есть нпс с оружием, и есть бутылка яда.  И я пытаюсь наложить яд на оружие.

Код
Potion property DamageHealth01 auto
Event OnCombatStateChanged(Actor akTarget, int aeCombatState)        
if (aeCombatState == 1)            
    Utility.Wait(1.5)               
        if (selfactor.GetEquippedItemType(1) < 7 && selfactor.GetEquippedItemType(1) != 0)
            debug.notification("try to apply poison")                    
            form MyPoison = DamageHealth01 as Form                    
           selfactor.EquipItem(MyPoison, false, true)            
        endif        
endif        
EndEvent


но...

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

Помогите идеей как заставить нпс это сделать?

emelya8307  Offline Сообщение №2863 написано: 13 Апреля 2020 в 17:52 | Отредактировано: emelya8307 - Понедельник, 13 Апреля 2020, 17:53


Странник


12
Dsion
Фух, возился долго, но сделал по твоему совету квест, запускающийся ивентом OnStoryKillActor, написал Скрипт (на пределе своих умственных возможностей), который при убийстве актера выводит сообщение "вы убили человека" либо "вы убили животное", по кейворду определяет, что в алиас жертвы попало. По началу срабатывал через раз, либо вообще переставал срабатывать. Потом сделал алиас на игрока, указал его как киллера, и все поехало как по маслу. Но я рано радовался, потому что идея с форм-листом не проходит. Потому что если заносить жертву в формлист, то при загрузке более раннего сохранения, получится ерунда.
Надо брать данные именно из сохранения.
Я могу менять статистику функцией IncrementStat, но я не знаю, какой функцией добыть MiscStat из игры.

Dsion  Offline Сообщение №2864 написано: 13 Апреля 2020 в 18:14



1285
emelya8307,  хм, не очень понимаю, какие могут возникнуть проблемы с формлистом... В формлист из СК добавляешь нужных акторов (базовых). А в ивенте OnStoryKillActor(ObjectReference akVictim, ObjectReference akKiller, Location akLocation, int aiCrimeStatus, int aiRelationshipRank) потом нужно проверить:
1. Чтоб akKiller был игрок (Game.GetPlayer())
2. Чтоб akVictim был в списке допустимых жертв. Как-то типа myList.HasForm(akVictim.GetBaseObject())

И в конце функции может еще быть нужно остановить квест командой Stop()

emelya8307  Offline Сообщение №2865 написано: 13 Апреля 2020 в 20:58


Странник


12
Dsion, это я понял. Такой способ будет работать, если очищать статистику прямо на месте убийства. А с задумкой типа алтаря уже не получится. Особенно если жертва не одна, а две или три. Эти данные где хранить? Если в каком то форм листе, то если задумаешь загрузить более раннее сохранение и переиграть по другому, а в формлисте уже 2 жертвы. Или я чего-то не понимаю?

Вообще очень интересно, особенно когда что-то начинает получаться. Да, я допер вчера, что нужно после функции писать команду Stop()

Dsion  Offline Сообщение №2866 написано: 13 Апреля 2020 в 21:21



1285
Цитата emelya8307 ()
Эти данные где хранить?

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

emelya8307  Offline Сообщение №2867 написано: 14 Апреля 2020 в 00:06 | Отредактировано: Multigone - Вторник, 21 Апреля 2020, 22:23


Странник


12
Dsion,

Нашел функцию int Function QueryStat(string asStat) native global

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

yakor77  Offline Сообщение №2868 написано: 15 Апреля 2020 в 00:09 | Отредактировано: Multigone - Среда, 22 Апреля 2020, 16:32


Странник


26
myav, очень часто мешает необходимость подтверждения нанесения яда вручную. В случае с нанесением яда - есть мод, которое это надоедливое подтверждение убирает.
nexusmods . com / skyrim / mods / 33916/

Есть мод, который автоматически наносит яд на оружие, пока он неисчерпается в запасах. Но там надо подтверждать вручную.
tes-game . ru / load / skyrim / gejmplej / 7640 / 47-1-0-9692

Есть мод на изменение количества ударов ядом, тут устранен эффект подверждения.
tesall . ru / files / file / 9078-otravlenie-orujiya /
gamer-mods . ru / load / skyrim_se / gejmplej / kela_poison_project / 158-1-0-7630

Наконец, есть мод на постоянный яд, наносишь только один раз, и навсегда.
mod-all . clan . su / load / skyrim / raznoe / neogranichennoe_dejstvie_jada / 15-1-0-129

Об иных способах нанесения уроня ядом (кольчуга, щупальца, посох магнуса, ядовитые пауки, ядовитые руны, и пр.):
tiarum . com / wiki / Skyrim : %D0%A3%D1%80%D0%BE%D0%BD_%D1%8F%D0%B4%D0%BE%D0%BC

Экзотика: мод создает яд для ловли душ
all-mods . ru / skyrim / raznoe-skyrim / skyrim-yad-lovli-dushi /

Короче на любой вкус. Разбирайтесь, пользуйтесь.

С уважением.
Маг Иридий.
myav  Offline Сообщение №2869 написано: 15 Апреля 2020 в 11:40 | Отредактировано: Multigone - Вторник, 21 Апреля 2020, 23:46


Странник


30
Мой осмотр модов (с ссылок):

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

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

Код
_selfRef.EquipItem(_foodDummyRestoreHealth as form, false, true)

а если зелье не дает себя выпить))) то радикальный обход:

Код

  _selfRef.RemoveItem(_foodEffectRestoreHealth [indexArray]as form, countItem, true, none)
                    _selfRef.RestoreActorValue("Health", (_multFoodEffectRestoreHealth [indexArray]* countItem) as Float)


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

Теоретически - можно создать "кустом" оружие (сразу с ядом) и удалять обычное оружие/добавлять ядовитые на место (я так делал с ледяными топорами для драугов).  Но оружия в скайриме - много, и моды на оружие - еще больше множат вплоть до гор (особенно immersive weapons).  Метод (удалить обычное, добавить ядовитое) плох, так как большой шанс, что он не обхватит кустом оружие. Правильно будет - именно заставить НПС использовать бутылку.

Dsion  Offline Сообщение №2870 написано: 15 Апреля 2020 в 12:31



1285
myav, та чо там искать-то...

Сначала (на всякий случай) трижды перепроверяем, что equipitem() действительно не работает (не заставляет НИП применить яд). Для этого - максимально упростить скрипт, убрав всё сомнительное. Тот кусочек, что ты выложил, я проверить не могу т.к. это не полный скрипт. Можно временно заменить equipitem() на additem() и проверить, добавляется ли предмет в инвентарь именно НИП. Если additem() работает, а equipitem() - нет, то придется принять то, что equipitem() нам не походит.

Если equipitem() не работает и SKSE не доступно, то лично я другого способа заставить НИП применить зелье не знаю. Значит, нужно реализовывать яды иначе. Например, есть entry point у перка что-то типа "apply hit spell". Если выдать его НИП, то каждый раз при ударе оружием они будут накладывать на противника указанный маг. эффект. А в эффекте уже можно что-угодно делать. Например, удалять из инвентаря бутылку с ядром и наносить дополнительный урон.
Так же есть тип магического эффекта что-то типа "enhance weapon" - временное зачарование для оружия. Сам я его не юзал, но на вики написано, что работает. Эти варианты точно будут работать, но не смогут копировать эффекты, их силу и длительность именно с кастомных бутылочек, созданных игроком.

А если охота все-таки, чтоб эффекты яда в точности повторяли эффекты бутылочки, то в SKSE, вроде как, есть необходимые функии, но я их не юзал. Надо тестить, работают ли они и работают ли с кастомными ядами.

Добавлено (15 Апреля 2020, 12:38)
---------------------------------------------
Если equipitem() не работает с ядами для НИП, но работает для игрока, то можно еще попробовать временно передавать оружие игроку. Если яд работает только на один удар, то это будет бред полный. Но если (с помощью перка) переделать яды, чтоб он работал хоть на 50 ударов, то может иметь смысл. Хотя тут тоже свои проблемы: если передавать оружие скриптом, то может передаться не то, что нужно.


yakor77  Offline Сообщение №2871 написано: 15 Апреля 2020 в 16:08 | Отредактировано: Multigone - Вторник, 21 Апреля 2020, 22:05


Странник


26
Цитата myav ()
так как нету ванильного оружия с ядом, чтобы можно было просто удалить меч, и добавить меч с ядом, как он прописал на хил бутылки
Так вот, это не точно. Ранее я давал Вам подсказку, цитирую: "Об иных способах нанесения уроня ядом (кольчуга, щупальца, посох магнуса, ядовитые пауки, ядовитые руны, и пр.)": ссылка. Очень рекомендую прочесть эту статью, и обратить внимание на перечисленное.
Теперь по поводу консоли. Да, консольной команды именно по нанесению именно яда - нет. Да, эквипмент тут - не работает. Но есть консольные команды по зачарованию оружия. Не на пентаграмме душ. Следовательно, общий алгоритм такой: 1) узнать набор эффектов, который присущ данному яду в данной бутылочке 2) удалить бутылочку из инвентаря 3) применить данный конкретный набор параметров от яда - к зачарованию оружия. (Ограничение на два зачарования - легко снимается. Есть куча модов, которая позволяет нанести на одно оружие до 10 разных зачарований.)
Зачарование предметов и оружия. Для зачарования используйте команду: PlayerEnchantObject [id предмета] [id зачарования №1] [id зачарования №2]. Предмет или оружие должно быть без улучшений, а навык зачарования желательно равен 100. Каждый предмет может принять только два зачарования! Далее ниже список всех ID зачарований.
(список легко ищется по Инету, например, здесь: ссылка.

С уважением.
Маг Иридий.
Dsion  Offline Сообщение №2872 написано: 15 Апреля 2020 в 18:04 | Отредактировано: Multigone - Вторник, 21 Апреля 2020, 22:22



1285
Ты же знаешь, что из ванильного папируса нельзя вызывать консольные команды, да? Лично я могу сделать плагин для skse, но это не считается.
И зачаровать оружие из папируса тоже нельзя. Хотя я мог что-то и забыть. Не стесняйся назвать функцию, если я о ней забыл.
О, да и получить список эффектов с бутылочки без SKSE нельзя...
Ну вот и ответь (самому себе): были ли твои "подсказки по концепту" полезными. Или человек только зря потратит время, пытаясь им следовать.

Я-то, если что, могу поставить 1000$ против 15$, что через "enhance weapon" или "apply hit spell" реализовать яд можно. Есть ограничения, но о них я предупредил...

emelya8307  Offline Сообщение №2873 написано: 17 Апреля 2020 в 00:34 | Отредактировано: Multigone - Вторник, 21 Апреля 2020, 21:56


Странник


12
Dsion, еще один вопрос можно? Вот я создал квест, запускающийся при убийстве актера. Написал скрипт (ух как долго бился)При убийстве выходит сообщение "Вы убили человека" или "Вы убили животное" или "Вы убили нежить". Проверяется по кейворду ActorType... скриптовых персонажей забил в формлист и они отправляются в GlobalVariable, вобщем всё работает))
Но блин, убийство КУРИЦЫ не высвечивается на экране, хотя в статистику попадает, как убийство животного. У курицы Кейворд ActorTypeAnimal , как и у остальных животных. Не подскажешь тупому, почему не появляется сообщение?
(Эти сообщения мне необходимы, чтобы вовремя заметить убийство, так как я играю прохождение без убийств).

Myprism  Offline Сообщение №2874 написано: 17 Апреля 2020 в 05:48 | Отредактировано: Multigone - Вторник, 21 Апреля 2020, 21:55


Физик


1615
To all В Скайриме есть возможность локализовать моды, вынося строковые переменные в стринговые файлы (по 3 на каждый мод и на каждый язык). Собственно говоря, так сам Скайрим и устроен. Моды с вынесенными стрингами легко локализовать. Достаточно перевести на любой язык только стринговые файлы, не трогая сам мод. Если положить в архив стринговые файлы для многих языков, то мод автоматически становится мультиязычным.
А вопрос у меня в том, как выносить в стринговые файлы сообщения из скриптов, чтобы можно было локализовать их в общем процессе?

Dsion  Offline Сообщение №2875 написано: 17 Апреля 2020 в 12:09



1285
Myprism, если говорить о ванильных скриптах, то они должны выводить сообщения только через Message, которые и локализуются. А Debug.* - только для отладки. Но ты об SKSE, да?

Myprism  Offline Сообщение №2876 написано: 17 Апреля 2020 в 12:59


Физик


1615
Dsion, нет, я о скриптах зарубежных мододелов. Они ведь не знают проблем с локализацией. Просто я сейчас копаюсь в моде на спутников Amazing Follower Tweaks. Довольно сложный мод. Он переведён на русский язык. Но переводчик жалуется на то, что некоторые вещи в скриптах не может перевести, так как они тогда теряют работоспособность. Всё, что находится в Message, прекрасно выносится в стринги и они прекрасно переводятся, это я уже проверил. Видимо там есть что-то что сделано иначе и что я пока ещё не откопал.

Multigone  Offline Сообщение №2877 написано: 17 Апреля 2020 в 13:33



648
Myprism, значит, там есть Property-переменные String, которые не только выводятся в Debug.Notification(), MCM ShowMessage(), MCM SetInfoText(), MCM-название-опций или что-то подобное, но и участвуют в проверках или каких-то операциях. Например, такое в качестве иллюстрации и грубого примера:


Код
String Property MyArmorPart = "Cuirass" Auto

EVENT OnPageReset(String sP)
    AddHeaderOption(MyArmorPart) ; Добавить заголовок МСМ - нужен перевод "Cuirass" как "Нагрудник"
ENDEVENT

FUNCTION MyFun(String sPart)
    IF sPart == "Cuirass"
        ; Это не будет работать, если где-то вызывается MyFun(MyArmorPart) и при этом "Cuirass" переведено как "Нагрудник"

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

風たちぬ今和歌春神髪
Dsion  Offline Сообщение №2878 написано: 17 Апреля 2020 в 15:09 | Отредактировано: Dsion - Пятница, 17 Апреля 2020, 15:12



1285
Я считаю, что лучше не иметь в коде скрипта строки, которые выводятся игроку.

1. Если скрипт ванильный (без skse или mcm), то используем Message. Тут больше нечего добавить.

2. Если скрипт на skse и mcm, то... я в этом не шарю. Но прописывать значение проперти в коде скрипта - все-равно не вариант. Пример Multigone надо исправить, как минимум, вот так:

Код
String Property MyArmorPart Auto
...
If (sPart == MyArmorPart)

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

3. Если скрипт на skse и mcm, но описанные условия не соблюдаются, то можно создать какой-то предмет для каждой строки и использовать GetName().

Код
Armor Property MyArmorPart Auto
...
AddHeaderOption(MyArmorPart.GetName())
...
Костыль, конечно, жуткий. Но тогда строки, используемые в скриптах, будут переводиться через strings файлы.

4. Если все-таки обязательно надо прописывать текст именно в скрипте, то можно хоть вынести их в отдельный файл, чтоб локализаторам было легче:
Код
AddHeaderOption(MyLocalizedStrings.CuirassString()) ; CuirassString() - глобальная функция на отдельном скрипте MyLocalizedStrings
AddHeaderOption(MyLocalizedStringsInstance.CuirassString) ; MyLocalizedStringsInstance - инстанс скрипта MyLocalizedStrings, CuirassString - проперти на нем.

Или вообще полная дичь (не рекомендовано):

Код
AddHeaderOption(MyLocalizer.tr("Cuirass"));
А в MyLocalizer глобальная функция такого типа:

Код
string function tr(string s) global
    if (s == "Cuirass") return "Кираса" endif
endfunction
итд.
Похожий способ (на последний) используется в Qt(C++). Только там map, конечно, а не куча if блоков.

Multigone  Offline Сообщение №2879 написано: 17 Апреля 2020 в 16:04 | Отредактировано: Multigone - Пятница, 17 Апреля 2020, 16:59



648
Dsion, я не советовал делать так). Просто представил ситуацию, когда перевод сломает работоспособность скрипта (как и описывал Myprism.)

Цитата Dsion ()
Это при условии, что строковые проперти можно заполнять извне (как другие виды проперти) и при условии, что для них работает оператор == (я этого не проверял). И еще при условии, что локализация проперти не помешает работе оператора ==.
Заполнять можно, оператор работает, локализация помешает (т.е., как если бы мы вместо (Int Property iN = 2 Auto) поменяли в СК Property значение на 3, естественно, у нас бы не выполнялось условие iN == 2; если в String поменять хоть один знак, исключая тот же самый знак в другом регистре, то это будет уже другое значение переменной / другой литерал; в общем, ты и так это знаешь).

Еще что хотел сказать (то же самое, что и Dsion): при правильном построении мода (для локализации), неважно, где будут собраны String Property переменные, подлежащие переводу, в одном ли скрипте или размазаны равномерно по всему моду (естественно, удобней, чтобы в одном). Главное, чтобы с ними не совершались проверки вида (MyArmorPart == "Cuirass") и операции (например, какая-то переменная, важная для работы мода, не собирала свое значение путем String sMatter = "Armor" + MyArmorPart (англ. получится sMatter = "ArmorCuirass", а локализованная - "ArmorНагрудник")).

А, вот еще что требует пояснения:
Цитата Dsion ()
Но прописывать значение проперти в коде скрипта - все-равно не вариант.

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

風たちぬ今和歌春神髪
Myprism  Offline Сообщение №2880 написано: 17 Апреля 2020 в 17:42


Физик


1615
Multigone, Dsion, всё понял. Локализуемых строк в скрипте быть не должно. Английские - сколько угодно, но не выводить их пользователю.
В общем то не гоже лазить по всем скриптам (в моём случае, их несколько десятков), чтобы искать, что там можно безопасно перевести.
Я почему занялся этим модом. Я же раньше спрашивал, как сделать переодевание, когда персонаж залезает в воду. Вот ГГ я это сделал (заодно и переодевание дома и в городе), но правильно сделать это и для компаньонов. Но тогда надо модифицировать управление ими. Но если я что-то в этом направлении сделаю, то сразу же получу несовместимость как минимум с тремя популярными модами на компаньонов. Да и работа делать такое (хороший мод на управление компаньонами) с нуля - очень велика. Вот и выбрал я тот мод, автор которого не возражает против модификаций, а его продукт вызывает наименьшее количество нареканий у пользователей. Вот сюда всё и встраиваю. А чем больше разбираюсь, тем больше он мне нравится. Приятно смотреть на хорошо выполненную работу.
Вот только первый раз такое вижу у него
Код
if (0 == MyInt)...
:) как думаете откуда ноги растут у такой манеры записи, когда константа стоит слева?

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