Skip to content

Commit

Permalink
Apply appgurueu's suggestions (part 3)
Browse files Browse the repository at this point in the history
new, simplified API for wear bar coloring
  • Loading branch information
techno-sam committed Jan 24, 2024
1 parent 8eff690 commit 4d4465d
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 191 deletions.
83 changes: 23 additions & 60 deletions doc/lua_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2400,62 +2400,31 @@ Wear bar colors definition

### Syntax

For non-blending mode:
```lua
{
{
color = "#ff00ff",
min_durability = 0.2, -- inclusive
max_durability = 0.3 -- exclusive
},
{
color = "#c0ffee",
min_durability = 0.45,
max_durability = 0.6
},
-- color to use if no other ranges match the durability
default = "#ffff00",
blend = false
}
```

For blending mode:
```lua
{
-- specify color for a specific durability percent, and blend between them
[0.2] = "#ff00ff",
[0.45] = "#c0ffee",
-- used for 0% and 100% durability if no color explicitly specified
default = "#ffff00",
blend = true
-- 'constant' or 'linear'
-- (nil defaults to 'constant')
blend = "linear",
color_stops = {
[0.0] = "#ff0000",
[0.5] = "slateblue",
[1.0] = {r=0, g=255, b=0, a=150},
}
}
```

### Blend mode `blend`

* If true, it blends smoothly between each defined color point.
* If false, no interpolation is used and instead colors are defined for ranges of durabilities.
`blend` is optional and defaults false.

### Default color `default`

* If `blend` is false, the color to use if the percentage of remaining durability does not match any values.
* If `blend` is true, the color to use on the outside of the range of colors if no such color is defined.
* `linear`: blends smoothly between each defined color point.
* `constant`: each color starts at its defined point, and continues up to to the next point

### Color values
### Color stops `color_stops`

In blending mode, specified as `float` keys assigned to a `ColorString` values.

In non-blending mode, specified as tables containing the following keys:
* `min_durability`: `float`, minimum durability to show color at (inclusive)
* `max_durability`: `float`, maximum durability to show color at (exclusive)
* `color`: `ColorString`, color to use for bar in the specified range
Specified as `float` keys assigned to `ColorSpec` values.

### Shortcut usage

Wear bar color can also be specified as a single `ColorString` instead of a table.
In this case, it is automatically converted to a table, where there are no color points,
`blend` is false, and `default` is the specified `ColorString`.
Wear bar color can also be specified as a single `ColorSpec` instead of a table.



Expand Down Expand Up @@ -8852,23 +8821,17 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
-- fallback behavior.
},

-- Set wear bar color of the tool by setting color points or ranges
-- See "Wear Bar Color" section for further explanation including example
-- Set wear bar color of the tool by setting color stops and blend mode
-- See "Wear Bar Color" section for further explanation including an example
wear_color = {
{
color = "#ff00ff",
min_durability = 0.2,
max_durability = 0.3
},
{
color = "#c0ffee",
min_durability = 0.45,
max_durability = 0.6
},
default = "#ffff00",
-- default color for fallback
blend = false
-- whether to blend the colors
-- interpolation mode: 'constant' or 'linear'
-- (nil defaults to 'constant')
blend = "linear",
color_stops = {
[0.0] = "#ff0000",
[0.5] = "#ffff00",
[1.0] = "#00ff00",
}
},

node_placement_prediction = nil,
Expand Down
29 changes: 16 additions & 13 deletions games/devtest/mods/basetools/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -423,20 +423,23 @@ minetest.register_tool("basetools:dagger_steel", {
-- Test tool uses, punch_attack_uses, and wear bar coloring
local uses = { 1, 2, 3, 5, 10, 50, 100, 1000, 10000, 65535 }
local wear_colors = { nil, nil, nil, "#5865f2", "slateblue",
{blend = true, default = "#ff00ff", [0.0] = "red", [0.5] = "yellow", [1.0] = "blue"},
{
{
color = "#ff00ff",
min_durability = 0.2, -- minimum durability is inclusive
max_durability = 0.3 -- maximum durability is exclusive
},
{
color = "#c0ffee",
min_durability = 0.45,
max_durability = 0.6
},
default = "#ffff00", -- color to use if no other ranges match the durability
blend = false
color_stops = {
[0] = "red",
[0.5] = "yellow",
[1.0] = "blue"
},
blend = "linear"
},
{
color_stops = {
[0] = "#ffff00",
[0.2] = "#ff00ff",
[0.3] = "#ffff00",
[0.45] = "#c0ffee",
[0.6] = {r=255, g=255, b=0, a=100}, -- continues until the end
},
blend = "constant"
}, nil, nil, nil }
local wear_color_desc = { nil, nil, nil, "Solid color: #5865f2", "Solid color: slateblue", "Ranges from blue to yellow to red", "Random blocks", nil, nil, nil }
for i=1, #uses do
Expand Down
90 changes: 37 additions & 53 deletions src/script/common/c_content.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ void read_item_definition(lua_State* L, int index,
def.wear_bar_params = std::optional(new WearBarParams(read_wear_bar_params(L, -1)));
} else if (lua_isstring(L, -1)) {
def.wear_bar_params = std::optional(new WearBarParams());
parseColorString(luaL_checkstring(L, -1), def.wear_bar_params.value()->defaultColor, false);
video::SColor color;
read_color(L, -1, &color);
def.wear_bar_params.value()->colorStops.emplace(0.0, color);
}

// If name is "" (hand), ensure there are ToolCapabilities
Expand Down Expand Up @@ -1425,35 +1427,15 @@ void push_wear_bar_params(lua_State *L,
const WearBarParams &params)
{
lua_newtable(L);
setstringfield(L, -1, "default", encodeHexColorString(params.defaultColor));
if (params.blend) {
// insert into table using minPercent as key, and the ColorString as the value
for (const WearBarParam &param : params.params) {
lua_pushnumber(L, param.minPercent); // key
lua_pushstring(L, encodeHexColorString(param.color).c_str()); // value
lua_rawset(L, -3);
//setstringfield(L, -1, std::to_string(param.minPercent).c_str(),
// encodeHexColorString(param.color));
}
} else {
// For each value
int i = 0;
for (const WearBarParam &param : params.params) {
i++;
lua_pushnumber(L, i); // key

// Create value table
lua_newtable(L);
// Set simple parameters
setfloatfield(L, -1, "min_durability", param.minPercent);
setfloatfield(L, -1, "max_durability", param.maxPercent);
setstringfield(L, -1, "color", encodeHexColorString(param.color));
setstringfield(L, -1, "blend", es_BlendMode[params.blend].str);

// Insert value table
lua_rawset(L, -3);
}
lua_newtable(L);
for (const std::pair<const float, const video::SColor> item: params.colorStops) {
lua_pushnumber(L, item.first); // key
push_ARGB8(L, item.second);
lua_rawset(L, -3);
}
setboolfield(L, -1, "blend", params.blend);
lua_setfield(L, -2, "color_stops");
}

/******************************************************************************/
Expand Down Expand Up @@ -1620,39 +1602,41 @@ WearBarParams read_wear_bar_params(
lua_State *L, int table)
{
WearBarParams params;
std::basic_string<char> default_color_string;
if (getstringfield(L, table, "default", default_color_string))
parseColorString(default_color_string, params.defaultColor, false);
bool blend = getboolfield_default(L, table, "blend", false);
params.blend = blend;

lua_getfield(L, table, "color_stops");
if (!check_field_or_nil(L, -1, LUA_TTABLE, "color_stops")) {
video::SColor color;
read_color(L, -1, &color);
params.colorStops.emplace(0.0, color);
lua_pop(L, 1);
return params;
}

// color stops table is on the stack
int table_values = lua_gettop(L);
lua_pushnil(L);
while(lua_next(L, table_values) != 0) {
// key at index -2 and value at index -1 within table_values
// color value entries are stored in a flat 'list' along with the default color,
// but in non-blend mode color entries can be distinguished by that value being a table
// (in blend mode, color entries can be distinguished by having a numerical key)
if (lua_istable(L, -1)) {
int value_table = lua_gettop(L);
WearBarParam param;
getfloatfield(L, value_table, "min_durability", param.minPercent);
getfloatfield(L, value_table, "max_durability", param.maxPercent);
std::string color_string;
if (getstringfield(L, value_table, "color", color_string))
parseColorString(color_string, param.color, false);
params.params.push_back(param);
} else if (blend && lua_isnumber(L, -2) && lua_isstring(L, -1)) {
WearBarParam param;
float point = luaL_checknumber(L, -2);
std::string color_string = luaL_checkstring(L, -1);
param.minPercent = param.maxPercent = point;
parseColorString(color_string, param.color, false);
params.params.push_back(param);
}
float point = luaL_checknumber(L, -2);
video::SColor color;
read_color(L, -1, &color);
params.colorStops.emplace(point, color);

// removes value, keeps key for next iteration
lua_pop(L, 1);
}
lua_pop(L, 1); // pop color stops table

lua_getfield(L, table, "blend");
if (check_field_or_nil(L, -1, LUA_TSTRING, "blend")) {
std::string blend = getstringfield_default(L, table, "blend", "constant");
int result = params.blend;
string_to_enum(es_BlendMode, result,
std::string(lua_tostring(L, -1)));
params.blend = static_cast<enum BlendMode>(result);
}
lua_pop(L, 1);

return params;
}

Expand Down
2 changes: 1 addition & 1 deletion src/script/lua_api/l_item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ int LuaItemStack::l_add_wear_by_uses(lua_State *L)
// get_wear_bar_params(self) -> table
// Returns the effective wear bar parameters.
// Returns nil if this item has none associated.
int LuaItemStack::l_get_wear_bar_params(lua_State *L) // todo test
int LuaItemStack::l_get_wear_bar_params(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
LuaItemStack *o = checkObject<LuaItemStack>(L, 1);
Expand Down
5 changes: 4 additions & 1 deletion src/script/lua_api/l_itemstackmeta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_itemstackmeta.h"
#include "lua_api/l_internal.h"
#include "common/c_content.h"
#include "common/c_converter.h"

/*
ItemStackMetaRef
Expand Down Expand Up @@ -68,7 +69,9 @@ int ItemStackMetaRef::l_set_wear_bar_params(lua_State *L)
metaref->setWearBarParams(params);
} else if (lua_isstring(L, 2)) {
WearBarParams params;
parseColorString(luaL_checkstring(L, 2), params.defaultColor, false);
video::SColor color;
read_color(L, 2, &color);
params.colorStops.emplace(0, color);
metaref->setWearBarParams(params);
} else {
luaL_typerror(L, 2, "table, ColorString, or nil");
Expand Down

0 comments on commit 4d4465d

Please sign in to comment.