Я правильно тебя понял, что для полного исправления навмешей в талморском посольстве у меня есть только один выход: полное удаление их и создание заново?
Схватил рефинализацию - плохо, тогда читай ту инструкцию по лечению этой проблемы. К сожалению, ничем другим вылечить не получается, только полное удаление всех навмешей и откат до дефолта (иначе рефинализацию не снять), а дальше исправление дефолтных багов и только после этого добавление своих нужных навмешей.
*********** valambar, анимацию можно и в Нифскопе перекрутить, но вот добавить в игру свою новую анимацию уже проблема, придётся использовать FNIS не только модмейкеру, но и игроку тоже (не всем, но очень многим).
С перками... вот что-то я не припомню модов со своими новыми собственными ветками, все их только перекручивают/изменяют. Сам же я никогда не пытался такого делать, вот и не знаю.
Я имел ввиду изменить значение переменной Target процедуры Activate из ActivateSpecialFurniture.
Так именно это я уже два раза тебе писал: Пакет делается собственностью твоего квеста, тогда в нём можно будет в качестве цели использовать алиас из твоего квеста. Вот этот алиас ты можешь менять/переназначать хоть каждую минуту и каждый раз целю этого пакета будет новый референс, который ты назначаешь на этот алиас. Это и есть менять Target в процедуре.
Вот сам твой пакет имеет процедуру активации, вот НПС и активирует с анимацией "сесть". А тебе надо процедура "сидеть", тогда и при загрузки эта процедура уже сразу загрузит сидящего НПС. Можно вместо Activate дать пакет Sit, или собрать свой пакет на основе Sit.
AleksTirex, да с квестом я уже понял концепцию. Я спрашивал нельзя ли это менять если пакет не к квесту привязан а к НПС?
Так назначь алиасу №1 твоего НПС, а на этом алиасе пакет с динамической целью - алиаас №2. Менять как либо параметры пакета, кроме как изменение параметров алиаса, никак.
Единственно, что можно сделать, так в пакете кучу процедур со своей целью и с условием на срабатывание, тогда в зависимости от условия будет срабатывать нужная процедура и нужная цель. Но в этом случае всё равно придётся заранее прописывать сами цели, они должны быть заранее известны и назначены в пакете.
Дело в том, что при отбирании кольца у персонажа, он одевает несколько шмоток в свой оутфит и они на самом деле из инвентаря пропадают, а вот из меню - нет. При наведении на них мышки - вылет.
Так попробуй сделать другой алгоритм/последовательность. Например, удаляй шмотки после закрытия инвентаря, а не в режиме меню и отбирания кольца. В принципе, если происходят вылеты, то желательно всегда менять сам принцип действий, иначе вылеты могут быть у игроков, даже если у тебя их уже и не стало (я сталкивался с подобными явлениями).
Myprism, оутфит не виден в инвентаре, почему у тебя эти шмотки видны? Если менять оутфит на актёре, то старые шмотки "проявляются" в инвентаре, а если менять на базовом актёре, то старых шмоток не будет видно.
Так же можно сделать "не игровыми" эти шмотки из оутфита, тогда ГГ ни в каком варианте их не увидит в инвентаре. Ищи сперва простые варианты.
Если менять оутфит на актёре, то старые шмотки "проявляются" в инвентаре, а если менять на базовом актёре, то старых шмоток не будет видно.
***********************
Можно менять оутфит после закрытия инвентаря, попробуй. После команды открытия инвентаря напиши команду Utility.Wait(1), и всё, что после неё, сработает только после закрытия инвентаря, вот тогда и меняй оутфит.
auto state defaultState Event OnUnequipped(Actor akActor) gotoState("waitState") Utility.Wait(0.5) if !akActor.IsEquipped(self) akActor.SetOutfit(kOutfit) endif gotoState("defaultState") endEvent endState
state waitState ; endState
(статус нужен для исключения "дребезга", т.е. от режима снял-одел-снял-одел) При первом же снятии кольца срабатывает событие и заканчивается только после закрытия инвентаря. (повторное событие не сработает, т.к. статус не позволит)
Добавлено (28 Ноября 2013, 20:37) --------------------------------------------- Вот только вместо self надо ID кольца, т.к. в контейнере это ID не получить через self (там написано чисто для примера).
auto state defaultState Event OnUnequipped(Actor akActor) gotoState("waitState") Utility.Wait(0.5) if !akActor.IsEquipped(akKolco) akActor.SetOutfit(kOutfit) endif gotoState("defaultState") endEvent endState
state waitState ; endState
Свойству akKolco назначаешь своё кольцо.
gotoState("waitState") - это поменять статус defaultState на waitState. И пока у скрипта статус waitState, то события могут срабатывать только внутри этого статуса. Событие на снятие предмета находится в другом статусе, поэтому оно не может сработать. Как первое событие снятия кольца сработало, переключается статус и последующие снять-одеть кольцо уже не будут срабатывать, пока в скрипте не установится статус defaultState. При срабатывании события срабатывают команды, команда Wait() начинается, но закончится только в режиме "не меню", т.е. после закрытия инвентаря. Далее проверка "если кольцо не одето" тогда смена оутфит, если одето, то ничего не происходит. Статус меняется после этого на defaultState.
********** Всё прекрасно работает, проверил.
Добавлено (28 Ноября 2013, 23:37) ---------------------------------------------
Цитата Myprism
Но я не понимаю и синтаксиса кода: gotoState("waitState") , наверное, переход на state waitState, а тогда там и не должно ничего выполняться.
Должно! Если функция или событие уже начали выполняться, то уже без разницы статус и всё остальное, они будут исполнятся до полного завершения/отработки всех команд. Так одно событие может длиться хоть пол года, пока не отработает последняя команда. Этот принцип очень часто вызывает баги модов, и даже если мод отключить, то незавершённые скрипты продолжат работать до полного завершения. Поэтому циклы, ожидания и OnUpdate() надо очень осторожно использовать.
Этот же принцип вызывает иногда вылеты на стол при перезагрузки сохранений (когда без перезапуска всей игры).
Изменение репутации для пользователя AleksTirex
AleksTirexOffline
Сообщение №249
| Тема: Вопросы по скриптам Papyrus
написано: 2 декабря 2013, 20:03
| Отредактировано: AleksTirex - 2 декабря 2013, 20:17
Int SetNum = ListTopItem.GetSize() If TopEquipped While (SetNum >0) SetNum -= 1 If TargetActor.IsEquipped(ListTopItem.GetAt(SetNum )) Return SetNum EndIf SetNum -= 1 EndWhile
В списках нумерация начинается с нуля "0", поэтому длина списка всегда больше на 1, чем последний номер списка. В твоём варианте проверяется несуществующий номер списка, а вот первый нулевой предмет вообще не проверяется. Поэтому SetNum -= 1 надо ставить перед командой GetAt().
Немного не понятно, зачем делать проверки "Если одето...", когда можно гораздо проще сделать - сразу одевать трусы при снятии юбки. Если я правильно понял, то надо вместо снятой шмотки с №кейвордом одеть другую шмотку? Тогда так:
Scriptname LB_NoNude extends activemagiceffect
Keyword Property KeywordTopItem Auto Keyword Property KeywordBottomItem Auto FormList Property ListTopItem Auto FormList Property ListBottomItem Auto Bool TopEquipped Bool BottomEquipped
auto state DefaultState Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer) Actor TargetActor = Self.GetTargetActor() if akBaseItem as Armor if akBaseItem.HasKeyword(KeywordTopItem) TargetActor.EquipItem(ListTopItem.GetAt(Utility.RandomInt(0, ListTopItem.GetSize() - 1)) as armor, true) TopEquipped = true endif if akBaseItem.HasKeyword(KeywordBottomItem) TargetActor.EquipItem(ListBottomItem.GetAt(Utility.RandomInt(0, ListBottomItem.GetSize() - 1)) as armor, true) BottomEquipped = true endif endif if TopEquipped && BottomEquipped gotoState("DoneState") endif EndEvent EndState
state DoneState ; endState
*****************
Но и... а не проще ли было сделать свой "одетый" скин для НПС, ведь они все твои и твоей расы, и скрипт тогда вообще не нужен.
***************** ***************** Вместо события удаления лучше использовать событие снятия - OnObjectUnequipped(), это будет корректнее работать.
И не удивительно, такой команды нет. Есть команда Cast. akSpell.Cast(akCaster, akTarget)
akCaster - кто кастует akTarget - на кого кастуют (цель) akSpell - заклинание
При этой команде добавлять заклинание не обязательно, оно добавится само автоматически.
(!Game.GetPlayer().HasSpell(VampDetectLife)) - это проверка наличия данного заклинания у игрока (если нужна проверка на "воздейстие заклинания на ГГ", то команда должна быть другой). Все проверки делаются через If/elseIf/endIf if !Game.GetPlayer().HasSpell(VampDetectLife) VampDetectLife.Cast(Game.GetPlayer(), Game.GetPlayer()) endif
AleksTirex, не сталкивался с таким вопросом: Если добавить в Magic Effect источник света, при касте почему то игнорируется Flicker Effect?
Как-то такое даже не замечал. Возможно, что так оно и есть, но и... мне кажется (или не кажется), что "Свет свечи" и подобные "светящиеся шарики" не совсем равномерно светят, а как бы мерцают (но может, мне это только кажется). Как будет время, посмотрю в игре на этот эффект.
Да, я понимаю, что это SKSE и кагбэ не против его использовать... но как заставить ЭТО работать?
Кстати, стиль боя можно менять и без SKSE - пакетами. Даёшь своему алиасу три одинаковых пакета, но с разными условиями и у каждого пакета назначаешь свой стиль боя. А дальше уже понятно, что делать.
Две функции RegisterForUpdate(08.00) и OnUpdate(12) выдают ошибку. Я так понял первая включает предмет в заданное время, а вторая поддерживает указанное количество часов?
Добавлено (06 Декабря 2013, 23:59) --------------------------------------------- nine-dragon-art, SKSE - расширитель скриптового языка Папирус. Он добавляет свои функции/команды/события. ScriptDragon я не пользовался, да и не вижу сейчас модов с ним, т.е. он не получил развитие.
может ли любой кто зайдет в триггер вызвать действие скрипта? Или нужно подправить скрипт?
Скрипт поправлять не надо, ведь он по определению срабатывает только на актёров. Это прописано в самом триггер-боксе на объекте по умолчанию. Там же сменить принцип срабатывания бокса триггера.
Если речь идёт о срабатывании на НПС, т.е. на человека, а не на любого актёра (мышь, драугр и т.д.), тогда надо вводить условия, но уже не (akActionRef as Actor),а akActionRef.HasKeyword(ActorTypeNPC).
а можно как-то рекурсивно добавить весь FormList и так же рекурсивно его удалить?
Можно:
int iIndex = ListSpell.GetSize() While(iIndex > 0) iIndex -= 1 akActor.RemoveSpell(ListSpell.GetAt(iIndex) as Spell) endWhile
Естественно, если надо добавлять заклинания, тогда команда AddSpell, если не заклинания, а перки, тогда AddPerk, и т.д. Можно любое количество заклинаний так добавлять/удалять.
Добавлено (07 Декабря 2013, 16:15) --------------------------------------------- DarkVetal, всё зависит от конкретной ситуации. Одного общего универсального решения почти нет (оно есть, но не удобное). В каждом случае желательно делать свой метод, заточенный под данную ситуацию и необходимые действия.
Сам принцип "универсального" метода: при попадании ГГ в локацию срабатывает событие, например, OnCellAttach(). В нём проверяется текущее время, вычисляется необходимое время ожидания до старта цикла на включение/выключение чего-либо. Потом это время выжидается событием OnUpdate() и по его срабатыванию запускается цикл на вкл/выкл. Если ГГ зашёл когда уже должен работать цикл, то вычисляется время до первой смены цикла, сам цикл запускается на это время и по его окончании запускается этот цикл уже со своими параметрами. Этим ты синхронизировал игровое время и свой цикл. Если цикл не постоянный, а может меняться, то нужно вводить и эти расчёты тоже.
(попробуй сам написать этот скрипт по этому алгоритму, это не так сложно, как кажется)
Уважаемые, можно ли сделать так, чтобы после разговора с нпс, показывалось содержимое сундука, но как содержимое сумки этого нпс? (то бишь, как торговля, но без ценников).
Сделай сундук и поставь его в игрой мир. Дай название не "сундук", а имя этого НПС. В результирующем скрипте диалога напиши akObject.Activate(Game.GetPlayer()) где akObject назначаешь свой сундук.
DarkVetal, на любой постоянный и невыключаемый объект в центре локации (например, камень или столб) вешается скрипт:
ObjectReference Property akObject Auto GlobalVariable Property GameHour Auto float fTimeStart = 20.00 ; время старта, когда фонари должны включиться float fTimeStop = 6.00 ; время финиша, когда фонари должны выключиться float fTimeWait
Где akObject назначается свой основной объект (маркер или нечто подобное), а все остальные объекты для выключения подвязываются к этому объекту через Enable Parent (все остальные фонари-лампы).
fTimeStart и fTimeStop - время включения и выключения фонарей. Это уже сам в скрипте поставишь нужные значения, сейчас в 20.00 включаются, а в 6.00 утра выключаются.
При входе в локацию (при её загрузки) проверяется время, и по результатам фонари включаются или выключаются. Там же рассчитывается время для ближайшего переключения фонарей и запускается режим ожидания до этого переключения. Когда наступит нужное время, фонари переключатся, рассчитается время для следующего переключения, и опять запустится режим ожидания. При выходе из локации все фонари выключаются и сбрасывается режим ожидания. И дальше опять при входе в локацию... и так каждый раз. Пока ГГ в той локации, режим ожидания сам будет включать и отключать фонари.
как назначить нужный предмет на akObject? И кроме фонарей можно же прицепить любой предмет?
Рядом со скриптом, есть кнопочка Properties, нажимаешь её, выделяешь своё свойство akObject и Edit Value, дальше как и везде - мишенью тыркаешь по своему объекту в окне мира. ОК.
Назначать akObject можно любой постоянный объект, а уже к нему привязывать можно хоть тысячу любых других объектов. Изначально галочек "выключен" ставить нигде не надо, скрипт сам сделает нужное действие.
все пытаюсь добавить скрипт - вылетает редактор, что на лестницу вешал, что на хединг маркер, одинаково вылетает при нажатии кнопки ОК (добавить новый скрипт)
После нажатия Add появится окно с выбором скриптов, выделяешь первую строку NewScript и ОК. Появится окно, там надо вписать своё название скрипта (и если нужно, поменять тип). В окне объекта появится скрипт. Далее правой кнопкой по нему Edit Source, откроется редактор скрипта. Туда и надо прописывать сам текст скрипта.
Если ты делаешь так и СК вылетает, то он битый, и надо его "чинить". Как именно... просто удали и установи с нуля.
Это не понял, что такое "2 столбца"? Это 2 скрипта на один объект или что-то другое?
Если надо сделать новый скрипт и добавить к объекту, то можно делать/создавать скрипт на любом объекте, потом удалить этот скрипт с этого объекта, сам же файл скрипта останется в папке, и потом этот скрипт просто назначить на свой нужный объект.
Я вообще не представляю как можно нормально работать со скриптами в том убожестве, что встроено в СК.
Например я, всё пишу в строннем редакторе (Notepad++ с поддержкой языка Папирус, очень удобно, когда есть подсветка), а в родной редактор только вставляю готовый текст скрипта и компилирую.
*************************
DarkVetal, странно, я такой эффект ни разу не встречал, и даже не слышал о таком от других людей. Тебе просто "повезло", наверное. Как с этим бороться не знаю.
Это да, так удобнее компилировать, НО, при компиляции через родной редактор меньше шансов, что забудешь инициализировать свойства, т.к. всё равно открываешь нужный объект, а там и скрипт сразу вставляешь, и свойства назначаешь. А при компиляции через нотепад всё равно надо лезть туда же и делать тоже самое. Но это уже кто к чему привык.
Изменение репутации для пользователя AleksTirex
AleksTirexOffline
Сообщение №266
| Тема: Вопросы по скриптам Papyrus
написано: 13 декабря 2013, 15:53
| Отредактировано: AleksTirex - 13 декабря 2013, 22:00
DarkVetal, вот интересно, а как скрипт узнаёт текущее время в игре, не задумался над этим?
Всем читающим эту тему: в названиях функций/команд/событий/свойств ВСЕГДА присутствует подсказка, что именно это "слово" обозначает. Например, Game Hour в переводе на русский язык - "игровое время", т.е. "сколько сейчас времени в Скайриме". Вот это и есть то, как именно скрипт узнаёт текущее время, и если на это свойство не назначен нужный ID, то скрипт не имеет понятия, сколько времени в Скайриме, и естественно, ничего работать не будет.
Надо назначить нужный ID этому свойству.
*********** Тип скрипта правильно написал.
Изменение репутации для пользователя AleksTirex
AleksTirexOffline
Сообщение №267
| Тема: Вопросы по скриптам Papyrus
написано: 13 декабря 2013, 17:21
| Отредактировано: AleksTirex - 13 декабря 2013, 21:59
а разве в редакторе есть такое понятие "время", то есть в игре оно присутствует, в редакторе есть ползунок, отвечающий за перемотку времени,но это нематериальный обьект,в отличие от предметов, как же узнать его id?
А как же, конечно есть. Хоть время и не материально, но циферки то... вполне материальны. Game Hour - это глобальная переменная, которая заполняется движком, и в ней записано текущее игровое время на момент вызова этой функции.
Всем, кто читает эту тему: при заполнении свойств, сперва нажмите кнопку автозаполнения Auto-Fill, и тогда все свойства, которые называются также как и ID, сами заполнятся, а остальные свойства придётся заполнять как обычно вручную.
DarkVetal, нажми на эту кнопку, и свойство само заполнится.
есть такой крик "Бесплотность", в нём сказано, что ни вы, ни вам во время его действия нельзя нанести урон. Попробуй поправить его скрипт в нужную тебе сторону.
Этот крик делает ГГ "Ghost", т.е. неуязвимым для оружия и магии, но коллизия всё равно остаётся - ГГ не может пройти сквозь стену или другого НПС. Коллизию НПС можно отключить: убив НПС, глобальной функцией отключающей всю коллизию в игре Debug.ToggleCollisions(), и привязкой НПС к объекту функцией akActor.SetVehicle(akObject).
У всех этих способов есть свои "недостатки". Убивать - не вариант. Глобально отключать ВСЮ коллизию - это имитация TCL, а результат такого вы сами представляете. Привязывать НПС к маркеру/объекту - это только на ГГ хорошо работает, он может ходить сквозь стены и т.д., т.е. коллизия снимается только с ГГ, а все остальные объекты/НПС живут полноценной жизнью. Но если привязать НПС, то он не сможет самостоятельно ходить, а будет всё время находится у этого маркера и впустую перебирать ногами, типа идёт, но с места не сдвинется.
В принципе, можно визуально "обмануть" движок и игрока, но это довольно сложный наворот. Для этого можно использовать TranslateTo()для перемещения НПС, тогда в момент этого перемещения коллизия НПС отключается. Если это связать с анимацией ходьбы/бега, то можно визуально добиться эффекта "НПС идёт сквозь препятствия и его можно тоже пройти насквозь". Понадобится вычислять путь "куда идёт НПС" и вести его данной командой по этому пути. Но это сложно, проще отказаться от идеи бесплотности призраков.
Ни один маг.эффект не позволяет отключать коллизию, поэтому о магии можно забыть.
В итоге актер никого не атакует, но все равно убегает при возникающей угрозе.
Делаешь нужный пакет (или берёшь подходящий дефолтный), и делаешь форм-лист, в лист заносишь этот пакет. У алиаса с этим НПС в графе Spectator Override Package List назначаешь этот форм-лист. Тогда НПС будет отрабатывать этот пакет, а не использовать дефолтную процедуру, когда НПС игнорирует бой.