// Copyright (C) 2012-2015 ChaosForge Ltd // http://chaosforge.org/ // // This file is part of Nova libraries. // For conditions of distribution and use, see copying.txt file in root folder. #include "nv/lua/lua_aux.hh" #include "nv/lua/lua_raw.hh" #include "nv/core/random.hh" static nv::random lua_rng; static int nluaaux_table_copy( lua_State* L ) { luaL_checktype( L, 1, LUA_TTABLE ); lua_settop( L, 1 ); nlua_shallowcopy( L, 1 ); return 1; } static int nluaaux_table_deepcopy( lua_State* L ) { luaL_checktype( L, 1, LUA_TTABLE ); lua_settop( L, 1 ); nlua_deepcopy( L, 1 ); return 0; } static int nluaaux_table_icopy( lua_State* L ) { luaL_checktype( L, 1, LUA_TTABLE ); lua_settop( L, 1 ); nlua_shallowicopy( L, 1 ); return 1; } static int nluaaux_table_merge( lua_State* L ) { luaL_checktype( L, 1, LUA_TTABLE ); luaL_checktype( L, 2, LUA_TTABLE ); lua_settop( L, 2 ); nlua_shallowmerge( L, 1 ); return 0; } static int nluaaux_table_reversed( lua_State* L ) { luaL_checktype( L, 1, LUA_TTABLE ); lua_settop( L, 1 ); nlua_pushreversed( L, 1 ); return 1; } static int nluaaux_table_toset( lua_State* L ) { luaL_checktype( L, 1, LUA_TTABLE ); lua_settop( L, 1 ); nlua_toset( L, 1 ); return 1; } static int nluaaux_table_tokeyset( lua_State* L ) { luaL_checktype( L, 1, LUA_TTABLE ); lua_settop( L, 1 ); nlua_tokeyset( L, 1 ); return 1; } static const struct luaL_Reg nluaaux_table_aux_f [] = { { "copy", nluaaux_table_copy }, { "deepcopy", nluaaux_table_deepcopy }, { "icopy", nluaaux_table_icopy }, { "merge", nluaaux_table_merge }, { "reversed", nluaaux_table_reversed }, { "toset", nluaaux_table_toset }, { "tokeyset", nluaaux_table_tokeyset }, { NULL, NULL } }; static int nluaaux_math_clamp( lua_State* L ) { double v = luaL_checknumber( L, 1 ); double min = luaL_optnumber( L, 2, 0 ); double max = luaL_optnumber( L, 3, 1 ); if ( min > max ) luaL_argerror( L, 2, "min is larger than max!" ); lua_pushnumber( L, v < min ? 2 : ( v > max ? 3 : 1 ) ); return 1; } static int nluaaux_math_dieroll( lua_State* L ) { lua_Integer dice = luaL_checkinteger( L, 1 ); lua_Integer sides = luaL_checkinteger( L, 2 ); if ( dice < 1 ) luaL_argerror( L, 1, "die count lower than 1!" ); if ( sides < 1 ) luaL_argerror( L, 2, "side count lower than 1!" ); lua_pushnumber( L, lua_rng.dice( static_cast< nv::uint32 >( dice ), static_cast< nv::uint32 >( sides ) ) ); return 1; } static int nluaaux_math_random( lua_State* L ) { if ( lua_gettop( L ) == 0 ) { lua_pushnumber( L, lua_rng.frand(1.0f) ); } else { if ( lua_gettop( L ) == 1 ) { lua_Integer arg1 = luaL_checkinteger( L, 1 ); if ( arg1 < 1 ) arg1 = 1; nlua_pushunsigned( L, lua_rng.urange( 1, static_cast( arg1 ) ) ); } else { int arg1 = static_cast< int >( luaL_checkinteger( L, 1 ) ); int arg2 = static_cast< int >( luaL_checkinteger( L, 2 ) ); int result = ( arg2 >= arg1 ? lua_rng.srange( arg1, arg2 ) : lua_rng.srange( arg2, arg1 ) ); lua_pushinteger( L, result ); } } return 1; } static int nluaaux_math_randomseed( lua_State* L ) { lua_rng.set_seed( nlua_tounsigned( L, 1 ) ); return 0; } static const struct luaL_Reg nluaaux_math_aux_f [] = { { "clamp", nluaaux_math_clamp }, { "random", nluaaux_math_random }, { "randomseed",nluaaux_math_randomseed }, { "dieroll", nluaaux_math_dieroll }, { NULL, NULL } }; nv::random & nv::lua::rng() { return lua_rng; } void nv::lua::register_aux( lua::state* state ) { nlua_register( state->get_raw(), "table", nluaaux_table_aux_f ); nlua_register( state->get_raw(), "math", nluaaux_math_aux_f ); }