New [remove_object] WML tag

This commit is contained in:
Celtic Minstrel 2016-08-02 00:52:52 -04:00
parent 6dab777f66
commit 53828a01b9
4 changed files with 50 additions and 2 deletions

View file

@ -18,9 +18,19 @@ Version 1.13.5+dev:
* [modify_unit] now understands [effect] tags, which it applies directly.
This replaces the use of [object] with no_write=yes (which will be removed
in the next release).
* Add [object]take_only_once=yes|no (default yes) - if set to no, automatic
tracking is disabled for this object (allowing it to be taken multiple times
even if it has an id).
* New [remove_object] tag which removes applied [object]s from matched units;
it can filter on the entire [object] WML. The most efficient use is to
remove all objects with a specific duration value.
* Lua API:
* Added new functions wesnoth.fire_event_by_id and fire_event_by_name. The old
function wesnoth.fire_event is now an alias for wesnoth.fire_event_by_name
* Added new function wesnoth.remove_modifications, which removes applied
modifications of the chosen type from a unit. The most efficient use is to
remove all modifications with a specific duration value.
Also callable as u:remove_modifications.
* Performance:
* When a heuristic determines that it's probably faster, the game predicts battle
outcome by simulating a few thousand fights instead of calculating exact

View file

@ -10,8 +10,10 @@ function wml_actions.object(cfg)
local context = wesnoth.current.event_context
-- If this item has already been used
local unique = cfg.take_only_once
if unique == nil then unique = true end
local obj_id = utils.check_key(cfg.id, "id", "object", true)
if obj_id and used_items[obj_id] then return end
if obj_id and unique and used_items[obj_id] then return end
local unit, command_type, text
@ -43,7 +45,7 @@ function wml_actions.object(cfg)
wesnoth.highlight_hex(unit.x, unit.y)
-- Mark this item as used up
if obj_id then used_items[obj_id] = true end
if obj_id and unique then used_items[obj_id] = true end
else
text = tostring(cfg.cannot_use_message or "")
command_type = "else"
@ -86,6 +88,13 @@ function wesnoth.game_events.on_save()
return cfg
end
function wml_actions.remove_object(cfg)
local obj_id = cfg.object_id
for _,unit in ipairs(wesnoth.get_units(cfg)) do
wesnoth.remove_modifications(unit, {id = obj_id})
end
end
function wesnoth.wml_conditionals.found_item(cfg)
return used_items[utils.check_key(cfg.id, "id", "found_item", true)]
end

View file

@ -3622,6 +3622,32 @@ static int intf_add_modification(lua_State *L)
return 0;
}
/**
* Removes modifications from a unit
* - Arg 1: unit
* - Arg 2: table (filter as [filter_wml])
* - Arg 3: type of modification (default "object")
*/
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");
config::const_attr_itors ai = filter.attribute_range();
config::all_children_itors ci = filter.all_children_range();
if(std::distance(ai.first, ai.second) == 1 && std::distance(ci.first, ci.second) == 0 && ai.first->first == "duration") {
u.expire_modifications(filter["duration"]);
} else {
for(config& obj : u.get_modifications().child_range(tag)) {
if(obj.matches(filter)) {
obj["duration"] = "now";
}
}
u.expire_modifications("now");
}
return 0;
}
/**
* Advances a unit if the unit has enough xp.
* - Arg 1: unit.
@ -4617,6 +4643,7 @@ game_lua_kernel::game_lua_kernel(CVideo * video, game_state & gs, play_controlle
{ "get_traits", &intf_get_traits },
{ "get_viewing_side", &intf_get_viewing_side },
{ "modify_ai", &intf_modify_ai },
{ "remove_modifications", &intf_remove_modifications },
{ "set_music", &intf_set_music },
{ "transform_unit", &intf_transform_unit },
{ "unit_ability", &intf_unit_ability },
@ -4985,6 +5012,7 @@ int game_lua_kernel::return_unit_method(lua_State *L, char const *m) {
{"extract", &dispatch<&game_lua_kernel::intf_extract_unit>},
{"advance", intf_advance_unit},
{"add_modification", intf_add_modification},
{"remove_modifications", intf_remove_modifications},
{"resistance", intf_unit_resistance},
{"defense", intf_unit_defense},
{"movement", intf_unit_movement_cost},

View file

@ -317,6 +317,7 @@ public:
std::vector<std::pair<std::string,std::string> > amla_icons() const;
std::vector<config> get_modification_advances() const;
config& get_modifications() { return modifications_; }
typedef boost::ptr_vector<config> t_advancements;
void set_advancements(std::vector<config> advancements);