Difference between revisions of "Добавление Lua"
(→Инцализация) |
(→Making Your own Lua Instance) |
||
Line 40: | Line 40: | ||
</source> | </source> | ||
− | == | + | ==Создаём Lua Экземпляр == |
− | + | Это самое интересная часть, создание lua экземпляра . Вам необходимо создать класс которые наследуется от LuaHandle и имеет функции Init, Shutdown, RegFunctions and RegGlobals. | |
− | |||
=== Init === | === Init === | ||
− | Init | + | Init вызываетстся после инициализации Lua и таким образом это лучшее место для загрузки скрипта. |
<source lang=cpp> | <source lang=cpp> | ||
Line 84: | Line 83: | ||
=== Shutdown === | === Shutdown === | ||
− | Shutdown | + | Shutdown тут обрабатывается завершение lua. |
=== RegGlobals === | === RegGlobals === | ||
− | RegGlobals | + | RegGlobals регистрирует глобальные переменные lua. |
<source lang=cpp> | <source lang=cpp> | ||
Line 118: | Line 117: | ||
=== RegFunctions === | === RegFunctions === | ||
− | + | Как и Globals, RegFunctions здесь все C функции которые вы хотите что бы работали в Lua. | |
<source lang=cpp> | <source lang=cpp> |
Revision as of 12:51, 26 February 2014
Добавить Lua в Source очень просто, А создание несколько экземпляров ещё проще.
Contents
Исходники
Надо добавить два файла в ваш порект:
Инцализация
Теперь нужно инициализацию и завершение функций. В gameinterface.cpp добавьте этот код в функции DLLInit перед return true строкой (557 строка):
#ifdef GE_LUA
// Start LUA
GELua()->InitDll();
#endif
И добавляем в функцию DLLShutdown:
#ifdef GE_LUA
// Shutdown LUA, close all open gameplays
GELua()->ShutdownDll();
#endif
Также убедитесь что вы подключение заголовочный файл.
#ifdef GE_LUA
#include "ge_luamanager.h"
#endif
Создаём Lua Экземпляр
Это самое интересная часть, создание lua экземпляра . Вам необходимо создать класс которые наследуется от LuaHandle и имеет функции Init, Shutdown, RegFunctions and RegGlobals.
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);
}
Macros provided allow for different types as well. LG_DEFINE_INT for int, LG_DEFINE_STRING for string and LG_DEFINE_BOOL for boolean.
RegFunctions
Как и Globals, RegFunctions здесь все C функции которые вы хотите что бы работали в Lua.
void MyLuaHandle::RegFunctions()
{
REG_FUNCTION( Msg );
REG_FUNCTION( ConMsg );
REG_FUNCTION( ClientPrintAll );
REG_FUNCTION( GetTime );
}
Again this has been shorten using a macro. And thus you will need to define this functions in another file.
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;
}
Note: The function name must be the same as the one used in the macro with lua infront.
Creating The Instance
On the top of your new LuaHandle class you need to add a function allowing global access to your Lua instance. Add something like this:
MyLuaHandle* g_LuaHandle = NULL;
MyLuaHandle *GetLuaHandle()
{
return g_LuaHandle;
}
And in your constructor of your LuaHandle add a call to set the instance when you make a new one:
MyLuaHandle::MyLuaHandle() : LuaHandle()
{
g_LuaHandle = this;
Register();
}
Note: Its important to have Register here other wise it wont work!
And finally in your game rules constructor make a new LuaHandle:
CGameRules::CGameRules()
{
//other stuff here
// Start our LUA GamePlay Engine
if (!GetLuaHandle())
new MyLuaHandle();
}
Project Settings
In the server project settings you need to add GE_LUA to the preprocesser options (Configure properties -> c++ -> Preprocesser -> Preprocesser defines). Also you will need to add the lua lib (should be the same name as the lib file, mines lua5.1.lib) to the linker settings (Configure properties -> Linker -> Input -> Additional Dependencies )
Note: Make sure you do this for both release and debug.
Now place the lua lib into the src/lib folder. And you should be able to compile and now have a working Lua.
Creating Calls from c into Lua
This is a bit harder and you will need to consult the lua documents for this but here is an example on how ges does it:
void CGELUAGamePlay::PostRoundBegin()
{
if (m_bLuaLoaded)
{
lua_getglobal(GetLua(), "RoundStart");
CallLUA(GetLua(), 0, 0, 0, "RoundStart");
}
}