allow units.remove_modifications to remove multiple types

previously it needed multiple calls to remove multiple types of modifications (which could be slow since each call involves a full rebuild of the unit).
This commit is contained in:
gfgtdf 2023-12-12 22:26:39 +01:00
parent be8aa13aa0
commit 99399a2b26
4 changed files with 134 additions and 5 deletions

View file

@ -1 +0,0 @@
git doesn't allow adding empty directories; delete this once any test is added

View file

@ -0,0 +1,120 @@
# wmllint: no translatables
#####
# API(s) being tested: wesnoth.units.remove_modifications
##
# Actions:
# adds and removed modifications
##
# Expected end state:
# The asserts pass.
#####
#ifndef SCHEMA_VALIDATION
{GENERIC_UNIT_TEST "test_remove_modifications" (
[event]
name = start
[unit]
side = 1
type = "Test Melee Quintain"
x = 4
y = 4
[modifications]
[object]
[effect]
apply_to=hitpoints
increase_total=20
[/effect]
[/object]
[advancement]
[effect]
apply_to=hitpoints
increase_total=5
[/effect]
[/advancement]
[trait]
[effect]
apply_to=hitpoints
increase_total=50
[/effect]
[/trait]
[/modifications]
[/unit]
{ASSERT (
[have_unit]
formula="max_hitpoints=175"
x,y = 4,4
[/have_unit]
)}
#{ASSERT (
# [false]
# [/false]
#)}
[lua]
code = <<
local u = wesnoth.units.get(4,4)
u:remove_modifications({}, "trait")
>>
[/lua]
{ASSERT (
[have_unit]
formula="max_hitpoints=125"
x,y = 4,4
[/have_unit]
)}
[lua]
code = <<
local u = wesnoth.units.get(4,4)
u:remove_modifications({}, {"trait", "object", "advancement"})
>>
[/lua]
{ASSERT (
[have_unit]
formula="max_hitpoints=100"
x,y = 4,4
[/have_unit]
)}
[unit]
side = 1
type = "Test Melee Quintain"
x = 5
y = 4
[modifications]
[object]
a = 7
[effect]
apply_to=hitpoints
increase_total=20
[/effect]
[/object]
[advancement]
a = 8
[effect]
apply_to=hitpoints
increase_total=5
[/effect]
[/advancement]
[trait]
a = 9
[effect]
apply_to=hitpoints
increase_total=50
[/effect]
[/trait]
[/modifications]
[/unit]
[lua]
code = <<
local u = wesnoth.units.get(5,4)
u:remove_modifications({ a = 8 }, {"trait", "object", "advancement"})
>>
[/lua]
{ASSERT (
[have_unit]
formula="max_hitpoints=170"
x,y = 5,4
[/have_unit]
)}
{SUCCEED}
[/event]
)}
#endif

View file

@ -3825,14 +3825,23 @@ static int intf_remove_modifications(lua_State *L)
{
unit& u = luaW_checkunit(L, 1);
config filter = luaW_checkconfig(L, 2);
std::string tag = luaL_optstring(L, 3, "object");
std::vector<std::string> tags;
if(lua_isstring(L, 3)) {
tags.push_back(lua_check<std::string>(L, 3));
} else if (lua_istable(L, 3)){
tags = lua_check<std::vector<std::string>>(L, 3);
} else {
tags.push_back("object");
}
//TODO
if(filter.attribute_count() == 1 && filter.all_children_count() == 0 && filter.attribute_range().front().first == "duration") {
u.expire_modifications(filter["duration"]);
} else {
for(config& obj : u.get_modifications().child_range(tag)) {
if(obj.matches(filter)) {
obj["duration"] = "now";
for(const std::string& tag : tags) {
for(config& obj : u.get_modifications().child_range(tag)) {
if(obj.matches(filter)) {
obj["duration"] = "now";
}
}
}
u.expire_modifications("now");

View file

@ -547,5 +547,6 @@
0 lua_map_find
0 mapgen_filter_range
0 mapgen_filter_terrain
0 test_remove_modifications
0 simulate_combat_clone_adjacent
0 simulate_combat_occupied