diff --git a/data/lua/core/mathx.lua b/data/lua/core/mathx.lua index 958b4e4d4fe..980ecea61ec 100644 --- a/data/lua/core/mathx.lua +++ b/data/lua/core/mathx.lua @@ -112,6 +112,16 @@ function mathx.lerp(lo, hi, alpha) return lo + alpha * (hi - lo) end +---Choose an element from a list based on a ratio. +---@generic T +---@param list T[] +---@param alpha number +---@return T +function mathx.lerp_index(list, alpha) + if #list == 0 then return nil end + return list[mathx.round(mathx.lerp(1, #list, alpha))] +end + ---Clamp a number into a specified range ---@param val number ---@param lo number diff --git a/src/scripting/lua_kernel_base.cpp b/src/scripting/lua_kernel_base.cpp index 00bc36d2136..b65e082ce08 100644 --- a/src/scripting/lua_kernel_base.cpp +++ b/src/scripting/lua_kernel_base.cpp @@ -1229,6 +1229,30 @@ int lua_kernel_base::intf_kernel_type(lua_State* L) lua_push(L, my_name()); return 1; } +static void push_color_palette(lua_State* L, const std::vector& palette) { + lua_createtable(L, palette.size(), 1); + lua_rotate(L, -2, 1); // swap new table with previous element on stack + lua_setfield(L, -2, "name"); + for(size_t i = 0; i < palette.size(); i++) { + luaW_push_namedtuple(L, {"r", "g", "b", "a"}); + lua_pushinteger(L, palette[i].r); + lua_rawseti(L, -2, 1); + lua_pushinteger(L, palette[i].g); + lua_rawseti(L, -2, 2); + lua_pushinteger(L, palette[i].b); + lua_rawseti(L, -2, 3); + lua_pushinteger(L, palette[i].a); + lua_rawseti(L, -2, 4); + lua_rawseti(L, -2, i); + } +} +static int impl_palette_get(lua_State* L) +{ + char const *m = luaL_checkstring(L, 2); + lua_pushvalue(L, 2); + push_color_palette(L, game_config::tc_info(m)); + return 1; +} int lua_kernel_base::impl_game_config_get(lua_State* L) { char const *m = luaL_checkstring(L, 2); @@ -1245,6 +1269,36 @@ int lua_kernel_base::impl_game_config_get(lua_State* L) 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; } int lua_kernel_base::impl_game_config_set(lua_State* L) diff --git a/utils/emmylua/wesnoth.lua b/utils/emmylua/wesnoth.lua index c86c35ba8fd..cc79d08aeed 100644 --- a/utils/emmylua/wesnoth.lua +++ b/utils/emmylua/wesnoth.lua @@ -197,6 +197,9 @@ wesnoth.colors = {} ---@field event_context event_context wesnoth.current = {} +---@class color_palette : color[] +---@field name string + ---Holds global game configuration options ---@class game_config ---@field base_income integer @@ -214,6 +217,11 @@ wesnoth.current = {} ---@field debug_lua boolean ---@field mp_debug boolean ---@field strict_lua boolean +---@field red_green_scale color_palette +---@field red_green_scale_text color_palette +---@field blue_white_scale color_palette +---@field blue_white_scale_text color_palette +---@field palettes table wesnoth.game_config = {} ---@type table