Dennis_Chikin 3 658 Опубликовано 4 Января 2015 Поделиться Опубликовано 4 Января 2015 (изменено) С чего начинать и где взять. Установка Lua:http://www.amk-team.ru/forum/index.php?showtopic=11584&p=629106 Руководство «Программирование на языке Lua», третье издание:http://www.amk-team.ru/forum/index.php?showtopic=11584&p=905308 Изменено 2 Марта 2015 пользователем Kirgudu Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
*Shoker* 322 Опубликовано 13 Сентября 2013 Поделиться Опубликовано 13 Сентября 2013 (изменено) Ну я рассматриваю этот вопрос конкретно в рамках Сталкера и его Луа, просто в Сталкере в свякзе с Lua-перехватчиком появляется возможность читать и редактировать память игры по адресами, в связи с чем я вот и смотрю можно ли чего хорошего из этого добиться помимо уже достигнутого. Другое дело что в том же сталкере все эти объекты Lua-биндовские, но наверняка какая нибудь связь между луа-биндовским и реальным движковым (си-шным) объектом существует. Изменено 13 Сентября 2013 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
*Shoker* 322 Опубликовано 30 Сентября 2013 Поделиться Опубликовано 30 Сентября 2013 (изменено) Вот такой вопрос возник, связанный с Lua\Lua-Биндом. Решил попробовать переопределять движковые функции в сталкере, экспортированные в Lua, для теста взял метод local xml = CScriptXmlInit() xml:ParseFile ("ui_mm_main.xml") Который используется для чтения параметров объектов из xml-файлов. Переопределить его мне не составило проблем, я просто написал: function CScriptXmlInit:ParseFile(name) get_console():execute("ParseFile") get_console():execute(tostring(name)) end И в итоге все вызовы этой функции стали перенаправляться в мою. Но я также захотел иметь возможность изнутри моей переопределённой функции вызывать оригинальную движковую, не переопределённую функцию, а вот как это сделать мне не понятно. Метод local original_func = CScriptXmlInit.ParseFile и его вариации само собой мне не подошли, и привели к вылету pure virtual function call. Осуществимо ли задуманное в сталкере средствами штатного Lua\Lua-бинда? Такое тоже не получилось: class "CScriptXmlInit_orig" (CScriptXmlInit) function CScriptXmlInit:ParseFile(name) get_console():execute("ParseFile") get_console():execute(tostring(name)) return CScriptXmlInit_orig:ParseFile(name) end Изменено 30 Сентября 2013 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
abramcumner 1 145 Опубликовано 30 Сентября 2013 Поделиться Опубликовано 30 Сентября 2013 (изменено) @*Shoker*, надеюсь self не забывал передавать? Конструкция с запоминанием функции абсолютно корректна и должна работать. Изменено 30 Сентября 2013 пользователем abramcumner Ссылка на комментарий
*Shoker* 322 Опубликовано 30 Сентября 2013 Поделиться Опубликовано 30 Сентября 2013 (изменено) Нет, а как можно передать его явно? Такое не заработало: local original_func = CScriptXmlInit.ParseFile function CScriptXmlInit:ParseFile(name) get_console():execute("ParseFile") get_console():execute(tostring(name)) original_func.self = self -- это функция - вылет return original_func(name) -- return original_func(self, name) -- pure virtual - вылет end Здесь тоже не получилось: class "CScriptXmlInit_orig" (CScriptXmlInit) function CScriptXmlInit:ParseFile(name) get_console():execute("ParseFile") get_console():execute(tostring(name)) local orig_obj = CScriptXmlInit_orig() orig_obj.self = self return orig_obj:ParseFile(name) end Ругнулось что вызываю nil-функцию. Изменено 30 Сентября 2013 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
Shredder 49 Опубликовано 30 Сентября 2013 Поделиться Опубликовано 30 Сентября 2013 Как-то тоже самое пытался сделать с классом ini_file. Ничего не вышло Ссылка на комментарий
abramcumner 1 145 Опубликовано 30 Сентября 2013 Поделиться Опубликовано 30 Сентября 2013 (изменено) @*Shoker*, можно сделать так: function create_xml() local xml = CScriptXmlInit() xml.PrevParseFile = xml.ParseFile xml.ParseFile = function (self, name) get_console():execute("ParseFile") get_console():execute(tostring(name)) get_console():execute(type(self)) return self.PrevParseFile(self, name) end return xml end local xml = create_xml() xml:ParseFile("test.xml") Изменено 30 Сентября 2013 пользователем abramcumner Ссылка на комментарий
*Shoker* 322 Опубликовано 30 Сентября 2013 Поделиться Опубликовано 30 Сентября 2013 (изменено) Хм, смысл именно в том чтобы избежать необходимости редактировать ориг. файлы и заменять в них CScriptXmlInit() на create_xml(), хотя метод интересный придумал, но что то не могу переварить как его применить без замены класса на функцию в коде. В принципе на мою текущую задачу хватит и того, что я написал (мне не обязательно иметь доступ к ориг. функции, хочу заменить функцию best_weapon() из класса game_object) но вообще для будущих целей такое может понадобится, чтобы например расширить функционал имеющихся функций. Вся соль как раз в том, чтобы не трогать ориг. файлы, а просто подменить содержание функции на другое. Изменено 30 Сентября 2013 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
abramcumner 1 145 Опубликовано 30 Сентября 2013 Поделиться Опубликовано 30 Сентября 2013 (изменено) @*Shoker*, если у класса функций немного, можно сделать что-то вроде такого(подменяется без правки других скриптов): OldScriptXmlInit = CScriptXmlInit class "MyScriptXml" function MyScriptXml:__init() log("MyScriptXml ctor") self.xml = OldScriptXmlInit() end function MyScriptXml:ParseFile(name) log("ParseFile New") get_console():execute(tostring(name)) get_console():execute(type(self)) return self.xml:ParseFile(name) end --[[ здесь реализуются все остальные функции ]] _G.CScriptXmlInit = MyScriptXml С game_object такое конечно не подходит. Ну и честно говоря, я сомневаюсь, что с переопределением best_weapon боевка изменится. Я бы покопал в сторону своих экшенов для комбат_планера, ну и ai/common/weaponeffectiveness.efd, который используется в функции best_weapopn и который кстати учитывает расстояние до врага, тип оружия нпц, тип оружия врага Изменено 30 Сентября 2013 пользователем abramcumner 1 Ссылка на комментарий
*Shoker* 322 Опубликовано 30 Сентября 2013 Поделиться Опубликовано 30 Сентября 2013 (изменено) local func = CScriptXmlInit().ParseFile function CScriptXmlInit:ParseFile(name) get_console():execute("ParseFile") get_console():execute(tostring(name)) get_console():execute("flush") return func(self,name) end Charsi показал. Действительно заработало так как изначально и хотел. Моя ошибка была что скобки не написал и self соответственно не передавал\передавался не правильно. abramcumner- тоже спасибище за код, хоть и не совсем то что нужно было но тоже интересный. Последний ещё не смотрел правда. Я бы покопал в сторону своих экшенов для комбат_планера, ну и ai/common/weaponeffectiveness.efd, который используется в функции best_weapopn и который кстати учитывает расстояние до врага, тип оружия нпц, тип оружия врага Я уже пишу простую боевую логику которая заставляет НПС сокращать дистанцию с врагом до боевой, так что не страшно. Это же я делаю чтобы написать свой менеджер оружия на замену best_weapon() без необходимости править ориг. скрипты. Изменено 30 Сентября 2013 пользователем *Shoker* 3 Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
Карлан 1 049 Опубликовано 21 Октября 2013 Поделиться Опубликовано 21 Октября 2013 (изменено) Мне нужно получить массив вида aParam = {key1 = value1, key2 = value2...} И отсортировать его по value, далее получить первый элемент таблицы. Оба параметра типа 'number'. local aParam = {} for i=1,10 do local key = math.random(100) local value = math.random(100,200) table.insert(aParam.key, value) --//table.insert(aParam[i].key, value) table.sort(aParam) end print(aCond[1]) => bad argument #1 to 'insert' (table expected, got nil) Даже без результата я знаю, что делаю не верно, ибо массив у меня выходит вида aParam = {key1 = value1}, {key2=value2}... Изменено 21 Октября 2013 пользователем Карлан Ссылка на комментарий
Artos 99 Опубликовано 21 Октября 2013 Поделиться Опубликовано 21 Октября 2013 (изменено) @Карлан, у тебя банальная ошибка. Попробуй просто "человеческим языком" прочитать свой Lua-скрипт: table.insert(aParam.key, value) - Вставить в (суб)таблицу (точнее добавить в конец) 'aParam.key' элемент 'value'. - а теперь вопрос к написавшему сею строку: "А он позаботился создать эту (суб)таблицу, перед тем как в нее что-то добавлять?" (собственно лог на это и указывает, говоря об отсутствии требуемой таблицы!) А для твоей задумки требуется простое: aParam[key] = value - чтобы получить {key1 = value1, key2 = value2...} Вот только вряд ли ты таким макаром получишь желаемое, т.к. key = math.random(100) может генерить далеко не эксклюзивные ключи и при их добавлении в {key1 = value1, key2 = value2...} у тебя уже имеющиеся будут затираться новыми... Изменено 21 Октября 2013 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Rosad 0 Опубликовано 3 Ноября 2013 Поделиться Опубликовано 3 Ноября 2013 Всем доброго времени суток. Вроде в нужную тему пишу. Такая ситуация: Нужно по нажатию кнопки отрабатывать определённое действие. Само действие уже написал давно, а вот как при помощи луа отрабатывать нажатие кнопки не знаю. Долгое гугленье выдало лишь это: lua_pushinteger(lvm,KEY_A); lua_setglobal(lvm,"KEY_A"); lua_pushinteger(lvm,KEY_; lua_setglobal(lvm,"KEY_B"); lua_pushinteger(lvm,KEY_; lua_setglobal(lvm,"KEY_B"); //And so on Then define and register the isKeyDown function: static int isKeyDown(lua_State *l) { int key=luaL_checkint(l,1); lua_pushboolean(lvm,KEY[key]); return 1; } //...VM is initialized, etc. //Now we register the functions lua_pushcfunction(lvm,isKeyDown); lua_setglobal(lvm,"isKeyDown"); Хотя не уверен, что это именно по-моему случаю. На сколько я понял в самом lua нет функции, которая бы считывала нажатие кнопки, быть может есть уже написанный вариант функции? P.S. Пишу не для движка сталкера Кидайте понты в предназначенных для этого местах. @rosadman Ссылка на комментарий
Malandrinus 615 Опубликовано 4 Ноября 2013 Автор Поделиться Опубликовано 4 Ноября 2013 @Rosad, В Lua как таковом нет таких возможностей. Lua предназначен для встраивания в хост-программу, которая уже и должна делать такие вещи, как например отлавливать нажатия клавиш. Вот как это делается к примеру в движке сталкера: движок ловит нажатия, дальше уже вызывается скриптовый колбек. Если же надо сделать это в Lua в его самостоятельном варианте, то придётся добавлять туда такие возможности самому. Причём это будет разумеется делаться по-разному для каждой платформы. Под виндой надо будет сделать Lua-обёртку над функциями API типа GetKeyState. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
*Shoker* 322 Опубликовано 4 Ноября 2013 Поделиться Опубликовано 4 Ноября 2013 Если вопрос всё же касается сталкера, то возможно поможет эта вещь: http://www.amk-team.ru/forum/index.php?showtopic=6185&p=678277 Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
DJ_Yar 3 Опубликовано 16 Февраля 2014 Поделиться Опубликовано 16 Февраля 2014 Ребят, кто подскажет как получить координаты мыши внутри сталкера?(ПДА, Инвентарь, Главное меню и пр.)З.Ы. Пытался получить через Lua самописной dll-кой, внутри которой была функция GetMousePos() {это Delphi}, но получал координаты, которые имели очень большую погрешность в зависимости от скорости передвижения мыши. Ссылка на комментарий
Nazgool 250 Опубликовано 16 Февраля 2014 Поделиться Опубликовано 16 Февраля 2014 http://www.amk-team.ru/forum/index.php?showtopic=10538 Ссылка на комментарий
DJ_Yar 3 Опубликовано 16 Февраля 2014 Поделиться Опубликовано 16 Февраля 2014 (изменено) Gun12 1) Не могу пропатчить2) Даже если и пропатчить, то не наблюдаю нужного функционала. Изменено 17 Февраля 2014 пользователем ColR_iT 1 Ссылка на комментарий
Nazgool 250 Опубликовано 16 Февраля 2014 Поделиться Опубликовано 16 Февраля 2014 Колбеки на клавиши и мышь.[ТЧ/ЧН] Добавлены колбеки актора на нажатие/удержание/отпускание клавиш а также на вращение мышиного колеса и движение мыши. Коды колбеков:нажатие - 123отпускание - 124удержание - 125кручение колёсика мыши - 126движение мыши - 127Установка производится также, как и всех других колбеков в биндере:self.object:set_callback(123, self.on_key, self) ... function actor_binder:on_key(key) log1("actor_binder:on_key "..key.." "..dik_to_bind(key) ) endСнятие:self.object:set_callback(123, nil)Аргументы колбеков:для клавиш - коды клавиш, для которых в скриптовом классе DIK_keys есть удобные обозначения. Среди прочего, там есть и коды для мышиных кнопок, т.е. таким образом будут ловиться также мышиные нажатия.для колеса мыши аргумент - скорость вращения + 100000. Т.е. из аргумента надо вычесть 100000, чтобы получить нужное значение. У меня после вычитания всегда выходило +/-120для движения мыши два аргумента - смещения мыши с последнего перемещения, также каждое + 100000. Это не координаты мыши, а выходит больше скорость перемещения.Для предотвращения вылета при выходе из игры по Alt+F4 вызов данных колбеков на Alt заблокирован совсем. F4 разрешён только на нажатие. Ссылка на комментарий
DJ_Yar 3 Опубликовано 16 Февраля 2014 Поделиться Опубликовано 16 Февраля 2014 (изменено) Gun12Немного некрасивая реализация и нестабильная. Но все равно спасибо!Придется искать более красивый выход из положения.З.Ы. Хочу в ТЧ реализовать инфу о предмете при наведении курсора на него (как в ЗП). Вот для этого мне нужны координаты. Изменено 17 Февраля 2014 пользователем ColR_iT Ссылка на комментарий
Nazgool 250 Опубликовано 16 Февраля 2014 Поделиться Опубликовано 16 Февраля 2014 (изменено) [ТЧ/ЧН/ЗП] Добавлена функция получения расстояния до точки, на которую смотрим (игровой дальномер, который отображается под прицелом): level.get_target_dist() [ЧН] Добавлен метод определения объекта, на который смотрит камера. Метод добавлен к классу game_object, так что можно вызывать для любого клиентского объекта, хотя наверное самым разумным будет использовать актора. Пользуемся так: local obj = db.actor:get_target_obj() возвращает клиентский объект. Если ни на что не смотрим, то возвращает nil. Объекты без визуала так увидеть невозможно. [ТЧ/ЗП] это-же реализовано в виде функции level.get_target_obj() Изменено 16 Февраля 2014 пользователем Gun12 Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти