/** * Returns a random numer, same interface as math.random. */ static int intf_random(lua_State *L) { if (lua_isnoneornil(L, 1)) { double r = static_cast<double>(randomness::generator->next_random()); double r_max = static_cast<double>(std::numeric_limits<uint32_t>::max()); lua_push(L, r / (r_max + 1)); return 1; } else { int32_t min; int32_t max; if (lua_isnumber(L, 2)) { min = lua_check<int32_t>(L, 1); max = lua_check<int32_t>(L, 2); } else { min = 1; max = lua_check<int32_t>(L, 1); } if (min > max) { return luaL_argerror(L, 1, "min > max"); } lua_push(L, randomness::generator->get_random_int(min, max)); return 1; } }
/** * Returns a random numer, same interface as math.random. */ static int intf_random(lua_State *L) { boost::mt19937& rng = lua_kernel_base::get_lua_kernel<mapgen_lua_kernel>(L).get_default_rng(); if(lua_isnoneornil(L, 1)) { double r = double (rng()); double r_max = double (rng.max()); lua_push(L, r / (r_max + 1)); return 1; } else { int32_t min; int32_t max; if(lua_isnumber(L, 2)) { min = lua_check<int32_t>(L, 1); max = lua_check<int32_t>(L, 2); } else { min = 1; max = lua_check<int32_t>(L, 1); } if(min > max) { return luaL_argerror(L, 1, "min > max"); } lua_push(L, min + static_cast<int>(rng() % (max - min + 1))); return 1; } }
static int intf_format(lua_State* L) { config cfg = luaW_checkconfig(L, 2); config_variable_set variables(cfg); if(lua_isstring(L, 1)) { std::string str = lua_tostring(L, 1); lua_push(L, utils::interpolate_variables_into_string(str, variables)); return 1; } t_string str = luaW_checktstring(L, 1); lua_push(L, utils::interpolate_variables_into_tstring(str, variables)); return 1; }
static int intf_format_list(lua_State* L) { const t_string empty = luaW_checktstring(L, 1); auto values = lua_check<std::vector<t_string>>(L, 2); lua_push(L, (conjunct ? utils::format_conjunct_list : utils::format_disjunct_list)(empty, values)); return 1; }
/** * Logs a deprecation message. See deprecation.cpp for details * Arg 1: Element to be deprecated. * Arg 2: Deprecation level. * Arg 3: Version when element may be removed. * Arg 4: Additional detail message. */ static int intf_deprecated_message(lua_State* L) { const std::string elem = luaL_checkstring(L, 1); // This could produce an invalid deprecation level, but that possibility is handled in deprecated_message() const DEP_LEVEL level = DEP_LEVEL(luaL_checkinteger(L, 2)); const std::string ver_str = lua_isnoneornil(L, 3) ? "" : luaL_checkstring(L, 3); const std::string detail = luaW_checktstring(L, 4); const version_info ver = ver_str.empty() ? game_config::wesnoth_version.str() : ver_str; const std::string msg = deprecated_message(elem, level, ver, detail); if(level < DEP_LEVEL::INDEFINITE || level >= DEP_LEVEL::REMOVED) { // Invalid deprecation level or level 4 deprecation should raise an interpreter error lua_push(L, msg); return lua_error(L); } return 0; }
/** * Gets some data on a unit type (__index metamethod). * - Arg 1: table containing an "id" field. * - Arg 2: string containing the name of the property. * - Ret 1: something containing the attribute. */ static int impl_unit_type_get(lua_State *L) { const unit_type& ut = luaW_checkunittype(L, 1); char const *m = luaL_checkstring(L, 2); // Find the corresponding attribute. return_tstring_attrib("name", ut.type_name()); return_string_attrib("id", ut.id()); return_string_attrib("alignment", ut.alignment().to_string()); return_string_attrib("race", ut.race_id()); return_int_attrib("max_hitpoints", ut.hitpoints()); return_int_attrib("max_moves", ut.movement()); return_int_attrib("max_experience", ut.experience_needed()); return_int_attrib("cost", ut.cost()); return_int_attrib("level", ut.level()); return_int_attrib("recall_cost", ut.recall_cost()); return_cfgref_attrib("__cfg", ut.get_cfg()); if (strcmp(m, "traits") == 0) { lua_newtable(L); for (const config& trait : ut.possible_traits()) { const std::string& id = trait["id"]; lua_pushlstring(L, id.c_str(), id.length()); luaW_pushconfig(L, trait); lua_rawset(L, -3); } return 1; } if (strcmp(m, "abilities") == 0) { lua_push(L, ut.get_ability_list()); return 1; } if (strcmp(m, "attacks") == 0) { push_unit_attacks_table(L, 1); return 1; } // TODO: Should this only exist for base units? if(strcmp(m, "variations") == 0) { *new(L) const unit_type* = &ut; luaL_setmetatable(L, UnitTypeTable); return 1; } return 0; }
/** * Reads a file into a string, or a directory into a list of files therein. * - Arg 1: string containing the file name. * - Ret 1: string */ int intf_read_file(lua_State *L) { std::string p = luaL_checkstring(L, 1); if(!resolve_filename(p, get_calling_file(L))) { return luaL_argerror(L, -1, "file not found"); } if(filesystem::is_directory(p)) { std::vector<std::string> files, dirs; filesystem::get_files_in_dir(p, &files, &dirs); filesystem::default_blacklist.remove_blacklisted_files_and_dirs(files, dirs); std::size_t ndirs = dirs.size(); std::copy(files.begin(), files.end(), std::back_inserter(dirs)); lua_push(L, dirs); lua_pushnumber(L, ndirs); lua_setfield(L, -2, "ndirs"); return 1; } const std::unique_ptr<std::istream> fs(filesystem::istream_file(p)); fs->exceptions(std::ios_base::goodbit); std::size_t size = 0; fs->seekg(0, std::ios::end); if(!fs->good()) { return luaL_error(L, "Error when reading file"); } size = fs->tellg(); fs->seekg(0, std::ios::beg); if(!fs->good()) { return luaL_error(L, "Error when reading file"); } luaL_Buffer b; luaL_buffinit(L, &b); //throws an exception if malloc failed. char* out = luaL_prepbuffsize(&b, size); fs->read(out, size); if(fs->good()) { luaL_addsize(&b, size); } luaL_pushresult(&b); return 1; }
static void push( lua_State* lua_state, const std::pair<Key, Data>& value ) { lua_push( lua_state, value.second ); }
static void push( lua_State* lua, const stdext::hash_set<Key, Traits, Allocator>& value ) { lua_push( lua, value.begin(), value.end() ); }
int lua_kernel_base::intf_kernel_type(lua_State* L) { lua_push(L, my_name()); return 1; }
static int intf_get_language(lua_State* L) { lua_push(L, get_language().localename); return 1; }
static void push( lua_State* lua_state, const stdext::hash_map<Key, Data, Traits, Allocator>& value ) { lua_push( lua_state, value.begin(), value.end() ); }