Четверг, 18.04.2024, 15:23


[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]

Форум » Модификации Painkiller » Разработка модификаций и контента к ним » Помощь с Lua-скриптами (Задаем вопросы, отвечаем.)
Помощь с Lua-скриптами
Str_GhostСуббота, 25.02.2012, 17:58 | Сообщение # 16





Quote (ItramariN)
но вот как заставить моба атаковать только монстров - это уже другой вопрос

В Resurrection, помнится, был бот в коопе, который атаковал только монстров happy
 
ItramariNСуббота, 25.02.2012, 23:36 | Сообщение # 17
Аластор
Сообщений: 591
Награды: 12
Репутация: 55
Статус: Offline
Quote (Str_Ghost)
В Resurrection, помнится, был бот в коопе, который атаковал только монстров

Он же используется в PK++


Я люблю людей... особенно - убивать!^__^
 
Str_GhostВоскресенье, 26.02.2012, 01:15 | Сообщение # 18





ItramariN, Ну, вообще они разные) Учитывая, что в PK++ нет коопа то и невозможно было его настроить под отстрел монстров.
 
ItramariNСуббота, 03.03.2012, 02:20 | Сообщение # 19
Аластор
Сообщений: 591
Награды: 12
Репутация: 55
Статус: Offline
Quote (Str_Ghost)
Ну, вообще они разные) Учитывая, что в PK++ нет коопа то и невозможно было его настроить под отстрел монстров.

В PK++ просто часть файла, который касался консольных команд, загнали в консоль. А вообще настроить можно, теоретически. В конце-концов, товарищей по команде бот не обстреливает. Но это уже будет особый коопский ботО_о А карта должна призывать Актора, которому как-то надо переиначить определение цели для атаки...


Я люблю людей... особенно - убивать!^__^
 
Str_GhostВоскресенье, 04.03.2012, 09:46 | Сообщение # 20





Вчера пытался что-то натворить с меню, и понял одну вещь - копипастингом ничего не добьюсь. Нужно учиться. И поэтому у меня есть ко всем вопрос: есть у кого-нибудь хороший учебник по Lua? Думаю, не плохо будет изучить хотя бы основы, тем более луа ещё и в Serious Sam используется... happy
 
ItramariNПонедельник, 05.03.2012, 21:03 | Сообщение # 21
Аластор
Сообщений: 591
Награды: 12
Репутация: 55
Статус: Offline
Quote (Str_Ghost)
И поэтому у меня есть ко всем вопрос: есть у кого-нибудь хороший учебник по Lua? Думаю, не плохо будет изучить хотя бы основы, тем более луа ещё и в Serious Sam используется...

Хочешь совет? Изучай Delphi. От ЛУА отличается немного синтаксисом, но в целом основы ты поймешь. А учебников по Дельфи куда больше + это самостоятельный язык, ан не скриптовый, что очень сильно влияет. Можно вообще с Паскаля начинать - от него у Дельфи ноги растут) Да и я за гайд "основы программирования" возьмусь на днях)


Я люблю людей... особенно - убивать!^__^
 
ItramariNПонедельник, 05.03.2012, 22:40 | Сообщение # 22
Аластор
Сообщений: 591
Награды: 12
Репутация: 55
Статус: Offline
Итак, написал тут немного нужной информации. Сумбурно, не совсем точно, но все же.
Прежде чем начать разбираться со скриптами Пейнкиллера, давайте научимся хотя бы основам программирования.
Первое – двоичный код. Советую ознакомится, он нам понадобится для логики. А теперь – Паскаль. Ну, или Дельфи – это как посмотреть. С учетом того, что Дельфи – расширенный Паскаль, работать пока мы будем в Дельфи, но на Паскале. Я буду использовать Дельфи 7, но версия существенной роли не играет. Очень советую скачать Дельфи и действительно писать проги, а не просто читать данный текст.
Чтобы писать программы на Паскале, давайте разберемся вначале, что же такое программа. Говоря простым языком – программа это всего лишь инструкции машине, что нужно делать, потому и пишутся на разных языках. Языки бывают разных уровней. Самый первый, «машинный» - это язык ассемблера. Фишка в том, что оный – тот же двоичный код, только записанный командами, а не единицами и ноликами. Следующий уровень – процедурно ориентированные, в которые входит Паскаль, Си и прочие. Затем – объектно-ориентированные – это Паскаль с какой-то там версии, Си++ и тд. И последние – Дельфи и прочие – языки с самой современной визуальной фигней. Но мы - программисты, нашему сердцу мила консоль. И формы нам ни к чему. Да и при работе со скриптами нам интерфейс зачастую будет побоку. Поехали!
Запускаем Дельфятину. Создаем новый проект – нам нужно консольное приложение. Нам откроется окошко с текстом проги. Увидим что-то вроде такого:
Code
Program project1;

Uses
    SysUtils;

Begin
End.

Итак, давайте разбираться. Первая строка – ключевое слово program и название программы. Да, точка с запятой обязательна после каждой строчки (почти). Такой уж синтаксис языка. Я думаю, не надо говорить, зачем программе название? Нет, ну и ладно. Затем идет строка uses. Здесь через запятую мы пишем все модули, которые будем использовать. Модуль или библиотека (вообще-то библиотечный модуль) – кипа определенных процедур. Нам надо что-то вывести на экран – мы запускаем заранее определенную процедуру и передаем ей параметры того, что нам на экран надо вывести. Проще говоря, процедуры облегчаю жизнь. Свои модули мы писать не будем, хотя если кого-то заинтересует, можем к этому вернутся.
В нашем проекте мы юзаем только SysUtils. Важно! – Паскаль да и Дельфи не различает строчные и прописные буквы. Не будем разбиратся, что дает нам данный модуль, просто он нужен.
А теперь пошла сама программа. Она начинается словом begin, кончается end’ом. Кстати, эти слова – этакие скобки для программы, в которые можно заключать куски кода, поэтому перед Begin'ом точка с запятой не ставится. Здесь мы и будем кодить. Однако есть проблема – программе нужны какие-то данные, чтобы работать. Чтобы работать, нужно зарезервировать память, а для этого перед началом кода мы ставим слово var и «объявляем» переменные и их тип, например так:
Code
Var
x,y:integer;
z:real;

Тип определяет размер выделяемой для переменной памяти а так же определяет те значения, которые эта переменная может применять. Теперь немного о типах: Integer – целочисленный тип (от -32768 до 32767), есть несколько разновидностей этого типа (long, Shortint) но нам это как-то побоку. Real – это целые и дробные числа, в двоичном коде представляются с плавающей точке (каждое число это значение числа плюс сдвиг, если хотите понять получше – почитайте литературу, самое главное для нас то, что это целые и дробные числа, но в их представлении бывают погрешности). Char – символ ASCII. Вы не знаете, что это? Это просто таблица символов (буквы, цифры, знаки препинания, прочая радость…). Array – массив, т.е. несколько переменных одного типа (о массивах поговорим позже). String – строка символов, аналог массива. Record – несколько переменных разного типа, можно сказать, что это основа класса (и об этом поговорим). Вот и все, что нам пока надо.
Давайте наконец напишем прогу!
А вот хрен мы ее напишем. Пусть пока та куча инфы, которую я на вас так сумбурно вылил утрясется и уляжется по полочкам и скажите – что вы все-таки поняли?


Я люблю людей... особенно - убивать!^__^

Сообщение отредактировал ItramariN - Вторник, 06.03.2012, 14:47
 
ned18kВторник, 06.03.2012, 00:22 | Сообщение # 23
Страж
Сообщений: 190
Награды: 3
Репутация: 62
Статус: Offline
Str_Ghost
Я как-то тоже изучал один язык программирования, экшн скрипт (используется в флеш плеере). Сначала конечно понял как что конкретно делать. Но чем дальше, тем больше читал теорию ООП. Очень увлекательная вещь. Рекомендую.

Потом когда открыл коды пк, то, к своему удивлению, многое было понятно. Хотя с луа никогда не работал. smile Т.е. я не знал что конкретно делает тот или иной код, но понимал общее направление хода мысли программистов.
Ведь коды луа в пк это сплошные классы.

ItramariN
А может примеры сразу в пк делать? И объяснять сразу. Будет отличное практическое программирование. Т.е. все под рукой: и приложение и редактор (взять редактор кода какой-нибудь стандартный. Кстати рассказать какой лучше тоже можно.)

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


Добро всегда побеждает зло. Поэтому кто победил, тот и добрый.

Сообщение отредактировал ned18k - Вторник, 06.03.2012, 00:39
 
ItramariNВторник, 06.03.2012, 14:59 | Сообщение # 24
Аластор
Сообщений: 591
Награды: 12
Репутация: 55
Статус: Offline
Quote (ned18k)
Потом когда открыл коды пк, то, к своему удивлению, многое было понятно. Хотя с луа никогда не работал. Т.е. я не знал что конкретно делает тот или иной код, но понимал общее направление хода мысли программистов.

У многих языков похожий синтаксис. Я изучал Паскаль, Дельфи, Си, немного видел Ассемблер и говорю - ЛУА более чем похож на Дельфи.
Quote (ned18k)
Ведь коды луа в пк это сплошные классы.

Это везде так. Почему - долго объяснять, но если хочешь - могу расписать.
Quote (ned18k)
А может примеры сразу в пк делать? И объяснять сразу. Будет отличное практическое программирование.

Угу, программа считающая периметр и площадь прямоугольника в скрипте будет смотреться просто шикарно! biggrin Разве что в консоль вогнать команду) Не волнуйся, дойдем и до ПК, никуда не денемся) Я и так стараюсь максимально коротко рассказывать.
Вдобавок лучше тыкаться в ошибки в компиляторе с вполне самостоятельным языком, чем фэйлиться с языком скриптовым.
Quote (ned18k)
Т.е. все под рукой: и приложение и редактор (взять редактор кода какой-нибудь стандартный. Кстати рассказать какой лучше тоже можно.)

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

Про все расскажем. Даже кооператив будем вместе "делать". Кстати, спорим, что ты и трети служебных данных не выводил? Все потому, что в ПК переменных как и в любой игре до чертиков, и большая часть из них - в движке, который ну никак не раскомпилишь. Это не УТ какой-нибудь, тут движок закрытый.


Я люблю людей... особенно - убивать!^__^
 
ned18kВторник, 06.03.2012, 15:09 | Сообщение # 25
Страж
Сообщений: 190
Награды: 3
Репутация: 62
Статус: Offline
Quote (ItramariN)
Это везде так. Почему - долго объяснять, но если хочешь - могу расписать.

Очень хочу. ))
Распиши пожалуйста. Еще как точно оформлены свойства классов и методы, области видимости и прочее. Мне этой инфы в свое время очень не хватало.
Хорошо бы примеры использования свойств и методов. События. Именно в коде пк.
Но это просто пожелание. smile

Quote (ItramariN)
Есть очень офигенный редактор кода - блокнот называется. Для скриптов - самое оно.

Бе. smile Некомфортно же ведь. Я даже с хмл работал в спец. редакторе. Он мне сам недостающее вставлял.
Хороший редактор сам форматирует код и указывает на ошибки. Такие есть?


Добро всегда побеждает зло. Поэтому кто победил, тот и добрый.

Сообщение отредактировал ned18k - Вторник, 06.03.2012, 15:14
 
ItramariNСреда, 07.03.2012, 05:16 | Сообщение # 26
Аластор
Сообщений: 591
Награды: 12
Репутация: 55
Статус: Offline
Quote (ned18k)
Очень хочу. ))

Короче, у нас есть монстр. Мы описываем его переменными (модель, текстуры, рэгдолл и т.д.), но нам же надо чтобы он еще и ходил! Вот мы и пишем процедуру, с помощью которой он будет ходить. Эту процедуру мы включаем в класс, так как такой метод работает только для монстров. Вуаля. Вот и получаем, что у каждого предмета есть переменные описывающие его состояние и то, что этот предмет должен делать - методы класса. Так для уровня, монстра, игрока, даже менюшки. Да и сама программа в какой-то мере класс.
Quote (ned18k)
Еще как точно оформлены свойства классов и методы, области видимости и прочее. Мне этой инфы в свое время очень не хватало.

А вот это я уже расписать не могу - кое-что сокрыто в движке игры, кое в чем еще сам до конца не разобрался. Я до сих пор не понимаю большую часть скриптов, переменных и прочей радости. На эксперименты времени катастрофически не хватает.
Quote (ned18k)
Хорошо бы примеры использования свойств и методов. События. Именно в коде пк.

Даже не знаю... давай так - найди сам какой-нибудь непонятный пример в скриптах и вместе разберемся, ок? Только бери самое примитивное - скрипты с уровней, например, там кода мало)
События: У нас в программе возникают разные ситуации. Например, монстра убили. Игра нам говорит - "о, монстр убит!" - вот и событие. А затем игра проверяет - а не должна ли она на это собитие что-то сделать? Да, должна - разорвать монстра на кусочки и реснуть душу. что она и делает. Все, все счастливы) События выглядят как функции с названием <класс>_on<название события>. Например CActor_OnKill. Событие таким образом - просто флаг, логическая переменная, которая при принятии некоторых значений указывает какие процедуры надо запустить.
А примера на событие не будет - просто полистай GameMP, там примеров выше крыши.
Quote (ned18k)
Хороший редактор сам форматирует код и указывает на ошибки. Такие есть?

Хороший редактор не исправляет ошибки, он указывает на них во время компиляции, иначе сам потом своих ошибок не замечаешь, что не есть хорошо.
насчет редактора - залезь на сайт ЛУА, может что и найдешь.


Я люблю людей... особенно - убивать!^__^

Сообщение отредактировал ItramariN - Воскресенье, 18.03.2012, 16:18
 
Str_GhostЧетверг, 15.03.2012, 21:01 | Сообщение # 27





А когда продолжение уроков будет? smile
 
ItramariNВоскресенье, 18.03.2012, 17:00 | Сообщение # 28
Аластор
Сообщений: 591
Награды: 12
Репутация: 55
Статус: Offline
Quote (Str_Ghost)
А когда продолжение уроков будет?

Сейчас.
Ладно, едем дальше.
Итак, что должна делать программа? Она должна получать данные, обрабатывать их и выводить результат. Это если по-простому. Потом все будет сложнее. А игры в этом плане вообще интересны - большую часть данных они получают от самих себя, а не от пользователя и выводят фактически сами для себя, а не для нашего брата. Но ладно, давайте рассмотрим простую программу. Код паскалевский, а не дельфский, но это несущественно.
Program proga;
uses crt; {стандартный паскалевский модуль ввода\вывода на консоль}
var
x,y:integer;
z:real;
begin
clrscr;
writeln('Vvedyte x i y');
readln(x,y);
x:=x+y;
z:=x/y;
writeln('x=',x,' z=',z);
readkey;
end.
Итак, поехали: Вначале мы назвали прогу, подключили модуль (в луа скриптах Пейнкиллера такое нам не понадобится, там мы только с классами будем работать), определили три переменные... Кстати, я написал небольшой комментарий к одной из строчек - в Паскале\Дельфи заключенный в {} игнорится программой и служит только помощью программисту. Если вы серьезно изменяете текст скриптов, то лучше всего пишите комменты к всему, что делаете. На случай если с вашими скриптами будет работать кто-то еще, да и сами не забудете чего вы там делали.
Следующий блок - тело программы начинающееся begin'ом включает в себя наш код. Первая же строчка - очистка экрана, т.е. подготовка к работе. Вначале программы можно инициализировать какие-нибудь начальные данные, но нам пока по барабану. Итак, вначале мы вводим данные. Вернее, выводим сообщение пользователю а что ему надо ввести. Команда Writeln выводит строковую переменную (т.е. или переменную специального типа, или просто фразу в кавычках), т.е. то, что увидит пользователь. Кстати, в этой строке могут содержатся специальные символы, которые юзик не увидит, но они повлияют на формат вывода. Нас это сильно не волнует, до логов нам еще крякать и крякать. Кстати, есть две процедуры - write и writeln, первая выводит строку и оставляет курсор на месте, а вторая по завершению переводит курсор на новую строку. С процедурой ввода read то же самое. надеюсь вы догадались, что readln\writeln - это сокращение read\write line? Тогда молодцы. Итак, readln заставил юзика ввести переменные. Затем начинается интересное. Мы присвоили переменной х ЕЕ ЖЕ ДА ЕЩЕ ПЛЮС Y! Что за прикол? А все логично. Вначале вычисляется выражение справа, а потом присваивается левому. И никаких лишних переменных для хранения суммы. Запомните этот прикол, это не расходует лишней памяти. В остальном порядок операций такой же, как в математике - вначале умножение\деление, потом сложение\вычитание и т.д. Особняком стоят логические операции, операции взятия адреса и прочее, но мы этим заниматься не будем - с обычными бы разобраться. Важный момент - НЕЛЬЗЯ писать 2х, нужно писать 2*х, иначе компилятор будет ругаться. То же самое со скобками - не 2(х+4), а 2*(х+4). Кстати, надо упомянуть вот еще - в Паскале := - наше обычное математическое школьное равно, а = - операция сравнения. В ЛУА присваивание - =, а сравнение - ==, что является элементом синтаксиса языка Си.
Итак, потом вывод собственно и все. Последняя команда Readkey требует от пользователя нажать любую кнопку - это чтобы программа не закрылась до того, как пользователь увидит выводимый результат. А пока наша прога завершается, рассмотрим понятие быдлокода.
Быдлокод - понятие обширное. Изначально - это был неоправданно длинный код (кто-то умный платил за длинну кода), теперь же в нашей среде это любой код, который настолько корявый, что это сразу бросается в глаза (если не бросается, то и принадлежность к быдлокоду не всегда определишь). Т.е. - алгоритм можно было сделать проще, переменных - меньше...
Код должен быть эффективным - минимум времени, минимум затрачиваемой памяти, максимально рациональное использование оной... Для сравнения - на одной карте Пейнкиллера может быть больше тысячи объектов. Это - туева хуча требуемой памяти. Так вот, если не думать о том, как бы уменьшить все эти затраты, то тормоза будут знатные на самых крутых компах. Тоже самое можно видеть в самых различных играх - например в Supreme Commander после часа игры с четырьмя ботами очень сильно падает ФПС. А теперь подумайте, что нам надо еще передавать всю эту туеву хучу данных по жалкому соединению в 32 килобита в секунду... одним словом, жопа. Поэтому мы должны максимально рационально юзать память и бла-бла-бла...
Итак, наш идеал - минимум переменных (это не значит, что их должно быть три на всю игру, тут придется разбираться в игровой логике, так что по любому переменных будет много. Мы игру делаем, а не тостер программируем!), максимально эффективные алгоритмы (с этим в Пейнкиллере тоже будут проблемы - если конечно не создавать уж совсем отсебятского кода а редактировать старый) и минимум требуемого времени (не проверишь средствами Пейнкиллера, так что компенсируем предыдущими двумя пунктами)
Кстати, немного о игровой логике, ибо некоторым это кажется совсем уж запредельной вещью - вот у нас перемещается противник. Вы думаете, что он действительно идет? Фиг вам! Просто переменная анимации изменила свое значение, следовательно моб начинает шагать на месте, вдобавок вычисляется вектор направления движения, следовательно изменяются пространственные координаты. Еще есть поправка на его максимальную скорость, т.е. координаты не могут изменяться быстрее чем какая-то переменная. И все. Никакой магии - только работа с переменными! На самом деле есть еще куча проверок - может ли он шагать, не блокирует ли что-то дорогу и прочее, но нам пока хватит и такого простого примера.


Я люблю людей... особенно - убивать!^__^

Сообщение отредактировал ItramariN - Пятница, 23.03.2012, 17:39
 
ItramariNВоскресенье, 01.04.2012, 17:03 | Сообщение # 29
Аластор
Сообщений: 591
Награды: 12
Репутация: 55
Статус: Offline
Итак, мы можем написать простую программу. Но этого нам мало. Поэтому поговорим о процедурах и функциях.
Процедуры и функции - это подпрограммы, программы внутри программы. Выглядят они так:
procedure <имя_процедуры>(<список_параметров>)
<собсно_процедура>
в процедуре мы можем объявлять переменные, писать что угодно и так далее. Функция аналогична процедуре за одним лишь исключением - она возвращает свое значение в место вызова и описывается чуть по-другому. а именно:
function name ():integer
тип в конце - тип возвращаемого значения. Кстати, я не упомянул, что мы сами можем создавать типы, но в скриптах Пэйнкиллера я такого не видел, значит забьем. Как работает функция? очень просто. Мы пишем a:=sin(a) например, sin - функция, она вычисляет значение и возвращает его в место вызова, т.е. вместо sin(a). И затем это значение присваивается а. Вот так-то просто. Процедура так не умеет, она просто выполняет свои действия ничего не возвращая.
В функции в паскале обязательно должна быть строка <Имя_функции>:=<значение>? а в ЛУА - нет. В последнем как и в Си используется команда return <значение>. И в луа не используются процедуры. Если нам нужна процедура то просто не пишем в функиции return.
давайте рассмотрим пример процедуры и функции:
Program proga;
uses crt; {стандартный паскалевский модуль ввода\вывода на консоль}
var
x,y:integer;
z:real;
procedure proc(x,y:integer;z:real) {заголовок функции}
begin
x:=x+y;
z:=x/y;
end;
begin
clrscr;
writeln('Vvedyte x i y');
readln(x,y);
proc(x,y,z)
writeln('x=',x,' z=',z);
readkey;
end.

Program proga;
uses crt; {стандартный паскалевский модуль ввода\вывода на консоль}
var
x,y:integer;
z:real;
function proc(x,y:integer)
begin
x:=x+y;
proc:=x/y;
end;
begin
clrscr;
writeln('Vvedyte x i y');
readln(x,y);
z:=proc(x,y);
writeln('x=',x,' z=',z);
readkey;
end.
Как видно в заголовке функции пишутся типы переменных. В ЛУА такого нет, что есть некоторый плюс.
А теперь поговорим о локальных и глобальных переменных. у нас в процедуре определена какая-то переменная х. Для этой процедуры она локальная. Для программы которая эту процедуру вызывает переменная х вообще недоступна. Для всех процедур, которые вызывает наша процедура с переменной х эта переменная - глобальная, они имеют к ней доступ.
В ЛУА можно объявлять в теле процедуры локальные и глобальные переменные словами local и global соответственно.


Я люблю людей... особенно - убивать!^__^
 
EvgeniyПятница, 18.05.2012, 23:15 | Сообщение # 30





Знатоки lua-скрипта не могли бы вы ответить мне на один вопрос:
можно ли создать с помощью скриптов какое-нибудь чудо задание на карту таро,например выиграть уровень на 5 звёзд или не собрать ни одной звезды?
 
Форум » Модификации Painkiller » Разработка модификаций и контента к ним » Помощь с Lua-скриптами (Задаем вопросы, отвечаем.)
Поиск: