diff --git a/changelog b/changelog index d159c172cf2..13fc68a4358 100644 --- a/changelog +++ b/changelog @@ -15,6 +15,7 @@ Version 1.13.7+dev: * Small change to animator API - facing parameter replaced with target and required to be a space adjacent to the unit. * New modifiable theme attribute in wesnoth.game_config + * New wesnoth.zoom() function allows changing the zoom level * Multiplayer: * Fixed statistics being lost when reloading an MP game. * Performance: @@ -40,6 +41,7 @@ Version 1.13.7+dev: the color as a list of its components, eg "([r, g, b, a])" * Empty tags are no longer written to the configs of [unit]s and [side]s. * New [change_theme] tag to change the theme mid-scenario + * New [zoom] tag allows changing the zoom level from an event Version 1.13.7: * AI: diff --git a/data/lua/wml-tags.lua b/data/lua/wml-tags.lua index d4df4f95b05..3e858995abd 100644 --- a/data/lua/wml-tags.lua +++ b/data/lua/wml-tags.lua @@ -1417,6 +1417,10 @@ function wesnoth.wml_actions.change_theme(cfg) wesnoth.game_config.theme = cfg.theme end +function wesnoth.wml_actions.zoom(cfg) + wesnoth.zoom(cfg.factor, cfg.relative) +end + function wesnoth.wml_conditionals.proceed_to_next_scenario(cfg) local endlevel_data = wesnoth.get_end_level_data() if not endlevel_data then diff --git a/src/display.cpp b/src/display.cpp index 9642d861fa4..69a515e6a9c 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -2006,7 +2006,7 @@ bool display::set_zoom(bool increase) bool display::set_zoom(unsigned int amount, const bool validate_value_and_set_index) { - const unsigned int new_zoom = utils::clamp(amount, MinZoom, MaxZoom); + unsigned int new_zoom = utils::clamp(amount, MinZoom, MaxZoom); LOG_DP << "new_zoom = " << new_zoom << std::endl; @@ -2016,13 +2016,22 @@ bool display::set_zoom(unsigned int amount, const bool validate_value_and_set_in // Confirm this is indeed a valid zoom level. if(validate_value_and_set_index) { - auto iter = std::find(zoom_levels.begin(), zoom_levels.end(), new_zoom); + auto iter = std::lower_bound(zoom_levels.begin(), zoom_levels.end(), new_zoom); - // TODO: do we need an error? if(iter == zoom_levels.end()) { + // This should never happen, since the value was already clamped earlier return false; + } else if(iter != zoom_levels.begin()) { + float diff = *iter - *(iter - 1); + float lower = (new_zoom - *(iter - 1)) / diff; + float upper = (*iter - new_zoom) / diff; + if(lower < upper) { + // It's actually closer to the previous element. + iter--; + } } + new_zoom = *iter; zoom_index_ = iter - zoom_levels.begin(); } diff --git a/src/scripting/game_lua_kernel.cpp b/src/scripting/game_lua_kernel.cpp index 9073166e596..2fab49e0c1e 100644 --- a/src/scripting/game_lua_kernel.cpp +++ b/src/scripting/game_lua_kernel.cpp @@ -1394,6 +1394,23 @@ int game_lua_kernel::intf_open_help(lua_State *L) return 0; } +int game_lua_kernel::intf_zoom(lua_State* L) +{ + if(!game_display_) { + return 0; + } + double factor = luaL_checknumber(L, 1); + bool relative = luaW_toboolean(L, 2); + if(relative) { + factor *= game_display_->get_zoom_factor(); + } + // Passing true explicitly to avoid casting to int. + // Without doing one of the two, the call is ambiguous. + game_display_->set_zoom(factor * game_config::tile_size, true); + lua_pushnumber(L, game_display_->get_zoom_factor()); + return 1; +} + /** * Dumps a wml table or userdata wml object into a pretty string. * - Arg 1: wml table or vconfig userdata @@ -4181,6 +4198,7 @@ game_lua_kernel::game_lua_kernel(game_state & gs, play_controller & pc, reports { "switch_ai", &intf_switch_ai }, { "synchronize_choice", &intf_synchronize_choice }, { "synchronize_choices", &intf_synchronize_choices }, + { "zoom", &dispatch<&game_lua_kernel::intf_zoom > }, { "teleport", &dispatch<&game_lua_kernel::intf_teleport > }, { "unit_ability", &dispatch<&game_lua_kernel::intf_unit_ability > }, { "view_locked", &dispatch<&game_lua_kernel::intf_view_locked > }, diff --git a/src/scripting/game_lua_kernel.hpp b/src/scripting/game_lua_kernel.hpp index 355e1d85241..568b9a6e9eb 100644 --- a/src/scripting/game_lua_kernel.hpp +++ b/src/scripting/game_lua_kernel.hpp @@ -172,6 +172,7 @@ class game_lua_kernel : public lua_kernel_base int intf_toggle_fog(lua_State *L, const bool clear); int intf_get_fog_or_shroud(lua_State *L, bool fog); int intf_log_replay(lua_State* L); + int intf_zoom(lua_State* L); //private helpers std::string synced_state();