diff --git a/src/formula/callable_objects.cpp b/src/formula/callable_objects.cpp index 9c9481bff62..95372b3cd35 100644 --- a/src/formula/callable_objects.cpp +++ b/src/formula/callable_objects.cpp @@ -1010,4 +1010,27 @@ variant event_callable::get_value(const std::string &key) const return variant(); } +void color_callable::get_inputs(formula_input_vector& inputs) const +{ + add_input(inputs, "red"); + add_input(inputs, "green"); + add_input(inputs, "blue"); + add_input(inputs, "alpha"); +} + +variant color_callable::get_value(const std::string& key) const +{ + if(key == "red") { + return variant(clr_.r); + } else if(key == "green") { + return variant(clr_.g); + } else if(key == "blue") { + return variant(clr_.b); + } else if(key == "alpha") { + return variant(clr_.a); + } + + return variant(); +} + } // namespace wfl diff --git a/src/formula/callable_objects.hpp b/src/formula/callable_objects.hpp index 8a74a1bfb78..cbec5ee0530 100644 --- a/src/formula/callable_objects.hpp +++ b/src/formula/callable_objects.hpp @@ -15,6 +15,7 @@ #pragma once +#include "color.hpp" #include "formula/callable.hpp" #include "formula/formula.hpp" #include "map/location.hpp" @@ -193,6 +194,25 @@ private: const team& team_; }; + +class color_callable : public formula_callable +{ +public: + color_callable(color_t clr) + : clr_(clr) + {} + + void get_inputs(formula_input_vector& inputs) const override; + variant get_value(const std::string& key) const override; + + const color_t get_color() const { return clr_; } + +private: + color_t clr_; +}; + + + class set_var_callable : public action_callable { public: diff --git a/src/formula/function.cpp b/src/formula/function.cpp index 9df049033c8..878c18ae3fd 100644 --- a/src/formula/function.cpp +++ b/src/formula/function.cpp @@ -725,6 +725,40 @@ DEFINE_WFL_FUNCTION(lerp, 3, 3) return variant(static_cast((lo + alpha * (hi - lo)) * 1000.0), variant::DECIMAL_VARIANT); } +DEFINE_WFL_FUNCTION(lerp_index, 2, 2) +{ + const std::vector items = args()[0]->evaluate(variables, fdb).as_list(); + if(items.empty()) return variant(); + const double alpha = args()[1]->evaluate(variables, fdb).as_decimal() / 1000.0; + // Same formula as red_to_green etc + const double val_scaled = std::clamp(0.01 * alpha, 0.0, 1.0); + const int idx = int(std::nearbyint((items.size() - 1) * val_scaled)); + return items[idx]; +} + +DEFINE_WFL_FUNCTION(get_palette, 1, 1) +{ + const std::string name = args()[0]->evaluate(variables, fdb).as_string(); + std::vector colors; + if(name == "red_green_scale") { + colors = game_config::red_green_scale; + } else if(name == "red_green_scale_text") { + colors = game_config::red_green_scale_text; + } else if(name == "blue_white_scale") { + colors = game_config::blue_white_scale; + } else if(name == "blue_white_scale_text") { + colors = game_config::blue_white_scale_text; + } else { + colors = game_config::tc_info(name); + } + std::vector result; + result.reserve(colors.size()); + for(auto clr : colors) { + result.emplace_back(std::make_shared(clr)); + } + return variant(result); +} + DEFINE_WFL_FUNCTION(clamp, 3, 3) { const variant val = args()[0]->evaluate(variables, add_debug_info(fdb, 0, "clamp:value")); @@ -1623,7 +1657,9 @@ std::shared_ptr function_symbol_table::get_builtins() DECLARE_WFL_FUNCTION(hypot); DECLARE_WFL_FUNCTION(type); DECLARE_WFL_FUNCTION(lerp); + DECLARE_WFL_FUNCTION(lerp_index); DECLARE_WFL_FUNCTION(clamp); + DECLARE_WFL_FUNCTION(get_palette); } return std::shared_ptr(&functions_table, [](function_symbol_table*) {}); diff --git a/src/game_config.cpp b/src/game_config.cpp index 7e84955d10a..db8b2f09f30 100644 --- a/src/game_config.cpp +++ b/src/game_config.cpp @@ -138,8 +138,8 @@ std::string flag_rgb, unit_rgb; std::vector red_green_scale; std::vector red_green_scale_text; -static std::vector blue_white_scale; -static std::vector blue_white_scale_text; +std::vector blue_white_scale; +std::vector blue_white_scale_text; std::map> team_rgb_range; // Map [color_range]id to [color_range]name, or "" if no name diff --git a/src/game_config.hpp b/src/game_config.hpp index 3f730d82593..b3aebf27fea 100644 --- a/src/game_config.hpp +++ b/src/game_config.hpp @@ -148,6 +148,8 @@ namespace game_config extern std::string flag_rgb, unit_rgb; extern std::vector red_green_scale; extern std::vector red_green_scale_text; + extern std::vector blue_white_scale; + extern std::vector blue_white_scale_text; extern std::vector foot_speed_prefix; extern std::string foot_teleport_enter, foot_teleport_exit; diff --git a/src/image_modifications.cpp b/src/image_modifications.cpp index b648d12ebc6..b27fcbc1585 100644 --- a/src/image_modifications.cpp +++ b/src/image_modifications.cpp @@ -26,7 +26,7 @@ #include "utils/from_chars.hpp" #include "formula/formula.hpp" -#include "formula/callable.hpp" +#include "formula/callable_objects.hpp" #define GETTEXT_DOMAIN "wesnoth-lib" @@ -238,23 +238,20 @@ void wipe_alpha_modification::operator()(surface& src) const } // TODO: Is this useful enough to move into formula/callable_objects? -class pixel_callable : public wfl::formula_callable +class pixel_callable : public wfl::color_callable { public: pixel_callable(SDL_Point p, color_t clr, uint32_t w, uint32_t h) - : p(p), clr(clr), w(w), h(h) + : color_callable(clr), p(p), w(w), h(h) {} void get_inputs(wfl::formula_input_vector& inputs) const override { + color_callable::get_inputs(inputs); add_input(inputs, "x"); add_input(inputs, "y"); add_input(inputs, "u"); add_input(inputs, "v"); - add_input(inputs, "red"); - add_input(inputs, "green"); - add_input(inputs, "blue"); - add_input(inputs, "alpha"); add_input(inputs, "height"); add_input(inputs, "width"); } @@ -266,14 +263,6 @@ public: return variant(p.x); } else if(key == "y") { return variant(p.y); - } else if(key == "red") { - return variant(clr.r); - } else if(key == "green") { - return variant(clr.g); - } else if(key == "blue") { - return variant(clr.b); - } else if(key == "alpha") { - return variant(clr.a); } else if(key == "width") { return variant(w); } else if(key == "height") { @@ -284,12 +273,11 @@ public: return variant(p.y / static_cast(h)); } - return variant(); + return color_callable::get_value(key); } private: SDL_Point p; - color_t clr; uint32_t w, h; };