Index: trunk/nv/array2d.hh
===================================================================
--- trunk/nv/array2d.hh	(revision 161)
+++ trunk/nv/array2d.hh	(revision 162)
@@ -184,5 +184,5 @@
 		inline reference operator[] ( const ivec2& c )
 		{
-			NV_ASSERT( x >= 0 && y >= 0 && x < m_size.x && y < m_size.y, "Bad parameters passed to array2d[]" );
+			NV_ASSERT( c.x >= 0 && c.y >= 0 && c.x < m_size.x && c.y < m_size.y, "Bad parameters passed to array2d[]" );
 			return m_data[ c.y * m_size.x + c.x ];
 		}
Index: trunk/nv/flags.hh
===================================================================
--- trunk/nv/flags.hh	(revision 162)
+++ trunk/nv/flags.hh	(revision 162)
@@ -0,0 +1,160 @@
+// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// http://chaosforge.org/
+//
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+
+/**
+ * @file flags.hh
+ * @author Kornel Kisielewicz
+ * @brief flags
+ */
+
+#ifndef NV_FLAGS_HH
+#define NV_FLAGS_HH
+
+#include <nv/common.hh>
+#include <bitset>
+#include <type_traits>
+
+namespace nv
+{
+
+	template < uint32 SIZE, typename T = uint32 >
+	class flags
+	{
+	public:
+
+		class reference
+		{
+			friend class flags<SIZE,T>;
+		public:
+			typedef bool value_type;
+			typedef T    index_type;
+
+			reference& operator=( value_type a_value )
+			{
+				m_flags->set( m_index, a_value );
+				return (*this);
+			}
+			reference& operator=( const reference& a_value )
+			{
+				m_flags->set( m_index, bool( a_value ) );
+				return (*this);
+			}
+			operator bool() const 
+			{
+				return m_flags->test( m_index );
+			}
+
+		private:
+			reference() : m_flags( nullptr ), m_position( 0 ) {}
+
+			reference( flags<SIZE,T>* a_flags, index_type a_index )
+				: m_flags( a_flags ), m_index( a_index )
+			{	
+			}
+
+		private:
+			flags<SIZE,T>* m_flags;
+			index_type     m_index;
+		};
+
+		typedef uint8  data_type;
+		typedef bool   value_type;
+		typedef T      index_type;
+		typedef uint32 size_type;
+		typedef typename std::underlying_type<T>::type raw_index_type;
+
+		static const size_type data_type_size = sizeof( data_type ) * 8;
+		static const size_type data_count     = SIZE;
+		static const size_type data_size      = (SIZE+data_type_size-1) / data_type_size;
+
+		flags()
+		{
+			reset();
+		}
+
+		explicit flags( const data_type* a_data )
+		{
+			assign( a_data );
+		}
+
+		void assign( const data_type* a_data )
+		{
+			std::copy( a_data, a_data + data_size, m_data );
+		}
+
+		void reset()
+		{
+			std::fill( m_data, m_data + data_size, 0 );
+		}
+
+		void include( index_type i )
+		{
+			raw_index_type idx = static_cast< raw_index_type >( i ) / data_type_size;
+			raw_index_type pos = < raw_index_type >( i ) % data_type_size;
+			m_data[ idx ] |= 1 << static_cast< data_type >( pos );
+		}
+
+		void exclude( index_type i )
+		{
+			raw_index_type idx = static_cast< raw_index_type >( i ) / data_type_size;
+			raw_index_type pos = static_cast< raw_index_type >( i ) % data_type_size;
+			m_data[ idx ] &= ~(1 << static_cast< data_type >( pos ) );
+		}
+
+		void set( index_type i, value_type value )
+		{
+			raw_index_type idx = static_cast< raw_index_type >( i ) / data_type_size;
+			raw_index_type pos = static_cast< raw_index_type >( i ) % data_type_size;
+			if ( value )
+				m_data[ idx ] |= 1 << static_cast< data_type >( pos );
+			else
+				m_data[ idx ] &= ~(1 << static_cast< data_type >( pos ) );
+		}
+
+		bool test( index_type i ) const
+		{
+			raw_index_type idx = static_cast< raw_index_type >( i ) / data_type_size;
+			raw_index_type pos = static_cast< raw_index_type >( i ) % data_type_size;
+			return ( m_data[ idx ] & ( 1 << static_cast< data_type >( pos ) ) ) != 0;
+		}
+
+		const data_type* data() const
+		{
+			return m_data;
+		}
+
+		data_type* data()
+		{
+			return m_data;
+		}
+
+		size_type size() const
+		{
+			return data_count;
+		}
+
+		size_type capacity() const
+		{
+			return data_size;
+		}
+
+		bool operator[]( index_type idx ) const
+		{
+			return test( idx );
+		}
+
+		reference operator[]( index_type idx )
+		{
+			return reference( this, idx );
+		}
+
+	private:
+		data_type m_data[ data_size ];
+	};
+
+} // namespace nv
+
+#endif // NV_FLAGS_HH
Index: trunk/nv/lua/lua_raw.hh
===================================================================
--- trunk/nv/lua/lua_raw.hh	(revision 161)
+++ trunk/nv/lua/lua_raw.hh	(revision 162)
@@ -11,6 +11,9 @@
 #include <istream>
 #include <string>
-#include <bitset>
 #include <map>
+
+void nlua_toflags_flat( lua_State *L, int index, nv::uint8* data, nv::uint32 count );
+void nlua_toflags_array( lua_State *L, int index, nv::uint8* data, nv::uint32 count );
+void nlua_toflags( lua_State *L, int index, nv::uint8* data, nv::uint32 count );
 
 std::string nlua_typecontent( lua_State* L, int idx );
Index: trunk/nv/lua/lua_state.hh
===================================================================
--- trunk/nv/lua/lua_state.hh	(revision 161)
+++ trunk/nv/lua/lua_state.hh	(revision 162)
@@ -11,4 +11,5 @@
 #include <map>
 #include <nv/common.hh>
+#include <nv/flags.hh>
 #include <string>
 
@@ -52,5 +53,21 @@
 			double get_double( const std::string& element, double defval = 0.0 );
 			bool get_boolean( const std::string& element, bool defval = false );
-		public:
+
+			template< uint32 SIZE, typename T >
+			flags< SIZE, T > get_flags( const std::string& element )
+			{
+				flags< SIZE, T > result;
+				get_raw_flags( element, result.data(), result.size() );
+				return result;
+			}
+
+			template< uint32 SIZE, typename T >
+			void load_flags( const std::string& element, flags< SIZE, T >& flags )
+			{
+				get_raw_flags( element, flags.data(), flags.size() );
+			}
+		private:
+			void get_raw_flags( const std::string& element, uint8* data, uint32 count );
+
 			state* L;
 			stack_guard m_guard;
Index: trunk/src/lua/lua_raw.cc
===================================================================
--- trunk/src/lua/lua_raw.cc	(revision 161)
+++ trunk/src/lua/lua_raw.cc	(revision 162)
@@ -188,2 +188,62 @@
 	lua_pop( L, 1 );
 }
+
+void nlua_toflags( lua_State *L, int index, nv::uint8* data, nv::uint32 count )
+{
+	index = lua_absindex( L, index );
+	nv::uint32 flag;
+	if ( lua_istable( L, index ) )
+	{
+		lua_pushnil( L );
+		while ( lua_next( L, index ) != 0 )
+		{
+			if ( lua_type( L, -1 ) == LUA_TBOOLEAN )
+				flag = static_cast< nv::uint32 >( lua_tointeger( L ,-2 ) );
+			else
+				flag = static_cast< nv::uint32 >( lua_tointeger( L ,-1 ) );
+			lua_pop( L, 1 );
+			if ( flag < count )
+			{
+				data[ flag / 8 ] |= ( 1 << static_cast< nv::uint8 >( flag % 8 ) );
+			}
+		}
+	}
+}
+
+void nlua_toflags_set( lua_State *L, int index, nv::uint8* data, nv::uint32 count )
+{
+	index = lua_absindex( L, index );
+	nv::uint32 flag;
+	if ( lua_istable( L, index ) )
+	{
+		lua_pushnil( L );
+		while ( lua_next( L, index ) != 0 )
+		{
+			flag = static_cast< nv::uint32 >( lua_tointeger( L ,-2 ) );
+			lua_pop( L, 1 );
+			if ( flag < count )
+			{
+				data[ flag / 8 ] |= ( 1 << static_cast< nv::uint8 >( flag % 8 ) );
+			}
+		}
+	}
+}
+
+void nlua_toflags_array( lua_State *L, int index, nv::uint8* data, nv::uint32 count )
+{
+	index = lua_absindex( L, index );
+	nv::uint32 flag;
+	if ( lua_istable( L, index ) )
+	{
+		lua_pushnil( L );
+		while ( lua_next( L, index ) != 0 )
+		{
+			flag = static_cast< nv::uint32 >( lua_tointeger( L ,-1 ) );
+			lua_pop( L, 1 );
+			if ( flag < count )
+			{
+				data[ flag / 8 ] |= ( 1 << static_cast< nv::uint8 >( flag % 8 ) );
+			}
+		}
+	}
+}
Index: trunk/src/lua/lua_state.cc
===================================================================
--- trunk/src/lua/lua_state.cc	(revision 161)
+++ trunk/src/lua/lua_state.cc	(revision 162)
@@ -279,4 +279,17 @@
 }
 
+void lua::table_guard::get_raw_flags( const std::string& element, uint8* data, uint32 count )
+{
+	lua_getfield( L->L, -1, element.c_str() );
+	if ( lua_type( L->L, -1 ) != LUA_TTABLE )
+	{
+		lua_pop( L->L, 1 );
+		return;
+	}
+	nlua_toflags( L->L, -1, data, count );
+	lua_pop( L->L, 1 );
+}
+
+
 void lua::state::log_stack()
 {
