Перейти к содержанию

Морровинд и LUA-скрипты


Рекомендуемые сообщения

upl_1519723828_772.png

 

 

Шёл 2019 год. Очередное переиздание Скайрима на микроволновке прекрасно продаётся. А что же Шинд, его предшественник аж 17-летней давности? Так и он тоже живее всех живых! Почему? Благодаря модам, разумеется. Так уж сложилось исторически: ТЕС – это моды, а моды – это ТЕС, и одно без другого немыслимо.

Вы помните свои первые впечатления, когда узнали о существовании КС и открыли редактор? Это что же, все данные игры аккуратно рассортированы по таблицам, и я могу их менять? Как сам того пожелаю?! Я что, теперь разработчик игор? Ооо дааа!

Нужен убер-меч? Пожалуйста! А может личный домик в Балморе? Заверните мне два! А что это тут за колонка «scripts»? Ну, if – это если, это понятно, тааак падажжите… ОГО! Так вот почему Фаргот крадётся к своему любимому пню! Так это что получается, я теперь не только гейм-дизайнер, но ещё и погроммист?!

И ЧИМ был познан… И весь Аурбис разверзся пред волей нового Демиурга! Целые квестовые линейки, компаньоны, перки, крафт… да всё что угодно! Скрипты разрастались, превращаясь в монструозные громадины. Иногда многоэтажки из 30 if-elseif рушились под тяжестью собственного веса, а если не рушились, то подвешивали двемеропекарню секунд на 5. Ох, на какие только ухищрения не приходилось идти молодым ЧИМанутым Демиургам дабы привести свою Волю в исполнение! Узрев их, поездоголовый человек немедленно разогнался бы до околосветовой скорости от осознания своей непомерной нормальности и улетел бы за пределы Нирна, прямо вслед за двемерами.

О, эврика! Долго ломал голову и придумал наконец, как отследить одно очень заковыристое событие! Сделаю я это по звукам, издаваемым жопками скрибов, долбящих ими по камням. Отслеживать, правда, придётся нонстопом, а потом проверять ещё полсотни сторонних условий, а скрибов в округе развелось нынче немало! И все с жопами! И все непрерывно стучат! Ах да, и ещё всё тело скрипта выполнялось каждый фрейм, а число самих фреймов у обладателей особо мощных двемеропекарен доходило до 15! Только вдумайтесь, какие вычислительные мощности расходовались вхолостую вместо того чтобы вычислять биткойн!

MWSE оказался ложкой скуумы в бочке скаттла. Привнеся кучу новых функций (а вместе с ними и багов), он позволил особо смышлёным Демиургам вывести своё постижение ЧИМа на новый уровень и гульнуть на широкую ногу. Но скуумовая эйфория была недолгой. Чего не скажешь о послевкусии после многочисленных бочек со скаттлом. Да, у всего в этом мире есть предел. И предел скриптового языка КС был давно достигнут.

Но хвала Троим! – всё изменилось с приходом MWSE 2.1. Ни говоря ни слова больше, ЧИМанутый Демиург вынул костыль из своей задницы… и создал папку

Data Files\MWSE\mods\MyAwesomeMod

 

Затем он создал в ней пустой текстовый файл main.txt и сменил его расширение на аббревиатуру языка Истинных Богов Кодинга – lua

Получившаяся скрижаль main.lua по-прежнему прекрасно открывалась блокнотом, Демиург улыбнулся – ему не придётся страдать фигнёй с редакторами и компиляцией. Но пока что перед ним был чистый холст. Уже обладая опытом в постижении Языков Богов, Демиург понял, что быстрее всего это выйдет сделать на готовом примере. Открывая и изучая файлы других творцов, он чувствовал себя культистом карго в китайской комнате. И тут и там встречались интуитивно понятные элементы, но что с ними делать и как сложить в единую картину? Он мог изменить цифры в готовых функциях, и поначалу этого было достаточно. Однако ему хотелось большего осознания того, что он делает и зачем.

 

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

local function MyAwesomeFunction(e)

end

local function initialized(e)
event.register(" ", MyAwesomeFunction)
end

event.register("initialized", initialized)

Суть была такова:

Игра не будет прокручивать всё тело скрипта каждый фрейм. Двемеропекарня вздохнула свободно. От одного осознания этого факта число кадров в секунду сразу скакнуло аж до двадцати! В луа игра только регистрирует конкретные события – эвенты. И каждый раз когда указанное событие происходит, игра выполнит указанную функцию, в данном случае – MyAwesomeFunction. Да, названия и наполнение функций можно придумывать самому. Сейчас наполнение функции пустует, да и с отслеживаемым событием мы не определились. Для каждого эвента есть своё зарезервированное название, которое нужно знать точно. Так, посмотрим, что у нас в меню?

https://mwse.readthedocs.io/en/latest/lua/event.html

 

Неплохо, да? О, что это у нас тут? calcHitChance. Это же то о чём я думаю? Решено! Сколько себя помнил, всякие зумерки всегда плевались от боевой системы Шинда, не в силах попасть по грязекрабу даже 1 раз из 10. В этом даже было некоторое очарование, но быть может скайримодети в чём-то правы, и система попаданий действительно нуждается в починке?

Итак. У каждого эвента есть определённый список игровых данных. Что же может предложить нам эвент calcHitChance? Смотрим:

attackerMobile

targetMobile

target

attacker

hitChance

Ридонли, ридонли, ридонли… о! hitChance не ридонли! Да, это означает, что его можно менять! Вот мы и подошли к сути работы с эвентами – граалю MWSE 2.1 – перехват игровых данных событий и изменение этих данных на свой вкус в собственноручно составляемых функциях! Оператор присвоения значения переменной – это знак равенства. Ну, сколько забабахаем? Не будем мелочиться! 100% шанса, 10 попаданий по грязекрабу из 10!

Теперь наш манускрипт выглядит так, и он УЖЕ в полностью рабочем состоянии!

local function MyAwesomeFunction(e)
e.hitChance = 100
end

local function initialized(e)
event.register("calcHitChance", MyAwesomeFunction)
end

event.register("initialized", initialized)

Да, вот так просто! Скрипт перехватил игровые данные о шансе на попадание и изменил их. И не один раз – а всегда. Функция вызывается при каждом событии удара, и теперь при каждом ударе шанс будет выставляться на сотку.

А может, не стоит быть столь радикальными? Сотня шанса это хоть и прекрасно, и мы одной строчкой кода почти превратили Шинд в Подливион, но всё же – не пропадать ведь шарму промахов в упор? Особенно если этот механизм можно довести до ума.

 

Изменим наш код следующим образом:

local function MyAwesomeFunction(e)
  local hitreduction
  if ((e.targetMobile.isMovingLeft or e.targetMobile.isMovingRight) and (e.targetMobile.isMovingForward == false)) then -- если цель движется влево или вправо и при этом не движется вперёд
              hitreduction = e.targetMobile.agility.current / 2
  else
              hitreduction = 0
  end
  e.hitChance = 100 + (e.attackerMobile.agility.current / 2) - e.attackerMobile.blind - (e.targetMobile.sanctuary / 2) - (e.targetMobile.chameleon / 2) - hitreduction
end

local function initialized(e)
event.register("calcHitChance", MyAwesomeFunction)
end

event.register("initialized", initialized)

Что всё это значит? Попробуем разобраться.

 

* Сразу бросаются в глаза уже знакомые нам по esscript блоки if-end. else и elseif тоже в деле. Что изменилось? После условия обязательно надо прописывать ещё и оператор then.

 

* Комменты идут после сдвоенного минуса --

 

* С пробелами и скобками тут куда больше вольностей. А вот регистр букв важен – его надо чётко соблюдать.

 

* Операторы and и or, два барата-бубенца кастрированного хаджита вернулись на своё законное место! Больше не надо громоздить монструозные мгногоэтажки. Вообще, в луа как в полноценном языке есть много фич, недоступных ущербному esscript. И таймеры, боже, настоящие таймеры! Как же их не хватало в КС!

 

* Нужна своя переменная? Провозгласите её с помощью волшебного слова local. Так мы прописали local hitreduction и ввели переменную hitreduction. Она будет доступна скрипту только в пределах той функции или блока if-end, в котором она была провозглашена. Так что если вы хотите, чтобы ваши локальные переменные были доступны для всего скрипта – провозгласите их в самом-самом начале файла.

 

* А что это за вездесущие буковки e? В MWSE для Шинда есть очень много зарезервированных названий игровых данных. Многие данные представляют собой целые базы данных. Сначала пишем название базы данных, затем точка без пробелов, затем опять же без пробелов название переменной внутри этой базы, причём сама эта переменная в свою очередь тоже может оказаться базой данных со своими переменными внутри. Это как путь к файлам в многочисленных папках. Укажите весь путь через точки.

Так e – это база данных всего события. В нашем примере, события расчёта шанса на попадание. Какие переменные есть внутри этой базы данных? Мы их уже видели:

attackerMobile

targetMobile

target

attacker

hitChance

Нам пока нужно знать что в этом конкретном событии attackerMobile означает атакующего, targetMobile означает цель атаки, а hitChance – собственно сам шанс на попадание.

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

e.attackerMobile.agility.current

Нужно узнать, сколько у защищающегося эффекта светоча – прописываем:

e.targetMobile.sanctuary

Где же посмотреть все зарезервированные имена баз данных и их содержимое? Для мобильного актёра (коим и являются наши e.attackerMobile и e.targetMobile) например здесь:

https://mwse.readthedocs.io/en/latest/lua/type/tes3/mobileActor.html

А для остальных типов данных – здесь:

https://mwse.readthedocs.io/en/latest/lua/type.html

 

Теперь, зная всё это, мы можем прочесть скрипт и понять, что мы сотворили. Сначала проверили, движется ли защищающийся влево или вправо и не движется ли он при этом вперёд? Если да, то присвоили созданной нами переменной hitreduction значение половины от текущей ловкости защищающегося. А если нет, то присвоили hitreduction 0.

Потом вычисляем сам шанс на попасть. Взяли 100%, прибавили половину от текущей ловкости нападающего, отняли величину слепоты нападающего, отняли половину от величины светоча и хамелеона защищающегося, и наконец отняли величину нашей переменной hitreduction. Вуаля! Теперь очень ловкий персонаж получает нехилый шанс уклониться от атаки, если будет правильно двигаться. Светоч и хамелеон защищающегося, а также слепота и ловкость нападающего так же окажут эффект.

 

Вообще-то вы можете придумать свою формулу, поставив зависимость шанса на попадание от почти чего-угодно, хоть от погоды на Массере. Доступных событий множество – вы можете легко изменять наносимый урон, параметры объектов и актёров, раздавать и удалять предметы и заклинания, менять прирост опыта в навыках, разрешать и запрещать использование предметов, отслеживать состояние боя, сохранения, загрузку, нажатие определённых кнопок и многое, многое другое… Особо искушённые творцы сумеют изменить интерфейс, создавать собственные продвинутые меню, добавлять новые навыки и даже новые магические эффекты! Открывающиеся возможности просто поразительны.

 

Теперь же, когда вы узрели силу луа в самых элементарных алгоритмах, вы получите заряд к познанию большего. Изучите общие принципы языка луа, посмотрите гайды от авторов МВСЕ. Постарайтесь прочесть несколько уже готовых плагинов, например эти:

https://www.nexusmods.com/morrowind/mods/47056

https://www.nexusmods.com/morrowind/mods/47035

https://www.nexusmods.com/morrowind/mods/47062

Если удастся – то вы уже освоили достаточно и теперь можете сотворить что-то своё.

 

Так сделайте это и Живите в Своём Собственном Благословлённом Мире, который Сами и Создали!

Изменено пользователем Dagot_Prolaps
Ссылка на комментарий
Поделиться на другие сайты

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

Ссылка на комментарий
Поделиться на другие сайты

На боёвку здесь:

https://www.nexusmods.com/morrowind/mods/46993/

 

На новый маг. эффект например здесь:

https://www.nexusmods.com/morrowind/mods/47008

 

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

Ссылка на комментарий
Поделиться на другие сайты

Окей, был неправ. Полазил по списку функций -- выглядит действительно любопытно. О возможности отслеживать начало/конец боя давно мечтали.

Ссылка на комментарий
Поделиться на другие сайты

Боевка - очень вкусная штука. В перспективе ведь там можно замутить и пробитие брони, и поломку оружия, и разные фишки именно для оружия определенного класса (что уже показано в этом плагине с Nexus).

 

Черт, все это очень круто. Закочну с Fallout - вернусь в Morrowind :D

Ссылка на комментарий
Поделиться на другие сайты

Нафига этот мясе, если можно дождаться опенмв?

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

Изменено пользователем Larkin
Ссылка на комментарий
Поделиться на другие сайты

Боевка - очень вкусная штука. В перспективе ведь там можно замутить и пробитие брони, и поломку оружия, и разные фишки именно для оружия определенного класса (что уже показано в этом плагине с Nexus).

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

Нафига этот мясе, если можно дождаться опенмв?

Хороший вопрос. Тем более, в OpenMW тоже планируют вынести игровую логику в lua скрипты.

Ссылка на комментарий
Поделиться на другие сайты

В перспективе ведь там можно замутить и пробитие брони

 

Да, он как раз сделал пробой брони для дробящего, причём заморочился и сделал его настраиваемым, так что с балансом тут проблем никаких. Я написал автору свои мысли по поводу эффектов для каждого вида оружия. Посмотрим, как отреагирует.

 

Нафига этот мясе, если можно дождаться опенмв?

 

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

Изменено пользователем Dagot_Prolaps
Ссылка на комментарий
Поделиться на другие сайты

Да, он как раз сделал пробой брони для дробящего, причём заморочился и сделал его настраиваемым, так что с балансом тут проблем никаких. Я написал автору свои мысли по поводу эффектов для каждого вида оружия. Посмотрим, как отреагирует.

Спроси у него лучше, как он учился на Lua кодить, а то мы его своими хотелками заколебаем :)

 

Может, он скинет тебе свой личный гайд с исследованиями скриптов Lua :)

Ссылка на комментарий
Поделиться на другие сайты

Спроси у него лучше, как он учился на Lua кодить, а то мы его своими хотелками заколебаем :)

 

Может, он скинет тебе свой личный гайд с исследованиями скриптов Lua :)

Так а что, такая проблема с языком? Или я чего-то не понимаю? http://www.cronos.ru/kb-cronospro-lua.html

 

https://forum.mtasa.com/topic/27040-%D1%80%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B5-%D0%B4%D0%BE%D0%BA%D0%B8-%D0%BC%D0%B0%D0%BD%D1%83%D0%B0%D0%BB%D1%8B-%D1%82%D1%83%D1%82%D0%BE%D1%80%D0%B8%D0%B0%D0%BB%D1%8B-%D0%BF%D0%BE-lua-%D0%B8-mtasa/

Изменено пользователем danmer78
Ссылка на комментарий
Поделиться на другие сайты

3d7f214286c058cb70981fc3a6b44ca5.jpg

 

 

 

1 строчка. 1 строчку нового кода понадобилось внести в плагин, чтобы запилить зависимость урона от стамины. И ещё 3 строчки отредактировать, добавив 1 параметр в функцию и ссылку на неё.

 

Всё. Теперь я гуру. Ждите луа-репак.

Изменено пользователем Dagot_Prolaps
Ссылка на комментарий
Поделиться на другие сайты

Всё. Теперь я гуру. Ждите луа-репак.

Надеюсь, он будет реалистичный :D

 

На самом деле очень здорово. Успехов.

Ссылка на комментарий
Поделиться на другие сайты

Ох какую штукенцию я сейчас запилил... закачаешься! В буквальном смысле!

 

Продвинутый 100% шанс попасть с активными уворотами! Как в дисхонореде. Ну почти. Увернуться можно, но для этого надо стрейфить влево или вправо (но при этом не идти вперёд). Вместо анимации уклонения будет обычная анимация стрейфа туда-сюда.

Я сделал шансы зависимыми от ловкости, но это черновой вариант - можно сделать как угодно!

 

local function alwaysHit(e)

local hitreduction
local hitbonus = e.attackerMobile.agility.current * 0.5
if ((e.targetMobile.isMovingLeft or e.targetMobile.isMovingRight) and (e.targetMobile.isMovingForward == false)) then
hitreduction = e.targetMobile.agility.current * 0.5
else
hitreduction = 0
end
e.hitChance = (100 - e.attackerMobile.blind + hitbonus - hitreduction)
end
Изменено пользователем Dagot_Prolaps
Ссылка на комментарий
Поделиться на другие сайты

Где можно заценить? И как с НПС? Они научились увровачиваться? Изменено пользователем Moran Remar
Ссылка на комментарий
Поделиться на другие сайты

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

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

Ссылка на комментарий
Поделиться на другие сайты

  • 4 месяца спустя...

Кто интересуется  lua скриптами.  Кому-нибудь нужен гайд по скриптингу, например использованию системы типов mwse 2.1 в lua ?

Изменено пользователем mintmike
Ссылка на комментарий
Поделиться на другие сайты

Приготовил для вас несколько забавных уроков по Lua. Думаю как назвать тему? Просто "Уроки по Lua скриптам" ...

 

https://www.fullrest.ru/forum/topic/41708-mwse-21-uroki-po-lua-skriptam/

 

*UPD количество уроков увеличено до шести

Изменено пользователем mintmike
Ссылка на комментарий
Поделиться на другие сайты

  • 2 недели спустя...

Малый учебник: https://lua.org.ru/main.html#the-little-lua-book

Средний учебник: https://lua.org.ru/contents_ru.html

Большой учебник: https://vk.com/doc-127857710_437836162

Ссылка на комментарий
Поделиться на другие сайты

  • 5 месяцев спустя...

Приятно видеть, как проект постоянно развивается. Документация по mwse не успевает, что естественно, поэтому не все возможности там можно найти.

 

Появилась возможность заменять меш крови, что и реализовано в Blood Diversity:

for object in tes3.iterateObjects(tes3.objectType.creature) do
	
  --...

  object.blood = bloodmesh

end

 

Ссылка на комментарий
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...