Форум » Записи участника [AleksTirex]

Результаты поиска
AleksTirex  Offline  Сообщение №271 | Тема: Вопросы по Creation Kit. Старая тема написано: 15 декабря 2013, 16:20


Архимаг


371
Цитата Myprism

Изложен простой метод исправления проблемы с помощью TES5Edit.



В принципе, это голимый откат навмешей на дефолт, такое можно и в СК сделать (само же переписывание FormID... вот лично я, как-то противник такого). И это не исправление как таковое, а если вы нажмёте "финализацию", то опять получите рефинализацию ячейки. Баг разрабов никуда не денется с таким методом, как были кривые навмеши, так они такими и останутся. Увы.

AleksTirex  Offline  Сообщение №272 | Тема: Вопросы по скриптам Papyrus написано: 16 декабря 2013, 17:51


Архимаг


371
DarkVetal, вот скрипт, он вешается на лифт.
 
Скрипт на лифте.
 
float fZZ = 512.0
bool bHight


auto state StateDefault
Event OnActivate(ObjectReference akActionRef)
  gotoState("StateWait")
  if bHight
    TranslateTo(akObject.X, akObject.Y, akObject.Z - fZZ, 0.0, 0.0, 0.0, 200.0)
    bHight = false
  else
    TranslateTo(akObject.X, akObject.Y, akObject.Z + fZZ, 0.0, 0.0, 0.0, 200.0)
    bHight = true
  endif
endEvent
endState

 
state StateWait
Event OnTranslationComplete()
  gotoState("StateDefault")
endEvent
endState

 
Event OnTranslationFailed()
  OnCellDetach()
endEvent

 
Event OnCellDetach()
  gotoState("StateDefault")
  bHight = false
  Reset()
endEvent

 
**********************************************

Скрипт на рычагах. На каждом рычаге назначается лифт в графе LinkedRef.
 
Event OnActivate(ObjectReference akActionRef)
  GetLinkedRef().Activate(self)
endEvent


***********************************************
Если выйти из этого помещения с лифтом, то сам лифт опустится на исходную позицию (вниз).
Если лифт изначально стоит на верху, то поменяй местами "+" и "-" в команде перемещения.
При неудачном движении лифта есть "авариный сброс" и лифт со скриптом придут в исходное положение.
Пока лифт движется активировать его невозможно, надо подождать до полной остановки.
Все рычаги работают однотипно, нет рычагов "вниз" и "наверх". Если лифт внизу, то при нажатии на любой рычаг он поедет вверх, а если на верху, то поедет вниз.

Добавлено (16 Декабря 2013, 21:51)
---------------------------------------------

Цитата LordVadim

Scriptname LiftUp extends ObjectReference 
Event OnActivate(ObjectReference akActionRef)     
if GetLinkedRef().Z == координата                                        ; лифт внизу (координату по оси Z взять из СК)            GetLinkedRef().TranslateTo(GetLinkedRef().X, GetLinkedRef().Y, GetLinkedRef().Z + fZZ, 0.0, 0.0, 0.0, 200.0)  ; отправка лифта вверх     
 endif 
endEvent



Так делать нельзя. ;)
Если в скрипте присутствует "добавляющее число" (fZZ) и нет жёсткой привязки (координата, параметр и прочее), то при повторной активации команды это "добавленное число" добавится и получится уже двойное значение.
Чтобы этого избежать необходимо блокировать повторный/внеочередной вызов команды. Можно доп. переменными или статусами.
 
Это касается любых скриптов с подобными переменными типа fZZ.

AleksTirex  Offline  Сообщение №273 | Тема: Вопросы по Creation Kit. Старая тема написано: 17 декабря 2013, 15:30


Архимаг


371
MeeRaGe, удали/вытащи из папки Скайрима файлы ENB (d3d9.dll, d3d9.fx, d3d9_SFX.dll).

AleksTirex  Offline  Сообщение №274 | Тема: Вопросы по скриптам Papyrus написано: 18 декабря 2013, 14:05


Архимаг


371
Цитата Greez

подскажите наиболее правильный способ подсчитать кол-во видов предметов в инвентаре определенной категории.



int iFormIndex = akActor.GetNumItems() - количество категорий/типов/базовых предметов
 
Определить конкретный тип объекта, типа "мясо", стандартыми методами нельзя, т.к. мясо лося и мясо крысы ничем не отличается вообще, только ID.
(разрабы не простовляли кейворды на типы предметов)
 
Можно проверить по основному типу объекта: яд, пища, зелье (по кейвордам). Но выделить "это == мясо" не получится.
 
int iPotion
int iPoison
int Food

 
Function ChengInventory()
  int iFormIndex = akActor.GetNumItems()
  iPotion = 0
  iPoison = 0
  Food = 0
  While iFormIndex > 0
    iFormIndex -= 1
    Form kForm = akActor.GetNthForm(iFormIndex)
    if kForm.GetType() == 46 ; Potion
      if kForm.HasKeywordString("vendoritempotion") ; зелье
        iPotion += 1
      elseif kForm.HasKeywordString("vendoritempoison") ; яд
        iPoison += 1
      elseif kForm.HasKeywordString("vendoritemfood") ; пища/вино
        Food += 1
      endif
    endif
  endWhile
endFunction

 
*****************************************************
 
Можно конкретизировать поиск, тогда надо сделать форм-лист со своими проверяемыми предметами. Например, в лист сперва вносите всё вино, потом добавляете всё мясо, потом всё ... и т.д. Получится список, в котором отсортированы предметы Potion. Можно сделать отдельными списками на каждый тип продукта, это как будет удобнее автору. Далее проверка очень простая:
 
FormList Property ListItemPotion Auto
 
Function ChengInventory()
  int iFormIndex = akActor.GetNumItems()
  While iFormIndex > 0
    iFormIndex -= 1
    Form kForm = akActor.GetNthForm(iFormIndex)
    int iIndex = ListItemPotion.Find(kForm)
    if iIndex != -1
      if iIndex <= 12 ; это вино, т.к. в листе первые 12 объектов == вино
        ; считаем кол-во вина
      elseif iIndex > 12 && iIndex <= 25 ; это мясо, т.к. в листе с 13 по 25 объект == мясо
        ; считаем кол-во мяса
      elseif iIndex > 25 ; это продукты питания типа сыра и лука, т.к. ...
        ; считаем кол-во
      endif
    endif
  endWhile
endFunction

 
*********************************************
 
На этом принципе построения можно создать много разных вариантов скрипта.
(необходимые переменные добавь сам, и не забудь назначить/обозначить akActor)

AleksTirex  Offline  Сообщение №275 | Тема: Вопросы по скриптам Papyrus написано: 20 декабря 2013, 15:17


Архимаг


371
Цитата DarkVetal

AleksTirex, не знаеш случайно, а можна ли во время движения лифта сделать так, чтобы ГГ или напарник стояли жёстко на платформе.  А то лифт едет вверх - ноги встряют в модель, едет вниз - персонаж зависает в воздухе, а потом падает вдогонку на лифт.  Всё бы ничего, но кроме двухэтажного дома планирую ещё и небоскрёб, а там уже падение критично (шутка ли, 100 этажей, вровень с Высоким Хротгаром)



Скинь ниф лифта и заодно положи в архив все исходники скриптов, связанные с этим лифтом.
Есть разные варианты решения, я посмотрю, какой лучше подойдёт.

AleksTirex  Offline  Сообщение №276 | Тема: Вопросы по Creation Kit. Старая тема написано: 30 декабря 2013, 18:35


Архимаг


371
Цитата VALKNUT

Пока Криста не начнет создавать НПС, будем с этим иметь геморрой с кулак... я давно спрашивал Кристу об этом... она не отказала, но и воз по ныне там.



А причём здесь Криста? Подобные вопросы надо задавать создателям этих моделей, а не ей.
 
При создании любой модели автор обязательно проверяет её в игре, и не увидеть такого положения модели в СК просто невозможно. А раз автор видел и ничего не исправил, значит, это или невозможно, или слишком трудно.
 
На сколько я знаю, на этом и большинстве других форумов нет ни единого модмейкера, способного создать/переделать модель головы, а уж сделать её без багов... и речи не идёт.
Увы, но привыкайте к такому виду в СК этой головы, по другому никогда не будет.
 
********************
Я тоже попробовал использовать эту модель головы для своего НПС, но в последствии отказался. Уж больно забагована она, особенно в плане лицевой анимации, да и "морфинг" плохой - лицо получается гораздо хуже/некрасивее, нежели  на дефолтной модели.

AleksTirex  Offline  Сообщение №277 | Тема: Вопросы по Creation Kit. Старая тема написано: 30 декабря 2013, 19:06


Архимаг


371
Цитата VALKNUT

Хотеть НОРМАЛЬНУЮ голову в редакторе, это не плохой тон, это надежда на возможное исправление БАГА(а это именно баг, а не фича)



Тогда извини, я совсем не это имел в виду.

AleksTirex  Offline  Сообщение №278 | Тема: Вопросы по скриптам Papyrus написано: 24 января 2014, 18:49 | Отредактировано: AleksTirex - 24 января 2014, 22:43


Архимаг


371
Цитата Иероним

при активации рычага или же попадание в определённое место на карте, скажем ходьба через коридор где игрок наступает на триггер и появляется нужный объект. Например чтобы пройдя коридор за спиной появился, предположим, скелет.



Скрипт вешается на активатор(рычаг) или на триггер. Там пошагово расписано, поэтому там всё понятно.

Scriptname TriggerActivatorToCreateActorScript extends ObjectReference

ActorBase Property akActorBase auto  ; базовый актёр, который появится за спиной ГГ
Static Property xMarkerHeading auto  ; маркер (нажать кнопку Auto-Fill)

Event OnActivate(ObjectReference akActionRef)
if akActionRef == Game.GetPlayer()
CreateActor()
endif
endEvent

Event OnTriggerEnter(ObjectReference akActionRef)
if akActionRef == Game.GetPlayer()
CreateActor()
endif
endEvent

Function CreateActor()
Actor akPlayer = Game.GetPlayer()
ObjectReference akMarker = akPlayer.PlaceAtMe(xMarkerHeading) ; создаём маркер у ГГ
float postargX = akPlayer.X - 100 * Math.Sin(akPlayer.GetAngleZ())
float postargY = akPlayer.Y - 100 * Math.Cos(akPlayer.GetAngleZ())
akMarker.MoveTo(akPlayer, postargX, postargY) ; отодвигаем маркер на 100 ед. за спину ГГ
Actor akNewActor = akMarker.PlaceActorAtMe(akActorBase) ; создаём актёра у маркера
; можно заставить актёра что-то делать, например akNewActor.StartCombat(akPlayer)
Utility.Wait(5.0)  ; ждём 5 сек. потом удаляем актёра и временный маркер
akMarker.Disable()
akMarker.Delete()
akNewActor.Disable()
akNewActor.Delete()
endFunction

AleksTirex  Offline  Сообщение №279 | Тема: Вопросы по скриптам Papyrus написано: 24 января 2014, 22:42 | Отредактировано: AleksTirex - 24 января 2014, 22:45


Архимаг


371
Цитата LordVadim

AleksTirex, разве с xMarkerHeading нужно использовать не PlaceAtMe()?  И зачем удалять созданного актера через 5 секунд после создания? Он же для чего то создавался...  И попутно вопрос: вот таким образом созданный, а потом удаленный актер оставляет какие либо следы в сейвах или нет?



Да, всё верно, это я со слепу и по запарке ошибся надо PlaceAtMe().

Удалять же актёра... так он сам писал: "...появлялся скелет, а потом исчезал." (но сейчас уже не нахожу этой строки, или он откорректировал сообщение, или я уже совсем суперстар, типа совсем старый, слепой и чуть-чуть в маразме :D ).
Если актёра удалять не надо, тогда просто удалить строки ожидания и удаления актёра:
  Utility.Wait(5.0)  ; ждём 5 сек. потом удаляем актёра и временный маркер
  akNewActor.Disable()
  akNewActor.Delete()


Следов в сейвах, в принципе, остаться не должно, для этого и пишется команда Delete(), т.е. не выключить, а именно удалить.

******************************************

Иероним, свойствам назначил нужные ID? (маркер и актёра)

И замени akPlayer.PlaceActorAtMe(xMarkerHeading) на akPlayer.PlaceAtMe(xMarkerHeading)

AleksTirex  Offline  Сообщение №280 | Тема: Вопросы по скриптам Papyrus написано: 25 января 2014, 11:18


Архимаг


371
Цитата LordVadim

"Я Стар, я Суперстар, я Мегастар... ".  "Это я раньше был - Гендальф Серый, а теперь я - Саша Белый".   ("Властелин колец" в переводе Гоблина).



Ты даже не представляешь, на сколько ты прав. :)

AleksTirex  Offline  Сообщение №281 | Тема: Вопросы по скриптам Papyrus написано: 25 января 2014, 12:53


Архимаг


371
Цитата Иероним

Звуки, можно их вешать на триггеры или активаторы?



http://www.creationkit.com/Play_-_Sound

AleksTirex  Offline  Сообщение №282 | Тема: Вопросы по скриптам Papyrus написано: 10 февраля 2014, 19:18


Архимаг


371
Цитата VIPerMX

Это код из модификации Lightning Just in Time. Он очень хитрий и я решил не трогать его а добавить свой скрипт.



Если правильно понял, то надо не включать объект при каких-то условиях. И этот объект один из light_1...light_3 и т.д? Если это так, и очень не хочется вмешиваться/изменять тот скрипт, то можно просто в том скрипте удалять (стирать) ссылку на свой объект если включать нельзя, и потом опять её добавлять, когда включать/управлять можно.

Например, твой объект light_3, тогда на него повесь скрипт:
 
ObjectReference Property akObject Auto
 
Function OnOff()
  if ; условие запрета включения объекта light_3
    (akObject as LightingBall).light_3 = none
  else
    (akObject as LightingBall).light_3 = self as ObjectReference
  endif
endFunction


akObject - это объект, на котором висит основной скрипт,
LightingBall - название того скрипта.
 
В любой функции или событии запускается команда на эту функцию OnOff(), или при загрузки локации, или по какому-то триггеру (но до срабатывания основного триггера того скрипта), или ещё как. Там в зависимости от условий, можно включаться или нет, стирается или восстанавливается ссылка на свой объект.
 
Если нет ссылки на объект, то его и выключить нельзя, просто нечего выключать.

*************
 
Можно и на другой объект повесить такой скрипт, тогда вместо self передавать назначенное свойство на свой объект.
Это сам принцип, дальше уже придумаете что и как.

AleksTirex  Offline  Сообщение №283 | Тема: Вопросы по Creation Kit. Старая тема написано: 10 февраля 2014, 21:24


Архимаг


371
Цитата Myprism

Собственно говоря, задача в том, чтобы вправлять мозги редактору и заставить его считать валидным тот меш, который считаю валидным я сам и не позволить ему диктовать мне, когда мне этот меш экспортировать, а когда нет.



Myprism, вот я прочитав это, подумал, а зачем это надо, для какой цели? Не проще ли нажимать кнопки и генерить снимки после редактирования внешности головы?
 
Если это надо для "динамических голов", т.е. когда прямо в игре меняется голова, например при смене расы, то тогда понятно, но при редактировании в СК, не понятно (честно, не могу придумать ни одного примера).
 
Например я, для манекенов вообще не использую эти снимки, и мои манекены могут менять и расу и пол. При этом их головы всегда нормальные, ничего серого и неправильного, и это без всяких снимков. Дело в том, что у движка есть баг с генерацией/чтением снимков головы НПС во время игры, и это дело можно использовать во благо.
Так вот, при загрузки НПС генерится голова на основе снимка (который FormID.nif) и сравнивается с записями в ESP/ESM, и если есть различия, то и происходит баг "серой головы", т.е. движок начинает игнорировать снимок.
Но и это не всё, при повторной генерации головы движок как бы "понимает", что накосячил и генерит правильную голову, но только от предыдущего варианта, т.е. запаздывает.
 
Так если принудительно быстро заставить перегенерить голову 2-3 раза со сменой расы так, чтобы предпоследний вариант головы совпал с нужной/желаемой нам головой, то голова сгенерится правильная, на основе записей из ESP, а не из снимка. Геометрия и текстуры будут правильные, серого бага не будет. Хотя, для идеала желательно, чтобы "тон кожи" у НПС отсутствовал вообще, или как минимум, был совсем белым, тогда цвет головы и тела будут идентичны.
 
*********
Это информация для самых любопытных искателей. Пробуйте, это работает точно.

AleksTirex  Offline  Сообщение №284 | Тема: Вопросы по Creation Kit. Старая тема написано: 11 февраля 2014, 02:04 | Отредактировано: AleksTirex - 11 февраля 2014, 02:09


Архимаг


371
Цитата Myprism

Так вот мой вопрос в том и заключался - как обходиться без этих шаманских бубнов?



А никак. :)
В нынешнем СК даже довольно безобидные операции, причём даже дефолтные, практически и есть тот самый бубен.
А сам принцип "безснимковых голов" довольно прост, и в игре этого даже не видно, в смысле бубна и остального.

Для твоих целей, конечно, этот метод не нужен, но вот ты в игре попробуй командой любому НПС сменить расу, и сразу увидишь, что от "серого эффекта" ничем не спастись, Скайрим просто на такое не рассчитывался. Корректная смена расы только у ГГ. А этот метод позволяет менять расы НПС с сохранением внешности.

AleksTirex  Offline  Сообщение №285 | Тема: Вопросы по скриптам Papyrus написано: 15 февраля 2014, 01:41


Архимаг


371
Цитата Arin

Не могли бы вы помочь со скриптом? Мне нужен скрипт, при котором между игроком и нпс начинается поединок, при этом  - или нпс не наносить никакого урона (и магией тоже, или магия блокируется).  - или стоит со щитом и просто блокирует удары.  Мне этот скрипт нужен для создания тренера, который учит не только с помощью окно, но и проводит настоящие тренировочные поединки.



akFaction - любая фракция с Ally сама на себя.
Перк - EntryPoint - Mod Attac Damage -  *0.0, т.е. наносимый урон неписем никакой.
 
Старт "дружбы":

akActor.IgnoreFriendlyHits()
akActor.AddPerk(akPerk)
akActor.AddToFaction(akFaction)
Game.GetPlayer().AddToFaction(akFaction)
akActor.GetActorBase().SetInvulnerable()  ; актёр теперь неуязвимый, ему не нанести урон
 
Теперь непися можно лупить как угодно, он не ответит.

Далее пакет или сцена-пакет: НПС атакует UseWeapon (желательно правильно поставить все галочки), или НПС стоит лицом к ГГ и оборняется (пакет Travel, галочки Weapon Draw + Ignore Combat). Запуск сцены akScena.Start().
 
Стоп "дружбы", вернуть на как было:

akActor.IgnoreFriendlyHits(false)
akActor.RemovePerk(akPerk)
akActor.RemoveFromFaction(akFaction)
Game.GetPlayer().RemoveFromFaction(akFaction)
akActor.GetActorBase().SetInvulnerable(false) 
 
Можно давать перк ГГ, тогда Modif Incoming Damage * 0.01, т.е. входящий урон для ГГ уменьшится в 100 раз.

AleksTirex  Offline  Сообщение №286 | Тема: Вопросы по скриптам Papyrus написано: 24 марта 2014, 19:38


Архимаг


371
Цитата Alliria

Однако эффекта не вижу. Похоже, спеллы просто не назначаются. Лог папируса выдает следующее:



Если компилятор выдаёт ошибки, то это значит, что скрипт не скомпилирован и работать не будет. Поэтому и эффекта не видно.
 
Возможно, компилятору не нравится сам массив. Тогда просто введи временную переменную Actor  и назначай на неё актёра из массива, потом работай с этой переменной, а не с массивом. Тогда компилятор будет видеть "чистого актёра", и возможно, он перестанет кочевряжиться.
Попробуй такой вариант:
 



 
Радиус поиска 30000 - это слишком много, т.к. загружаются в игру максимум 3 ячейки от ГГ (1 ячейка == 4098), в интерьерах так вообще будут видны и обрабатываться все имеющиеся там НПС, хоть и находятся они "в трёх днях пути".
А так же в скрипте нет проверки на "что это за актёр", т.е. скрипт без этого будет вешать абилки и на крабов, и на драугов и на всё движущееся и шевелящееся, а оно надо? (достаточно проверки наличия кейворда ActorTypeNPC).

AleksTirex  Offline  Сообщение №287 | Тема: Вопросы по скриптам Papyrus написано: 2 апреля 2014, 19:38


Архимаг


371
Для справки:
 
Так делать нельзя, возможны лажи, т.к. событие смерти скорее всего придёт позже окончания эффекта (если не стоит галочка No Dispel Death).
 

 


 
Для гарантированного получения события смерти через маг.эффект достаточно в событиии OnEffectFinish() обозначить условие IsDead() (галочку No Dispel Death обязательно снять), и уже там прописать нужное действие.
 
Event OnEffectFinish(Actor akTarget, Actor akCaster)
  if akTarget.IsDead()
    ; делаем
  endIf
endEvent

 

***********************************************************************************
 
Для получения референса кастующего и цели в маг.эффекте не обязательно использовать перенос переменной из OnEffectStart наружу и запоминать его. Можно их получать непосредственно в теле любой функции скрипта:
 
Function AAA()
Actor akActorCaster = GetCasterActor()
Actor akActorTarget = GetTargetActor()
 ;
endFunction

 
*************************************************************************************
 

Alliria, если у тебя цель скрипта "повесить абилку на НПС и потом её удалить при отдалении или смрти НПС", то не надо никаких массивов и форм-листов, и не надо вообще запрминать каких-либо НПС. Есть решение проще:
делаешь цикл только на поиск НПС и раздачу абилок тем, у кого нет такой абилки. Это работает на порядок быстрее и надёжнее. На самой абилке условие: расстояние self-player < №№ и GetDead == 0. Тогда абилка сама выключится. Для полного удаления абилки на её эффекте вешается простой скрипт:
 
Spell Property akSpell Auto
Event OnEffectFinish(Actor akTarget, Actor akCaster)
  akTarget.RemoveSpell(akSpell)
endEvent

 
В результате в рабочем скрипте останется только цикл на поиск и раздачу. Несовместимостей и лаж будет минимум.
 
***********************************************************************
 
Так делать нельзя, точнее бесполезно. Пересчёта запусков не будет.
Статус тоже бесполезен, второго OnEffectStart в данном эффекте по определению возниктуть не может. Считать количество OnEffectStart, естественно, тоже не получится.
 



При оконяании эффекта заканчивается работа данного скрипта, и всё, что было в нём - переменные, свойства и т.д. безвозвратно теряются. При следующем возникновении этого эффекта будет работать уже другой скрипт, копия этого, но другой, и все данные в нём будут девственно чисты.
 
Если необходим просчёт количества стартов этого эффекта, то надо запоминать вне этого эффекта, например в квесте или устойчивом референсе. Наапрмер:
 
Event OnEffectStart(Actor akTarget, Actor akCaster)
  (muQuest as muQuestScript).ivCounter += 1
endEvent

 
*****

Для справки: таким же эффектом обладают массивы (!), при перезапуске скрипта они обнуляюся и их надо назначать по новой. Напимер, если создать массив в квестовом скрипте, то при выключении квеста массив стирается, что не происходит с другими переменными и свойствами в этом скрипте.
 
**********************************************************************
 
Скрипты начинают работать сразу при их создании и инициализации в игре.
Если скрипт не запустился, то ищите причину не в порядке загрузки и прочем подобном, а в самом написании скрипта.
Скрипт может не запустится, если его команда "зависает" и/или не может выполнится, из-за некорректных команд и т.д.
Так же следует проверить "возможно, уже запущен твой маг.эффект", вот скрипт и как бы не срабатывает, т.е. стартеффект не запускается, что вполне естественно.
Событие-функция OnInit() отрабатывает только один раз при инициализации скрипта движком. В квестах оно срабатывает ещё и при каждом запуске этого квеста (квестовый скрипт и алиас).
Так же не надо забывать о свойствах - они не изменятся, если скрипт уже начал свою работу и вы сохранились. Как не меняй значение этого своёства в СК, оно так и останется тем старым, что было при запуске скрипта, эти данные остаются в сохранке.

Добавлено (02 Апреля 2014, 23:38)
---------------------------------------------
Форматирование стёрло содержание спойлера, тот оно:
 





AleksTirex  Offline  Сообщение №288 | Тема: Вопросы по скриптам Papyrus написано: 2 апреля 2014, 21:06


Архимаг


371
Цитата LordVadim

AleksTirex, а что происходит в игре если скрипт попал в сохранение, а после он был полностью заменен, то есть название тоже, а содержание (процедуры, события, свойства) другое. Можно новый скрипт как то заставить работать или это не реально?



Новые события и новые функции работать должны при любом изменении скрипта. Но желательно, чтобы на момент сохранения ВСЕ команды отработали полностью. Особо это касается циклов и OnUpdate(), они продолжат свою работу и в изменённом виде. Хотя, OnUpdate уже станет отрабатывать новые вложенные в него команды, если старые полностью отработали.
Сохранка запоминает своёства и работающие фрагменты скрипта. Если блок (событие/функция) отработали полностью, то их можно смело изменять, они начнут свою работу по новому сценарию.
А вот свойства так и останутся теми, что попали в сохранку, и менять их бесполезно, разве что создавать новые с новыми именами. Ну или грузится с чистой сохранки, что лучше.

AleksTirex  Offline  Сообщение №289 | Тема: Вопросы по скриптам Papyrus написано: 2 апреля 2014, 21:34 | Отредактировано: AleksTirex - 2 апреля 2014, 21:29


Архимаг


371
spellCast.cast(Game.GetPlayer())

Так нельзя, ГГ будет бросать спелл себе под ноги. Ведь спелл целевой, а не на себя, поэтому цель надо обозначить.
Проблема именно в определении этой цели, в её референсе. С НПС проще, можно взять Target и использовать как цель. С ГГ сложнее, Target толком не работает на нём, т.е. движок не может определить цель игрока.

Но можно схитрить и обмануть движок:
1. Делается свой визуально невидимый Projecticle с большой скоростью.
2. В основной спелл назначается этот Projecticle, и именно этим спеллом будет лупить ГГ.
3. На этот эффект вешается простой скрипт, который отдаёт референс жертвы, она и есть наша цель. Далее отдаёт его в ... это уже дело хозяйское куда именно, но туда, где будет команда для визуальных кастов, хоть дюжины.
Это можно сделать и в этом эффекте и никуда не передавать:

Event OnEffectStart(Actor akTarget, Actor akCaster)
akSpell.Cast(akCaster, akTarget)
akSpell2.Cast(akCaster, akTarget)
akSpell3.Cast(akCaster, akTarget)
endEvent

4. Делается спелл или берётся уже готовый, который будет визуально кастоваться на уже известную нам цель/референс.
 
Можно дать небольшую задержку между кастами, для большей визуальности.

Добавлено (03 Апреля 2014, 01:34)
---------------------------------------------
Забыл добавить: спеллы надо делать одного типа, чтобы визуально было подобие родного каста, ведь командой кастуется спелл без анимации.


AleksTirex  Offline  Сообщение №290 | Тема: Вопросы по скриптам Papyrus написано: 2 апреля 2014, 23:15


Архимаг


371
nepewka, а почему именно onSpellCast? Чем плохо событие OnEffectStart?
 
Тогда внимательно читаем мой пост:
Проблема именно в определении этой цели, в её референсе.
Так вот при любом событии, хоть onSpellCast, хоть при OnHit и т.д. нужно знать референс цели, куда направить заклинание. А где его взять то? Вот OnEffectStart и выдаст нам этот референс.
 
Если сделать быстрый Projecticle, то практически срезу при касте будет известен референс цели. И видимый спелл полетит в цель почти сразу же, так будет видимость, что именно этот спелл и кастовал ГГ.
 
Если Тебе надо один видимый Projecticle и несколько взрывов от него, то это совсем другой вариант, нежели ты описывал ранее. Вот здесь и нужен именно вариант с OnEffectStart в основном эффекте. Тогда при его срабатывании жертва сама на себя кастанёт нужные заклинания и в любом количестве. И не будет лишних визуальных Projecticle, а будет эффект, как будто твой спелл имеет несколько эффектов.

№ 3) - OnHit работать не будет. Какие либо другие события тоже не будут. Ведь любое событие должно на чём-то висеть. И оно отслеживает "что именно произошло с этим объектом". Так OnHit - это событие возникает, когда объект получает удар. И именно тот объект, на котором висит этот скрипт с этим событием. Чтобы его использовать, надо на всех возможных в игре жертвах повесить скрипт с этим событием, а это... сам понимаешь. Точно так же и с любым другим событием.
 
№ 4) вообще не понял.
 
"Смысл в том, чтобы не кастуя основной спелл, лишь запуская на долю секунды его анимацию, у нас вылетал уже готовый спелл по скрипту.. "
Вот это я и предлагал с быстрым Projecticle. (смотри начало этого поста)
 
Ты определись, сколько видимых Projecticle ты хочешь, и сколько и как видимых "взрывов". В разных пунктах своего поста у тебя разные мнения/пожелания.

Добавлено (03 Апреля 2014, 02:43)
---------------------------------------------

Цитата nepewka

Animation events в CK wiki. Там есть анимации, BeginCastLeft, BeginCastRight, StopCast  Смысл в том, чтобы не кастуя основной спелл, лишь запуская на долю секунды его анимацию, у нас вылетал уже готовый спелл по скрипту..



Вот сам принцип этого:
 
Debug.SendAnimationEvent(Game.GetPlayer(), "BeginCastLeft")
Utility.Wait(0.5)
akSpell.Cast(Game.GetPlayer(), akTarget)

 
Но опять же, нужен референс цели akTarget. (а где его взять?..)
BeginCastLeft - должно быть событие, а не ID анимации (в настройках анимации оно написано)
Писать эти команды можно где угодно и в любом скрипте, событии, функции.

AleksTirex  Offline  Сообщение №291 | Тема: Вопросы по скриптам Papyrus написано: 2 апреля 2014, 23:40


Архимаг


371
Alliria, так нет проблем. ;)
Делаешь одну абику, и в ней сколько надо разных маг.эффектов. В каждом эффекте свои условия на своего актёра. Так при получении общей абики у каждого актёра сработает свой эффект, условия которого совпадут.
 
Все манипуляции можно проводить в том же эффекте, а можно и сделать отдельный эффект для всех актёров, а в нём играться с одеждой и прочим. Если возникнут проблемы нежелательного отключения эффекта и потере данных, то можно все функции и переменные вынести в не выключаемый квестовый скрипт, и уже командой из эффекта запускать нужные функции в том скрипте, при этом передавая все нужные данные в тот скрипт.
 
Проще, чем простое сканирование и простая раздача - уже никак, меньше просто некуда. Все остальные проверки пусть сам движок делает в своём дефолтном режиме.

AleksTirex  Offline  Сообщение №292 | Тема: Вопросы по скриптам Papyrus написано: 3 апреля 2014, 11:50


Архимаг


371
nepewka, так ты читай внимательно ;)
 
Но если ты повесишь этот скрипт на основной спелл и назначишь akSpell этот же самый спелл, то получишь цикл, почти бесконечный цикл.


Ты на одно из свойств akSpell назначил этот же спелл, на котором висит этот скрипт, т.е. самого себя. Вот ты и получил цикл. В итоге этот спелл плодит сам себя.
А надо назначать любой другой спелл, хоть самодельный, хоть дефолтный. Тогда при одном касте полетят только те спеллы, что прописаны в свойствах и в количестве равном количеству команд каста. И не будет ГГ строчить как из пулемёта. (я же всё это писал, надо только внимательно читать)

OnEffectEtart работает только один раз, и команды в нём срабатывают тоже только один раз.
 
 
 

Если хочешь сделать "очередь" как из пулемёта, но не бесконечную очередь, а 1-2-3 секунды, то можно так:
 
Event OnEffectStart(Actor akTarget, Actor akCaster)
  int index = 5
  While index > 0
    index -= 1
    akSpellXX.Cast(akCaster, akTarget)
    Utility.Wait(0.2)
  endWhile
endEvent

 
akSpellXX - другой спелл, не этот, на котором висит скрипт (!)
В течении одной секунды вылетит 5 файерболов. Количество кастов и задержку меняй сам по своему желанию.
 
************************
 
Твой пример скрипта не совсем корректный. Там при начале анимации ГГ кастует сам на себя заклинание. Тебе это не подходит, у тебя целевые заклинания (!). А где ты возьмёшь референс цели, на которую должны полететь заряды? Всё упирается именно в это. Пока ты не решишь вопрос с получением референса цели, что-либо дальше делать бесполезно. А вот когда в своём скрипте будет известен этот референс, то можно хоть сотню разных вариантов напридумывать.
 
Вот для этого и нужен скоростной невидимый спелл, который и определит этот референс. Этот спелл/эффект может просто отдать/передать значение референса в любой твой скрипт, и уже в нём можешь как угодно развлекаться с кастами по цели, она ведь будет уже определена.
 
*************
Внимательно прочитай самую первую строчку этого поста и хорошо запомни её. ;)

AleksTirex  Offline  Сообщение №293 | Тема: Вопросы по скриптам Papyrus написано: 3 апреля 2014, 13:17 | Отредактировано: AleksTirex - 3 апреля 2014, 14:35


Архимаг


371
Цитата nepewka

Создали мы этот спелл, что дальше. Как сделать из него референс?

Короче говоря, я не могу понять: а) как конкретно спелл может стать референсом? б) Чем спелл может помочь в определении референса цели? (в упор просто не пойму)



Из спелла никак не сделать, как и из любого объекта. Референс - это типа как имя, номер изделия, и т.д. У тебя есть имя? Есть, но ведь из тебя не получится сделать твоё имя, его можно только узнать, но не сделать (!).
Так же и с референсом, его можно узнать, какой именно референс у данного объекта, типа "какое имя у объекта".
Каждому объекту в игре назначается свой референс, типа имени или номера, а иначе как бы движок различал объекты в игре. И если надо что-то сделать с объектом, например с Алдуином, надо знать какой у него референс в игре.

Так вот при попадании на НПС заклинания на нём/НПС возникает магический эффект, это ты знаешь, так этот эффект непосредственно висит на этом НПС и он/эффект "знает", на ком именно он висит, что логично. Так можно узнать у этого эффекта, на ком именно он висит, как бы спросить у него.

При возникновении на НПС-жертве маг.эффекта возникает событие - "старт-эффект" Event OnEffectStart(Actor akTarget, Actor akCaster) , которое знает, кто послал это заклинание и в кого оно попало.

Так вот: akCaster - это кто послал этот спелл/заклинание, т.е. кто кастовал его. akTarget - это цель спелла/зклинания, т.е. в кого оно попало и на ком возник данный маг.эффект. Т.е. есть референсы кастующего и жертвы.

Вот этот референс akTarget и надо использовать как цель ГГ для каста новых заклинаний.

******
Сперва пойми и вникни в это. И пойми/разберись, что такое референс и что такое заклинание и маг.эффект. Тогда сможешь дальше сам писать скрипты и делать заклинания. :)

AleksTirex  Offline  Сообщение №294 | Тема: Вопросы по скриптам Papyrus написано: 3 апреля 2014, 14:23


Архимаг


371
Цитата VALKNUT

Как отследить момент, когда ГГ дает указание спутнику, чтоб тот взаимодействовал с миром, например обыскал сундук или колол дрова или крафтил ченить?



Твой созданный спутник или вообще любой?
 
В Скайриме всё построено на событиях, так вот их и надо отслеживать. Т.е. события, возникающие на НПС-спутнике. Для этого надо записать НПС в свой алиас и в нём отслеживать события, происходящие с НПС. Отслеживать можно изменение пакетов, активацию неписем каких-то объектов (это проще через перк на НПС) и т.д.
 
Если спутник твой, то просто в каждом топике/команде результирующий скрипт, который отдаст "описание" команды, которую даёт ему ГГ.
 
Если НПС может и без приказа что-то начать делать (колоть дрова, крафтить и т.д.), то только первый вариант.

AleksTirex  Offline  Сообщение №295 | Тема: Вопросы по скриптам Papyrus написано: 3 апреля 2014, 14:45


Архимаг


371
Цитата VALKNUT

А именно, при указании спутнику на алтарь Боэтии сделать агр персонажа с неизбежной смертью ГГ.



Не ругайтесь и не смейтесь - опять заклинание-абилка. :)
 
Делаешь абилку и даёшь алиасу НПС (дак угодно даёшь).
В условиях заклинания (не на эффекте !) ставишь: Target - референс_Боэтии - ==1. И другие нужные условия (если надо).
На эффекте скрипт с нужными тебе командами.
 
Т.е. когда у НПС целью станет статуя Боэтии, тогда запустится эффект и отработает скрипт с твоими командами. Произвольно целью статуя стать не сможет, т.к. цель-Target возникает у НПС в момент, когда НПС "решил" активировать объект и пошёл к нему (вплоть до окончания взаимодействия с этим объектом). Сам по себе НПС ну очень вряд ли пойдёт активировать статую, пока ГГ не даст на это команду.

AleksTirex  Offline  Сообщение №296 | Тема: Вопросы по скриптам Papyrus написано: 3 апреля 2014, 15:38


Архимаг


371
nepewka, "выход"... какой выход? Получение референса цели? Так я же всё подробно расписал.
 
Вот этот референс akTarget и надо использовать как цель ГГ для каста новых заклинаний.

 
Референс - это не существо, это идентификационный номер объекта, любого объекта: НПС, грязекраб, статуя, камень на дороге, валяющаяся палка или монетка и т.д. Референс есть у каждого объекта в игровом мире.
 
********************************************
********************************************

LordVadimRegisterForUpdate(3) так нельзя. (читай свой собственный пост немного раньше)
 
Циклы и постоянное обновление вместе делать нельзя. В данном случае это не критично, но всё же не стоит (народ привыкнет так делать и... результат предсказуем ;) )

AleksTirex  Offline  Сообщение №297 | Тема: Вопросы по скриптам Papyrus написано: 3 апреля 2014, 20:33 | Отредактировано: AleksTirex - 3 апреля 2014, 20:41


Архимаг


371
Цитата LordVadim

Например если я надену шапку, то когда подпрыгну - буду висеть в воздухе в позе "лотоса"; а без шапки прыжок оставался бы обычным.



Анимация в Скайриме работает довольно глючно. Отследить событие своей анимации вряд ли получится, разрабы об этом позаботились. :)
Отслеживать событие прыжка тоже... не факт, что сможешь зарегистрировать и получить его событие, ведь довольно мало событий анимации можно так получить.
Если же ты не против SKSE, то всё гораздо проще - следишь за нажатием кнопки "пробел", а это работает стабильно.

Добавлять свою анимацию прыжка и подменять ей дефолтную, скорее всего можно (я именно прыжки не пробовал подменять).
Открываешь в СК анимацию, нужный бехавиор, ActionJamp. Дублируешь JumpRoot и вставляешь его выше родного. Там добавляешь новое условие: "subject - если надета шапка == 1". Возможно, в родной JumpRoot придётся добавить обратное условие: "если не надета шапка". (чаще всего порядок расположения анимаций движком игнорируется)
Далее внутри своего JumpRoot прописываешь свои события анимации. Естественно, что СК надо запускать только после создания своего бехавиора и после обновления мастер-бехавиора FNIS-сом, иначе СК не увидит этих событий. Названия файлов анимации и события должны быть исключительно уникальными, иначе однозначно возникнут лажи (IdleJamp - так писать нельзя).

Далее уже сам крути как хочешь, но зарегистрировать и получить событие этой анимации не получится, просто не сработает, увы. :)
 
Кстати, если ты хочешь сделать последовательную анимацию прыжок+висит, то забудь, FNIS это очень глючно прописывает, и как правило, стартовая анимация (s -a) пропускается и сразу начинает работать бесконечная (+). Это происходит с шансом ~20%, а при первом запуске этой анимации за сеанс ~95%.
Т.е. такую цепочку из анимаций лучше запускать отдельно, каждую анимацию отдельно, а не запускать стартовую в цепочке связанных анимаций.

********************************************

сергей007788, в играх, и Скайрим не исключение, весь мир крутится вокруг игрока, так что... не ищи ответа на этот вопрос. Разве что, телепортировать туда ГГ.

AleksTirex  Offline  Сообщение №298 | Тема: Вопросы по скриптам Papyrus написано: 3 апреля 2014, 21:29


Архимаг


371
LordVadim, безумный вариант: делаешь тестовый мод, копируешь в него свой ЗЭ, остальные удаляешь (!), сохраняешься и проверяешь. Поскольку твой там один (и оставь экран майн-меню), то и срабатывать он будет постоянно. Потом ESP удалишь. :)

AleksTirex  Offline  Сообщение №299 | Тема: Вопросы по скриптам Papyrus написано: 4 апреля 2014, 12:14 | Отредактировано: AleksTirex - 4 апреля 2014, 12:31


Архимаг


371
Цитата anton

MovableStatik сквозь них нпк не проваливаются.

Есть ли какие команды или способы сделать чтобы объект к которому применена команда Translate не проходил сквозь стены.

Заранее благодарен.



Чтобы объект перемещался с сохранением коллизии, надо делать MovableStatik с изменённым нифом, т.е. немного поправить нужный ниф:

bhkRigidBody
Layer:
Заменить OL_STATIC на OL_ANIM_STATIC.
Layer Copy:
Заменить OL_STATIC на OL_ANIM_STATIC.
Motion System:
Заменить MO_SYS_BOX_STABILIZED на MO_SYS_BOX.

В этом случае можно стоять на таком движущемся объекте и не проваливаясь двигаться вместе с ним, т.е. на нём.
При команде TranslateTo() коллизия статиков игнорируется, и объект проходит сквозь них. К сожалению, пока неизвестен вариант это изменить без багов.

AleksTirex  Offline  Сообщение №300 | Тема: Вопросы по скриптам Papyrus написано: 4 апреля 2014, 17:13


Архимаг


371
anton, у меня на озере, недалеко от Ривервуда в Полулунной лесопилке, есть лодка, на которой можно покататься по озеру. Можно с собой и подружек взять и покатать их. Лодка плавает, управляется, по ней можно ходить во время плавания и т.д. (но не ГГ, т.к. управление лодкой повторяет управление ГГ, а НПС могут по ней ходить)
Т.е. всё работает. Вот только проблему столкновения с препятствиями и берегом я не стал решать, так и оставил - лодка их не видит.
 
Эвента на столкновение с коллизией нет, в бехавиоре другой принцип - он использует эвенты для запуска анимации, а не генерит само событие. Это событие/эвент с привязкой к объекту генерит движок, а бехавиор реагирует на него и запускает нужную анимацию на нужном объекте (точнее это движок запускает анимацию, ведь бехавиор - это в принципе как список анимаций, а не исполнительное устройство). Если движок сгенерил событие Weapequip_Out, то бехавиор запускает анимацию вынимания оружия из ножен. А вот почему движок сгенерил это событие - он сам знает (нажата кнопка №№, если событие на НПС, то при начале атаки или режима Alert и т.д.).
Так же и с приземлением - движок определяет это дело, и выдаёт нужную команду/событие и т.д. И не факт, что можно найти и "выцепить" само событие приземления, в лучшем случае, можно засечь реакцию движка на это дело (например, запуск анимации приземления).
 
Высота прыжка действительно не зависит от анимации, это длительность воспроизведения/работы самой анимации зависит от высоты. Сама анимация прыжка длится около 10 сек. (точно не помню), и этого хватает для любой высоты.
SpeedMult - это скорость перемещения НПС. В параметрах/скиллах есть JumpingBonus, но вот работает ли он... не знаю.
akActor.SetAV("JumpingBonus", 100) - ??? я что-то разницы не замечал.

Добавлено (04 Апреля 2014, 21:09)
---------------------------------------------

Цитата anton

1. Коллизия у "статика" сама всё таки не перемещается. (перемещаю триггером со скриптом, командой Stone.TranslateToRef(Place, StoneSpeed))



Не Static, а MovableStatic. ;)  На статике и не будет работать, этот объект надо в моваблестатике прописать.

Добавлено (04 Апреля 2014, 21:13)
---------------------------------------------
anton, попробуй так: Game.SetGameSettingFloat("fJumpHeightMin", 200.0)


Форум » Записи участника [AleksTirex]
Поиск:





Ответ на жалобу смотрите в разделе жалоб