bool luaW_toscalar(lua_State *L, int index, config::attribute_value& v) { switch (lua_type(L, index)) { case LUA_TBOOLEAN: v = luaW_toboolean(L, -1); break; case LUA_TNUMBER: v = lua_tonumber(L, -1); break; case LUA_TSTRING: v = lua_tostring(L, -1); break; case LUA_TUSERDATA: { if (t_string * tptr = static_cast<t_string *>(luaL_testudata(L, -1, tstringKey))) { v = *tptr; break; } else { return false; } } default: return false; } return true; }
bool luaW_pushvariable(lua_State *L, variable_access_const& v) { try { if(v.exists_as_attribute()) { luaW_pushscalar(L, v.as_scalar()); return true; } else if(v.exists_as_container()) { lua_newtable(L); if (luaW_toboolean(L, 2)) luaW_filltable(L, v.as_container()); return true; } else { lua_pushnil(L); return true; } } catch (const invalid_variablename_exception&) { WRN_LUA << v.get_error_message(); return false; } }
/** * Sets a widget's state to active or inactive * - Arg 1: boolean. * - Args 2..n: path of strings and integers. */ int intf_set_dialog_active(lua_State *L) { const bool b = luaW_toboolean(L, 1); gui2::twidget *w = find_widget(L, 2, true); gui2::tcontrol *c = dynamic_cast<gui2::tcontrol *>(w); if (!c) return luaL_argerror(L, lua_gettop(L), "unsupported widget"); c->set_active(b); return 0; }
/** * Checks if a file exists (not necessarily a Lua script). * - Arg 1: string containing the file name. * - Arg 2: if true, the file must be a real file and not a directory * - Ret 1: boolean */ int intf_have_file(lua_State *L) { std::string m = luaL_checkstring(L, 1); if(!resolve_filename(m, get_calling_file(L))) { lua_pushboolean(L, false); } else if(luaW_toboolean(L, 2)) { lua_pushboolean(L, !filesystem::is_directory(m)); } else { lua_pushboolean(L, true); } return 1; }
/** * Loads a WML file into a config * - Arg 1: WML file path * - Arg 2: (optional) Array of preprocessor defines, or false to skip preprocessing (true is also valid) * - Arg 3: (optional) Path to a schema file for validation (omit for no validation) * - Ret: config */ static int intf_load_wml(lua_State* L) { std::string file = luaL_checkstring(L, 1); bool preprocess = true; preproc_map defines_map; if(lua_type(L, 2) == LUA_TBOOLEAN) { preprocess = luaW_toboolean(L, 2); } else if(lua_type(L, 2) == LUA_TTABLE || lua_type(L, 2) == LUA_TUSERDATA) { lua_len(L, 2); int n = lua_tonumber(L, -1); lua_pop(L, 1); for(int i = 0; i < n; i++) { lua_geti(L, 2, i); if(!lua_isstring(L, -1)) { return luaL_argerror(L, 2, "expected bool or array of strings"); } std::string define = lua_tostring(L, -1); lua_pop(L, 1); if(!define.empty()) { defines_map.emplace(define, preproc_define(define)); } } } else if(!lua_isnoneornil(L, 2)) { return luaL_argerror(L, 2, "expected bool or array of strings"); } std::string schema_path = luaL_optstring(L, 3, ""); std::shared_ptr<schema_validation::schema_validator> validator; if(!schema_path.empty()) { validator.reset(new schema_validation::schema_validator(filesystem::get_wml_location(schema_path))); validator->set_create_exceptions(false); // Don't crash if there's an error, just go ahead anyway } std::string wml_file = filesystem::get_wml_location(file); filesystem::scoped_istream stream; config result; if(preprocess) { stream = preprocess_file(wml_file, &defines_map); } else { stream.reset(new std::ifstream(wml_file)); } read(result, *stream, validator.get()); luaW_pushconfig(L, result); return 1; }
static int ai_move(lua_State *L, bool exec, bool remove_movement) { int index = 1; if (false) { error_call_destructors: return luaL_typerror(L, index, "location (unit/integers)"); } int side = get_readonly_context(L).get_side(); map_location from, to; if (!to_map_location(L, index, from)) goto error_call_destructors; if (!to_map_location(L, index, to)) goto error_call_destructors; bool unreach_is_ok = false; if (lua_isboolean(L, index)) { unreach_is_ok = luaW_toboolean(L, index); } ai::move_result_ptr move_result = ai::actions::execute_move_action(side,exec,from,to,remove_movement, unreach_is_ok); return transform_ai_action(L,move_result); }
bool luaW_checkvariable(lua_State *L, variable_access_create& v, int n) { int variabletype = lua_type(L, n); try { switch (variabletype) { case LUA_TBOOLEAN: v.as_scalar() = luaW_toboolean(L, n); return true; case LUA_TNUMBER: v.as_scalar() = lua_tonumber(L, n); return true; case LUA_TSTRING: v.as_scalar() = lua_tostring(L, n); return true; case LUA_TUSERDATA: if (t_string * t_str = static_cast<t_string*> (luaL_testudata(L, n, tstringKey))) { v.as_scalar() = *t_str; return true; } goto default_explicit; case LUA_TTABLE: { config &cfg = v.as_container(); cfg.clear(); if (luaW_toconfig(L, n, cfg)) { return true; } // no break } default: default_explicit: return luaW_type_error(L, n, "WML table or scalar") != 0; } } catch (const invalid_variablename_exception&) { WRN_LUA << v.get_error_message() << " when attempting to write a '" << lua_typename(L, variabletype) << "'\n"; return false; } }
/** * Finds a path between two locations. * - Args 1,2: source location. * - Args 3,4: destination. * - Arg 5: cost function * - Args 6,7 size of map. * - Arg 8 include border. * - Ret 1: array of pairs containing path steps. * - Ret 2: path cost. */ static int intf_find_path(lua_State *L) { int arg = 1; map_location src, dst; src.x = luaL_checkinteger(L, 1) - 1; src.y = luaL_checkinteger(L, 2) - 1; dst.x = luaL_checkinteger(L, 3) - 1; dst.y = luaL_checkinteger(L, 4) - 1; if(lua_isfunction(L, arg)) { const char *msg = lua_pushfstring(L, "%s expected, got %s", lua_typename(L, LUA_TFUNCTION), luaL_typename(L, 5)); return luaL_argerror(L, 5, msg); } lua_pathfind_cost_calculator calc(L, 5); int width = luaL_checkinteger(L, 6); int height = luaL_checkinteger(L, 7); bool border = false; if(lua_isboolean(L, 8)) { border = luaW_toboolean(L, 8); } pathfind::plain_route res = pathfind::a_star_search(src, dst, 10000, &calc, width, height, nullptr, border); int nb = res.steps.size(); lua_createtable(L, nb, 0); for (int i = 0; i < nb; ++i) { lua_createtable(L, 2, 0); lua_pushinteger(L, res.steps[i].x + 1); lua_rawseti(L, -2, 1); lua_pushinteger(L, res.steps[i].y + 1); lua_rawseti(L, -2, 2); lua_rawseti(L, -2, i + 1); } lua_pushinteger(L, res.move_cost); return 2; }
inline boost::shared_ptr<bool> lua_object<bool>::to_type(lua_State *L, int n) { return boost::shared_ptr<bool>(new bool(luaW_toboolean(L, n))); }
/** * Sets the value of a widget on the current dialog. * - Arg 1: scalar. * - Args 2..n: path of strings and integers. */ int intf_set_dialog_value(lua_State *L) { gui2::twidget *w = find_widget(L, 2, false); #ifdef GUI2_EXPERIMENTAL_LISTBOX if (gui2::tlist *l = dynamic_cast<gui2::tlist *>(w)) #else if (gui2::tlistbox *l = dynamic_cast<gui2::tlistbox *>(w)) #endif { int v = luaL_checkinteger(L, 1); int n = l->get_item_count(); if (1 <= v && v <= n) l->select_row(v - 1); else return luaL_argerror(L, 1, "out of bounds"); } else if (gui2::tmulti_page *l = dynamic_cast<gui2::tmulti_page *>(w)) { int v = luaL_checkinteger(L, 1); int n = l->get_page_count(); if (1 <= v && v <= n) l->select_page(v - 1); else return luaL_argerror(L, 1, "out of bounds"); } else if (gui2::tselectable_ *s = dynamic_cast<gui2::tselectable_ *>(w)) { s->set_value(luaW_toboolean(L, 1)); } else if (gui2::ttext_box *t = dynamic_cast<gui2::ttext_box *>(w)) { const t_string& text = luaW_checktstring(L, 1); t->set_value(text.str()); } else if (gui2::tslider *s = dynamic_cast<gui2::tslider *>(w)) { const int v = luaL_checkinteger(L, 1); const int m = s->get_minimum_value(); const int n = s->get_maximum_value(); if (m <= v && v <= n) s->set_value(v); else return luaL_argerror(L, 1, "out of bounds"); } else if (gui2::tprogress_bar *p = dynamic_cast<gui2::tprogress_bar *>(w)) { const int v = luaL_checkinteger(L, 1); if (0 <= v && v <= 100) p->set_percentage(v); else return luaL_argerror(L, 1, "out of bounds"); } else { t_string v = luaW_checktstring(L, 1); gui2::tcontrol *c = dynamic_cast<gui2::tcontrol *>(w); if (!c) return luaL_argerror(L, lua_gettop(L), "unsupported widget"); c->set_label(v); } return 0; }
typename boost::enable_if<typename boost::is_same<T, bool>::type, bool>::type lua_check(lua_State *L, int n) { return luaW_toboolean(L, n); }