Difference between revisions of "Добавление Lua"
m (VAX325 moved page Adding Lua:ru to Добавление Lua: Перевод названия на русский язык.) |
|||
(9 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
{{otherlang2 | {{otherlang2 | ||
− | |title= Добавление Lua | + | |title= Добавление Lua в Source |
|en=Adding_Lua | |en=Adding_Lua | ||
|de=Adding_Lua:de | |de=Adding_Lua:de | ||
}} | }} | ||
− | Добавить [http://en.wikipedia.org/wiki/Lua_%28programming_language%29 Lua] в Source очень просто, А | + | Добавить [http://en.wikipedia.org/wiki/Lua_%28programming_language%29 Lua] в Source очень просто, А создать несколько обработчиков ещё проще. |
+ | Главное иметь базовые знания в c++. | ||
== Исходники == | == Исходники == | ||
− | Надо добавить два файла в ваш | + | Надо добавить два файла в ваш проект: |
*[[LuaManager_CPP]] | *[[LuaManager_CPP]] | ||
*[[LuaManager_H]] | *[[LuaManager_H]] | ||
− | == | + | == Инициализация == |
− | + | Все изменения будут выполняться в проекте Server. | |
− | |||
+ | Сначала добавте include в файл gameinterface.cpp. | ||
+ | <source lang=cpp> | ||
+ | #ifdef GE_LUA | ||
+ | #include "ge_luamanager.h" | ||
+ | #endif | ||
+ | </source> | ||
+ | В gameinterface.cpp добавьте этот вызов в функцию DLLInit перед "return true". | ||
<source lang=cpp> | <source lang=cpp> | ||
#ifdef GE_LUA | #ifdef GE_LUA | ||
Line 23: | Line 30: | ||
#endif | #endif | ||
</source> | </source> | ||
− | И добавляем в | + | И добавляем вызов в конец функции DLLShutdown: |
− | |||
<source lang=cpp> | <source lang=cpp> | ||
#ifdef GE_LUA | #ifdef GE_LUA | ||
Line 32: | Line 38: | ||
</source> | </source> | ||
− | + | == Создаём Lua Обработчик == | |
+ | Это самая интересная часть. Вам необходимо создать класс, который наследуеться от LuaHandle и имеет функции Init, Shutdown, RegFunctions и RegGlobals. | ||
+ | Это изначальный вид класса (g_LuaHandle и GetLuaHandle() нам понадобяться в будуещем): | ||
<source lang=cpp> | <source lang=cpp> | ||
− | + | class MyLuaHandle : LuaHandle | |
− | + | { | |
− | + | MyLuaHandle(); | |
− | + | ~MyLuaHandle(); | |
+ | |||
+ | void Init(); | ||
+ | void Shutdown(); | ||
− | + | void RegFunctions(); | |
+ | void RegGlobals(); | ||
+ | }; | ||
− | + | MyLuaHandle* g_LuaHandle = NULL; | |
+ | MyLuaHandle *GetLuaHandle(); | ||
+ | </source> | ||
=== Init === | === Init === | ||
− | + | Init вызывается после инициализации Lua, а это означает, что это лучшее место для загрузки скрипта. | |
− | Init | ||
<source lang=cpp> | <source lang=cpp> | ||
Line 84: | Line 98: | ||
=== Shutdown === | === Shutdown === | ||
− | Shutdown | + | В функции Shutdown обрабатывается завершение работы Lua. |
=== RegGlobals === | === RegGlobals === | ||
− | RegGlobals | + | RegGlobals регистрирует глобальные переменные lua. |
<source lang=cpp> | <source lang=cpp> | ||
Line 114: | Line 128: | ||
</source> | </source> | ||
− | + | Данные макросы также могут регистрировать и другие типы данных (LG_DEFINE_INT для чисел,LG_DEFINE_STRING для строк и LG_DEFINE_BOOL для булева). | |
=== RegFunctions === | === RegFunctions === | ||
− | + | В этой функции вы регистрируете функции для Lua. | |
<source lang=cpp> | <source lang=cpp> | ||
Line 130: | Line 144: | ||
</source> | </source> | ||
− | + | Также вам необходимо определить эти функции в другом файле. | |
+ | Необходимо объявлять с приставкой lua. Например: REG_FUNCTION( Msg ) тогда объявление будет int luaMsg(lua_State *L). | ||
<source lang=cpp> | <source lang=cpp> | ||
Line 182: | Line 197: | ||
</source> | </source> | ||
− | + | === GetLuaHandle === | |
− | + | Эта функция говорит о том, инициализирован обработчик или нет. | |
− | == | ||
− | |||
− | |||
− | |||
<source lang=cpp> | <source lang=cpp> | ||
− | |||
MyLuaHandle *GetLuaHandle() | MyLuaHandle *GetLuaHandle() | ||
{ | { | ||
Line 196: | Line 206: | ||
</source> | </source> | ||
− | + | == Использование Обработчика == | |
+ | |||
+ | В конструктор вашего обработчика нужно добавить регистрацию обработчика и установить переменную инициализации : | ||
<source lang=cpp> | <source lang=cpp> | ||
MyLuaHandle::MyLuaHandle() : LuaHandle() | MyLuaHandle::MyLuaHandle() : LuaHandle() | ||
Line 205: | Line 217: | ||
</source> | </source> | ||
− | + | И наконец в файле правил игры нужно добавить конструктор нашего обработчика: | |
− | |||
− | |||
<source lang=cpp> | <source lang=cpp> | ||
CGameRules::CGameRules() | CGameRules::CGameRules() | ||
Line 214: | Line 224: | ||
//other stuff here | //other stuff here | ||
− | |||
if (!GetLuaHandle()) | if (!GetLuaHandle()) | ||
new MyLuaHandle(); | new MyLuaHandle(); | ||
Line 220: | Line 229: | ||
</source> | </source> | ||
− | == | + | Не забудте добавить include с вашим обработчиком. |
+ | == Под конец == | ||
− | + | В вашем проекте "Server" нужно добавить новое опредиление препроцессора (Свойства -> C++ -> Препроцессор -> Определения препроцессора). | |
− | + | Также вы должны иметь скомпилированную библиотеку lua (в моём случае lua5.1.lib) и добавить её в зависимости компоновщика (Свойства -> Компоновщик -> Ввод -> Дополнительные зависимости ) | |
− | + | Вы дожны сделать это и для Debug и Release конфигурации. | |
− | + | Также поместите вашу lua библиотеку в папку "src/lib/public/". | |
− | == | + | == Привязка вызовов к луа == |
− | + | Это посложнее чем обработчик. Вот пример: | |
<source lang=cpp> | <source lang=cpp> |
Latest revision as of 06:26, 3 March 2020
Добавить Lua в Source очень просто, А создать несколько обработчиков ещё проще. Главное иметь базовые знания в c++.
Contents
Исходники
Надо добавить два файла в ваш проект:
Инициализация
Все изменения будут выполняться в проекте Server.
Сначала добавте include в файл gameinterface.cpp.
#ifdef GE_LUA
#include "ge_luamanager.h"
#endif
В gameinterface.cpp добавьте этот вызов в функцию DLLInit перед "return true".
#ifdef GE_LUA
// Start LUA
GELua()->InitDll();
#endif
И добавляем вызов в конец функции DLLShutdown:
#ifdef GE_LUA
// Shutdown LUA, close all open gameplays
GELua()->ShutdownDll();
#endif
Создаём Lua Обработчик
Это самая интересная часть. Вам необходимо создать класс, который наследуеться от LuaHandle и имеет функции Init, Shutdown, RegFunctions и RegGlobals.
Это изначальный вид класса (g_LuaHandle и GetLuaHandle() нам понадобяться в будуещем):
class MyLuaHandle : LuaHandle
{
MyLuaHandle();
~MyLuaHandle();
void Init();
void Shutdown();
void RegFunctions();
void RegGlobals();
};
MyLuaHandle* g_LuaHandle = NULL;
MyLuaHandle *GetLuaHandle();
Init
Init вызывается после инициализации Lua, а это означает, что это лучшее место для загрузки скрипта.
void MyLuaHandle::Init()
{
const char* luaFile = "myLuaFile.lua";
//Load into buffer
FileHandle_t f = filesystem->Open( luaFile, "rb", "MOD" );
if (!f)
return;
// load file into a null-terminated buffer
int fileSize = filesystem->Size(f);
unsigned bufSize = ((IFileSystem *)filesystem)->GetOptimalReadSize( f, fileSize + 1 );
char *buffer = (char*)((IFileSystem *)filesystem)->AllocOptimalReadBuffer( f, bufSize );
Assert(buffer);
((IFileSystem *)filesystem)->ReadEx( buffer, bufSize, fileSize, f ); // read into local buffer
buffer[fileSize] = '\0'; // null terminate file as EOF
filesystem->Close( f ); // close file after reading
int error = luaL_loadbuffer( GetLua(), buffer, fileSize, luaFile );
if (error)
{
Warning("[LUA-ERR] %s\n", lua_tostring(GetLua(), -1));
lua_pop(GetLua(), 1); /* pop error message from the stack */
Warning("[LUA-ERR] One or more errors occured while loading lua script!\n");
return;
}
CallLUA(GetLua(), 0, LUA_MULTRET, 0, luaFile );
m_bLuaLoaded = true;
}
Shutdown
В функции Shutdown обрабатывается завершение работы Lua.
RegGlobals
RegGlobals регистрирует глобальные переменные lua.
void MyLuaHandle::RegGlobals()
{
LG_DEFINE_INT("FOR_ALL_PLAYERS", -1);
LG_DEFINE_INT("INVALID_ENTITY", -1);
LG_DEFINE_INT("NULL", 0);
LG_DEFINE_INT("GE_MAX_HEALTH", MAX_HEALTH);
LG_DEFINE_INT("GE_MAX_ARMOR", MAX_ARMOR);
LG_DEFINE_INT("MAX_PLAYERS", gpGlobals->maxClients);
//Team Indices
LG_DEFINE_INT("TEAM_NONE",TEAM_UNASSIGNED);
LG_DEFINE_INT("TEAM_SPECTATOR",TEAM_SPECTATOR);
LG_DEFINE_INT("TEAM_MI6",TEAM_MI6);
LG_DEFINE_INT("TEAM_JANUS",TEAM_JANUS);
//ClientPrintAll Types
LG_DEFINE_INT("HUD_PRINTNOTIFY",HUD_PRINTNOTIFY);
LG_DEFINE_INT("HUD_PRINTCONSOLE",HUD_PRINTCONSOLE);
LG_DEFINE_INT("HUD_PRINTTALK",HUD_PRINTTALK);
LG_DEFINE_INT("HUD_PRINTCENTER",HUD_PRINTCENTER);
}
Данные макросы также могут регистрировать и другие типы данных (LG_DEFINE_INT для чисел,LG_DEFINE_STRING для строк и LG_DEFINE_BOOL для булева).
RegFunctions
В этой функции вы регистрируете функции для Lua.
void MyLuaHandle::RegFunctions()
{
REG_FUNCTION( Msg );
REG_FUNCTION( ConMsg );
REG_FUNCTION( ClientPrintAll );
REG_FUNCTION( GetTime );
}
Также вам необходимо определить эти функции в другом файле. Необходимо объявлять с приставкой lua. Например: REG_FUNCTION( Msg ) тогда объявление будет int luaMsg(lua_State *L).
extern "C"
{
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
int luaClientPrintAll(lua_State *L)
{
int n = lua_gettop(L); /* number of arguments */
switch(n)
{
case 2:
UTIL_ClientPrintAll( lua_tointeger(L,1), lua_tostring(L,2));
break;
case 3:
UTIL_ClientPrintAll( lua_tointeger(L,1), lua_tostring(L,2),lua_tostring(L,3));
break;
case 4:
UTIL_ClientPrintAll( lua_tointeger(L,1), lua_tostring(L,2),lua_tostring(L,3),lua_tostring(L,4));
break;
case 5:
UTIL_ClientPrintAll( lua_tointeger(L,1), lua_tostring(L,2),lua_tostring(L,3),lua_tostring(L,4),lua_tostring(L,5));
break;
case 6:
UTIL_ClientPrintAll( lua_tointeger(L,1), lua_tostring(L,2),lua_tostring(L,3),lua_tostring(L,4),lua_tostring(L,5),lua_tostring(L,6));
break;
}
return 0;
}
int luaMsg(lua_State *L)
{
Msg("%s\n",lua_tostring(L,1));
return 0;
}
int luaConMsg(lua_State *L)
{
return luaMsg(L);
}
int luaGetTime(lua_State *L)
{
lua_pushnumber( L, gpGlobals->curtime );
return 1;
}
GetLuaHandle
Эта функция говорит о том, инициализирован обработчик или нет.
MyLuaHandle *GetLuaHandle()
{
return g_LuaHandle;
}
Использование Обработчика
В конструктор вашего обработчика нужно добавить регистрацию обработчика и установить переменную инициализации :
MyLuaHandle::MyLuaHandle() : LuaHandle()
{
g_LuaHandle = this;
Register();
}
И наконец в файле правил игры нужно добавить конструктор нашего обработчика:
CGameRules::CGameRules()
{
//other stuff here
if (!GetLuaHandle())
new MyLuaHandle();
}
Не забудте добавить include с вашим обработчиком.
Под конец
В вашем проекте "Server" нужно добавить новое опредиление препроцессора (Свойства -> C++ -> Препроцессор -> Определения препроцессора). Также вы должны иметь скомпилированную библиотеку lua (в моём случае lua5.1.lib) и добавить её в зависимости компоновщика (Свойства -> Компоновщик -> Ввод -> Дополнительные зависимости )
Вы дожны сделать это и для Debug и Release конфигурации.
Также поместите вашу lua библиотеку в папку "src/lib/public/".
Привязка вызовов к луа
Это посложнее чем обработчик. Вот пример:
void CGELUAGamePlay::PostRoundBegin()
{
if (m_bLuaLoaded)
{
lua_getglobal(GetLua(), "RoundStart");
CallLUA(GetLua(), 0, 0, 0, "RoundStart");
}
}