1) OnActivate() срабатывает на объекте, который активируют. Поскольку скрипт на алиасе игрока, то событие сработает, если игрока попытается активировать другой объект.
2) У тебя 2 разные переменные с одинаковым именем BanneredMareBad. Скрипт не скомпилируется.
3) Property BanneredMareBad в скрипте не используется (либо скрипт выложен не полностью).
Lissenok, ну почему, почему броня на манекенах и оружие на стойках будут пропадать? Разве манекены не являются актерами, размещаемыми через PlaceAtMe? А значит, их инвентарь, состояние и скрипты не будут затронуты при обновлении ячейки? То же можно сказать про стойки? А даже если и нет, и эти объекты являются включаемыми / отключаемыми, разве обязательно указывать флаг Respawn у их СК-референсов? Может, нужно проверить их реальное поведение, набрав в консоли (SetGameSetting iHoursToRespawnCell 1), выйти с этой локации, подождать пару часов и вернуться обратно? Так много вопросов, так мало ответов...
Lissenok, броня у них может пропасть, если они обновляются, теряя свой инвентарь и/или переменные скрипта MannequinActivatorSCRIPT (при обновлении скрипт ре-инициализируется). Если броня, выданная в СК, не пропадает, это тоже может говорить в пользу их обновления. Это можно проверить, добавив референсу манекена скрипт...
Или, добавить референсу манекена другой скрипт, и, дав манекену броню в игре, проверить переменную скрипта после обновления ячейки (предполагается, что скрипт MannequinActivatorSCRIPT ванильный):
ScriptName _TESTNEWMANN Extends ObjectReference
EVENT OnCellAttach() Utility.Wait(0.5) MannequinActivatorSCRIPT xS = (self AS Actor) AS MannequinActivatorSCRIPT IF !xS Debug.MessageBox("MannequinActivatorSCRIPT не найден!") ELSEIF !xS.ArmorSlot01 Debug.MessageBox("Манекен не имеет запомненных слотов брони!") ELSE Debug.MessageBox("Манекен имеет хотя бы один запомн. слот") Debug.MessageBox(xS.ArmorSlot01.GetName())
Debug.MessageBox("Количество этих предметов в его инвентаре " + GetItemCount(xS.ArmorSlot01))
Lissenok, первый скрипт должен выводить сообщение, когда (если) происходит обновление манекена. Для этого он должен быть добавлен к референсу, а не базовому актеру. Если он добавляется базовому актеру, скрипт должен расширять Actor (т.е. ScriptName _TESTNEWMANN Extends Actor).
Второй, да, я его не проверял на компиляцию. Строка 5:
MannequinActivatorSCRIPT xS = ((self AS ObjectReference) AS Actor) AS MannequinActivatorSCRIPT
Он должен выводить сообщение при каждой загрузке ячейки о состоянии манекена (есть ли у него запомненные слоты одежды и что надевать для этого). Если манекен обновляется, нужно задаться вопросом, почему это происходит в обход отсутствия у него флага Respawn, либо почему в вики указана неполная инфа.
Lissenok, если от первого скрипта сообщение выводилось, значит, обновляется в обход флага. Референсы ванильных манекенов ни с чем не связаны, кроме XMarkerHeading (которые в свою очередь связаны только с конкретными манекенами и не имеют скриптов). Поэтому, маловероятно, что какой-то внешний скрипт может управлять обновлением манекена напрямую (для этого FormID манекена должно вызываться из скрипта, минуя Property). Сложно сказать.
Цитата Lissenok
Кстати, ванильный скрипт тоже компилируется с ошибкой: не является функцией или не существует.
"У меня есть заклинания, которых ты еще не знаешь. Изучи их".
Actor xP = Game.GetPlayer() ; объявляется переменная с типом актер, ее значение становится равным "игрок" Spell xS ; объявляется пустая переменная с типом заклинание Int iC = xP.GetSpellCount() ; объявляется переменная Int (целые числа) = кол-во заклинаний у актера xP (т.е. игрока) WHILE iC > 0 ; пока iC > 0, выполняется цикл iC -= 1 ; уменьшаем значение iC на 1 xS = xP.GetNthSpell(iC) ; переменная xS = заклинание в списке актера xP за номером iC, т.е. с конца в начало, первый элемент списка имеет номер 0. IF !akSpeaker.HasSpell(xS) ; если akSpeaker (актер, участвующий в диалоге с игроком, особая перем. топиков) не имеет заклинания xS akSpeaker.AddSpell(xS) ; то добавляем ему заклинание xS ENDIF ENDWHILE ; конец цикла, возврат в начало цикла для проверки условия ; конец кода, удаление объявленных перем. из памяти игры.
Цитата valambar
"Есть ли у тебя заклинания, которым я могу научиться?".
Actor xP = Game.GetPlayer() ; то же самое, только игрок и akSpeaker меняются местами Spell xS Int iC = akSpeaker.GetSpellCount() WHILE iC > 0 iC -= 1 xS = akSpeaker.GetNthSpell(iC) IF !xP.HasSpell(xS) xP.AddSpell(xS) ENDIF ENDWHILE
Требуется SKSE. Строки диалога будут показываться всегда, даже в случае, если игрок и актер синхронизировали заклинания. Потому, что простого условия, которое можно было бы использовать в Conditions, и которое проверяло бы соответствие заклинаний, конечно же, не существует. Для этого надо заранее проверять синхронность заклинаний и управлять определенной глобальной, а в Conditions диалога уже проверять ее значение. Как компилировать фрагменты.
2) Посмотри квест DialogueFollower и его осн. скрипт DialogueFollowerScript, как отпустить напарника. За это отвечает его функция DismissFollower(). В скрипте и квесте все существенные стороны добавления актера в напарники и удаление из напарников - в какие фракции добавлять, какие AI-пакеты использовать в алиасе, какие диалоги произносить, какие AV менять...
Чтобы удалить актера из напарников навсегда, нужно воспрепятствовать выполнению условий соотв. строк диалога ("мне нужна твоя помощь" и т.д.). Например, это можно сделать, отпустив этого напарника, и затем удалив его из фракции PotentialFollowerFaction. Некоторые топики могут быть в квесте DialogueFavorGeneric (проверить все вкладки квеста).
Следует помнить, что квест DialogueFollower отвечает только за ванильного напарника. Он может быть изменен другими модами, расширяющими систему напарников. Некоторые моды могут добавлять своих напарников, не зависящих от DialogueFollower (в простейшем случае это делается добавлением актеру пакета следования и добавлением его во фракции игрока, что можно произвести из любого скрипта). Поэтому, таких напарников отпустить нельзя, пока этот мод не учитывается твоим напрямую.
Чтобы отпустить напарника в определенный момент (выполнение стадии квеста), нужно делать это либо из скрипта стадии этого квеста (т.е. менять ванильный скрипт, что не есть хорошо с точки зрения совместимости), либо отслеживать состояние квеста (или нахождение игрока во фракции) из стороннего апдейта.
Предположим, у нас есть алиас игрока в модном квесте, который мы можем использовать для этого:
Quest Property DialogueFollower Auto ; авто Faction Property PotentialFollowerFaction Auto ; авто Actor Property pActor Auto ; конкретный актер, который покинет игрока в случае его присоединения к гр. войне Faction Property pFaction1 Auto ; фракция братьев бури (?) Faction Property pFaction2 Auto ; фракция империи (?)
EVENT OnUpdate() Actor xP = Game.GetPlayer() IF xP.IsInFaction(pFaction1) || xP.IsInFaction(pFaction2) DialogueFollowerScript xDFS = DialogueFollower AS DialogueFollowerScript IF pActor == xDFS.pFollowerAlias.GetReference() AS Actor xDFS.DismissFollower() ENDIF pActor.RemoveFromFaction(PotentialFollowerFaction) ELSE RegisterForSingleUpdate(10.0) ENDIF ENDEVENT
; апдейт будет выполняться с момента инициализации алиаса и до момента, когда игрок вступит (либо уже вступил) во фракцию гр. войны, после чего указанный актер удаляется из текущих и потенциальных напарников. Далее скрипт будет бесконечно бездействовать. Работает только для ванильной системы напарников.
3) Вроде там еще голос должен соответствовать ванильному перечню (форм-лист).
valambar, попробуй, может, получится проще. Если просто ставить условия: когда указанный актер в текущих напарниках, и игрок вступает в гр. конфликт, пакет следования отключается в результате невыполнения условий, актер уходит. При этом он продолжает оставаться в квесте DialogueFollower, как текущий напарник. Это значит, что он будет вынимать оружие вместе с игроком, будет вступать в бой на стороне игрока, если находится поблизости, ну, и все остальное, что делают напарники. Других нанять будет нельзя, пока этот не будет отпущен функцией DismissFollower(), либо эквивалентным этому кодом.
valambar, напарник - как правило, это AI-пакеты (следования и чего угодно еще), функция SetPlayerTeammate(), которая отвечает за одновременное с игроком обнажение оружия, вход в скрытность и прочее, фракции игрока (и/или Relationship, я в этом не сильно шарю), и доп. возможности, определяемые модными скриптами.
Единственность ванильного напарника заключается только в том, что в квесте всего 1 алиас, предназначенный для этого. Если сделать 128 алиасов, игра будет поддерживать столько же одновременных напарников. Конечно, придется немного поменять DialogueFollowerScript, условия связанных диалогов, добавить кейворды в алиасы, но, в целом, ничего сложного.
Чтобы отпустить напарника (очистить алиас, SetPlayerTeammate(false)), скриптовую функцию придется использовать в любом случае. Посмотри, как это реализовано в указанном квесте, что написано в главном скрипте, скриптах диалогов. Там нет ничего страшного.
valambar, диалоги не появляются, потому что квест не запущен, пока игра не будет сохранена и вновь загружена. В осн. вкладке нужно убрать (или наоборот) StartGameEnabled, RunOnce (я уже не помню, поищи в этой теме или теме по скриптам, тут это не раз обсуждалось). Квест запустится автоматически скриптом на нем:
EVENT OnInit() IF !IsCompleted() Start() ENDIF ENDEVENT
СК делает бэкапы .esp в папку Skyrim\Backup. На случай, если вылет связан с ошибкой в плагине.
nepewka, ты ж это еще в апреле спрашивал. Аbility раздаются актерам через плащ с большим радиусом, или через заклинание с большим радиусом (площадью), периодически (3 сек) кастуемое от игрока. На конечном эффекте плаща / эффекте заклинания скрипт "добавить указанное ability цели этого эффекта". Аbility отвечает за пересчет сопротивления актеров (каким именно образом, тебе виднее, поскольку мы сейчас говорим о Ф4, а не о Скайриме).
Сопротивление игрока пересчитывается в апдейте скрипта отдельного ability, выданного игроку в референс-алиасе (каким именно образом, не в курсе, т.к. это Ф4). Об особенностях апдейтов Ф4 мы уже говорили выше.
Сам плащ выдается игроку так же в референс-алиасе. Заклинание с площадью кастуется из второго апдейта в том же скрипте, в котором производится пересчет сопротивления игрока.
valambar, если не ошибаюсь, ИИ актеров самостоятельно выбирает оружие (посохи, заклинания), которое, по их мнению, является наиболее эффективным (с учетом боевого стиля актера). Поэтому, чтобы заставить актера пользоваться конкретным типом оружия, нужно поменять его боевой стиль, (возможно) уровни навыков, и исключить возможность использования другого оружия (например, скриптом убрав остальное оружие из инвентаря и заклинания из списка).
valambar, думаю, сразу после каста призванного лука актеру нужно менять боевой стиль с предпочтением Ranged. Также убрать все заклинания, которыми актер может пользоваться (либо модифицировать расход магии, чтобы заклинания заведомо не могли колдоваться, либо уменьшить макс. значение магии). Все эти предположения нужно тестировать.
Возможно, ИИ рассматривает призванный лук как бафф (атронах / маг. броня и т.д.). И накладывает его перед боем или в его начале. А далее пользуется магией разрушения, потому что может. Напрямую боевым ИИ управлять нельзя, что и написано в вики. Но можно создавать условия, направляющие боевые алгоритмы в определенное русло. Этим должен заниматься отдельный скрипт, который будет проверять обстановку и состояние актера, убирать лишние на данный момент его возможности, менять боевой стиль и прочее (например, заставлять его проигрывать опред. анимацию или идти в указанную точку, отключив от боя). Да, не думаю, что это просто.
Класс влияет на распределение очков при расчете уровня актера (т.е. на его финальные параметры). Поскольку актеры не могут повышать уровень, класс имеет значение только при первой встрече. В дальнейшем, их параметры можно менять скриптом.
valambar, да, значит, могут. Подзабыл уже. Но сути это не меняет - класс влияет только на распределение параметров актера. Либо при первой встрече, либо при повышении уровня игрока. Если планируется менять боевые стили в процессе боя, от изменения класса в бою не произойдет ровным счетом ничего.