class LuaEntityFactory : public IEntityFactory { public: CBaseEntity* factory_pEnt; void LuaSetupFactory( const char *pClassName) { char fstr[ 512 ]; Q_snprintf( fstr, sizeof( fstr ), "return %s()", pClassName); luaL_dostring( luaState, fstr ); luabind::object obj( luabind::from_stack(luaState, -1) ); if ( !obj || luabind::type(obj) == LUA_TNIL ) //neo { cvar->ConsoleColorPrintf( LUA_ERROR_PRINT_COLOUR, "[Lua] LINK_ENTITY_TO_CLASS, Hey put a valid object in it will you!\n"); return; } CBaseEntity* pEnt; try { pEnt = luabind::object_cast(obj ); } catch ( const luabind::cast_failed& e ) { // deal with it cvar->ConsoleColorPrintf( LUA_ERROR_PRINT_COLOUR, "[Lua] LINK_ENTITY_TO_CLASS, Unable to cast your object to its base class! - %s|%s\n", e.what(), e.info()); return; } factory_pEnt = pEnt; } IServerNetworkable *Create( const char *pClassName ) { CBaseEntity* pEnt = factory_pEnt; pEnt->PostConstructor(pClassName); 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 void LUA_LINK_ENTITY_TO_CLASS( const char* pClassName ) { static LuaEntityFactory lua_entity_factory; lua_entity_factory.LuaSetupFactory( pClassName ); EntityFactoryDictionary()->InstallFactory( &lua_entity_factory, pClassName ); } struct CBaseEntity_wrapper : CBaseEntity, luabind::wrap_base { CBaseEntity_wrapper( bool bServerOnly=false ) : CBaseEntity(bServerOnly) {} virtual void Spawn( void ) { call("Spawn");} static void default_Spawn(CBaseEntity* ptr) { return ptr->CBaseEntity::Spawn();} virtual void Precache( void ) { call("Precache");} static void default_Precache(CBaseEntity* ptr) { return ptr->CBaseEntity::Precache();} virtual void Think( void ) { call("Think");} static void default_Think(CBaseEntity* ptr) { return ptr->CBaseEntity::Think();} virtual int OnTakeDamage( const CTakeDamageInfo &inputInfo ) { return call("OnTakeDamage", inputInfo); } static int default_OnTakeDamage(CBaseEntity* ptr, const CTakeDamageInfo &inputInfo ){ return ptr->CBaseEntity::OnTakeDamage( inputInfo );} }; luabind::class_("CBaseEntity") // Export CBaseEntity (only some members here) .def(luabind::constructor()) // if bool is yes then its server side only apparently .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("GetAbsVelocity", &CBaseEntity::GetAbsVelocity ) .def("SetAbsVelocity", &CBaseEntity::SetAbsVelocity ) .def("Precache", &CBaseEntity::Precache ) .def("Spawn", &CBaseEntity::Spawn, &CBaseEntity_wrapper::default_Spawn) .def("OnTakeDamage", &CBaseEntity::OnTakeDamage, &CBaseEntity_wrapper::default_OnTakeDamage) .def("Think", &CBaseEntity::Think, &CBaseEntity_wrapper::default_Think) .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("EmitSound", (void(CBaseEntity::*)(const char*, float, float*)) &CBaseEntity::EmitSound ) .def("GetAbsOrigin", &CBaseEntity::GetAbsOrigin ),