From 64892b8c81c3da7af87c820508c6cef9cf98adf5 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Wed, 30 Mar 2016 02:15:21 -0400 Subject: [PATCH] Align formula and Lua views of unit types - New key in both - race --- changelog | 10 +++++++--- src/formula/callable_objects.cpp | 21 ++++++++++++++++++--- src/scripting/game_lua_kernel.cpp | 9 +++++---- src/scripting/lua_unit_type.cpp | 18 ++++++++++++++++++ 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/changelog b/changelog index cc2921d5a2cd..8ea39cd7ef6e 100644 --- a/changelog +++ b/changelog @@ -127,6 +127,10 @@ Version 1.13.4+dev: * abilities - list of the IDs of all abilities * Additional fields in table returned by wesnoth.get_terrain_info: * icon, editor_image, light + * Additional fields in unit type proxu: + * race, id, alignment + * attacks, which returns the same thing as unit.attacks + * abilities, same as unit.abilities * LuaAI: * The table returned by check_*() now has a "result" field which gives a description of the action's result; similar to "status" @@ -165,9 +169,9 @@ Version 1.13.4+dev: total_movement -> max_moves movement_left -> moves states -> status - * Nearly All side, weapon, and terrain attributes available to Lua code - are now also exposed to WFL. The exceptions are mainly translatable - strings. + * Nearly all unit type, side, weapon, and terrain attributes available + to Lua code are now also exposed to WFL. The exceptions are mainly + translatable strings. * The 'special' attribute of weapons was renamed to 'specials', and it now contains the special IDs rather than their translateable names. * New syntax features: diff --git a/src/formula/callable_objects.cpp b/src/formula/callable_objects.cpp index 4eafc80e38c8..0f4b8c339868 100644 --- a/src/formula/callable_objects.cpp +++ b/src/formula/callable_objects.cpp @@ -376,6 +376,8 @@ variant unit_type_callable::get_value(const std::string& key) const return variant(u_.type_name()); } else if(key == "alignment") { return variant(lexical_cast(u_.alignment())); + } else if(key == "race") { + return variant(u_.race_id()); } else if(key == "abilities") { std::vector abilities = u_.get_ability_list(); std::vector res; @@ -388,6 +390,14 @@ variant unit_type_callable::get_value(const std::string& key) const res.push_back( variant(*it) ); } return variant( &res ); + } else if(key == "traits") { + std::vector res; + + FOREACH(const AUTO& config , u_.possible_traits()) + { + res.push_back(variant(config["id"].str())); + } + return variant(&res); } else if(key == "attacks") { std::vector att = u_.attacks(); std::vector res; @@ -395,13 +405,13 @@ variant unit_type_callable::get_value(const std::string& key) const for( std::vector::iterator i = att.begin(); i != att.end(); ++i) res.push_back(variant(new attack_type_callable(*i))); return variant(&res); - } else if(key == "hitpoints") { + } else if(key == "hitpoints" || key == "max_hitpoints") { return variant(u_.hitpoints()); - } else if(key == "experience") { + } else if(key == "experience" || key == "max_experience") { return variant(u_.experience_needed(true)); } else if(key == "level") { return variant(u_.level()); - } else if(key == "total_movement") { + } else if(key == "total_movement" || key == "max_moves" || key == "moves") { return variant(u_.movement()); } else if(key == "unpoisonable") { return variant(u_.musthave_status("unpoisonable")); @@ -411,6 +421,8 @@ variant unit_type_callable::get_value(const std::string& key) const return variant(u_.musthave_status("unplagueable")); } else if(key == "cost") { return variant(u_.cost()); + } else if(key == "recall_cost") { + return variant(u_.recall_cost()); } else if(key == "usage") { return variant(u_.usage()); } else { @@ -423,8 +435,10 @@ void unit_type_callable::get_inputs(std::vector* inpu using game_logic::FORMULA_READ_ONLY; inputs->push_back(game_logic::formula_input("id", FORMULA_READ_ONLY)); inputs->push_back(game_logic::formula_input("type", FORMULA_READ_ONLY)); + inputs->push_back(game_logic::formula_input("race", FORMULA_READ_ONLY)); inputs->push_back(game_logic::formula_input("alignment", FORMULA_READ_ONLY)); inputs->push_back(game_logic::formula_input("abilities", FORMULA_READ_ONLY)); + inputs->push_back(game_logic::formula_input("traits", FORMULA_READ_ONLY)); inputs->push_back(game_logic::formula_input("attacks", FORMULA_READ_ONLY)); inputs->push_back(game_logic::formula_input("hitpoints", FORMULA_READ_ONLY)); inputs->push_back(game_logic::formula_input("experience", FORMULA_READ_ONLY)); @@ -432,6 +446,7 @@ void unit_type_callable::get_inputs(std::vector* inpu inputs->push_back(game_logic::formula_input("total_movement", FORMULA_READ_ONLY)); inputs->push_back(game_logic::formula_input("undead", FORMULA_READ_ONLY)); inputs->push_back(game_logic::formula_input("cost", FORMULA_READ_ONLY)); + inputs->push_back(game_logic::formula_input("recall_cost", FORMULA_READ_ONLY)); inputs->push_back(game_logic::formula_input("usage", FORMULA_READ_ONLY)); } diff --git a/src/scripting/game_lua_kernel.cpp b/src/scripting/game_lua_kernel.cpp index 83c6ac9558b9..861de7a573cf 100644 --- a/src/scripting/game_lua_kernel.cpp +++ b/src/scripting/game_lua_kernel.cpp @@ -518,8 +518,8 @@ static int impl_unit_variables_get(lua_State *L) return luaW_pushvariable(L, v) ? 1 : 0; } /** - * Gets the attacks of a unit (__index metamethod). - * - Arg 1: table containing the userdata containing the unit id. + * 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. */ @@ -530,11 +530,12 @@ static int impl_unit_attacks_get(lua_State *L) } lua_rawgeti(L, 1, -1); const unit* u = luaW_tounit(L, -1); - if (!u) { + const unit_type* ut = static_cast(luaL_testudata(L, -1, "unit type")); + if (!u && !ut) { return luaL_argerror(L, 1, "unknown unit"); } const attack_type* attack = NULL; - const std::vector& attacks = u->attacks(); + const std::vector& attacks = u ? u->attacks() : ut->attacks(); if(!lua_isnumber(L,2)) { std::string attack_id = luaL_checkstring(L, 2); BOOST_FOREACH(const attack_type& at, attacks) { diff --git a/src/scripting/lua_unit_type.cpp b/src/scripting/lua_unit_type.cpp index 2ee9d8b6ddb9..478db31e07eb 100644 --- a/src/scripting/lua_unit_type.cpp +++ b/src/scripting/lua_unit_type.cpp @@ -15,6 +15,7 @@ #include "scripting/lua_unit_type.hpp" #include "scripting/lua_common.hpp" +#include "scripting/push_check.hpp" #include "units/types.hpp" #include @@ -47,6 +48,9 @@ static int impl_unit_type_get(lua_State *L) // 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()); @@ -64,6 +68,20 @@ static int impl_unit_type_get(lua_State *L) } return 1; } + if (strcmp(m, "abilities") == 0) { + lua_push(L, ut.get_ability_list()); + return 1; + } + if (strcmp(m, "attacks") == 0) { + lua_createtable(L, 1, 0); + lua_pushvalue(L, 1); + // hack: store the unit_type at -1 because we want positive indices to refer to the attacks. + lua_rawseti(L, -2, -1); + lua_pushlightuserdata(L, uattacksKey); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_setmetatable(L, -2); + return 1; + } return 0; }