Если ты со скобками всё правильно написал, то всё проще:
условие 1 and условие 4 and условие 2 or условие 3 or
В раньше языках TES приоритет имел "ИЛИ", в Папирусе теперь приоритет имеет "И". Но вот в "условиях" приоритет так и остался за "ИЛИ". "ИЛИ" имеет приоритет над "И", каждый "ИЛИ" создаёт свой "блок проверок" с проверкой всех условий, в данном случае полная проверка будет выглядеть так:
или (и (2) и (1) и (4)) или (и (3) и (1) и (4))
В общем, вещь это довольно муторная, если имеются несколько "ИЛИ" со своими "И". Я стараюсь такого избегать (да и разрабы тоже, судя по тем условиям, что у них есть в игре), проще сделать дубликат(ты) объекта (пакеты, эффекты и т.д.) со своим более простым набором условий.
Как скриптом изменять гендерную анимацию персонажа (Use opposit gender animation)? Как называется переменная и как к ней обращаться?
А никак! Даже если эту галочку поставить/снять в СК и запустить игру, то этот НПС всё равно так и останется со старой анимацией. Народ уже давно хотел переделать анимацию той же Лидии, но... обломились, без старта новой игры ничего не получается.
Подскажите, как можно в скрипте указать на обьект типа "Art Object" находящийся в разделе "Miscellanious" ? Пробовал тип "MiscObject Property _MyNewSuperArtObject Auto" - но СК его не видит, и заполнить свойство не даёт.
Делаешь форм-лист, заносишь туда нужные арт-объекты.
FormList Property ListArtObject Auto
ArtObject akArtObject = ListArtObject.GetAt(iIndex) as ArtObject
; iIndex - номер нужного объекта в форм-листе Таким способом можно любой объект назначать, минуя использование стандартного заполнения свойств.
Myprism, читай внимательно. Я же писал: "Проще сделать дубликат со своими условиями..."
Во-первых, не стоит переделывать дефолт, тем самым ты вносишь ненужные несовместимости, которых можно вообще избежать. Во-вторых, гораздо проще прописать условия конкретно для своего диалога, чем пытаться скрестить все нужные условия.
Сделай свой топик для учителя в своём квесте, условия поставь исключающие использование этого топика другими НПС, например, свою фракцию mySuperTrainerFaction и дай эту фракцию своему учителю. Если будут другие такие учителя на обучение других наук, то и фракции делай разные: mySuperTrainerDestructionFaction, mySuperTrainerRestorationFaction и т.д. Естественно, каждому учителю свою фракцию и в каждый топик условие с этой фракцией, тогда только нужный НПС будет говорить и обучать своей науке, да и никаких несовместимостей и вмешательств в дефолт не будет ("и овцы сыты и волки целы" ).
***************************************************************************************** Старайтесь как можно меньше вмешиваться в дефолт, а тем более, если есть возможность этого не делать.
А теперь внимание: В РЕДАКТОРЕ НЕЛЬЗЯ ЭТОТ ПУТЬ ИЗМЕНИТЬ И ВЫБРАТЬ ДРУГОЙ ФАЙЛ! Это значит, что если я буду использовать копии диалогов, то редактор заставляет меня включать в мод то, что у пользователя уже есть.
В ТЕС никогда нельзя было назначать названия для аудио файлов, и Скайрим не исключение. В название входит часть названия диалога и квеста, а так же FormID этого топика. При дублировании топика получается по любому уже другой топик с новым FormID, и естественно, что и название аудио файла будет уже другим, и совершенно без разницы, что в этих обоих топиках одинаковая фраза.
"у пользователя уже есть..." - э нет, у пользователя нет и не может быть файла в названием его квеста и "непонятным" FormID. Надо просто скопировать дефолтные файлы, переименовать их в нужные названия и положить в свою папку озвучки. Это так делалось всегда, пока были игры серии ТЕС.
**После дублирования дефолтных топиков (и вообще всего дефолтного), надо очищать свой мод от привязки с этими дефолтными топиками (снимать звёздочки). Это до загрузки в СК мода, выделяешь мод, жмёшь Detalies и на все дефолтные топики жмёшь Delete, потом продолжаешь загрузку мода и сохраняешь.
Код
Для этого квеста (ванильного, но с изменениями) редактор сохранил мне около сотни откомпилированных квестовых скриптов.
Это значит, что ты вмешался и изменил дефолтный квест и дефолтные скрипты, что крайне плохо. Надо делать свои квесты/объекты/скрипты по подобию дефолтных, а не изменять дефолт и не дублировать дефолт. Иначе проблем не оберёшься, потом. (Дублировать можно только мелочь: статики, предметы, маг.эффекты и прочее подобное. Что либо относящееся к квестам дублировать нельзя.)
************* Я в своих модах не затрагиваю вообще ни один дефолтный квест/объект/скрипт, только при необходимости даю ссылки на эти объекты, всё делаю только с нуля, без какого либо копирования/дублирования. И у меня параметр "в таком числе" == 0, т.е. всё только своё, ничего лишнего и изменённо-дефолтного.
а потом специальной программой убить все совпадающие.
Совет по жизни с компом (не только для ТЕС):
Если у тебя есть две папки с файлами, и у одной надо удалить все файлы копии второй папки, то можно просто скопировать все файлы из второй папки во первую (с заменой) и потом нажать Delete (все скопированные файлы остаются выделенными). При этом из первой папки удалятся все скопированные файлы, а останутся только отличные от них файлы. Т.е. достигнут нужный вариант удаления дубликатов, и без каких либо программ.
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(), скриптованные предметы не возвращают референса, точнее возвращают какую-то чушь (как мне кажется, возвращается референс скрипта), поэтому:
Уж лучше я добавлю пару своих домов в ванильный квест.
И это не обязательно надо именно вмешиваться в ванильный квест, можно сделать в своём квесте свой топик с нужными условиями: срабатывает только тогда, когда сработает ванильный топик + свои условия + свой итоговый скрипт (такой же, как и ванильный). Тогда получится параллельный топик, работающий именно в нужный момент и с результатом как у ванильного, но уже без изменения дефолтного квеста.
************** Вот чтобы дать курьеру отнести письмо для ГГ ведь не надо создавать новый квест WICourier или его изменять, надо просто правильно к нему "подцепиться" : (WICourier as WICourierScript).addItemToContainer(myLetter) и курьер побежит с вашим письмом к ГГ. При этом дефолт вообще никак не затрагивается. ********* Чтобы купить второй дом в Вайтране, не надо переделывать или добавлять топики в сам квест HousePurchase, достаточно сделать свой диалог в своём квесте. Условия топика скопировать и вставить в свой топик, голос/фраза там расшаренная, поэтому даже файлы озвучки копировать не надо, в результирующем скрипте даёшь ГГ свой ключ от дома и т.д. Тогда у управителя появятся два варианта продажи дома - ванильный дом и твой, и можно купить любой из них. И нет никакого вмешательства в дефолт. НО! Если сделаешь на изменении ванильного квеста, то и ванильный скрипт подвяжется к твоему моду, т.е. ты его должен будешь положить к себе в комплект, иначе работать не будет. А если и другой модмейкер так сделает, то один из ваших модов работать не будет, а вот в первом случает такой вариант исключается.
Код
Файлы там одинаковы по названию, иногда и по размеру, но различаются содержанием, поэтому тождественность файлов надо определять бинарным сравнением.
Но не в ТЕС (!). Здесь бывают идентичные файлы по содержанию, но различные по названиям, и оба таких файла необходимы и нужны в игре. Например, фраза "Иди сюда" может быть и в "приветствиях", и в "квестовом диалоге", и в сцене. Содержание идентичное, а файлы разные и нужные, и их нельзя удалять. Поэтому сравнивать файлы можно только по названию, но не по содержанию (в частности в ТЕС). (в Скайриме расшариваются не все однотипные фразы, а только самые ходовые)
То есть, невозможно активировать манекен (не реагирует на курсор). Как это исправить?
Есть два варианта: 1. Дать имя своему манекену и его можно будет активировать. Но "вслепую", надписи не будет. Это не лучший вариант. 2. Сделать свой активатор вместо MannequinActivateTrig (например, aaaMannequinActivateTrig) и в скрипте назначить его вместо дефолтного. На него добавить скрипт и добавить файл модели. Тогда всё будет правильно работать.
----------------- В событии OnCellLoad()последовательность команд должна быть именно такой.
Код
ни обьект самой одежды
Так всё-таки одежда... Что и предполагалось. Тогда забудь про референсы.
Бить актёра - это не педагогично, да и неправильно. Нет гарантии, что вообще он "Айкнит", или именно "Ай", а не пошлёт подальше, подобные реплики рендомные из разных фраз. Для этих целей есть команда Say(), но... делать свой топик придётся, если не найдёшь дефолтного такого топика.
Просто хотелось ещё менять анимацию лезвий, когда ГГ переходит в "боевой" режим ... но раз нельзя, то нельзя.
Почему нельзя, можно. Сделай ещё один маг.эффект на этом спелле с условиями боя, на него повесь новый арт-объект, точнее такой же, но уже с другой анимацией. И во время боя и нет, маг.эффекты сами будут меняться, и естественно, будут меняться арт-объекты (один с простой анимацией, другой с боевой).
Код
Да эта команда хоть что то бы произнесла. Выбирал на угад несколько ванильных топиков, но ГГ молчит как рыба.
А про тип голоса в топиках забыл? И про остальные условия в топиках тоже забыл, да и вообще тот квест мог быть не запущен.
Изменение репутации для пользователя AleksTirex
AleksTirexOffline
Сообщение №191
| Тема: Вопросы по скриптам Papyrus
написано: 30 октября 2013, 19:38
| Отредактировано: AleksTirex - 30 октября 2013, 19:50
Манекен и активатор перемещаются в новую позицию, затем активатор остается в новой позиции, а манекен возвращается в точку, где был создан. Как это поправить?
А ты в скрипте манекена заменил все команды MoveTo(GetLinkedRef()) на MoveTo(st_MarkerHeading)?
******************
С курсором не знаю, ни разу не задавался таким вопросом. Если придумаю как - скажу.
Получается "маг-эффекты" срабатывают только если я одеваю предмет (который собственно и запускает "спелл" на выполнение) и при этом заданное условие [u]уже выполняется. Например если я сидя надену предмет, то когти появятся. И не пропадут до тех пор, пока я предмет не сниму, вне зависимости встану я потом или нет.
Не, ты меня не понял, надо выставить условия в самих эффектах, а не в скрипте. Если на эффект повесить условие IsInCombat == 1, то сам спелл при надевании предмета запустится, но маг.эффект не будет действовать вне боя. Движок всё это время думает, что спелл и эффект действуют, а в реале ничего не действует, если условия на эффекте не выполняются. У тебя условие выполняется для запуска спелла, но не для отработки эффекта.
А вот теперь повесь на свой эффект условие Subject GetSitting > 0, и сам увидишь, что когти уберутся сразу, как ты встанешь. При этом, они сразу вновь появятся, когда ты опять сядешь.
Добавлено (31 Октября 2013, 01:11) --------------------------------------------- LordVadim, тогда весь скрипт показывай.
anton, если "на пальцах" объяснить, то условия на самом маг.эффекте являются как бы определение параметров цели, на которую будет применён этот эффект, т.е. срабатывать ему или нет. Условия в спелле на маг.эффекте - это как бы "общие" и условия самого заклинателя, т.е. применять ли этот эффект вообще. От этих условий зависит "наложить эффект или снять, если он наложен", а вот условия на самом эффекте - это сработает ли он на целе или нет (а если сработал, то и дальше будет работать).
***********************
Код
По курсору уточню: меня интересует положение курсора при выполнении заклинания, то есть в какой точке создавать манекен.
Так ты хочешь создавать манекена через заклинание? Тогда это ещё проще:
1. Делаешь свой спелл и маг.эффект призыва своего актёра (например маленького невидимого краба, или питомца). 2. Дальность призыва по желанию. Время призыва 1 секунда. 3. Делаешь свою способность со скриптом и даёшь её этому актёру. Скрипт:
ActorBase Property akManakenBase Auto Static Property XMarkerHeading Auto
Event OnEffectStart(Actor Target, Actor Caster) ObjectReference akMarker = Target.PlaceAtMe(XMarkerHeading) Target.Disable() Utility.Wait(0.25) float fAngle = akMarker.GetAngleZ() + akMarker.GetHeadingAngle(Game.GetPlayer()) akMarker.SetAngle(0.0, 0.0, fAngle) Actor akNewManaken = akMarker.PlaceActorAtMe(akManakenBase) akMarker.DisableNoWait() akMarker.Delete() (akNewManaken as MannequinActivatorSCRIPT).OnCellLoad() EndEvent
akManakenBase - базовый манекен MannequinActivatorSCRIPT - скрипт, который на этом базовом манекене (у тебя он свой)
Такое количество команд надо для точного позиционирования манекена в точке курсора. (команды и их последовательность не меняй)
Ничего в скрипте манекена изменять не надо. Все необходимые маркеры создадутся сами в скрипте манекена.
********* Вот только подумай над вариантом "отмены/удаления" манекенов, ведь игрок может их нафигачить, что пройти будет нельзя.
Изменение репутации для пользователя AleksTirex
AleksTirexOffline
Сообщение №195
| Тема: Вопросы по скриптам Papyrus
написано: 31 октября 2013, 14:21
| Отредактировано: AleksTirex - 31 октября 2013, 14:26
DarkVetal, сделай свой невидимый сундук. Возьми ниф любого сундука, открой в Нифскопе, на видимой части (NiTriShape) поставь Flags15 вместо 14, и сохрани со своим именем. Потом добавь этот ниф к себе в папку и назначь его на свой сундук. Тогда в игре сундук будет, а видно его не будет.
Всё правильно сказал Artem13, я уже многократно писал: "алиас предмета, который создаётся в другом алиасе, всегда должен стоять в списке ниже, чем алиас-контейнер, иначе ему просто негде будет создаваться".
Код
Нужно сделать табличку с надписью, выскакивающую при старте игры с модом [b]Но лишь одинажды, т.е. при следующей загрузке, таблички уже не было.
Если квест запускается только один раз и без перезапусков, то переменная bDone не нужна.
Код
Как форсировать включение этого пункта в заданиях, чтобы указатель появлялся сразу, как только игрок убил драугра?
Или на драугре в событии смерти, или в стадии квеста при смерти драугра:
if !myQuest.IsActive() myQuest.SetActive() endIf
Код
при переносе телепортом из одного помещения в другое, переносятся и звуки
Это как? Переноса звуков в Скайриме нет. Если ГГ не сменил локацию, а только телепортировался в другую точку в этом же помещении, тогда да, звуки могут остаться, но если локация другая, то и звуков быть не должно. (я таких эффектов ни разу не встречал)
Код
[color=#ffffff] Невидимый сундук должен покрывать конструкцию снаружи, иначе он может оказаться недоступен и это не сразу будет понято, так как он не виден [img]http://modgames.net/smilesgood/smile.gif
Можно ещё проще и без новых нифов сделать (на подобии активатора манекена). 1. Создаётся активатор с именем "Сундук" без модели. 2. В нужном месте создаётся триггер на основе этого активатора. Во вкладке Primitive ставим галочку Player Activation. В этой же вкладке (или через кнопку "2") настраиваем нужный размер и местоположение бокса-сундука. 3. Добавляется свой нужный сундук и прячется или ниже уровня земли/пола, или ещё где. 4. На этом сундуке во вкладке Activate Parents ставится галочка Parent Activate Only и назначается сделанный активатор-сундук.
Теперь активация спрятанного сундука будет при активации этого активатора, как и в случае с манекенами.
Добавлено (01 Ноября 2013, 19:23) ---------------------------------------------
Код
Нужны автоматически раскрывающиеся двери (не загрузочные) перед персонажем, но без кнопки в полу (это можно сделать по принципу ловушки), а с помощью триггера
!!! Друзья, если вы чувствуете/предполагаете, что ваша проблема связана с применением скриптов, а не с работой в СК, то сразу пишите именно в нужную тему по скриптам, дабы другим пользователям было легче искать ответы на свои вопросы/проблемы.
Тут компилятор не принимает название квеста. Получилось так:
И не примет, пока ты не создашь свойство: Quest Property myQuest Auto;)
Self.SetActive() - работать не будет (на актёре/алиасе/и т.д.), если эта команда не находится в самом квестовом скрипте или стадии. (Self - это хозяин скрипта, на котором висит данный скрипт)
Если событие смерти находится на алиасе, то можно так:
if !GetOwningQuest().IsActive() GetOwningQuest().SetActive() endIf
Если эти команды в стадии квеста, тогда так (можно с Self или без него):
какой триггер выбрать (их много) и как его привязать к двери (выделять какие-то ассоциации типа активатор - цель), куда прикрутить код, к двери или к триггеру?
В разделе "Активаторы" создаёшь свой активатор. В нём в окне Scripts жмёшь Add и делаешь новый скрипт, в нём пишешь тот код и Ctrl+S (что выше написан). ОК. Тыркаешь на дверь, потом нажимаешь Create Trigger (кубик с буквой Т), в выскочившем окне выбираешь свой созданный активатор. ОК. У тебя по размеру двери создастся бокс. Стрелочками растягиваешь свой триггер-бокс на нужные размеры (для выключения этого режима "2" или "W" на клавиатуре). Потом тырк-тырк по этому боксу-триггеру, и в окне во вкладке Linked Ref назначаешь свою дверь.
Можно к любой анимированной двери так сделать, хоть к своей, хоть к дефолтной, везде создаёшь триггер и выбираешь этот активатор, и на получившемся боксе назначаешь LinkedRef свою сопрягаемую дверь.
Нет друзья, так не пойдёт, писать такие слишком уж подробные инструкции "вдруг" как-то расхотелось - вы не читаете, что вам пишут! Так зачем я тогда всё это пишу?
Код
(команды и их последовательность не меняй)
Читал? И где ты видел там Target = Player() ?
Способность у призванного актёра, вот и манекен создаётся у этого призванного актёра (который сразу же удаляется). Откуда взялся там ГГ? Если сам что-то меняешь или добавляешь, то как минимум, надо об этом писать, телепатией тут никто не обладает.
Если сделать всё от и до, как там написано, то всё будет прекрасно работать.
То есть в нее, почему то, записана ссылка на игрока, а не на создаваемое существо.
Код
1. Делаешь свой спелл и [b]маг.эффект призыва своего [u]актёра (например маленького невидимого краба, или питомца). 2. Дальность призыва по желанию. Время призыва 1 секунда. 3. Делаешь свою [b]способность [u]со скриптом и даёшь её [u]этому актёру.
И даёшь её этому призываемому актёру. Способность висит на актёре, а не на ГГ. Скрипт на способности, а не на заклинании призыва. Два спелла - призыв актёра и способность на актёре, на способности скрипт.
Код
триггер со скриптом, проходя через который все живые существа мгновенно умирают,
Event OnTriggerEnter(ObjectReference akActionRef) if akActionRef != Game.GetPlayer() (akActionRef as Actor).Kill() endif EndEvent
Если надо и ГГ убивать, то тогда условия можно убрать.
Они и перед нею открываются и за ней тоже закрываются
Я бы ещё одно условие добавил для закрытия дверей - "Если в зоне нет актёров". Если спутник бежит рядом, то дверь может перед ним захлопнуться, а с условием закроется только при выходе последнего актёра:
1. - Как мне избавиться от ее "лишних" диалогов? Чтоб просто молча лежала и начинала диалог только при обращении к ней? 2. - Как заставить ее поверить, что ей хуже всех в данный момент и что ей сражаться совсем не обязательно, пока она ранена?
Если у неё пакет дефолт, то сделай свой. На пакете сними ВСЕ флаги, кроме Allow Idle Chatter. Поставь флаг Ignore Combat.
Скриптом или ещё как сделай ей режим Ghost: akActor.SetGhost()
По окончании "умирания", когда она должна стать "нормальной" девушкой - akActor.SetGhost(false) и смена пакета на нормальный.
Диалог с разговором должен быть с типом Blocking (светло-зелёный), чтобы ни один другой диалог не мог сработать, пока она "помирает".
В разделе "Активаторы" создаёшь свой активатор. В нём в окне Scripts жмёшь Add и делаешь новый скрипт, в нём пишешь тот код и Ctrl+S (что выше написан). ОК. Тыркаешь на место установки триггера, потом нажимаешь Create Trigger (кубик с буквой Т), в выскочившем окне выбираешь свой созданный активатор. ОК. У тебя по размеру ??? создастся бокс. Стрелочками растягиваешь свой триггер-бокс на нужные размеры (для выключения этого режима "2" или "W" на клавиатуре).
где находится список ячеек Тамриэля, доступных для посещения?
А нигде. Такого списка нет. Есть граница, за которую игрок не может выйти. Они как реальная граница, типа черты, и эта черта является контуром региона, на котором висит флаг Border Region, т.е. игроку нельзя выйти за границу этого региона. Регионы находятся в World - Regions... Можно изменить размеры/контур этого региона - добавить свою ячейку, путём перемещения границы так, чтобы в этот регион вошла твоя ячейка. Но это ни есть правильный выход. Лучше передвинуть твои предметы в "зону доступа ГГ", чем менять/изменять регион.
(В Тамриеле - BorderRegionSkyrim - надо его изменять)
*************
DarkVetal, проверь, точно ли у тебя созданы скрипты и висят ли они на своих объектах? А так же, сохранил ли ты изменения в ESP? (и такое бывает)
именно все так и сделал, никто так и не сдох, хотя бегали раз по десять через него.
Ты заметь, что у тебя вообще ни один свой созданный триггер не работает, ни на убийство, ни на дверь... Команда Kill() не может не убить простого НПС. У тебя проблема с самими триггерами или с их созданием.
DarkVetal, да ты читер , если ГГ не дохнет. Или ты не убрал условия в скрипте (там было запрещено убивать ГГ), или играешь с TGM. Чтобы киллить всех и квестовых НПС тоже, надо так:
Event OnTriggerEnter(ObjectReference akActionRef) (akActionRef as Actor).KillEssential() EndEvent
Но если на НПС стоит галочка Invulnerable, то такого НПС ничем не убьёшь (это галочка "неуязвимый").
************* Вот только зачем нужных квестовых НПС убивать, не понятно, ведь квесты встанут/зависнут.
Так постом выше написано, там полный скрипт (событие и одна команда). Вообще никаких условие не надо в скрипте.
KillInvulnerable - такой команды нет.
**************
Event OnTriggerEnter(ObjectReference akActionRef) bool bInvulnerable if (akActionRef as Actor).GetActorBase().IsInvulnerable() (akActionRef as Actor).GetActorBase().SetInvulnerable(false) bInvulnerable = true endIf (akActionRef as Actor).KillEssential() if bInvulnerable Utility.Wait(0.25) (akActionRef as Actor).GetActorBase().SetInvulnerable() endif EndEvent
Работают: WinterholdGate01; SDoorJail01, не работают SSingleDoorIntJail01R.
Я вот не поленился и воткнул твои "нерабочие" двери в тестовую локацию, причём без скриптов. Так они даже в дефолтном режиме глючат - проблема с коллизиями, не совпадают коллизия и видимая часть двери после дефолтного использования.
Т.е. проблема в самих дверях, а не в скрипте.
Для переключения "типа" двери можно ввести в скрипт флаг, и на "проблемной" двери не делать проверку на наличие НПС. На скрипте на самой двери (референсе) просто ставится галочка на свойстве, на остальных дверях ничего делать и ставить не надо. (хотя, какая связь двери с проверкой... не пойму)