Ð’Ñе взаимодейÑтвие Lua и Си проиÑходит через некий Ñтек. Ð”Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ Ñтим Ñтеком в Lua предуÑмотрен Ñ€Ñд функций которые мы и будем иÑпользовать. Я не буду опиÑывать подробно Ñти функции что они делают и зачем. РазъÑÑÐ½ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ найти на форумах в интернете откуда Ñ ÑобÑтвенно Ñто вÑе и брал. Итак допуÑтим нам нужно проинициализировать Ð´Ð»Ñ Lua объект конкретного игрока или моба. У Ð¼ÐµÐ½Ñ Ð² маде Ñтруктура такого типа ноÑит название CHAR_DATA. Создадим функцию Ð´Ð»Ñ Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ð¸ Ñтого объекта в Lua.
| void initmetach (const char* tname,lua_State *vLm,CHAR_DATA *ch) { void** ptch; //Заводим войдовÑкий указатель ptch=(void**)lua_newuserdata(vLm, sizeof(void*)); //Резервируем под указатель памÑть в Lua машине *ptch=ch;//ПриÑваиваем указателю значение нашего объекта lua_newtable(vLm);//Создаем новую таблицу в Lua lua_pushstring(vLm,"__newindex"); lua_pushlightuserdata(vLm,ch); lua_pushcclosure(vLm, ch_set, 1); //ПривÑзываем к полю __newindex функцию Ð´Ð»Ñ ÑƒÑтановки значений объекта ch lua_rawset(vLm, -3); lua_setmetatable(vLm,-2); lua_getmetatable(vLm, -1); lua_pushstring(vLm, "__index"); lua_pushlightuserdata(vLm,ch); lua_pushcclosure(vLm, ch_get, 1); //ПривÑзываем к полю __index фукнцию Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ð¹ lua_rawset(vLm, -3); lua_setmetatable(vLm, -2);//УÑтанавливаем метатаблицу Ð´Ð»Ñ Ð½Ð°ÑˆÐµÐ¹ новой таблицы lua_setglobal(vLm, tname); //УÑтанавливаем Ð¸Ð¼Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ по которому она будет доÑтупна в Lua например «ch». } |
Теперь вызвав в каком-нибудь меÑте Ñту функцию и передав ей Ð¸Ð¼Ñ Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð° в Lua – tname указатель на машину в Lua – vLm и объект перÑонажа – ch мы получим в lua переменную Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ ch ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÑвÑзана Ñ Ð½Ð°ÑˆÐ¸Ð¼ объектом ch в Си.
Ð’ Lua Ñто будет выглÑдеть например так:
local hit=ch.hit --Получаем кол-во жизни у игрока
ch.hit=hit+100 –ДобавлÑем к текущей жизни игрока 100
Теперь о Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ ch_set и ch_get. ÐŸÐµÑ€Ð²Ð°Ñ Ð¸Ð· них будет у Ð½Ð°Ñ Ð¾Ñ‚Ð²ÐµÑ‡Ð°Ñ‚ÑŒ за приÑвоение значений полей объекта CHAR_DATA из Lua, а Ð²Ñ‚Ð¾Ñ€Ð°Ñ Ð´Ð»Ñ Ð¿Ð¾Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ð¹ полей CHAR_DATA в Lua.
Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ ch_set:
static int ch_set(lua_State *vLm) if(!str_prefix(var,"hit")) //ЕÑли в Lua идет обращение к полю hit тогда… (str_prefix) внутреннÑÑ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¼Ð°Ð´Ð° |
Ð’ данной функции идет мы получаем указатель на объект нашего перÑонажа, получаем Ð¸Ð¼Ñ Ð¿Ð¾Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð¼Ñƒ в Lua пытаютÑÑ Ð¿Ñ€Ð¸Ñвоить значение и затем в завиÑимоÑти от имени Ð¿Ð¾Ð»Ñ Ð¼Ñ‹ уже производим какие-то дейÑтвиÑ.
Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ ch_get аналогична функции ch_set только так Ñказать Ñ Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ñ‹Ð¼ знаком
| static int ch_get(lua_State *vLm) { void** pch; CHAR_DATA *ch; const char *var; var= luaL_checkstring(vLm, 2); pch=(void**)lua_touserdata(vLm,1); if(pch==NULL) return 0; ch=*pch; if(!str_prefix(var,"hit")) //ЕÑли в Lua у Ð½Ð°Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñили значение Ð¿Ð¾Ð»Ñ hit Ñтруктуры ch { lua_pushnumber(vLm,ch->hit); //Пихаем в Ñтек Lua значение Ð¿Ð¾Ð»Ñ return 1; } return 0; } |
То еÑть Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÑ€Ð° процеÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ опиÑать так:
Ð’ игре у Ð½Ð°Ñ Ñрабатывает триггер на какое-либо Ñобытие. Ðу например на мобе виÑит триггер на вход в локацию. Ð’ Ñтом триггере при Ñрабатывании обычно два объекта назовем их например ch и vic – ch – Ñто моб на котором виÑит триггер к которому привÑзан Ñкрипт который у Ð½Ð°Ñ Ð±ÑƒÐ´ÐµÑ‚ выполнÑтьÑÑ Ð¿Ñ€Ð¸ Ñрабатывании триггера, а vic Ñто объект игрока или моба который зашел в комнату таким образом в Си при подготовке Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñкрипта тригера у Ð½Ð°Ñ Ð±ÑƒÐ´ÐµÑ‚:
initmetach (“ch”, vLm, ch);//Помещаем в Lua объект моба выполнÑющего Ñкрипт
|
Ðу а в Ñамом Lua Ñкрипте работаем Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°Ð¼Ð¸ ch и vic и их полÑми так как нам надо. При иÑпользовании такого механизма Ð¿Ð¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ передавать и работать в Lua Ñ Ð»ÑŽÐ±Ñ‹Ð¼Ð¸ игровыми объектами мада, что очень удобно и функционально.
Прерывание Ñкриптов по времени.
Выполнение Ñкриптов имеет один неприÑтный момент. ЕÑли вдруг в Ñкрипте у Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° не ÑинтакÑичеÑкаÑ, а логичеÑÐºÐ°Ñ Ð¸ Ñкрипт начинает например выполнÑть вечный цикл, то и мад ÑоответÑтвенно у Ð½Ð°Ñ Ð·Ð°Ð²Ð¸Ñает, чтобы избежать такого Ñ€Ð°Ð·Ð²Ð¸Ñ‚Ð¸Ñ Ñобытий в Lua предуÑмотрена функци lua_sethook. Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ ÑƒÑтанавливает отладочную функцию Ð´Ð»Ñ Lua ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÑетÑÑ Ð¿Ñ€Ð¸ наÑтуплении каких-либо Ñобытий. Ð¡Ð¾Ð±Ñ‹Ñ‚Ð¸Ñ ÑƒÑтанавливаютÑÑ Ð¿Ð¾Ð±Ð¸Ñ‚Ñ‹Ð²Ð¾Ð¼Ñ‹Ð¼Ð¸ конÑтантами типа: LUA_MASKCALL - подробноÑти Ñмотрите в руководÑтве Lua. Ð’ нашем Ñлучае уÑтановка хука имеет вид:
| lua_sethook(vLm, LuaHook, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT|LUA_MASKLINE, 1); |
гдек LuaHook – Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÑющаÑÑÑ Ð¿Ñ€Ð¸ наÑтуплении ну например вечного цикла
| static void LuaHook(lua_State *vLm, lua_Debug *ar) { if(((long)time( NULL ))-script_time_start>time_out_script) { char buf[256]; sprintf(buf,"Превышен лимит времени выполнениÑ, выполнение преврвано."); luaL_error(vLm,buf); } } |
Перед начало Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñкрипта мы в переменную script_time_start помещаем Ð²Ñ€ÐµÐ¼Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° Ð²Ñ‹Ð¿Ð¾Ð»ÐµÐ½ÐµÐ½Ð¸Ñ Ñкрипта в Ñекундах. Рв конÑанта time_out_script Ñодержит значение Ñекунд которое отводитÑÑ Ð½Ð° выполнение Ñкрипта и еÑли у Ð½Ð°Ñ Ñ€Ð°Ð·Ð½Ð¸Ñ†Ð° в текущем времени и времени Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñкрипта превышает time_out_script – выполнение прерываетÑÑ.
| Навигация по статьям | |
Подключение Lua к MUD
|
Загрузка библиотек Lua при Ñтарте
|
|
Комментарии принадлежат их авторам. Мы не несем ответственности за их содержание.
|








