#include "cbase.h" #include "filesystem.h" // for hl2 classes #include "sdk_player.h" #include "util.h" // end for hl2 classes #include "luabind_hl2.h" #include #include extern "C" { #include "lua.h" #include "lualib.h" #include "lauxlib.h" } // This is the only header we need to include for LuaBind to work #include "luabind/luabind.hpp" lua_State *luaState; lua_State *GetLuaState( void ) { return luaState; } void TempMsg( const char* m ) { Msg( m ); } bool RunLuaFile( const char* scriptname ) { char char_filename[ _MAX_PATH ]; char char_output_full_filename[ _MAX_PATH ]; strcpy( char_filename, scriptname); filesystem->RelativePathToFullPath(char_filename,"MOD",char_output_full_filename,sizeof(char_output_full_filename)); const char *constcharpointer = reinterpret_cast( char_output_full_filename ); if (!filesystem->FileExists(constcharpointer)) { cvar->ConsoleColorPrintf( LUA_ERROR_PRINT_COLOUR, "[Lua] IFileSystem Cannot find the file: %s\n", constcharpointer); return false; } if (int error = luaL_dofile(luaState, constcharpointer) != 0) { cvar->ConsoleColorPrintf( LUA_ERROR_PRINT_COLOUR, "[LUA] Error while doing 'dofile': %s\n",constcharpointer); return false; } return true; } class LuaEntityFactory : public IEntityFactory { public: IServerNetworkable *Create( const char *pClassName ) { luabind::object obj = luabind::call_function( luaState, pClassName ); if ( !obj ) { // deal with it return NULL; } IServerNetworkable* pEnt; try { IServerNetworkable* pEnt = luabind::object_cast(obj); } catch ( const luabind::cast_failed& e ) { // deal with it return NULL; } pEnt->PostConstructor(); return pEnt->NetworkProp(); } void Destroy( IServerNetworkable *pNetworkable ) { if ( pNetworkable ) { pNetworkable->Release(); } } virtual size_t GetEntitySize() { return 0; // TODO: we could dispatch this to Lua somehow.... } }; static LUA_LINK_ENTITY_TO_CLASS( const char* pClassName ) { static LuaEntityFactory lua_entity_factory; EntityFactoryDictionary()->InstallFactory( &lua_entity_factory, pClassName ); } CBaseEntity *proxy_CreateEntityByName( const char* name ) { CBaseEntity *e = CreateEntityByName( name ); return e; } void proxy_PrecacheModel ( const char* name ) { engine->PrecacheModel( name ); } void proxy_LinkEntityToClass ( const char* mapname, const char* classname ) { //LuaEntityFactory( // GetClassMap().Add(mapname, classname); //lua_getglobal(luaState, mapname ); // static CEntityFactory mapClassName( #mapClassName ); } //static CEntityFactory mapClassName( #mapClassName ); namespace enum_struct_placeholders { struct SolidType_t_placeholder {};// our enum solidtype_t for the binding } void Lua_Startup( void ) { // Open the lua state luaState = lua_open(); // Load those cool? modules O_O! luaopen_base( luaState ); luaopen_table( luaState ); luaopen_string( luaState ); luaopen_math( luaState ); // Connect LuaBind to this lua state luabind::open(luaState); // Export our class with LuaBind luabind::module(luaState) [ /* // Use this in scripting like SetSolid( SOLID.NONE ) luabind::class_("SOLID") .enum_("SolidType_t") [ value("NONE", SOLID_NONE), value("BSP", SOLID_BSP), value("BBOX", SOLID_BBOX), value("OBB", SOLID_OBB), value("OBB_YAW", SOLID_OBB_YAW), value("CUSTOM", SOLID_CUSTOM), value("VPHYSICS", SOLID_VPHYSICS), value("LAST", SOLID_LAST), ], */ /* luabind::class_("SolidType_t") . */ /* luabind::namespace_("gpGlobals") [ .def_read("curtime", { return gpGlobals->curtime; }) ] *//*IServerNetworkable luabind::class_< IServerNetworkable >("IServerNetworkable") // Export the famous QAngle .def("GetEntityHandle", &IEntityFactory::GetEntityHandle ) .def("GetServerClass", &IEntityFactory::GetServerClass ) .def("GetEdict", &IEntityFactory::GetEdict ) .def("Release", &IEntityFactory::Release ) .def("AreaNum", &IEntityFactory::AreaNum ) .def("GetServerClass", &IEntityFactory::GetClassName ) , */ luabind::class_< IEntityFactory >("IEntityFactory") // Export the famous QAngle .def("Create", &IEntityFactory::Create ) .def("Destroy", &IEntityFactory::Destroy ) .def("GetEntitySize", &IEntityFactory::GetEntitySize ), luabind::class_< QAngle >("QAngle") // Export the famous QAngle .def(luabind::constructor()) .def_readwrite("x", &QAngle::x) .def_readwrite("y", &QAngle::y) .def_readwrite("z", &QAngle::z), luabind::class_< Vector >("Vector") // Export the famous HL2 Vector .def(luabind::constructor()) .def_readwrite("x", &Vector::x) .def_readwrite("y", &Vector::y) .def_readwrite("z", &Vector::z), luabind::class_("CBaseEntity") // Export CBaseEntity (only some members here) .def("KeyValue", (bool(CBaseEntity::*)(const char*, const char*)) &CBaseEntity::KeyValue ) // in the cbaseentity or whatever its called header there are many diffrent types of this function ;) .def("SetAbsOrigin", &CBaseEntity::SetAbsOrigin ) .def("SetAbsAngles", &CBaseEntity::SetAbsAngles ) .def("GetAbsOrigin", &CBaseEntity::GetAbsOrigin ) .def("GetAbsAngles", &CBaseEntity::GetAbsAngles ) .def("Precache", &CBaseEntity::Precache ) .def("Spawn", &CBaseEntity::Spawn ) .def("SetModel", &CBaseEntity::SetModel ) .def("SetSolid", &CBaseEntity::SetSolid ) .def("GetClassname", &CBaseEntity::GetClassname ) .def("entindex", &CBaseEntity::entindex ) .def("GetAbsAngles", &CBaseEntity::GetAbsAngles ) .def("SetHealth", &CBaseEntity::SetHealth ) .def("GetAbsOrigin", &CBaseEntity::GetAbsOrigin ), luabind::class_>("CBaseAnimating"), luabind::class_>("CBasePlayer") .def("GiveNamedItem", &CBasePlayer::GiveNamedItem ), // Some non-class functions, some nice common ones here for my example luabind::def("PrecacheModel", proxy_PrecacheModel), luabind::def("CreateEntityByName", proxy_CreateEntityByName), luabind::def("UTIL_EntityByIndex", UTIL_EntityByIndex), luabind::def("LUA_LINK_ENTITY_TO_CLASS", LUA_LINK_ENTITY_TO_CLASS) ]; // Now call our function in a lua script //lua_close(luaState); jesus this cost my hours ;/ } CON_COMMAND( dosample1 , "run my sample script 1") { lua_State *luaState = GetLuaState(); try { if (RunLuaFile("lua\\sample1.lua")) luabind::call_function(luaState, "sample"); } catch( luabind::error ex) { lua_State* L = ex.state(); cvar->ConsoleColorPrintf( LUA_ERROR_PRINT_COLOUR, "[Lua] %s\n", lua_tostring(L, -1)); lua_pop(L, 1); } }