Mdbelen Posted December 6, 2010 Share Posted December 6, 2010 Hi, i recently got into trouble with the get() function. I want to check if a setting (ghostmode) is set true or false or not at all in the meta.xml of a map. But get(..) returns false if it is set false and if it isn't set. Actually i wanted to set it true manually for all maps where it isn't set yet, but i can't distinguish the cases (so all maps-ghostmode would be set true^^). (If the setting is set to "false" then it returns false as string i think, but you can set it "[false]", too, then get() will return false as boolean.) So maybe it would be better to return nil if no setting is found and false only if the setting is rly set false. Am I wrong or should I bug-report this behavior? Link to comment
norby89 Posted December 6, 2010 Share Posted December 6, 2010 Yea I guess an 'bool isset ( string settingName )' function would be useful. As a workaround you could check if the setting exists using xml functions. Link to comment
eAi Posted December 6, 2010 Share Posted December 6, 2010 I'd report it, and even better, fix it. The code is open source and I reckon this would be an easyish thing to fix. Link to comment
Mdbelen Posted December 17, 2010 Author Share Posted December 17, 2010 eeh.. easyish? Well i don't have a big clue about C and i don't even know in which file i have to search.. but i found something in "svn/trunk/MTA10_Server/mods/deathmatch/logic/lua/CLuaFunctionDefinitions.cpp", Line 11580 int CLuaFunctionDefinitions::Get ( lua_State* luaVM ) { CResource* pResource = m_pResourceManager->GetResourceFromLuaState ( luaVM ); if ( lua_type ( luaVM, 1 ) == LUA_TSTRING ) { CLuaArguments Args; CXMLAttributes *pAttributes; unsigned int uiIndex = 0; bool bDeleteNode; // Extract attribute name if setting to be gotten has three parts i.e. resname.settingname.attributename SString strSetting = lua_tostring ( luaVM, 1 ); SString strAttribute = "value"; vector < SString > Result; strSetting.Split ( ".", Result ); if ( Result.size () == 3 && Result[2].length () ) { strAttribute = Result[2]; } // Get the setting CXMLNode *pSubNode, *pNode = g_pGame->GetSettings ()->Get ( pResource->GetName ().c_str (), strSetting.c_str (), bDeleteNode ); // Only proceed if we have a valid node if ( pNode ) { // Argument count unsigned int uiArgCount = 1; // See if we need to return a table with single or multiple entries if ( pNode->GetSubNodeCount () == 0 ) { // See if required attribute exists CXMLAttribute *pAttribute = pNode->GetAttributes().Find ( strAttribute.c_str () ); if ( !pAttribute ) { if ( bDeleteNode ) delete pNode; lua_pushboolean ( luaVM, false ); return 1; } // We only have a single entry for a specific setting, so output a string char *szDataValue = const_cast < char* > ( pAttribute->GetValue ().c_str () ); if ( !Args.ReadFromJSONString ( szDataValue ) ) { // No valid JSON? Parse as plain text Args.PushString ( szDataValue ); } Args.PushArguments ( luaVM ); uiArgCount = Args.Count (); /* Don't output a table because although it is more consistent with the multiple values output below, ** due to lua's implementation of associative arrays (assuming we use the "setting-name", "value" key-value pairs) ** it would require the scripter to walk through an array that only has a single entry which is a Bad Thing, performance wise. ** PUSH_SETTING ( pNode ); Args.PushAsTable ( luaVM ); **/ } else { // We need to return multiply entries, so push all subnodes char *szDataValue; while ( ( pSubNode = pNode->FindSubNode ( "setting", uiIndex++ ) ) ) { PUSH_SETTING ( pSubNode, szDataValue ); } // Push a table and return Args.PushAsTable ( luaVM ); } // Check if we have to delete the node if ( bDeleteNode ) delete pNode; return uiArgCount; } } else m_pScriptDebugging->LogBadType ( luaVM, "get" ); lua_pushboolean ( luaVM, false ); return 1; } I guess 11616 and 11654 (37 and 75 here) have to be changed to lua_pushnil( luaVM ); (Don't want to report this without confirmation, because i'm pretty unsure.) Link to comment
eAi Posted December 17, 2010 Share Posted December 17, 2010 Line 37 is where false is returned if get can't find the setting you specify, so you could use that as the basis for an 'isset' function (i.e. copy that function and rip out all the code that actually checks or returns a value). Link to comment
Recommended Posts