• Прежде, чем задать вопрос, пожалуйста, убедитесь, что такой вопрос не задавался раньше. Старайтесь описать суть вопроса как можно подробней. • Прежде, чем опубликовать ответ на вопрос, пожалуйста, убедитесь, что обладаете необходимыми для этого знаниями. Старайтесь cформулировать суть ответа как можно лаконичней. • При желании ответить в приватном порядке, пожалуйста, воспользуйтесь ЛС. • При желании поблагодарить ответившего, пожалуйста, воспользуйтесь кнопкой "+" полезного сообщения.
Сообщения, не относящиеся к вопросам по скриптам Papyrus, ответам на них или уточнениям, являются оффтопом и могут быть удалены.
Красное солнце Есть вопросы по скриптам Papyrus? Пиши не в ЛС, а в эту тему.
ObjectReference Property prCollision Auto - это в скрипт панели вставить? В какую лучше строку скрипта вставить, чтоб не поломать скрипт? И потом как назначить нужную панель, через Properties или LinkedRef? prCollision.Disable() prCollision.Enable() - это в скрипт ручек добавить надо, в какую лучше строку скрипта вставить, чтоб не поломать скрипт? И потом как назначить нужную панель, через Properties или LinkedRef? Я нуб в скриптах, поэтому и уточняю
У тебя панели поднимаются двумя кнопками. На каждой скрипт, я правильно понимаю? Если так, то в каждый скрипт, в начале, в разделе объявления свойств, вставляешь: ObjectReference Property prCollision Auto И в СК значению prCollision присваиваешь ссылку на плоскость коллизии (в обоих скриптах на одну и туже плоскость). В скрипт кнопки "опустить", после TranslateToRef вставляешь: prCollision.Enable() В скрипт кнопки "поднять", после TranslateToRef вставляешь: prCollision.Disable() Если сам не разберешься - скинь скрипты я посмотрю.
Заранее спасибо за помощь. Нужен скрипт, который будет одевать персонажа обратно. Т.е. Есть триггер, наступая на который нпс раздевается, покидая его он должен одеться обратно. Пока нашла выриант только с disable enable, но это настолько коряво смотрится в игре, что глаза на лоб лезут. П.С. Рздевающая часть скрипта уже готова.
А вот тут я его включаю и выключаю, от чего он, конечно, одевается но его нехило так мограет по локации тудыма сюдыма.
Есть три пути решения: 1) Использовать расширение SKSE для того, чтобы одеть персонажа не используя Disable/Enable. (Некоторые игроки не используют SKSE) 2) Скрывать персонажа на время операции Disable/Enable и возвращать его потом на место. (НПС моргнет, но мотать по локации его не будет) 3) Если скриптом раздеваются обычные НПС, то можно их одевать назначая Outfit. (самый простой вариант, но срабатывать будет только на НПС имеющих Outfit)
LordVadim, Мне нравятся два первых, ибо SKSE я использую и мод делаю для себя, так что его все равно никто никогда не увидит) Другое дело, что это всего навсего второй скрипт за всю мою жизнь и есть риск, что мне мозгов не хватит разобраться с SKSE. В общем любой из первых двух на ваш выбор, какой удобней и проще вам.
Изменение репутации для пользователя LordVadim
LordVadimOffline
Сообщение №757
написано: 21 марта 2014, 08:13
| Отредактировано: LordVadim - 21 марта 2014, 08:14
В общем любой из первых двух на ваш выбор, какой удобней и проще вам.
Попробуй сначала всё же через Outfit:
Event OnTriggerLeave (ObjectReference akActionRef) Actor akActor = akActionRef as Actor If (akActor != Game.GetPlayer()) Utility.Wait(5) akActor.SetOutfit(akActor.GetActorBase().GetOutfit()) EndIf EndEvent
Если не будет срабатывать, тогда так:
Event OnTriggerLeave (ObjectReference akActionRef) Actor akActor = akActionRef as Actor If (akActor != Game.GetPlayer()) Utility.Wait(5) Form akItem Int akCount = akActor.GetNumItems();- Количество вещей в инвентаре While akCount > 0 akCount -= 1 akItem = akActor.GetNthForm(akCount);- Берём вещь под номером akCount if akItem.GetType() == 26;- Если это "Armor" akActor.EquipItem(akItem);- Одеваем вещь EndIf EndWhile EndIf EndEvent
Изменение репутации для пользователя Revil
RevilOffline
Сообщение №758
написано: 21 марта 2014, 08:45
| Отредактировано: Frei_Engel - 21 марта 2014, 09:19
LordVadim, Спасибо, попробую отчитаюсь. ____________ Не хочет компилировать. Первый вариант выдает: Bathtriggerscript1.psc(12,49): GetOutfit is not a function or does not exist
Второй вариант выдает: Bathtriggerscript1.psc(13,30): GetNumItems is not a function or does not exist Bathtriggerscript1.psc(13,12): type mismatch while assigning to a int (cast missing or types unrelated) Bathtriggerscript1.psc(16,29): GetNthForm is not a function or does not exist Bathtriggerscript1.psc(17,22): GetType is not a function or does not exist Bathtriggerscript1.psc(17,32): cannot compare a none to a int (cast missing or types unrelated)
Под спойлером полные скрипты, на случай если нужно посмотреть построчно.
Event OnTriggerEnter(ObjectReference akActionRef) (akActionRef AS Actor).UnEquipAll() EndEvent
Event OnTriggerLeave (ObjectReference akActionRef) Actor akActor = akActionRef as Actor If (akActor != Game.GetPlayer()) Utility.Wait(5) akActor.SetOutfit(akActor.GetActorBase().GetOutfit()) EndIf EndEvent
Event OnTriggerEnter(ObjectReference akActionRef) (akActionRef AS Actor).UnEquipAll() EndEvent
Event OnTriggerLeave (ObjectReference akActionRef) Actor akActor = akActionRef as Actor If (akActor != Game.GetPlayer()) Utility.Wait(5) Form akItem Int akCount = akActor.GetNumItems() While akCount > 0 akCount -= 1 akItem = akActor.GetNthForm(akCount) if akItem.GetType() == 26 akActor.EquipItem(akItem) EndIf EndWhile EndIf EndEvent
Значит у тебя не установлены скрипты SKSE. Из архива SKSE взять все содержимое папки SKSE\Data\Scripts и скопировать с заменой в папку Skyrim\Data\Scripts
В общем, есть квестовый скрипт, который должен вещшать на мобов абилки в определенном радиусе. Скрипт этот сделан по шаблону, выложенному AlexTirex в этой теме с полгода назад. Квест запускается один раз при первом запуске игры с подключенным модом и не завершается.
Spell Property aaARCRWeapArmMatSpecBase auto Spell Property aaARCRabilityWeapArmMatSpecDrag auto Spell Property aaARCRabilityUndead auto Spell Property aaARCRabilityUndeadMod auto Faction Property _00SICUndeadFaction auto
Actor[] ClosestActors
Event OnInit() ClosestActors = new Actor[120] ; назначаем массив на 120 ячеек While IsRunning() ; работает, пока квест активный int iIndex = 40 ; количество попыток поиска актёров While(iIndex > 0) ; поиск актёров около ГГ iIndex -= 1 Actor randomActor = Game.FindRandomActorFromRef(Game.GetPlayer(), 30000.0) ; радиус поиска ~4096*7 If !randomActor.HasSpell(aaARCRWeapArmMatSpecBase) ; если у НПС нет спелла randomActor.AddSpell(aaARCRWeapArmMatSpecBase) ; добавляем спелл endIf If !randomActor.HasSpell(aaARCRabilityWeapArmMatSpecDrag) randomActor.AddSpell(aaARCRabilityWeapArmMatSpecDrag) endIf If !randomActor.HasSpell(aaARCRabilityUndead) randomActor.AddSpell(aaARCRabilityUndead) endIf If !randomActor.HasSpell(aaARCRabilityUndeadMod) && randomActor.IsInFaction(_00SICUndeadFaction) randomActor.AddSpell(aaARCRabilityUndeadMod) endIf int iEmpty = ClosestActors.Find(none) ; поиск свободного слота в массиве if iEmpty > -1 ClosestActors [iEmpty]= randomActor ; записываем актёра в массив endif int iIndexActor = 120 While iIndexActor > 0 ; проверка массива iIndexActor -= 1 if ClosestActors [iIndexActor]; если есть актёр под этим номером if (ClosestActors[iIndexActor].GetDistance(Game.GetPlayer())> 30000) || ClosestActors[iIndexActor].IsDead() ; если актёр далеко или актёр мёртв ClosestActors[iIndexActor].RemoveSpell(aaARCRWeapArmMatSpecBase) ClosestActors[iIndexActor].RemoveSpell(aaARCRabilityWeapArmMatSpecDrag) ClosestActors[iIndexActor].RemoveSpell(aaARCRabilityUndead) ClosestActors[iIndexActor].RemoveSpell(aaARCRabilityUndeadMod) ;ClosestActors[iIndexActor].DispelAllSpells() ClosestActors [iIndexActor]= none ; очищаем слот в массиве endif endif endWhile endWhile Utility.Wait(3.0) ; через 3 сек. новый поиск актёров endWhile int iIndexClear = 120 While iIndexClear > 0 ; очистка массива iIndexClear -= 1 if ClosestActors [iIndexClear]; если есть актёр под этим номером ClosestActors[iIndexClear].RemoveSpell(aaARCRWeapArmMatSpecBase) ClosestActors[iIndexClear].RemoveSpell(aaARCRabilityWeapArmMatSpecDrag) ClosestActors[iIndexClear].RemoveSpell(aaARCRabilityUndead) ClosestActors[iIndexClear].RemoveSpell(aaARCRabilityUndeadMod) ;ClosestActors[iIndexClear].DispelAllSpells() ClosestActors [iIndexClear]= none ; очищаем слот в массиве endif endWhile Debug.Notification("Alliria NPC quest and script had finished") ; сообщение для теста endEvent
Однако эффекта не вижу. Похоже, спеллы просто не назначаются. Лог папируса выдает следующее: stack:
Код
[aaAlliriaRCRNPCQuest (4A1536DE)].aaAlliriaRCRNPCQuestScript.OnInit() - "aaAlliriaRCRNPCQuestScript.psc" Line ? [03/24/2014 - 11:44:45PM] warning: Assigning None to a non-object variable named "::temp13" stack: [aaAlliriaRCRNPCQuest (4A1536DE)].aaAlliriaRCRNPCQuestScript.OnInit() - "aaAlliriaRCRNPCQuestScript.psc" Line ? [03/24/2014 - 11:44:45PM] Error: Cannot call RemoveSpell() on a None object, aborting function call
Однако эффекта не вижу. Похоже, спеллы просто не назначаются.
1) Ошибки возникают из за того, что функция FindRandomActorFromRef возвращает None (никого не найдено), а скрипт пытается добавить Spell. 2) На ком это должно срабатывать? В таком виде скрипт даже кроликам будет пытаться добавлять Spell. Можно сделать проверку GetRace() и FormListHeadPartsAllRacesMinusBeast. 3) Код скрипта не эффективен. Если хотите могу подправить, но напишите подробно условия срабатывания.
Однако эффекта не вижу. Похоже, спеллы просто не назначаются. Лог папируса выдает следующее:
Если компилятор выдаёт ошибки, то это значит, что скрипт не скомпилирован и работать не будет. Поэтому и эффекта не видно.
Возможно, компилятору не нравится сам массив. Тогда просто введи временную переменную Actor и назначай на неё актёра из массива, потом работай с этой переменной, а не с массивом. Тогда компилятор будет видеть "чистого актёра", и возможно, он перестанет кочевряжиться. Попробуй такой вариант:
Scriptname aaAlliriaRCRNPCQuestScript extends Quest Spell Property aaARCRWeapArmMatSpecBase auto Spell Property aaARCRabilityWeapArmMatSpecDrag auto Spell Property aaARCRabilityUndead auto Spell Property aaARCRabilityUndeadMod auto Faction Property _00SICUndeadFaction auto Actor[] ClosestActors Event OnInit() Actor TempActor ClosestActors = new Actor[120] ; назначаем массив на 120 ячеек While IsRunning() ; работает, пока квест активный int iIndex = 40 ; количество попыток поиска актёров While(iIndex > 0) ; поиск актёров около ГГ iIndex -= 1 Actor randomActor = Game.FindRandomActorFromRef(Game.GetPlayer(), 30000.0) ; радиус поиска ~4096*7 If !randomActor.HasSpell(aaARCRWeapArmMatSpecBase) ; если у НПС нет спелла randomActor.AddSpell(aaARCRWeapArmMatSpecBase) ; добавляем спелл endIf If !randomActor.HasSpell(aaARCRabilityWeapArmMatSpecDrag) randomActor.AddSpell(aaARCRabilityWeapArmMatSpecDrag) endIf If !randomActor.HasSpell(aaARCRabilityUndead) randomActor.AddSpell(aaARCRabilityUndead) endIf If !randomActor.HasSpell(aaARCRabilityUndeadMod) && randomActor.IsInFaction(_00SICUndeadFaction) randomActor.AddSpell(aaARCRabilityUndeadMod) endIf int iEmpty = ClosestActors.Find(none) ; поиск свободного слота в массиве if iEmpty > -1 ClosestActors [iEmpty]= randomActor ; записываем актёра в массив endif int iIndexActor = 120 While iIndexActor > 0 ; проверка массива iIndexActor -= 1 TempActor = ClosestActors [iIndexActor]if TempActor ; если есть актёр под этим номером if (TempActor.GetDistance(Game.GetPlayer()) > 30000) || TempActor.IsDead() ; если актёр далеко или актёр мёртв TempActor.RemoveSpell(aaARCRWeapArmMatSpecBase) TempActor.RemoveSpell(aaARCRabilityWeapArmMatSpecDrag) TempActor.RemoveSpell(aaARCRabilityUndead) TempActor.RemoveSpell(aaARCRabilityUndeadMod) ;TempActor.DispelAllSpells() ClosestActors [iIndexActor]= none ; очищаем слот в массиве endif endif endWhile endWhile Utility.Wait(3.0) ; через 3 сек. новый поиск актёров endWhile int iIndexClear = 120 While iIndexClear > 0 ; очистка массива iIndexClear -= 1 TempActor = ClosestActors [iIndexClear]if TempActor ; если есть актёр под этим номером TempActor.RemoveSpell(aaARCRWeapArmMatSpecBase) TempActor.RemoveSpell(aaARCRabilityWeapArmMatSpecDrag) TempActor.RemoveSpell(aaARCRabilityUndead) TempActor.RemoveSpell(aaARCRabilityUndeadMod) ; TempActor.DispelAllSpells() ClosestActors [iIndexClear]= none ; очищаем слот в массиве endif endWhile Debug.Notification("Alliria NPC quest and script had finished") ; сообщение для теста endEvent
Радиус поиска 30000 - это слишком много, т.к. загружаются в игру максимум 3 ячейки от ГГ (1 ячейка == 4098), в интерьерах так вообще будут видны и обрабатываться все имеющиеся там НПС, хоть и находятся они "в трёх днях пути". А так же в скрипте нет проверки на "что это за актёр", т.е. скрипт без этого будет вешать абилки и на крабов, и на драугов и на всё движущееся и шевелящееся, а оно надо? (достаточно проверки наличия кейворда ActorTypeNPC).
AleksTirex, скрипт из моего поста компиллятор компиллирует. Тот лог - это лог, который Папирус ведет в игре (Documents/My Games/Skyrim/Logs/Script/Papyrus0.log) Твой новый вариант - не компиллирует. Вот лог компиллятора:
Код
Starting 1 compile threads for 1 files... Compiling "aaAlliriaRCRNPCQuestScript"... F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(37,15): variable TempActor is undefined F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(37,15): type mismatch while assigning to a none (cast missing or types unrelated) F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(38,18): variable TempActor is undefined F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(39,23): variable TempActor is undefined F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(39,33): none is not a known user-defined type F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(39,62): cannot compare a none to a int (cast missing or types unrelated) F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(39,62): cannot relatively compare variables to None F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(40,22): variable TempActor is undefined F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(40,32): none is not a known user-defined type F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(41,22): variable TempActor is undefined F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(41,32): none is not a known user-defined type F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(42,22): variable TempActor is undefined F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(42,32): none is not a known user-defined type F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(43,22): variable TempActor is undefined F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(43,32): none is not a known user-defined type F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(55,4): variable TempActor is undefined F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(55,4): type mismatch while assigning to a none (cast missing or types unrelated) F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(56,7): variable TempActor is undefined F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(57,7): variable TempActor is undefined F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(57,17): none is not a known user-defined type F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(58,7): variable TempActor is undefined F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(58,17): none is not a known user-defined type F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(59,7): variable TempActor is undefined F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(59,17): none is not a known user-defined type F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(60,7): variable TempActor is undefined F:\Programs\Steam\steamapps\common\skyrim\Data\Scripts\Source\aaAlliriaRCRNPCQuestScript.psc(60,17): none is not a known user-defined type No output generated for aaAlliriaRCRNPCQuestScript, compilation failed.
Batch compile of 1 files finished. 0 succeeded, 1 failed. Failed on aaAlliriaRCRNPCQuestScript
LordVadim, так проблема в том, почему возвращается none или temp13 в ячейках, заполненных актерами.
По условиям срабатывания и типу актеров: aaARCRabilityUndead - выдается всей нежити, включая вампиров и дохлых драконов (условия прописаны в самом спелле); aaARCRabilityUndeadMod - выдается актерам, имеющим фракцию _00SICUndeadFaction; aaARCRabilityWeapArmMatSpecDrag (она пока "пустая") и aaARCRWeapArmMatSpecBase - выдаются всем гуманоидам.
Изменение репутации для пользователя LordVadim
LordVadimOffline
Сообщение №767
написано: 25 марта 2014, 17:35
| Отредактировано: LordVadim - 25 марта 2014, 18:21
Spell Property aaARCRWeapArmMatSpecBase auto Spell Property aaARCRabilityWeapArmMatSpecDrag auto Spell Property aaARCRabilityUndead auto Spell Property aaARCRabilityUndeadMod auto Faction Property _00SICUndeadFaction auto
FormList Property prClosestActors Auto;- Используем форм-лист вместо массива (создать пустой форм-лист prClosestActors в СК и не забыть присвоить свойство в скрипте)
Actor randomActor Int iIndex
Event OnInit() While IsRunning();- Работает, пока квест активный iIndex = 40;- Количество попыток поиска НПС While iIndex > 0;- Поиск НПС около ГГ iIndex -= 1 randomActor = Game.FindRandomActorFromRef(Game.GetPlayer(), 30000.0);- Алекс прав - радиус великоват, я бы поставил не более 10000 if randomActor != None;- Если НПС найден if !prClosestActors.HasForm(randomActor);- Если НПС нет в форм-листе значит и спелов у него нет (если они даются только из скрипта) prClosestActors.AddForm(randomActor);- Добавляем НПС в форм-лист randomActor.AddSpell(aaARCRWeapArmMatSpecBase);- Добавляем спелл randomActor.AddSpell(aaARCRabilityWeapArmMatSpecDrag);- Добавляем спелл randomActor.AddSpell(aaARCRabilityUndead);- Добавляем спелл if randomActor.IsInFaction(_00SICUndeadFaction);- Если НПС принадлежит фракции _00SICUndeadFaction randomActor.AddSpell(aaARCRabilityUndeadMod);- Добавляем спелл EndIf EndIf else;- Если поблизости нет НПС, то нет смысла 40 раз вызывать функцию FindRandomActorFromRef iIndex = 0;- Выходим из цикла While iIndex > 0, чтобы сработала задержка EndIf EndWhile iIndex = prClosestActors.GetSize();- Количество НПС в форм-листе While iIndex > 0;- Поиск далёких или мёртвых НПС iIndex -= 1 randomActor = prClosestActors.GetAt(iIndex) as Actor;- Текущий НПС из форм-листа if (randomActor.GetDistance(Game.GetPlayer()) > 30000) || (randomActor.IsDead());- Если НПС далеко или мёртв(я бы поставил 12000) if randomActor.HasSpell(aaARCRWeapArmMatSpecBase);- Если у НПС есть спелл randomActor.RemoveSpell(aaARCRWeapArmMatSpecBase);- Убираем спелл EndIf if randomActor.HasSpell(aaARCRabilityWeapArmMatSpecDrag);- Если у НПС есть спелл randomActor.RemoveSpell(aaARCRabilityWeapArmMatSpecDrag);- Убираем спелл EndIf if randomActor.HasSpell(aaARCRabilityUndead);- Если у НПС есть спелл randomActor.RemoveSpell(aaARCRabilityUndead);- Убираем спелл EndIf if randomActor.HasSpell(aaARCRabilityUndeadMod);- Если у НПС есть спелл randomActor.RemoveSpell(aaARCRabilityUndeadMod);- Убираем спелл EndIf prClosestActors.RemoveAddedForm(randomActor);- Убираем НПС из форм-листа iIndex = prClosestActors.GetSize();- Пересчитываем количество НПС в форм-листе EndIf EndWhile Utility.Wait(5.0);- Задержка. я поставил 5 сек. это снизит нагрузку на движок игры, да и при таком радиусе всё равно будет успевать срабатывать EndWhile;- Если Квест не завершается, то и цикл не кончится никогда - поэтому нет смысла писать какой либо код после EndWhile EndEvent
В скрипт не включил проверки на ком срабатывать, я так понял, что они прописаны в условиях спеллов. Кстати, если спеллы не срабатывают - проверь правильность написания этих условий.
Уважаемые скриптеры, срочно нужна ваша помощь! Проблема вот в чём: у меня деревья не ЛОДятся. Я хочу вручную расставить ЛОД-модели деревьев внутри обычных, отметить галочкой IsFullLod. Нужен скрипт, который делает так, чтобы на близких расстояниях этих ЛОД-деревьев не было видно, а на расстоянии появления лодов они включались. Если возможно, учитываться должен параметр UGridsToLoad (подгружаемые ячейки), так как некоторые игроки могут изменить этот параметр, и лоды деревьев могут перемежаться с обычными деревьями. Варианты типа пересоздай ЛОДы не прокатят. Я уже сделал всё что мог с лодами, остался только этот параметр. Большое спасибо всем, кто откликнеться.
Изменение репутации для пользователя LordVadim
LordVadimOffline
Сообщение №769
написано: 25 марта 2014, 19:27
| Отредактировано: LordVadim - 25 марта 2014, 20:06
Уважаемые скриптеры, срочно нужна ваша помощь! Проблема вот в чём: у меня деревья не ЛОДятся. Я хочу вручную расставить ЛОД-модели деревьев внутри обычных, отметить галочкой IsFullLod. Нужен скрипт, который делает так, чтобы на близких расстояниях этих ЛОД-деревьев не было видно, а на расстоянии появления лодов они включались. Если возможно, учитываться должен параметр UGridsToLoad (подгружаемые ячейки), так как некоторые игроки могут изменить этот параметр, и лоды деревьев могут перемежаться с обычными деревьями. Варианты типа пересоздай ЛОДы не прокатят. Я уже сделал всё что мог с лодами, остался только этот параметр. Большое спасибо всем, кто откликнеться.
Как привязать к UGridsToLoad - не знаю. Все, что могу предложить - скрипт для скрытия/отображения дерева:
ScriptName LodTreeOnOffSCRIPT extends ObjectReference;- Скрипт на статическом объекте
Event OnInit() RegisterForUpdate(5);- Включаем процедуру обновления 1 раз в 5 секунд EndEvent
Event OnUpdate();- Процедура обновления if GetLinkedRef().GetDistance(Game.GetPlayer()) > 30000;- Если расстояние до ГГ > 30000 (значение подобрать опытным путём) GetLinkedRef().Enable();- Показываем дерево else GetLinkedRef().Disable();- Скрываем дерево EndIf EndEvent
Скрипт на любой статический объект рядом с деревом. Дерево привязать к объекту через LinkedRef в СК. Если надо скрывать/отображать несколько стоящих рядом деревьев, то остальные привязываются к главному дереву, через Enable Parent в СК.
LordVadim, спасибо большущее, всё работает как часы. Интересная особенность игры: если выходить из ячейки, то предметы долго ещё не исчезают из поля зрения, а если заходить в нее, то появляются перед самым носом. Выбрал среднее значение - 8000.
LordVadim, сделала, как ты сказал: скомпиллировала твой скрипт, создала форм-лист, прописала его в свойствах скрипта, убрала условия из раздаваемого закла aaARCRabilityUndead (т.е. теперь он должен работать вообще на всех). То же самое, эффекта на нпс не вижу. Папирус в игровом логе пишет то же:
Код
stack: [aaAlliriaRCRNPCQuest (4B1536DE)].aaAlliriaRCRNPCQuestScript.OnInit() - "aaAlliriaRCRNPCQuestScript.psc" Line ? [03/26/2014 - 10:36:37PM] Error: Cannot call IsDead() on a None object, aborting function call stack: [aaAlliriaRCRNPCQuest (4B1536DE)].aaAlliriaRCRNPCQuestScript.OnInit() - "aaAlliriaRCRNPCQuestScript.psc" Line ? [03/26/2014 - 10:36:37PM] warning: Assigning None to a non-object variable named "::temp7"
Подскажите какую команду можно использовать чтобы заблокировать контейнер в событии OnActivate, т.е. чтобы меню контейнера не открывалось вовсе? Return не работает в этом событии, BlockActivation() тоже.
Изменение репутации для пользователя LordVadim
LordVadimOffline
Сообщение №779
написано: 27 марта 2014, 12:28
| Отредактировано: LordVadim - 27 марта 2014, 12:39
Пришлось кое что переделать, но у меня заработало. Подробности под спойлером:
В квесте сделать алиас игрока и на него скрипт:
Scriptname aaTestSCRIPT extends ReferenceAlias;- Скрипт на алиасе игрока
Spell Property aaTest_Spell auto;- Спелл должен быть способностью
FormList Property aaTest_FormList Auto;- Используем форм-лист вместо массива (создать пустой форм-лист prClosestActors в СК и не забыть присвоить свойство в скрипте)
Actor Property prActor Auto Hidden Int ivIndex
Event OnInit();- При инициализации RegisterForSingleUpdate(5) EndEvent
Event OnUpdate() ivIndex = 40;- Количество попыток поиска НПС While ivIndex > 0;- Поиск НПС около ГГ ivIndex -= 1 prActor = Game.FindRandomActorFromRef(Game.GetPlayer(), 10000.00);- Радиус поиска if (prActor != None) && (prActor != Game.GetPlayer());- Если НПС найден if !aaTest_FormList.HasForm(prActor);- Если НПС нет в форм-листе значит и спелов у него нет (если они даются только из скрипта) aaTest_FormList.AddForm(prActor);- Добавляем НПС в форм-лист prActor.AddSpell(aaTest_Spell, False);- Добавляем спелл EndIf else;- Если поблизости нет НПС, то нет смысла 40 раз вызывать функцию FindRandomActorFromRef ivIndex = 0;- Выходим из цикла While ivIndex > 0, чтобы сработала задержка EndIf EndWhile ivIndex = aaTest_FormList.GetSize();- Количество НПС в форм-листе While ivIndex > 0;- Поиск далёких или мёртвых НПС ivIndex -= 1 prActor = aaTest_FormList.GetAt(ivIndex) as Actor;- Текущий НПС из форм-листа if (prActor.GetDistance(Game.GetPlayer()) > 12000) || (prActor.IsDead());- Если НПС далеко или мёртв (радиус поиска) if prActor.HasSpell(aaTest_Spell);- Если у НПС есть спелл prActor.RemoveSpell(aaTest_Spell);- Убираем спелл EndIf aaTest_FormList.RemoveAddedForm(prActor);- Убираем НПС из форм-листа ivIndex = aaTest_FormList.GetSize();- Пересчитываем количество НПС в форм-листе EndIf EndWhile RegisterForSingleUpdate(5) EndEvent
Actor selfRef EffectShader Property FireFXShader Auto explosion property _MVADeathEXPL auto int Health float property Delay1 = 0.5 auto float property Delay2 = 0.5 auto float property Delay3 = 0.5 auto
EVENT OnEffectStart(Actor Target, Actor Caster) selfRef = caster ENDEVENT
EVENT onDying(actor myKiller) Health = selfRef.GetAV("Health") as int if Health <= 0 wait(Delay1) FireFXShader.Play(selfRef) wait(Delay2) selfRef.placeAtMe(_MVADeathEXPL) wait(Delay3) FireFXShader.Stop(selfRef) endif ENDEVENT
Без "EVENT OnEffectStart" отказывается работать (по-моему, даже не компилируется). И еще: если актер погибает под добиванием в ближнем бою, событие не активируется. Нужно это обойти. Скрипт взят с атронаха. Заранее спасибо.
Nothing is...
Форум » TES V: Skyrim » Мастерская » Вопросы по скриптам Papyrus (О скриптах Papyrus (Skyrim). Скриптеры не проходите мимо!)