vconfig luaW_checkvconfig(lua_State *L, int index, bool allow_missing) { vconfig result = vconfig::unconstructed_vconfig(); if (!luaW_tovconfig(L, index, result) || (!allow_missing && result.null())) luaW_type_error(L, index, "WML table"); return result; }
map_location luaW_checklocation(lua_State *L, int index) { map_location result; if (!luaW_tolocation(L, index, result)) luaW_type_error(L, index, "location"); return result; }
config luaW_checkconfig(lua_State *L, int index) { config result; if (!luaW_toconfig(L, index, result)) luaW_type_error(L, index, "WML table"); return result; }
t_string luaW_checktstring(lua_State *L, int index) { t_string result; if (!luaW_totstring(L, index, result)) luaW_type_error(L, index, "translatable string"); return result; }
/** * Counts the attacks of a unit (__len metamethod). * - Arg 1: table containing the userdata containing the unit id. * - Ret 1: size of unit attacks vector. */ static int impl_unit_attacks_len(lua_State *L) { if(!lua_istable(L, 1)) { return luaW_type_error(L, 1, "unit attacks"); } lua_rawgeti(L, 1, 0); const unit* u = luaW_tounit(L, -1); const unit_type* ut = luaW_tounittype(L, -1); if(!u && !ut) { return luaL_argerror(L, 1, "unknown unit"); } lua_pushinteger(L, (u ? u->attacks() : ut->attacks()).size()); return 1; }
static int impl_unit_attacks_set(lua_State* L) { if(!lua_istable(L, 1)) { return luaW_type_error(L, 1, "unit attacks"); } lua_rawgeti(L, 1, 0); const unit_type* ut = luaW_tounittype(L, -1); if(ut) { return luaL_argerror(L, 1, "unit type attack table is immutable"); } unit& u = luaW_checkunit(L, -1); attack_ptr atk = lua_isnumber(L, 2) ? find_attack(&u, luaL_checkinteger(L, 2) - 1) : find_attack(&u, luaL_checkstring(L, 2)); if(lua_isnumber(L, 2) && lua_tonumber(L, 2) - 1 > u.attacks().size()) { return luaL_argerror(L, 2, "attack can only be added at the end of the list"); } if(lua_isnil(L, 3)) { // Delete the attack u.remove_attack(atk); return 0; } auto iter = get_attack_iter(u, atk), end = u.attacks().end(); if(const_attack_ptr atk2 = luaW_toweapon(L, 3)) { if(iter == end) { atk = u.add_attack(end, *atk2); } else { iter.base()->reset(new attack_type(*atk2)); atk = *iter.base(); } } else { config cfg = luaW_checkconfig(L, 3); if(iter == end) { atk = u.add_attack(end, cfg); } else { iter.base()->reset(new attack_type(cfg)); atk = *iter.base(); } } if(!lua_isnumber(L, 2)) { atk->set_id(lua_tostring(L, 2)); } return 0; }
/** * Converts a Lua value at position @a src and appends it to @a dst. * @note This function is private to lua_tstring_concat. It expects two things. * First, the t_string metatable is at the top of the stack on entry. (It * is still there on exit.) Second, the caller hasn't any valuable object * with dynamic lifetime, since they would be leaked on error. */ static void tstring_concat_aux(lua_State *L, t_string &dst, int src) { switch (lua_type(L, src)) { case LUA_TNUMBER: case LUA_TSTRING: dst += lua_tostring(L, src); return; case LUA_TUSERDATA: // Compare its metatable with t_string's metatable. if (t_string * src_ptr = static_cast<t_string *> (luaL_testudata(L, src, tstringKey))) { dst += *src_ptr; return; } //intentional fall-through default: luaW_type_error(L, src, "string"); } }
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; } }
/** * Gets the attacks of a unit or unit type (__index metamethod). * - Arg 1: table containing the userdata containing the unit or unit type. * - Arg 2: index (int) or id (string) identifying a particular attack. * - Ret 1: the unit's attacks. */ static int impl_unit_attacks_get(lua_State *L) { if(!lua_istable(L, 1)) { return luaW_type_error(L, 1, "unit attacks"); } lua_rawgeti(L, 1, 0); lua_unit* lu = luaW_tounit_ref(L, -1); const unit_type* ut = luaW_tounittype(L, -1); if(lu && lu->get()) { unit* u = lu->get(); attack_ptr atk = lua_isnumber(L, 2) ? find_attack(u, luaL_checkinteger(L, 2) - 1) : find_attack(u, luaL_checkstring(L, 2)); luaW_pushweapon(L, atk); } else if(ut) { const_attack_ptr atk = lua_isnumber(L, 2) ? find_attack(ut, luaL_checkinteger(L, 2) - 1) : find_attack(ut, luaL_checkstring(L, 2)); luaW_pushweapon(L, atk); } else { return luaL_argerror(L, 1, "unit not found"); } return 1; }