void KeyValuesToTable( KeyValues* pKv, ILuaObject* pTable ) { char name[512]; CLuaTable* pChildTable = NULL; int iUniqueKey = 0; float fValue = 0.0f; KeyValues* kvSub = pKv->GetFirstSubKey(); while (kvSub) { Q_strncpy( name, kvSub->GetName(), sizeof(name) ); Q_strlower( name ); // Make sure the key is UNIQUE! while ( pTable->GetMember( name ) ) { Q_snprintf( name, sizeof(name), "%i", iUniqueKey++ ); } switch (kvSub->GetDataType()) { case KeyValues::TYPE_FLOAT: case KeyValues::TYPE_INT: fValue = kvSub->GetFloat(); fValue *= 10000.0f; fValue = floor( fValue ); fValue /= 10000.0f; pTable->SetMember( name, fValue ); break; case KeyValues::TYPE_NONE: pChildTable = new CLuaTable(); pTable->SetMember( name, pChildTable ); KeyValuesToTable( kvSub, pChildTable ); delete pChildTable; break; default: pTable->SetMember( name, kvSub->GetString() ); break; } kvSub = kvSub->GetNextKey(); } } void TableToKeyValues( ILuaObject* pTable, KeyValues* pKv ) { if ( !pTable || !pTable->isTable() ) return; CUtlLuaVector* pMembers = pTable->GetMembers(); FOR_EACH_VEC( (*pMembers), i ) { if ( (*pMembers)[i].pValue->isTable() ) { KeyValues* newkv = pKv->CreateNewKey(); newkv->SetName( (*pMembers)[i].pKey->GetString() ); TableToKeyValues( (*pMembers)[i].pValue, newkv ); continue; } pKv->SetString( (*pMembers)[i].pKey->GetString(), (*pMembers)[i].pValue->GetString() ); } } void KeyValuesToTablePreserveOrder( KeyValues* pKv, ILuaObject* pTable ) { char name [128 ]; CLuaTable* pChildTable = NULL; int iChildren = 1; int i = 1; float fValue = 0.0f; KeyValues* kvSub = pKv->GetFirstSubKey(); while (kvSub) { Q_strncpy( name, kvSub->GetName(), sizeof(name) ); Q_strlower( name ); // We need to handle instances where keys are all 0. // We need to get repeats, in a good way. if ( name[0] == '0' ) { if ( name[1] == 0) { Q_snprintf( name, sizeof(name), "%i", i++ ); } } CLuaTable pSubKey; pSubKey.SetMember( "Key", name ); pTable->SetMember( iChildren++, &pSubKey ); switch (kvSub->GetDataType()) { case KeyValues::TYPE_FLOAT: case KeyValues::TYPE_INT: fValue = kvSub->GetFloat(); fValue *= 10000.0f; fValue = floor( fValue ); fValue /= 10000.0f; pSubKey.SetMember( "Value", kvSub->GetFloat() ); break; case KeyValues::TYPE_NONE: pChildTable = new CLuaTable(); pSubKey.SetMember( "Value", pChildTable ); KeyValuesToTablePreserveOrder( kvSub, pChildTable ); delete pChildTable; break; default: pSubKey.SetMember( "Value", kvSub->GetString() ); break; } kvSub = kvSub->GetNextKey(); } }