WFL: Add lerp_index and get_palette functions

The latter exposes access to the [color_palette] tags in game_config, as well as the colour scales.
This commit is contained in:
Celtic Minstrel 2024-09-08 00:21:24 -04:00 committed by Celtic Minstrel
parent fc86cb0b93
commit 752f251a93
6 changed files with 88 additions and 19 deletions

View File

@ -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

View File

@ -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:

View File

@ -725,6 +725,40 @@ DEFINE_WFL_FUNCTION(lerp, 3, 3)
return variant(static_cast<int>((lo + alpha * (hi - lo)) * 1000.0), variant::DECIMAL_VARIANT);
}
DEFINE_WFL_FUNCTION(lerp_index, 2, 2)
{
const std::vector<variant> 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<color_t> 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<variant> result;
result.reserve(colors.size());
for(auto clr : colors) {
result.emplace_back(std::make_shared<color_callable>(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> 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<function_symbol_table>(&functions_table, [](function_symbol_table*) {});

View File

@ -138,8 +138,8 @@ std::string flag_rgb, unit_rgb;
std::vector<color_t> red_green_scale;
std::vector<color_t> red_green_scale_text;
static std::vector<color_t> blue_white_scale;
static std::vector<color_t> blue_white_scale_text;
std::vector<color_t> blue_white_scale;
std::vector<color_t> blue_white_scale_text;
std::map<std::string, color_range, std::less<>> team_rgb_range;
// Map [color_range]id to [color_range]name, or "" if no name

View File

@ -148,6 +148,8 @@ namespace game_config
extern std::string flag_rgb, unit_rgb;
extern std::vector<color_t> red_green_scale;
extern std::vector<color_t> red_green_scale_text;
extern std::vector<color_t> blue_white_scale;
extern std::vector<color_t> blue_white_scale_text;
extern std::vector<std::string> foot_speed_prefix;
extern std::string foot_teleport_enter, foot_teleport_exit;

View File

@ -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<float>(h));
}
return variant();
return color_callable::get_value(key);
}
private:
SDL_Point p;
color_t clr;
uint32_t w, h;
};