Lua API: Add __dir metamethod for wesnoth.game_config
This commit is contained in:
parent
03924aac1d
commit
6f0567df8f
4 changed files with 166 additions and 105 deletions
|
@ -1322,65 +1322,63 @@ static int intf_get_era(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets some game_config data (__index metamethod).
|
||||
* - Arg 1: userdata (ignored).
|
||||
* - Arg 2: string containing the name of the property.
|
||||
* - Ret 1: something containing the attribute.
|
||||
*/
|
||||
int game_lua_kernel::impl_game_config_get(lua_State *L)
|
||||
{
|
||||
DBG_LUA << "impl_game_config_get";
|
||||
char const *m = luaL_checkstring(L, 2);
|
||||
extern luaW_Registry& gameConfigReg();
|
||||
static auto& dummy = gameConfigReg(); // just to ensure it's constructed.
|
||||
|
||||
// Find the corresponding attribute.
|
||||
return_bool_attrib("do_healing", play_controller_.gamestate().do_healing_);
|
||||
return_string_attrib("theme", gamedata().get_theme());
|
||||
struct game_config_glk_tag {
|
||||
game_lua_kernel& ref;
|
||||
game_config_glk_tag(lua_kernel_base& k) : ref(dynamic_cast<game_lua_kernel&>(k)) {}
|
||||
auto& pc() const { return ref.play_controller_; }
|
||||
auto& gamedata() const { return ref.gamedata(); }
|
||||
auto& disp() const { return ref.game_display_; }
|
||||
};
|
||||
#define GAME_CONFIG_SIMPLE_SETTER(name) \
|
||||
GAME_CONFIG_SETTER(#name, decltype(game_config::name), game_lua_kernel) { \
|
||||
(void) k; \
|
||||
game_config::name = value; \
|
||||
}
|
||||
|
||||
if(strcmp(m, "global_traits") == 0) {
|
||||
lua_newtable(L);
|
||||
for(const config& trait : unit_types.traits()) {
|
||||
const std::string& id = trait["id"];
|
||||
//It seems the engine never checks the id field for emptiness or duplicates
|
||||
//However, the worst that could happen is that the trait read later overwrites the older one,
|
||||
//and this is not the right place for such checks.
|
||||
lua_pushstring(L, id.c_str());
|
||||
luaW_pushconfig(L, trait);
|
||||
lua_rawset(L, -3);
|
||||
}
|
||||
return 1;
|
||||
GAME_CONFIG_GETTER("do_healing", bool, game_lua_kernel) {
|
||||
game_config_glk_tag k2{k.ref};
|
||||
return k2.pc().gamestate().do_healing_;
|
||||
}
|
||||
|
||||
GAME_CONFIG_SETTER("do_healing", bool, game_lua_kernel) {
|
||||
game_config_glk_tag k2{k.ref};
|
||||
k2.pc().gamestate().do_healing_ = value;}
|
||||
|
||||
GAME_CONFIG_GETTER("theme", std::string, game_lua_kernel) {
|
||||
game_config_glk_tag k2{k.ref};
|
||||
return k2.gamedata().get_theme();
|
||||
}
|
||||
|
||||
GAME_CONFIG_SETTER("theme", std::string, game_lua_kernel) {
|
||||
game_config_glk_tag k2{k.ref};
|
||||
k2.gamedata().set_theme(value);
|
||||
k2.disp()->set_theme(value);
|
||||
}
|
||||
|
||||
using traits_map = std::map<std::string, config>;
|
||||
GAME_CONFIG_GETTER("global_traits", traits_map, game_lua_kernel) {
|
||||
(void)k;
|
||||
std::map<std::string, config> result;
|
||||
for(const config& trait : unit_types.traits()) {
|
||||
//It seems the engine never checks the id field for emptiness or duplicates
|
||||
//However, the worst that could happen is that the trait read later overwrites the older one,
|
||||
//and this is not the right place for such checks.
|
||||
result.emplace(trait["id"], trait);
|
||||
}
|
||||
|
||||
return lua_kernel_base::impl_game_config_get(L);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets some game_config data (__newindex metamethod).
|
||||
* - Arg 1: userdata (ignored).
|
||||
* - Arg 2: string containing the name of the property.
|
||||
* - Arg 3: something containing the attribute.
|
||||
*/
|
||||
int game_lua_kernel::impl_game_config_set(lua_State *L)
|
||||
{
|
||||
DBG_LUA << "impl_game_config_set";
|
||||
char const *m = luaL_checkstring(L, 2);
|
||||
|
||||
// Find the corresponding attribute.
|
||||
modify_int_attrib("base_income", game_config::base_income = value);
|
||||
modify_int_attrib("village_income", game_config::village_income = value);
|
||||
modify_int_attrib("village_support", game_config::village_support = value);
|
||||
modify_int_attrib("poison_amount", game_config::poison_amount = value);
|
||||
modify_int_attrib("rest_heal_amount", game_config::rest_heal_amount = value);
|
||||
modify_int_attrib("recall_cost", game_config::recall_cost = value);
|
||||
modify_int_attrib("kill_experience", game_config::kill_experience = value);
|
||||
modify_int_attrib("combat_experience", game_config::combat_experience = value);
|
||||
modify_bool_attrib("do_healing", play_controller_.gamestate().do_healing_ = value);
|
||||
modify_string_attrib("theme",
|
||||
gamedata().set_theme(value);
|
||||
game_display_->set_theme(value);
|
||||
);
|
||||
return lua_kernel_base::impl_game_config_set(L);
|
||||
}
|
||||
GAME_CONFIG_SIMPLE_SETTER(base_income);
|
||||
GAME_CONFIG_SIMPLE_SETTER(village_income);
|
||||
GAME_CONFIG_SIMPLE_SETTER(village_support);
|
||||
GAME_CONFIG_SIMPLE_SETTER(poison_amount);
|
||||
GAME_CONFIG_SIMPLE_SETTER(rest_heal_amount);
|
||||
GAME_CONFIG_SIMPLE_SETTER(recall_cost);
|
||||
GAME_CONFIG_SIMPLE_SETTER(kill_experience);
|
||||
GAME_CONFIG_SIMPLE_SETTER(combat_experience);
|
||||
|
||||
namespace {
|
||||
static config find_addon(const std::string& type, const std::string& id)
|
||||
|
|
|
@ -71,6 +71,7 @@ class game_lua_kernel : public lua_kernel_base
|
|||
friend struct current_tag;
|
||||
friend struct scenario_tag;
|
||||
friend struct schedule_tag;
|
||||
friend struct game_config_glk_tag;
|
||||
|
||||
// Private lua callbacks
|
||||
int intf_allow_end_turn(lua_State *);
|
||||
|
@ -105,8 +106,6 @@ class game_lua_kernel : public lua_kernel_base
|
|||
int intf_set_village_owner(lua_State *L);
|
||||
int intf_get_mouseover_tile(lua_State *L);
|
||||
int intf_get_selected_tile(lua_State *L);
|
||||
int impl_game_config_get(lua_State *L) override;
|
||||
int impl_game_config_set(lua_State *L) override;
|
||||
int impl_scenario_get(lua_State *L);
|
||||
int impl_scenario_set(lua_State *L);
|
||||
int impl_scenario_dir(lua_State *L);
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "scripting/debug_lua.hpp"
|
||||
#endif
|
||||
|
||||
#include "scripting/lua_attributes.hpp"
|
||||
#include "scripting/lua_color.hpp"
|
||||
#include "scripting/lua_common.hpp"
|
||||
#include "scripting/lua_cpp_function.hpp"
|
||||
|
@ -908,6 +909,8 @@ lua_kernel_base::lua_kernel_base()
|
|||
lua_setfield(L, -2, "__index");
|
||||
lua_pushcfunction(L, &dispatch<&lua_kernel_base::impl_game_config_set>);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pushcfunction(L, &dispatch<&lua_kernel_base::impl_game_config_dir>);
|
||||
lua_setfield(L, -2, "__dir");
|
||||
lua_pushstring(L, "game config");
|
||||
lua_setfield(L, -2, "__metatable");
|
||||
lua_setmetatable(L, -2);
|
||||
|
@ -1253,58 +1256,99 @@ static int impl_palette_get(lua_State* L)
|
|||
push_color_palette(L, game_config::tc_info(m));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// suppress missing prototype warning (not static because game_lua_kernel referenes it);
|
||||
luaW_Registry& gameConfigReg();
|
||||
luaW_Registry& gameConfigReg() {
|
||||
static luaW_Registry gameConfigReg{"game config"};
|
||||
return gameConfigReg;
|
||||
}
|
||||
static auto& dummy = gameConfigReg(); // just to ensure it's constructed.
|
||||
|
||||
#define GAME_CONFIG_SIMPLE_GETTER(name) \
|
||||
GAME_CONFIG_GETTER(#name, decltype(game_config::name), lua_kernel_base) { \
|
||||
(void) k; \
|
||||
return game_config::name; \
|
||||
}
|
||||
|
||||
GAME_CONFIG_SIMPLE_GETTER(base_income);
|
||||
GAME_CONFIG_SIMPLE_GETTER(village_income);
|
||||
GAME_CONFIG_SIMPLE_GETTER(village_support);
|
||||
GAME_CONFIG_SIMPLE_GETTER(poison_amount);
|
||||
GAME_CONFIG_SIMPLE_GETTER(rest_heal_amount);
|
||||
GAME_CONFIG_SIMPLE_GETTER(recall_cost);
|
||||
GAME_CONFIG_SIMPLE_GETTER(kill_experience);
|
||||
GAME_CONFIG_SIMPLE_GETTER(combat_experience);
|
||||
GAME_CONFIG_SIMPLE_GETTER(debug);
|
||||
GAME_CONFIG_SIMPLE_GETTER(debug_lua);
|
||||
GAME_CONFIG_SIMPLE_GETTER(strict_lua);
|
||||
GAME_CONFIG_SIMPLE_GETTER(mp_debug);
|
||||
|
||||
GAME_CONFIG_GETTER("palettes", lua_index_raw, lua_kernel_base) {
|
||||
(void)k;
|
||||
lua_newtable(L);
|
||||
if(luaL_newmetatable(L, "color palettes")) {
|
||||
lua_pushcfunction(L, impl_palette_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
return lua_index_raw(L);
|
||||
}
|
||||
|
||||
GAME_CONFIG_GETTER("red_green_scale", lua_index_raw, lua_kernel_base) {
|
||||
(void)k;
|
||||
lua_pushstring(L, "red_green_scale");
|
||||
push_color_palette(L, game_config::red_green_scale);
|
||||
return lua_index_raw(L);
|
||||
}
|
||||
|
||||
GAME_CONFIG_GETTER("red_green_scale_text", lua_index_raw, lua_kernel_base) {
|
||||
(void)k;
|
||||
lua_pushstring(L, "red_green_scale_text");
|
||||
push_color_palette(L, game_config::red_green_scale_text);
|
||||
return lua_index_raw(L);
|
||||
}
|
||||
|
||||
GAME_CONFIG_GETTER("blue_white_scale", lua_index_raw, lua_kernel_base) {
|
||||
(void)k;
|
||||
lua_pushstring(L, "blue_white_scale");
|
||||
push_color_palette(L, game_config::blue_white_scale);
|
||||
return lua_index_raw(L);
|
||||
}
|
||||
|
||||
GAME_CONFIG_GETTER("blue_white_scale_text", lua_index_raw, lua_kernel_base) {
|
||||
(void)k;
|
||||
lua_pushstring(L, "blue_white_scale_text");
|
||||
push_color_palette(L, game_config::blue_white_scale_text);
|
||||
return lua_index_raw(L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets some game_config data (__index metamethod).
|
||||
* - Arg 1: userdata (ignored).
|
||||
* - Arg 2: string containing the name of the property.
|
||||
* - Ret 1: something containing the attribute.
|
||||
*/
|
||||
int lua_kernel_base::impl_game_config_get(lua_State* L)
|
||||
{
|
||||
char const *m = luaL_checkstring(L, 2);
|
||||
return_int_attrib("base_income", game_config::base_income);
|
||||
return_int_attrib("village_income", game_config::village_income);
|
||||
return_int_attrib("village_support", game_config::village_support);
|
||||
return_int_attrib("poison_amount", game_config::poison_amount);
|
||||
return_int_attrib("rest_heal_amount", game_config::rest_heal_amount);
|
||||
return_int_attrib("recall_cost", game_config::recall_cost);
|
||||
return_int_attrib("kill_experience", game_config::kill_experience);
|
||||
return_int_attrib("combat_experience", game_config::combat_experience);
|
||||
return_bool_attrib("debug", game_config::debug);
|
||||
return_bool_attrib("debug_lua", game_config::debug_lua);
|
||||
return_bool_attrib("strict_lua", game_config::strict_lua);
|
||||
return_bool_attrib("mp_debug", game_config::mp_debug);
|
||||
|
||||
if(strcmp(m, "palettes") == 0) {
|
||||
lua_newtable(L);
|
||||
if(luaL_newmetatable(L, "color palettes")) {
|
||||
lua_pushcfunction(L, impl_palette_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
if(strcmp(m, "red_green_scale") == 0) {
|
||||
lua_pushstring(L, "red_green_scale");
|
||||
push_color_palette(L, game_config::red_green_scale);
|
||||
return 1;
|
||||
}
|
||||
if(strcmp(m, "red_green_scale_text") == 0) {
|
||||
lua_pushstring(L, "red_green_scale_text");
|
||||
push_color_palette(L, game_config::red_green_scale_text);
|
||||
return 1;
|
||||
}
|
||||
if(strcmp(m, "blue_white_scale") == 0) {
|
||||
lua_pushstring(L, "blue_white_scale");
|
||||
push_color_palette(L, game_config::blue_white_scale);
|
||||
return 1;
|
||||
}
|
||||
if(strcmp(m, "blue_white_scale_text") == 0) {
|
||||
lua_pushstring(L, "blue_white_scale_text");
|
||||
push_color_palette(L, game_config::blue_white_scale_text);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return gameConfigReg().get(L);
|
||||
}
|
||||
/**
|
||||
* Sets some game_config data (__newindex metamethod).
|
||||
* - Arg 1: userdata (ignored).
|
||||
* - Arg 2: string containing the name of the property.
|
||||
* - Arg 3: something containing the attribute.
|
||||
*/
|
||||
int lua_kernel_base::impl_game_config_set(lua_State* L)
|
||||
{
|
||||
std::string err_msg = "unknown modifiable property of game_config: ";
|
||||
err_msg += luaL_checkstring(L, 2);
|
||||
return luaL_argerror(L, 2, err_msg.c_str());
|
||||
return gameConfigReg().set(L);
|
||||
}
|
||||
/**
|
||||
* Gets a list of game_config data (__dir metamethod).
|
||||
*/
|
||||
int lua_kernel_base::impl_game_config_dir(lua_State* L)
|
||||
{
|
||||
return gameConfigReg().dir(L);
|
||||
}
|
||||
/**
|
||||
* Loads the "package" package into the Lua environment.
|
||||
|
|
|
@ -138,11 +138,31 @@ protected:
|
|||
|
||||
int intf_kernel_type(lua_State* L);
|
||||
|
||||
virtual int impl_game_config_get(lua_State* L);
|
||||
virtual int impl_game_config_set(lua_State* L);
|
||||
int impl_game_config_get(lua_State* L);
|
||||
int impl_game_config_set(lua_State* L);
|
||||
int impl_game_config_dir(lua_State* L);
|
||||
private:
|
||||
static lua_kernel_base*& get_lua_kernel_base_ptr(lua_State *L);
|
||||
std::vector<std::tuple<std::string, std::string>> registered_widget_definitions_;
|
||||
};
|
||||
|
||||
std::vector<std::string> luaW_get_attributes(lua_State* L, int idx);
|
||||
|
||||
struct game_config_tag {
|
||||
lua_kernel_base& ref;
|
||||
game_config_tag(lua_kernel_base& k) : ref(k) {}
|
||||
};
|
||||
#define GAME_CONFIG_GETTER(name, type, kernel_type) \
|
||||
LATTR_VALID(name, game_config_tag, k) { return dynamic_cast<kernel_type*>(&k.ref) != nullptr; } \
|
||||
LATTR_GETTER(name, type, game_config_tag, k)
|
||||
#define GAME_CONFIG_SETTER(name, type, kernel_type) \
|
||||
LATTR_VALID(name, game_config_tag, k) { return dynamic_cast<kernel_type*>(&k.ref) != nullptr; } \
|
||||
LATTR_SETTER(name, type, game_config_tag, k)
|
||||
|
||||
template<typename T> struct lua_object_traits;
|
||||
template<> struct lua_object_traits<game_config_tag> {
|
||||
inline static auto metatable = "game config";
|
||||
inline static game_config_tag get(lua_State* L, int) {
|
||||
return lua_kernel_base::get_lua_kernel<lua_kernel_base>(L);
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue