Вернуться   Raurin Forums > Raurin 3: The Silver Marches (NWN2 шард) > Скриптинг, маппинг и диалогинг :)

Ответ
 
Опции темы Опции просмотра
Старый 27.12.2009, 06:49   #1
Melshin
Приближенный Тира
 
Аватар для Melshin
 
Регистрация: 20.12.2007
Адрес: Санкт-Петербург
Сообщения: 2,096
Власть репутации: 700 Melshin У него еще все впереди!
По умолчанию Учебник (скриптинг)

NWSCRIPT - это встроенный в Neverwinter Nights 2 скриптовый язык с потрясающим кол-вом возможностей. На его основе работают Baldur's Gate 1, Baldur's Gate 2, Icewind Dale, Icewind Dale 2, Neverwinter Nights, Neverwinter Nights 2 и Dragon Age: Origins. Изучив этот язык, вы получите практически неограниченные возможности (точнее, ограниченные стандартной механикой ДнД или игровой механикой DAO) для создания модификаций вышеописанных игр.

Также в НВН 2 используется язык xml (NWN 2 GUI), liteSQl/MySQL (шарды) и разновидности ассемблера (шарды, РЕДКО).

Это сложная наука, требующая по крайней мере минимальных познаний в языках программирования и алгоритмизации, которые сейчас, к счастью, дают в школе (правда плохо). Практические задачки, выполняемые на nwscript равны по сложности ВУЗ-овским задачкам (а встречаются и страшный ZOMG, который еще сложнее - называется пофиксить криворукость разработчика).

Итак, для начала стоит узнать, как собственно вызывать скрипты.

1 тип вызова скрипта - это EVENTS ака эвенты ака события.

У каждого существующего в игре объекта существуют свои события, выполняемые им при определенных условиях. Открыв параметр любого объекта, вы увидите графы event_***_***, которые можно заполнять текстом - названиями скриптов. Когда выполняется условие начала события, запускается скрипт. Все просто.

Есть несколько типов объектов и у каждого есть свои события. Первый объект - это модуль. Модуль, который вы разрабатываете, весь ваш мир. Этот объект "абсолютно" стабилен, он гарантированно никуда не денется, покуда вы в игре (если денется, то вас выкинет из игры). Настройки модуля вызываются в панели сверху View->Module Properties

В настройках модуля есть следующие события:

1) On Acquire Item Script. Этот скрипт запускается каждый раз, когда кто-либо в игре поднимает любой предмет (точнее, когда предмет попадает в инвентарь, вне зависимости от того, как он туда попал). Собственно, вам не нужно редактировать значение этого эвента. Дело в том, что данный скрипт служит для запуска других скриптов, так называемых tag-based скриптов. Он вызывает скрипт с названием i_*тэг предмета, указанный в тулсете*_aq на поднявшем этот предмет объекте.

Пример: мы хотим, чтобы при краже тарелки рядом стоящий местный поднимал тревогу (или еще что, неважно, там можно хоть гору проверок на скрытность и подобное запихать). Для этого мы создаем в тулсе тарелку с тэгом tarelca и скрипт с названием i_tarelca_aq. При попадании тарелки в инвентарь автоматически будет запускать скрипт.

2) On Activate Item Script. Все то же самое, только на предмете должна быть настройка активации (там их несколько, активировать предмет на цели, на области и на себе в панели "Cast Spell"). Название скрипта должно быть i_*тэг*_ac

3) On Client Enter Script. Скрипт, выполняемый каждый раз, когда в модуль заходит игрок. Это актуально как для шардов (для каждого игрока), так и для сингла (для одного игрока).

4) On Client Leave Script. Скрипт, выполняемый каждый раз, когда игрок выходит из модуля.

5) On Cutscene Abort Script. Шардовики не пользуются катсценами, посему я хз, что это. Дословный перевод может помочь.

6) On Heartbeat Script. "Биение сердца модуля". Обычно это скрипт, который выполняется каждые 6 секунд. Есть раздражающая фигня у этого эвента. Обычно не проявляется в сингловых модулях (если это не ОГРОМНЫЙ сингловый модуль). Дело в том, что в игру встроена "защита от перегрузок" и при большом кол-ве объектов и выполняемых действий задержка между хартбитами удлиняется. Обычно это незначительно, в районе 2 секунд, но на больших шардах может растянуться и на часы. При этом, как ни странно, процессор больше чем на 20% не грузится, скорее всего это биотваревский код и основан он не на реальной нагрузке, а от кол-ва обрабатываемого. Упоротые Обсидианы это не изменили, сволочи . Т.к. хартбиты есть далеко не только у модуля - искуственный интеллект существ их тоже использует - бывают проблемы типа "мобы ничего не делают". Для обхода этого используют "псевдохартбиты" или на языке программистов "рекурсии" (простая штука на самом деле), но об этом позже.

7) On Module Load Script. Как только модуль загружается, этот скрипт выполняется. Рекомендую PC Loaded, просто выполнить 1 раз нужную часть.

8) On PC Loaded Script. Этот скрипт эквивалентен Client Enter, за исключением того, что запускается он уже не при входе игрока, а при входе персонажа. Т.е. Client Enter - это когда вы выбираете персонажа, а PC Loaded - вошли персонажем в игру.

9) On Player Death. Выполняется при окончательной смерти игрока. По умолчанию выводит ГУИ с выбором дальнейших действий.

10) On Player Dying. Выполняется при выводе персонажа игрока в минусовые хиты. До Шторма Зехира минусовыми хитами были хиты от 0 до -10, после Шторма Зехира от 0 до - половины макс. хитов персонажа.

11) On Player Equip Item. Выполняется при одевании предмета. Tag-based, темплэйт i_tag_eq

12) On Player Level Up. Ну тут все просто как грабли.

13) On Player Respawn. Выполняется после нажатии на ГУИ кнопки "respawn"

14) On Player Rest. Выполняется при отдыхе игрока.

15) On Player Unequip Item. Tag-based, снятие предмета, i_tag_ue

16) On Unacquire Item. Tag-based, предмет исчезает из инвентаря, i_tag_ua

17) On User Defined Event. Разное.

18) On Chat. Введен в НВН 2 в патче 1.23. Вызывается, когда игрок говорит что-то в любой чат (шардовикам полезно, для сингловиков всегда был ListeningPattern, о котором позже)

Существа. Любое существо (кроме игрока, у которого во всех полях используется один скрипт default) имеет следующие события (изменяют их значения крайне редко, но изменяют):

1) On Blocked. Этот скрипт запускается всегда, когда путь существа преграждает дверь, другое существо или объект.

2) On Conversation. Данный скрипт запускается, когда персонаж кликает на существе, инициируя диалог.

3) On Damaged. Данный скрипт запускается, когда существу наносится урон.

4) On Death. Данный скрипт запускается, когда существо погибает (существа всегда умирают сразу без кровотечений).

4) On End Combat Round. Только в бою, в конце каждого раунда. Надежная штука, но обычно там сидит ИИ. Кастомный ИИ пишется через Variables, об этом далекоооо потом.

5) On Heartbeat. Обычно 6 секунд, в отличие от предыдущего исполняется вне боя.

6) On Inventory Disturbed. Запускается, когда инвентарь существа модифицируется (оттуда что-то исчезает или наоборот появляется).

7) On Perception. Запускается, когда какой-либо объект входит в поле зрения существа (причем не важно, прячется/невидим или нет).

8) On Physically Attacked. При атаке на это существо любым оружием.

9) On Rested Script. Заметьте, пассивный залог. Т.е. это существо не отдыхает, а его отдыхают. Используется ДМ-ом в онлайне и для сопартийцев/хенчей в сингле.

10) On Spawn In Script. При создании (любом).

11) On Spell Cast At Script. При попадании на это существо эффекта заклинания.

12) On User Defined Event... Разное.

Двери.

Любая дверь имеет следующие события:

1) On Click Script (при щелке на дверь мышкой, хз, как это выглядит на практике)

2) On Closed. При закрытии двери.

3) On Conversation. Да, с дверями можно говорить. Типичный пример - врата на План Фуги в Маске Предателя. Это дверь и ГГ с ней разговаривает.

4) On Damaged. При нанесении двери урона.

5) On Death. При уничтожении двери. По умолчанию проиграть VFX "дверь разносится в щепки".

6) On Disarm. При снятии с двери ловушки.

7) On Fail To Open. Ловушку снять не получилось.

8) On Heartbeat. Уже понятно.

9) On Lock. При запирании на замок.

10) On Melee Attacked. При ударе по двери оружием ближнего боя (в т.ч. кулаками).

11) On Open. При открытии.

12) On Spell Cast At. При воздействии заклинания на дверь.

13) On Trap Triggered. При срабатывании триггера на двери (ловушка).

14) On Unlock. При взламывании замка на двери.

15) On Used. При использовании двери.


Stores (списки предметов, обычно - магазины)

1) On Open (при открытии Store, обычно туда в этот момент заливают предметы, если они зависят, допустим, от класса персонажа)

2) On Close (ноу комментс)

Placeables.

1) On Closed. У плэйсов может быть инвентарь (типичный пример - сундук), когда мы этот инвентарь закрываем (перестаем взаимодействовать с сундуком), запускается этот скрипт.

2) On Conversation. Да, можно говорить даже с цветочками и домиками.

3) On Damaged. Ну тут уже понятно.

4) On Death. Бла-бла-бла.

5) On Disarm. При снятии ловушки.

6) On Heartbeat. Бла-бла-бла...

7) On Inventory Disturbed. Скукота...

8) On Left Click. М-да...

9) On Lock. И на замок можно закрывать.

10) On Melee Attacked. И бить.

11) On Open. При открытии инвентаря.

12) On Spell Cast At

13) On Trap Triggered.

14) On Unlock.

15) On Used (и Use у плэйсов тоже есть, он не всегда инвентарь - допустим, рычаги)

Триггеры (их много, это ловушки, переходы с локи на локу, валкмеш каттеры, короче, тьма)

1) On Click. Мы щелкаем на триггер сами! Что же будет сейчас с нами?

2) On Disarm. В основном для ловушек, обезвредили.

3) On Enter. При входе в триггер.

4) On Exit. При выходе из него.

5) On Heartbeat. На хартбите триггера.

6) On Triggered. Любое действие, настроенное на срабатывание триггера.

Энкаунтеры (я не использую, пишу свои триггеры - но все же)

1) On Entered. Объект входит в энкаунтер.

2) On Exhausted. Энкаунтер кончился.

3) On Exit. Из энкаунтера вышли.

4) On Heartbeat. Уууух, как я его ненавижу за глюки...

Диалоги.

Важно: Abort Conversation (игрок прерывает разговор клавишей ESC, если таковое разрешается).

Не совсем: End Conversation. Это когда диалог доходит до своего логического конца.

Локации.

1) On Client Enter. Эвент запускается, когда локация полностью прогрузилась у того (или тех), кто на нее входит.

2) On Enter. Эвент запускается, когда что-то входит в локацию (неважно кто или что).

3) On Exit. Эвент запускается, когда что-то выходит из локации.

4) On Heartbeat.

Следующий способ запуска скриптов - таблица spells.2da

С ней легко разобраться, если знать английский (если вы его не знаете - в скриптинге вам делать нечего), собственно хорошая ссылка, там же можно найти и остальные таблицы - http://nwn2.wikia.com/wiki/Spells.2da

Любой скрипт может быть записан в эту таблицу и вызван:

1) При произнесении заклинания, если скрипт ассоциирован с определенным кругом определенного заклинания.

2) При использовании навыка, если строка spells.2da сассоциирована со строкой в feat.2da.

3) При входе персонажа в модуль или его отдыхе, если выполняется условие 2 и на навыке стоит галочка Persistent.

4) При использовании свитка/бутылки/заклинания с предмета, если строка spells.2da ассоциируется со строкой в iprp_spells.2da

5) При ударе оружием или при ударе по персонажу, носящему доспех, если строка spells.2da ассоциируется со строкой iprp_onhit.2da (вроде так).

Скрипт можно вызывать из ГУИ (интерфейса), для этого он должен начинаться с gui_

Скрипт можно вызывать из консоли после введения DebugMode 1 написанием rs *имя скрипта* *(параметры скрипта)* *ID объекта-цели*

Еще некоторые заклинания способны создавать PersistentEffect (облако, к примеру), его скрипты идентичны скриптам локи, но нету On Client Enter.

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

Все стандартные функции и константы вы можете найти в файле nwscript.nss, который для НВН 2 лежит в Data/Scripts, /Scripts_X1, /Scripts_X2 в зависимости от того, какой у вас аддон стоит. + все описания данных функций можно увидеть непосредственно в тулсете. В дальнейшем я постараюсь описать по крайней мере половину функций (их там оооочень много) из nwscript на примерах,
__________________
Мера наносит нам поражение.
Melshin is offline   Ответить с цитированием
Старый 27.12.2009, 06:49   #2
Melshin
Приближенный Тира
 
Аватар для Melshin
 
Регистрация: 20.12.2007
Адрес: Санкт-Петербург
Сообщения: 2,096
Власть репутации: 700 Melshin У него еще все впереди!
По умолчанию Re: Учебник (скриптинг)

Цитата таблица spells.2da

Я решил, что по ссылке она разобрана не до конца понятно и посчитал необходимым разобрать эту таблицу полностью и подробно.

Итак, у таблицы есть строки и столбцы. Каждая строка - заклинание. Каждый столбец, точнее, ячейка на пересечении строки n и столбца m - параметр m заклинания со SpellId n.

При работе с таблицами 2да никогда не вставляйте строку между двумя уже существующими. Никогда не ставьте пробелы, если эти пробелы не разделяют 2 параметра. Если параметр пуст, то вы должны заполнить его четырьмя звездочками "****".

Первый столбец означает SpellID заклинания. Ахтунг! На самом деле эта строка сама по себе ничего не означает. Важен именно порядковый номер строки. Т.е. если после строки с ID 1763 вы впишите строку с ID 3, на самом деле ID будет 1764! Это значит, что номер вы вписываете только для того, чтобы не запутаться.

Label. Имя заклинания. Никакой важности не имеет, но вы должны его заполнить такой последовательностью символов, чтобы вам было понятно, что находится в этой строке. Если вам уж очень хочется поставить пробел, то используйте кавычки типа "слово1 слово2", но я рекомендую поставить прочерк внизу типа Acid_Fog.

Name. ID строки в dialog.tlk. Являет собой название заклинания. Можно тут вводить и свой текст.

IconResRef. Имя иконки. Лежат в Neverwinter Nights 2\UI\default\images\icons (icons_X1 и т.п.), просматриваются всем, что читает tga (Adobe Bridge например).

School.

* G - общее (General)
* A - ограждение (Abjuration)
* C - вызов (Conjuration)
* D - предсказание (Divination)
* E - зачарование (Enchantment)
* V - воплощение (Evocation)
* I - иллюзия (Illusion)
* N - некромантия (Necromancy)
* T - превращение (Transmutation)


Можно модифицировать через spellschools.2da

Range. Макс. расстояние до цели.

* T - прикосновение
* S - короткое
* M - среднее
* L - большое.
* P - только на себя.
* I - Infinity (не пробовал)


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

Пишется либо ****, либо v, либо s, либо vs

Metamagic. Применяемая метамагия. Для того, чтобы рассчитать конечное число, откроем калькулятор Windows, переведем его в инженерный вид. У каждой метамагии есть свое число:

* 1 - Empower Spell, усиленное заклинание.
* 2 - продленное заклинание (Extend Spell)
* 4 - максимизированное заклинание (Maximise Spell)
* 8 - ускоренное заклинание (Quicken Spell)
* 16 - бесшумное заклинание (Silent Spell)
* 32 - Неподвижное заклинание (Still Spell)
* 64 - постоянное заклинание (Persistend Spell)


Складываем те числа, которые нам нужны и щелкаем "Hex", т.е. переводим в десятеричную систему. Результат записываем в виде 0x*результат*, если у результата число из 1 цифры, подписываем нолик.

Новую метамагию можно вводить в таблице metamagic.2da

Target Type. Возможная цель. Алгоритм вычисления итогового числа такой же, как и у метамагии.

* 1 - можно нацеливать на себя.
* 2 - можно нацеливать на другое существо.
* 4 - можно нацеливать на землю.
* 8 - Можно нацеливать на предмет.
* 16 - можно нацеливать на дверь.
* 32 - можно нацеливать на плэйс.



Impact Script. Сюда мы пишем имя скрипта, который мы хотим, чтобы данное заклинание запускало.

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

Cleric. Тоже, но для клерика.

Druid.

Paladin.

Ranger.

Wiz_Sorc. У них один спеллбук.

Warlock.

Innate - врожденный круг заклинания (у бардов он, допустим, неправильный).

ConjTime. В миллисекундах - время, требуемое на создание заклинания. Стандартно это полторы секунды, т.е. 1500. В это время игрок не может делать ничего другого (если он что-то сделает или провалит чек скилла концентрации, спелл сорвется).

ConjAnim. Первая анимация, которую проигрывает персонаж (так сказать, на замахе).

* attack - это когда персонаж отводит правую руку назад и потом ведет ее вперед.
* party - персонаж разводит обе руки вниз под углом относительно ног (пример - "Помощь")
* hand - персонаж вытягивает правую руку вниз-вперед ладонью вверх (очарования)
* major - персонаж взлетает
* defensive - персонаж складывает руки снизу ладонями вверх (щиты, доспехи)
* head - персонаж поднимает руки над головой.


ConjVisual0 - VFX, используемый при касте. Можно использовать любой уже готовый (их мнооого), свой или стандартный для спеллов из нижеперечисленных:

* sp_acid_conjure.sef - кислота
sp_enchantment_conjure.sef - зеленая аура школы зачарования
sp_necromancy_conjure.sef - красная аура некромантии
sp_transmutation_conjure.sef - коричневая аура трансмутации
sp_evocation_conjure.sef - белая вспышка воплощения
sp_bless_conjure.sef - желтая вспышка благословения
sp_fire_conjure.sef - огонь
sp_lighting_conjure.sef - молния
sp_inflict_conjure.sef - нанесения ранений
sp_illusion_conjure.sef - сине-серая школа иллюзии
sp_divination_conjure.sef - белая аура прорицания
sp_ice_conjure.sef - лед
sp_cure_conj_w.sef - лечение
sp_darkness_conjure.sef - тьма
sp_abjuratuion_conjure.sef - ограждение
sp_sonic_conjure.sef - звук
sp_holy_conjure.sef - белая священная вспышка


LowConjVisual0 - везде sp_magic_conjure.sef, хз почему

ConjVisual1 - не используется

ConjVisual2 - не используется

ConjSoundVFX - не знаю, что этакое, есть у True Name Scroll (которым риверов в ОС убивали).

ConjSoundMale - голос персонажа, голоса по одной и той же текстовой строке изменяются с кругом заклинания

* vs_chant_conj_hm - все заклинания школы вызова
vs_chant_ench_lm - зачарование
vs_chant_necr_lm - некромантия
vs_chant_evoc_hm - воплощение
vs_chant_illu_lm - иллюзия
vs_chant_conj_lm - ограждение


ConjSoundFemale - то же, что и выше, но для женского пола. Список идентичен, m-ки на конце только менять на f-ки

ConjSoundOverride - хз

CastAnim - анимация каста. Т.е. то, что идет после замаха. Некоторые комбинации могут выглядеть некрасиво.

* area - перс тыкает пальцем
self - перс поднимает руки над головой
general - перс вытягивает обе руки вперед
major - то же самое, но в полете
out - перс вытягивает руку вперед (как при использовании предмета)
defensive - перс разводит руки в сторону (щиты)


CastTime - время на выполнение вышеуазанной анимации. В это время персонаж не отвечает на какие-либо команды. По умолчанию 1000 (1 секунда, итого 2.5 секунды)

CastVisual0 - то же, что и ConjVisual0, только conjure заменить на каст.

LowCastVisual0 - продублировать CastVisual0

CastVisual1, CastVisual2, CastSound - не используется.

Proj - есть ли у заклинания летящий компонент (пример - файрболл). Скрипт заклинания исполнится только тогда, когда этот компонент коснется цели. Обычно сюда указывают 0, иначе вам придется заполнять тьму других строк.

ProjModel - модель компонента. Типично - missingobject, но еще бывают w_arrow01, w_flask, w_dart01, w_shurkn01, w_arrow. Короче говоря, сюда можно хоть домик указать.

ProjSEF

.sef, используемый как VFX, висящий на Projectile. Типичные примеры можно посмотреть все в том же spells.2da, я не буду это описывать, т.к. прожектайлы делают довольно редко.

LowProjSEF - дублируем предыдущее.

ProjType - физическое поведение прожектайла.

* accelerating - ускорение
homing - по ходу тупо летящее
linked - ???, кто-нибудь проверьте и расскажите
burstup - ???, по ходу это когда их много
Еще есть много других, но я забью, т.к. не разбираюсь


ProjSpawnPoint - где появляется прожектайл.

ProjSound - это можно сделать в самом .sef, так что здесь оно нафиг не нужно в принципе.

ProjOrientation - либо path, либо ****, хз что это

ImpactSEF - .sef, проигрываемый при попадании прожектайла в цель (пример - взрыв файрболла)

LowImpactSEF - дублировать

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

ItemImmunity. Может ли параметр предмета давать иммунитет к заклинанию. Если 1 (да), то допишите параметр в iprp_spellcost.2da

SubRadSpell1, 2, 3, 4, 5 - если вы хотите, чтобы при нажатии на иконку этого спелла запускался не скрипт, а менюшка с выбором нескольких заклинаний - вписывайте сюда SpellId нужных заклинаний.

Category. Смотрите в categories.2da, используется ИИ (точнее, не используется, поскольку АИ от Tony_k работает по-другому)

Master. Если это заклинание вызывается через SubRadSpell, укажите здесь (обязательно) тот SpellID, который его вызывает. Для SubRadSpell2 и далее SpellID писать не обязательно (только для первого)

UserType. Что это за заклинание.


1 - заклинание.
2 - заклинательно-подобная способность.
3 - навык.
4 - что-то другое (сила предмета)

SpellDesc. Строка в dialog.tlk, отвечающая за игровое описание спелла.

UseConcentration. Можно ли прервать спелл, 1/0

SpontaneouslyCast. Можно ли произнести заклинание без подготовки (спонтанные кастеры таких типов - клерик и друид, а заклинания соответственно - хилки и суммоны, вы будете первопроходцем, поработав с этим и последующим параметром)

SpontCastClassReq. Какой класс может произносить этот спелл спонтанно. Писать сюда ID из classes.2da

AltMessage - альтернативное сообщение, отображающееся при использовании этой штуки (по умолчанию кто-то произносит заклинание: *Name*) ID из dialog.tlk сюда пишется

Hostile Setting. Враждебное ли это заклинание или нет? (выводит ли из невидимости, санки и т.п.) 1/0

FeatID. Никакого значения обычно не имеет, для удобства пользователя. Указывает на ID фита, вызывающего скрипт по данному spellid. Есть исключение: навык, вызывающий список навыков (пример: формы друида). Тут уже все сложно и этот параметр заполнять обязательно.

Нужно вставить сюда число, равное: 65536*n+реальный вызывающий FeatID.

n должен быть больше 4999 и данный n не может использоваться больше 1 раза (даже для разных навыков). Если ваш мозг все еще на месте, продолжаем дальше.

Counter1, Counter2 - не пашет.

HasProjectile - есть ли прожектайл... (зачем 2 раза-то спрашивать?)

AsMetamagic - является ли данный спелл метамагией (надо для варлоков), не изучал.

TargettingUI - обращается к ID в spelltarget.2da, в общем-то это отображаемая форма действия заклинания (точнее, форма нацеливания) - реальная форма конечно в скрипте.

CastableOnDead - 1/0, можно ли нацеливать на трупы.

Removed - есть ли в игре, ставить 0, если вы его таки сделали, иначе работать не будет.

Продолжение следует...
__________________
Мера наносит нам поражение.
Melshin is offline   Ответить с цитированием
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
You may not post new threads
You may not post replies
You may not post attachments
You may edit your posts

BB code is Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT, время: 17:33.

Powered by vBulletin Version R.I.P., Copyright ©2000-2024, Jelsoft Enterprises Ltd. | Оформление: raurin.ru