Автор расскажет о специальных функциях NX из форка NVSE, добавляющих уникальные возможности для моддинга Fallout New Vegas.

Необходимые навыки: референсы и базовые формы, переменные скриптов (плавающие, целы, референсы), get\set

Навыки для продвинутых пользователей: строки, строковые переменные, переменные массивов, ссылающиеся на квестовые переменные в диалоге, другие условия

Что ж… Если немного побродить вокруг скриптинга, вылезет слово ‘nx’. Это экстра-функции из NVSE Extender от prideslayer. Самые популярные из них – переменные NX.

 

Переменная NX функций…

- позволяет хранить игровую информацию в референсе

- как переменная EVFI хранит плавающие и целые числа, как EVFo хранит формы, референсы и базовые формы, динамические референсы с помощью NX_Get или NX_Set

- без необходимости обьявлять её в скрипте: как только на ней применили set, она существует в референсе:

someRef.NX_SetEVFl “thenameyougiveit” someNumericValue/someFloat/someInteger
someRef.NX_SetEVFo “thenameyougiveit” someForm/someRef

“the name you give it” = ключ

И будучи функцией референсов (reference functions), NX_Set/GetEVF* функции становястя применимыми в синтаксисе референсов

 

 

Короче, если нужно отслеживать сколько напитков выпил непись, нужно и создать переменную ‘DrinksDrunk’ и изменять её значение, привязав его к референсу:

BuddyRef.NX_SetEVFl "DM:DrinksDrunk" 1

И то же для его любимого яда\алкоголя:

BuddyRef.NX_SetEVFo "DM:FavoriteDrink" Scotch

BuddyRef.NX_SetEVFo "DM:BestestFriendInTheWholeWorld" Buddy2Ref

- отслеживая всё это, переменная референса останется в сохранении, но только на том же референсе. Больше ей ничего не нужно, так что можно спокойно удалять мод, и она останется.

- и если любой мог захочет получить доступ к информации из переменной, он сможет получить её из референса, как только будет знать ключи доступа:

set somefloat/integer to someRef.NX_GetEVFl “whateverkeyithas”

set somescriptRef to someRef.NX_GetEVFo “whateverkeyithas”

Например:

int iDrinkCount

ref favDrink

set iDrinkCount to BuddyRef.NX_GetEVFl "DM:DrinksDrunk"

set favDrink to BuddyRef.NX_GetEVFo "DM:FavoriteDrink"

if BuddyRef.GetItemCount favDrink > 0 ; у нас есть напиток

     BuddyRef.CIOS favDrink             ; пьет его

     BuddyRef.removeitem favDrink 1     ; теперьнаединичкуменьше

     set iDrinkCount to iDrinkCount + 1

     BuddyRef.NX_SetEVFl "DM:DrinksDrunk" iDrinkCount ; продолжаем отслеживать

endif

if 10 < BuddyRef.NX_GetEVFl "DM:DrinksDrunk" ; возможно, перестарались

     BuddyRef.CIOS ReallyStinkingDrunkSpell

endif

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

И вы можете выполнять все эти отслеживания на стольких NPC, на скольких захотите.

ref BuddyRef

set BuddyRef to whoever

- можно иметь столько переменных NX на любом референсе, сколько захотите
- а если они не нужны, то избавляемся от них так:

someRef.NX_ClrEFVl “key”
someRef.NX_ClrEVFo “key”

а если нужно избавиться от кучи таких переменных, то вот так:

someRef.NX_ClrEVFl “partthatallkeysshare” 2
someRef.NX_ClrEVFo “partthatallkeysshare” 2

все наши ключи в моде на напитки начинаются с DM, так что уничтожение всей информации на референсе BuddyRef будет выглядеть вот так:

BuddyRef.NX_ClrEVFl "DM:" 2

BuddyRef.NX_ClrEVFo "DM:" 2

Очистим состояние и дух!

Это означает, что вы можете иметь целую кучу пользовательских переменных, привязанных к любому актору или предмету, какой захотите. Не требуется никаких эффектов, никаких токенов, никаких квестовых скриптов чтобы все это хранить, что уменьшает конфликты модов и позволяет модам общаться друг с другом вне зависимости от мастера и порядка загрузки. Если вы хотите сохранить какую-либо информацию об акторе, например, его любимую пиццерию, вы просто прикрепляете ее к этому актору, у которого потом вы и найдете ее, когда она вам понадобится.

Хорошей практикой будет:

Никогда не знаешь, будет ли повторено название твоего ключа для переменной nx, но для других целей. Поэтому в большинстве случаев, просто добавим немного акронимов своего мода в начале строки: «MyCleverModAcronym:restofthekey» и т. д.

 

Еще один полезный совет:

Поскольку это реально крутой инструмент взаимодействия между модами, лучше всего четко указать какие переменные NX вы используете, особенно если вы используете их в огромных количествах. Сохраните их в dummy esp или перечислите их в фиктивном скрипте, добавьте текстовый файл к архиву с модом, что угодно.

Обновление:

С выходом NX12 появляется возможность хранить и извлекать строки как переменную EVST: NX_SetEVST, NX_GetEVST и NX_ClrEVST. Вы можете делать это как с реальными строками, так и с переменными строк.

Продолжая пример с напитками:

string_var sv_quote

...

BuddyRef.NX_SetEVST "DM:BoozeQuote" "Champagne for my real friends - real pain for my sham friends, ha ha!"

BuddyRef.NX_SetEVST "DM:DrunkType" "Aggressive"

...

if BuddyRef.GetItemCount favDrink > 0 ; we have booze

    BuddyRef.CIOS favDrink ; drinking it

    let sv_quote := BuddyRef.NX_GetEVST "DM:BoozeQuote"

    MessageEX "%z" sv_quote ; will pop up a message with the quote in it

...

endif

if 10 < BuddyRef.NX_GetEVFl "DM:DrinksDrunk"

..

   if eval BuddyRef.NX_GetEVST "DM:DrunkType" == "Aggressive"

      BuddyRef.startcombat playerref

   endif

endif

В NVSE4+ есть целый ряд функций строковых переменных, которые позволяют вам сохранять, изменять и извлекать строки на лету. В сочетании с функцией ToString (сокращенно: $), которая позволяет вам передавать строковые переменные в функции, которые в противном случае ожидали бы фактическую строку, это означает, что вы можете динамически создавать ключи nx, а в случае EVST — и значения. Это означает, что вы можете сделать что-то вроде:

string_var sv_fightoutcome

string_var sv_nxkey

int iFightNum

int iIsFighting

float fTimer

 

if BuddyRef.GetCombatTarget == playerref

    set iFightNum to iFightNum + 1 ;(or: let iFightNum += 1)

    set iIsFighting to 1

endif

 

if eval iIsFighting && (ftimer += GetSecondsPassed) > 30

   BuddyRef.StopCombat

endif

 

if iIsFighting && 0 == BuddyRef.IsInCombat

   set iIsFighting to 0

   if playerref.GetAV Health > BuddyRef.GetAV Health

       let sv_fightoutcome := "Lost"

   else

       let sv_fightoutcome := "Won"

   endif

   let sv_nxkey := "DM:Fight:" + $iFightNum + ":Score"  ; creates a string that'll be like "DM:Fight:1:Score", "DM:Fight:2:Score" etc)

   BuddyRef.NX_SetEVST $sv_nxkey $sv_fightoutcome

endif

Также в NX12 появились новые функции, которые возвращают информацию nx об актере в строковой карте, с ключами nx в ключах строковых карт и значениями в значениях строковых карт: NX_GetEVFlAr, NX_GetEVFoAr и NX_GetEVStAr.

Допустим, у нас есть потасовки в барах, в которых buddyref то выиграл, то проиграл, а чтобы вренуть эту инфу мы напишем следующее:

array_var ar_results

let ar_results := BuddyRef.NX_GetEVStAr "DM:Fight"

ar_dump ar_results

и ar_dump инфа будет выглядет так:
[DM:Fight:1:Score] : Won
[DM:Fight:2:Score] : Lost

Нужно немного рабираться в массивах и циклах foreach чтобы работать с этой информацией. Позже я напишу гайд об этом.  

Обновление 2:

Об этом много говорили, и вот оно здесь: EVFL переменные nx теперь можно просматривать в условиях диалога/квеста/анимации. (Только EVFL, потому что такие условия имеют только числа для значений.)

Сначала вставляете строковую переменную в квестовый скрипт и устанавливаете ее на ключ nx, который вы хотите, чтобы она представляла. В соответствии с предыдущими примерами я выбрал "DM:DrinksDrunk":

Прикрепите скрипт к квесту, очевидно. Обратите внимание, что квест не обязательно должен быть включен, чтобы просто хранить переменную, но в этом случае я устанавливаю переменную в том же скрипте, поэтому я включаю ее, чтобы всё работало. (Я мог бы добавить let DSTestQst.sv_drinksdrunk := "DM:DrinksDrunk" в какой-нибудь другой скрипт и сделать то же самое.)

Поскольку у нас уже есть квест, давайте продолжим его тестирование с условиями диалога. Как вы видите, я создал тему и строку, которую я хочу сделать зависящей от EVFL, имеющего значение 1.

Я добавляю условие и выбираю NX_GetQVEVFL для функции условия. Появляется окно, очень похожее на то, которое вы увидите, если проверите обычную переменную квеста.

Выберите квест, в котором есть скрипт квеста со строковой переменной в нем в выпадающем меню. Чтобы выбрать переменную, вам нужно ввести ее индекс. Если это первая переменная в скрипте, она будет 1. Если вы не уверены, какой индекс имеет ваша строковая переменная, вы можете посмотреть его в FNVEdit:

И как вы можете видеть на следующих скринах, вы можете легко изменить переменную nx для актера в результирующем скрипте, и следующая строка обнаружит изменение.

Обратите внимание — и это справедливо для всех переменных квеста — что вам не следует переставлять переменные квеста после того, как вы уже сделали сохранения с активным квестом; вы можете добавлять новые в конец списка переменных скрипта, но не перемешивать их. (Ну, вы можете, если вас не волнует получение отчетов об ошибках.)

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

Материал подготовлен ArtemSH специально для TGM — Tesall Game Magazine.
Переводчик: ArtSH
Автор: DoctaSax
Источник: Перейти
1

Комментарии

Авторизуйтесь, чтобы оставить новый комментарий. Или зарегистрируйтесь.