• Прежде, чем задать вопрос, пожалуйста, убедитесь, что такой вопрос не задавался раньше. Старайтесь описать суть вопроса как можно подробней. • Прежде, чем опубликовать ответ на вопрос, пожалуйста, убедитесь, что обладаете необходимыми для этого знаниями. Старайтесь cформулировать суть ответа как можно лаконичней. • При желании ответить в приватном порядке, пожалуйста, воспользуйтесь ЛС. • При желании поблагодарить ответившего, пожалуйста, воспользуйтесь кнопкой "+" полезного сообщения.
Сообщения, не относящиеся к вопросам по скриптам Papyrus, ответам на них или уточнениям, являются оффтопом и могут быть удалены.
Красное солнце Есть вопросы по скриптам Papyrus? Пиши не в ЛС, а в эту тему.
SKSE нужен только, чтобы скомпиллировалось. По какой-то причине, компиллятор не распознает функции, прописанные в ReferenceAlias.psc. Но при этом позволяет скомпиллировать hidden скрипты. Перед запуском игры просто замени Alias.pcs на дефолтный, если тестишь на конфе с сксе - твой скрипт будет работать (если все остальное правильно написано, конечно.
Доброго времени суток. Подскажите как отключить коллизии игрока (или что нужно сделать) чтобы во время трансляции он не сталкивался с другими объектами.
akActor.SetOutfit(kOutfitEmpty)akActor.GetActorBase().SetOutfit(kOutfitEmpty) Результаты таких команд разные.
А в чём заключается разница? Возможно, первый вариант меняет оутфит у данного экземпляра неписи, а второй у всех экземпляров данной неписи? На одном уникальном персонаже (да Лидка это) я разницы не вижу.
Открываем ReferenceAlias.psc (дефолтный скрипт), выделяем все, кроме первых двух строк, и копируем в конец Alias.pcs (скрипт SKSE). Компиллируем Alias.pcs. Вуаля, все компиллируется.
Это помогло от части... скрипт скомплился, но требуемые действия не выполняются... То есть НПС, при диалоге "Жди меня в Х", забавно дергается, что видимо подтверждает работу скрипта, но все равно продолжает следовать за ГГ. Блин.. вроде куда проще, назначить пакет, который перекроет остальные, а оказывается, что не все так просто...
Если бы это был один НПС, то можно было бы прописать пакет только ему и запускать его по нужной стадии квеста... а если мне нужно, чтоб это был ЛЮБОЙ нужный НПС, то тут уже грабли... Жаль.. ништяк пропадает.. придется как-то по другому выходить из положения.
Кто к нам с чем и за чем, тот от того и того... ʘ_ʘ <a class="link" href="http://modgames.net/load/0-0-200451-0-17" rel="nofollow" target="_blank"> border="0" alt=""/</a>
Изменение репутации для пользователя Kepper
KepperOffline
Сообщение №425
написано: 23 октября 2013, 04:59
| Отредактировано: Kepper - 23 октября 2013, 05:04
Есть у меня в моде два призрака, которых можно брать в компаньоны. Отличает их от прочих неписей только 2 свойства: 1. Установлено isGhost, что делает их неуязвимыми и 2. Молитва GhostAbility - делает непись полупрозрачной и светящейся. Естественно возникло желание дать возможность игроку их воскрешать. Скрипт воскрешения вставил в колечко:
Event OnEquipped(Actor akActor) if akActor != Game.GetPlayer() akActor.RemoveSpell(RemovedSpell) endIf endEvent
Event OnUnequipped(Actor akActor) if akActor != Game.GetPlayer() akActor.SetGhost(false) endIf endEvent
В свойствах скрипту передаётся молитва GostAbility
Почти получилось Вернее, вторая часть работает идеально - после снимания кольца непись навсегда становится уязвимой. А во с первой частью хуже: 1. При одевании кольца свечение гаснет медленно и красиво, а вот полупрозрачность сохраняется. 2. При выходе в другую локацию свечение возобновляется и убирается повторным одеванием кольца. Почему не убирается полупрозрачность? И, почему свечение возвращается?
С полупрозрачностью разобрался, точнее научился её лечить, добавив строку akActor.SetAlpha(1)
Никаких строк с удалением всех вещей (в том числе и в сундук) ставить нельзя. Можно было бы, если бы это был скрипт молитвы, но строка удаления вещей удаляет и кольцо, в результате чего скрипт переходит во вторую фазу и ничего не делает Из-за этого я ранее неправильно интерпретировал его работу. В текущем же виде всё отлично. При одевании кольца неписью визуально ничего не меняется, но все шмотки, что раньше были у неё в оутфите становятся доступны для обмена и отбирания. Если кольцо снять, предварительно отобрав все шмотки, непись их восстановит себе при переходе в другую локацию. Если отобрать часть, то так и будет ходить полуголой, но если недостающие ей вернуть, то она будет считать их своим оутфитом, и примет их именно в оутфит!
Event OnEquipped(Actor akActor) if akActor != Game.GetPlayer() if akActor.HasSpell(RemovedSpell) akActor.removeSpell(RemovedSpell) endif akActor.SetAlpha(1) akActor.QueueNiNodeUpdate() endIf endEvent
Event OnUnequipped(Actor akActor) if akActor != Game.GetPlayer() akActor.SetGhost(false) endIf endEvent
Параметром тут передаётся установленная у моих призраков молитва GhostAbility. Скрипт работает как надо, за исключением одного: он снимает действие молитвы, но как будто не убирает у непися саму эту молитву. Дело в том, что при переносе в другую локацию непись снова находится под действием этой молитвы и для снимания этого действия надо снова одевать амулет (скрипт на пока амулете). Как убивать эту молитву с корнями?
И, раз я научился менять оутфиты, хочу сделать переодевание ко сну хоть у своих персонажей. В связи с этим вопрос: как засекать события засыпания и просыпания?
Добавлено (26 Октября 2013, 06:34) --------------------------------------------- Понял, почему призрачность восстанавливается при смене локаций. Проблема в том, что спеллы можно убирать только у актёра, а при смене локации происходит синхронизация спелов актёра с базовым актёром. А ведь GhostAbility стоит именно у базового актёра и у него я пока не знаю как её убирать
А ведь GhostAbility стоит именно у базового актёра и у него я пока не знаю как её убирать
Добавь условие срабатывание у способности призрака зависящее от глобально переменной и меняй её. Правда глобальная переменная не самый лучший способ. Можно попробовать задать в условии наличие на персонаже заклинания и этому заклинанию поставить большое время жизни. Либо вставить в условие одетый предмет или ключевое слово у предмета.
Если бы это был один НПС, то можно было бы прописать пакет только ему и запускать его по нужной стадии квеста... а если мне нужно, чтоб это был ЛЮБОЙ нужный НПС, то тут уже грабли...
Делаешь всой квест, там алиас с пустой позицией Specific Reference и галочкой Optional. Алиасу в соответстующем месте добавляешь пакет. Приоритет пакета определяется приоритетом его квеста, поэтому приоритет квеста надо ставить 75-90, тогда этот пакет перекроет все остальные пакеты. Добавление пакета НПСу - назначение этого НПС алиасу:
ReferenceAlias Property akMyAlias Auto
akMyAlias.ForceRefTo(akActor)
Удаление пакета у НПС - очистка алиаса от ссылки на этого НПС:
akMyAlias.Clear()
Важно: при работе с алиасами свойства должны быть ReferenceAlias, а не Alias.
Код
И, раз я научился менять оутфиты, хочу сделать переодевание ко сну хоть у своих персонажей. В связи с этим вопрос: как засекать события засыпания и просыпания?
Package Property akPackageSleep Auto
Event OnPackageStart(Package akNewPackage) if akNewPackage == akPackageSleep ; пакет начался, НПС идёт к кровати endif endEvent
Event OnPackageEnd(Package akOldPackage) if akOldPackage == akPackageSleep ; пакет продолжается, НПС лёг на кровать endif endEvent
Event OnPackageChange(Package akOldPackage) if akOldPackage == akPackageSleep ; пакет закончился, НПС встал с кровати endif endEvent
Код
А ведь GhostAbility стоит именно у базового актёра и у него я пока не знаю как её убирать
**** Но можно и не удалять сам спелл, а просто сделать условия на этом спелле, и управляя этим условием - управлять спеллом. Можно и глобалкой, но лучше привязать условие спелла к своему скрипту. Для этого надо сделать скрипт и свойство "общедоступными", т.е. conditional, тогда это свойство можно использовать в любых условиях на любых объектах.
Важно: при работе с алиасами свойства должны быть ReferenceAlias, а не Alias.
В этом была моя ошибка! Алекс, благодарю!!! Возник сопутствующий вопрос.
Диалог отправляет НПС в указанную локацию и возвращает его в отряд(более одного спутника). То есть код твой работает однозначно. Есть одно НО. Если я отправляю в указанное место НПС, то он возвращается ко мне, как только я отправляю в указанную локацию второго(третьего.. не важно) НПС... как побороть это?
Кто к нам с чем и за чем, тот от того и того... ʘ_ʘ <a class="link" href="http://modgames.net/load/0-0-200451-0-17" rel="nofollow" target="_blank"> border="0" alt=""/</a>
AleksTirex, с переодеванием на ночь получается отлично! Я просто для сна ставлю спальный оутфит вместо обычного. Вот только актёра я передаю скрипту через параметр, что наверняка не есть правильно Как узнать актёра в скрипте на отслеживание смены AI-пакетов?
Есть одно НО. Если я отправляю в указанное место НПС, то он возвращается ко мне, как только я отправляю в указанную локацию второго(третьего.. не важно) НПС... как побороть это?
Один алиас - один актёр. Двух актёров на один алиас не назначить, что очевидно. Поэтому второй актёр прописывается вместо первого, поэтому у первого уже нет пакета алиаса и он идёт обратно. Надо сделать необходимое количество алиасов и назначать нового актёра на свободный алиас. Те же актёры, которые больше не должны сидеть в "той локации", надо те алиасы очищать.
Т.е. надо делать цикл проверки алиасов на их заполнение. Проще всего сделать массив, прописать там алиасы и цклом проверять всё это. Сколько ты планируешь задействовать одновременно актёров для отправки в "ту локацию"? Учти, столько же надо будет сделать алиасов (они все идентичны). Если с массивами не справишься - помогу.
**** Увы, но с пакетами работают только алиасы и сцены (а в сценах - алиасы), т.е. пакет можно только через алиас передать актёру. Это фишка разрабов. (если кто знает другой вариант добавить пакет - пишите)
Код
Как узнать актёра в скрипте на отслеживание смены AI-пакетов?
Странный вопрос - на ком висит скрипт с отслеживанием работы пакета, тот и есть нужный актёр. Если имеешь в виду, какой референс у твоего актёра, то Self возвращает хозяина скрипта: Actor akActor = Self Если это алиас, то Actor akActor = Self.GetActorRef() Если скрипт висит на актёре, но имеет тип ObjectReference, тогда Actor akActor = Self as Actor
Код
Вот только актёра я передаю скрипту через параметр
Совсем ничего не понял. Что значит через параметр? Пример в студию.
Изменение репутации для пользователя Myprism
MyprismOffline
Сообщение №435
написано: 27 октября 2013, 02:25
| Отредактировано: Myprism - 27 октября 2013, 02:45
AleksTirex, то что нужно! Просто у меня на первых порах проблемы с синтаксисом и я не знал, как правильно использовать Self. Параметром я назвал передачу значения переменной в скрипт. В данном случае, у меня было Actor property akAktor Auto.
Добавлено (27 Октября 2013, 06:25) --------------------------------------------- И всё же не компилируется Вот начало скрипта: Scriptname aaSleeping extends ObjectReference
Package Property akPackageSleep Auto ;Actor akActor = Self ;Actor akActor = Self.GetActorRef() Actor akActor = Self as Actor Outfit kOutfit
Event OnPackageStart(Package akNewPackage) if akNewPackage == akPackageSleep ; пакет начался, НПС идёт к кровати kOutfit = akActor.GetActorBase().GetOutfit(false) akActor.SetOutfit(akActor.GetActorBase().GetOutfit(true)) endif endEvent
Ругается во всех трёх вариантах одинаково: (6,16): no viable alternative at input 'Self' (6,21): required (...)+ loop did not match anything at input 'as' (6,6): Unknown user flag Self
Сколько ты планируешь задействовать одновременно актёров для отправки в "ту локацию"? Учти, столько же надо будет сделать алиасов (они все идентичны).Если с массивами не справишься - помогу.
Да думаю, что не больше 10. Да, не справлюсь, помощь очень нужна. Заранее благодарен.
Кто к нам с чем и за чем, тот от того и того... ʘ_ʘ <a class="link" href="http://modgames.net/load/0-0-200451-0-17" rel="nofollow" target="_blank"> border="0" alt=""/</a>
Myprism, попробуй присваивание перенести в код обработки события. Похоже, что на этапе объявления переменных, скрипт еще не знает "объектов" Self.
<a class="link" href="http://nick-name.ru/sertificates/278209/" rel="nofollow" target="_blank"> border="0" alt=""/</a> Да, мы бандиты и бродяги, как злословит молва, Мы попадаем в передряги, помня эти слова. Смотри вперед и не сдавайся ты на милость судьбе! Предай их всех, останься верен себе. (Канцлер Ги - Кантри Бреган Д'Эрт)
Уважаемые гуру скриптинга, всех приветствую! Не профессионал в скриптинге и модостроении, но возникла необходимость, и как следствие - вопросы. Буду крайне признателен за любую помощь... И так:
У Actor запущена циклическая анимация PlayIdle, но в игре в некоторые моменты останавливается:
1) Как проверить проигрывается ли анимация в настоящий момент или нет? 2) Как остановить проигрывание анимации?
Делаешь своего актёра манекена. На него вешаешь свой скрипт вместо дефолтного, он сделан на основе скрипта манекена, но с маленькой доработкой:
Добавляешь свойства: Activator Property MannequinActivateTrig Auto Static Property XMarkerHeading Auto ObjectReference akMarkerHeading ; референс маркера XMarkerHeading
Добавляешь функцию: Function CreateMarkers() self.PlaceAtMe(MannequinActivateTrig) akMarkerHeading = self.PlaceAtMe(XMarkerHeading) endFunction
Во ВСЕХ местах скрипта меняешь MoveTo(GetLinkedRef()) на MoveTo(akMarkerHeading)
**************** В своём скрипте на создание манекена делаешь так:
Actor akNewMannequin = akMarker.PlaceActorAtMe(MannequinBase) Utility.Wait(0.5) (akNewMannequin as myMannequinActivatorScript).CreateMarkers()
myMannequinActivatorScript - название своего скрипта манекена, менять можно как угодно, но название скрипта и эта строка должны совпадать. Свойство MannequinBase - назначается свой базовый манекен, название любое.
Добавлено (27 Октября 2013, 15:59) ---------------------------------------------
Код
Ругается во всех трёх вариантах одинаково
И правильно ругается - команды не могут работать вне тела/блоков функций или событий. К тому же, событие OnPackageStart на ObjectReference работать не может, оно работает на актёре или алиасе.
Скрипт висит же на актёре? Тогда меняй тип скрипта Scriptname aaSleeping extends ObjectReferenceActor
Сами события будут такими:
Event OnPackageStart(Package akNewPackage) if akNewPackage == akPackageSleep ; пакет начался, НПС идёт к кровати kOutfit = self.GetActorBase().GetOutfit(false) self.SetOutfit(self.GetActorBase().GetOutfit(true)) endif endEvent
Или так:
Event OnPackageStart(Package akNewPackage) Actor akActor = Self as Actor if akNewPackage == akPackageSleep ; пакет начался, НПС идёт к кровати kOutfit = akActor.GetActorBase().GetOutfit(false) akActor.SetOutfit(akActor.GetActorBase().GetOutfit(true)) endif endEvent
Или так:
Event OnPackageStart(Package akNewPackage) if akNewPackage == akPackageSleep ; пакет начался, НПС идёт к кровати kOutfit = GetActorBase().GetOutfit(false) SetOutfit(GetActorBase().GetOutfit(true)) endif endEven
******* По умолчанию скрипт всегда использует "хозяина", т.е. Self, если для команды не назначен другой объект. Поэтому self.GetActorBase() == GetActorBase()
AleksTirex, Большое спасибо! Теперь всё в порядке. Не хватало правильного типа скрипта в заголовке. На случай, если кому ещё пригодится, вот работающий вариант:
Scriptname aaSleeping extends Actor
Package Property akPackageSleep Auto Outfit kOutfit0 Outfit kOutfit1 ;Сон
Event OnPackageStart(Package akNewPackage) if akNewPackage == akPackageSleep ; пакет начался, НПС идёт к кровати kOutfit0 = GetActorBase().GetOutfit(false) kOutfit1 = GetActorBase().GetOutfit(true) endif endEvent
Event OnPackageEnd(Package akOldPackage) if akOldPackage == akPackageSleep ; пакет продолжается, НПС лёг на кровать SetOutfit(kOutfit1) endif endEvent
Event OnPackageChange(Package akOldPackage) if akOldPackage == akPackageSleep ; пакет закончился, НПС встал с кровати SetOutfit( kOutfit0) endif endEvent
Скрипт переодевает персонажа в установленный ему спальный оутфит, когда персонаж ложится в кровать. Т.е. исправляет недоделку игры. В качестве параметра скрипту надо передать спальный пакет персонажа.
Да думаю, что не больше 10. Да, не справлюсь, помощь очень нужна.
На всякий случай сделал на 18 алиасов. Лучше всего использовать в квесте, причём постоянно работающий без выключения. Если будешь скрипт добавлять в свой уже существующий квест, то тест только на чистой сохранке. Всем свойствам алиасов не забывай назначать свои алиасы из квеста. На алиасах должна быть галочка Optional.
Scriptname aMyQuestScript extends Quest
ReferenceAlias Property Alias1 Auto ReferenceAlias Property Alias2 Auto ReferenceAlias Property Alias3 Auto ReferenceAlias Property Alias4 Auto ReferenceAlias Property Alias5 Auto ReferenceAlias Property Alias6 Auto ReferenceAlias Property Alias7 Auto ReferenceAlias Property Alias8 Auto ReferenceAlias Property Alias9 Auto ReferenceAlias Property Alias10 Auto ReferenceAlias Property Alias11 Auto ReferenceAlias Property Alias12 Auto ReferenceAlias Property Alias13 Auto ReferenceAlias Property Alias14 Auto ReferenceAlias Property Alias15 Auto ReferenceAlias Property Alias16 Auto ReferenceAlias Property Alias17 Auto ReferenceAlias Property Alias18 Auto ReferenceAlias[] aAliasAA
Function ClearAlias(Actor akActor) int index While index < 18 if aAliasAA[index].GetActorRef() == akActor aAliasAA[index].Clear() endif index += 1 endWhile endFunction
Function ForceAlias(Actor akActor) int index bool bForceAlias While index < 18 && bForceAlias == false bForceAlias = aAliasAA[index].ForceRefIfEmpty(akActor) if bForceAlias akActor.EvaluatePackage() endif index += 1 endWhile if index >= 18 ; debug.notification("Aliass Full !!!!!!") endif endFunction
************************************************************* aMyQuest - постоянно работающий квест
Назначить алиасу нужного актёра: (aMyQuest as aMyQuestScript).ForceAlias(akCurrentActor) ; если это из другого скрипта ForceAlias(akCurrentActor) ; если из этого же скрипта akCurrentActor - референс данного актёра для передачи алиасу
Удалить у алиаса актёра: (aMyQuest as aMyQuestScript).ClearAlias(akOldActor) ; если это из другого скрипта ClearAlias(akOldActor) ; если из этого же скрипта akOldActor - референс удаляемого актёра из алиаса
Добавлено (27 Октября 2013, 17:41) --------------------------------------------- Можешь добавить функцию на полную очистку всех алиасов:
Function ClearAllAliass() int index While index < 18 aAliasAA[index].Clear() index += 1 endWhile endFunction
На сам алиас желательно повесть скрипт на случай смерти НПС, чтобы его алиас очистился:
Event OnDeath(Actor akKiller) Clear() endEvent
На все алиасы один и тот же скрипт. Алисасы проще делать так: создал один и полностью его настроил, т.е. поставил нужные галочки и добавил скрипт. Потом просто дублируешь алиас и прописываешь дубликату своё имя.
Изменение репутации для пользователя VALKNUT
VALKNUTOffline
Сообщение №443
написано: 27 октября 2013, 14:09
| Отредактировано: VALKNUT - 27 октября 2013, 17:11
===================== Проверил. Все работает четко!!! Благодарю еще раз!!!
Кто к нам с чем и за чем, тот от того и того... ʘ_ʘ <a class="link" href="http://modgames.net/load/0-0-200451-0-17" rel="nofollow" target="_blank"> border="0" alt=""/</a>
Как скриптом изменять гендерную анимацию персонажа (Use opposit gender animation)? Как называется переменная и как к ней обращаться?
А никак! Даже если эту галочку поставить/снять в СК и запустить игру, то этот НПС всё равно так и останется со старой анимацией. Народ уже давно хотел переделать анимацию той же Лидии, но... обломились, без старта новой игры ничего не получается.
Изменение репутации для пользователя anton
antonOffline
Сообщение №446
написано: 29 октября 2013, 08:54
| Отредактировано: anton - 29 октября 2013, 08:56
Подскажите, как можно в скрипте указать на обьект типа "Art Object" находящийся в разделе "Miscellanious" ? Пробовал тип "MiscObject Property _MyNewSuperArtObject Auto" - но СК его не видит, и заполнить свойство не даёт.
Этот обьект мне нужен, т.к. в его НИФ файл можно напихать анимаций, и мне хотелось бы в последствии перебирать эту анимацию скриптом, с помощью функции "PlayGamebryoAnimation()"
Подскажите, как можно в скрипте указать на обьект типа "Art Object" находящийся в разделе "Miscellanious" ? Пробовал тип "MiscObject Property _MyNewSuperArtObject Auto" - но СК его не видит, и заполнить свойство не даёт.
Делаешь форм-лист, заносишь туда нужные арт-объекты.
FormList Property ListArtObject Auto
ArtObject akArtObject = ListArtObject.GetAt(iIndex) as ArtObject
; iIndex - номер нужного объекта в форм-листе Таким способом можно любой объект назначать, минуя использование стандартного заполнения свойств.
Изменение репутации для пользователя anton
antonOffline
Сообщение №448
написано: 29 октября 2013, 14:34
| Отредактировано: anton - 29 октября 2013, 19:10
ArtObject akArtObject = ListArtObject.GetAt(iIndex) as ArtObject
Так в этом то всё и дело, что нету такого типа как "ArtObject" и компилятор ругается...
Попробовал: form myForm = Game.GetFormFromFile(0x00000D62, "_MyMod.esp") as Form В переменной myForm что то появилось, но что - не знаю как проверить (и анимация с ней не меняется...).
Я тут ещё подумал, и мне кажется что понадобится не только FormID но и ObjectID, т.к. именно он отвечает за уже существующий обьект в игре, и именно ему надо будет давать команду на смену анимации. А вот как его из FormID получить пока не знаю...
anton, ты получил не FormID, а RefID базового объекта. А из базового объекта по определению нельзя получить референс объекта из игрового мира, ведь этих объектов может быть сотня, или вообще ни одного. (можно только наоборот - из референса получить базовый объект)
Референс объекта возьми "поиском", ведь, скорее всего, такого же второго объекта рядом быть не должно:
form myForm = Game.GetFormFromFile(0x00000D62, "_MyMod.esp") as Form ObjectReference closestObject = Game.FindClosestReferenceOfTypeFromRef(myForm, Game.GetPlayer(), 512.0)
Или возьми "напрямую" этот референс в момент добавления этого объекта в игровой мир. А если ты делаешь одежду с этим арт-объектом, то вообще забудь про референс - его просто не существует, пока предмет находится в инвентаре, он появится только в игровом мире.
Добавлено (30 Октября 2013, 00:42) --------------------------------------------- Кстати, при "выбросе" предмета из инвентаря командой Drop(), скриптованные предметы не возвращают референса, точнее возвращают какую-то чушь (как мне кажется, возвращается референс скрипта), поэтому:
В CK добавляю в локацию манекен без Trig и Mark, в игре срабатывает OnCellLoad(), Trig и Mark создаются, но они не привязаны к манекену. То есть, невозможно активировать манекен (не реагирует на курсор). Как это исправить? Создавать манекен из других скриптов (с вызовом f_CreateMarkers()) тоже пробовал - результат тот же, модель создается, но ни на что не реагирует. В Form есть функции RegisterFor... может надо их использовать?
Форум » TES V: Skyrim » Мастерская » Вопросы по скриптам Papyrus (О скриптах Papyrus (Skyrim). Скриптеры не проходите мимо!)