From 787bd1b9c538c73433c23d0ec52676bcbfa2a052 Mon Sep 17 00:00:00 2001 From: Elvish_Hunter Date: Wed, 10 Jun 2015 22:36:08 +0200 Subject: [PATCH] Moved [role] to Lua This fixes indirectly bug #23630 --- data/lua/wml-tags.lua | 44 +++++++++++++++++++++ src/game_events/action_wml.cpp | 70 ---------------------------------- 2 files changed, 44 insertions(+), 70 deletions(-) diff --git a/data/lua/wml-tags.lua b/data/lua/wml-tags.lua index f9fe98079cbb..5b73ee8456ec 100644 --- a/data/lua/wml-tags.lua +++ b/data/lua/wml-tags.lua @@ -1460,3 +1460,47 @@ end function wml_actions.print(cfg) wesnoth.print(cfg) end + +function wml_actions.role(cfg) + -- role= and type= are handled differently than in other tags, + -- so we need to remove them from the filter + local role = cfg.role + local filter = cfg.__shallow_literal + filter.role, filter.type = nil, nil + + local types = {} + for value in split(cfg.type) do + table.insert(types, value) + end + + -- first attempt to match units on the map + local i = 1 + repeat + -- give precedence based on the order specified in type= + if #types > 0 then + filter.type = types[i] + end + local unit = wesnoth.get_units(filter)[1] + if unit then + unit.role = cfg.role + return + end + i = i + 1 + until #types == 0 or i > #types + + -- then try to match units on the recall lists + i = 1 + repeat + if #types > 0 then + filter.type = types[i] + end + local unit = wesnoth.get_recall_units(filter)[1] + if unit then + unit.role = cfg.role + return + end + i = i + 1 + until #types == 0 or i > #types + + -- no matching unit found, fail silently +end diff --git a/src/game_events/action_wml.cpp b/src/game_events/action_wml.cpp index 808a21ae17bd..1068f66a5ac4 100644 --- a/src/game_events/action_wml.cpp +++ b/src/game_events/action_wml.cpp @@ -1021,76 +1021,6 @@ WML_HANDLER_FUNCTION(reset_fog, /*event_info*/, cfg) toggle_fog(false, cfg, cfg["reset_view"].to_bool(false)); } -WML_HANDLER_FUNCTION(role, /*event_info*/, cfg) -{ - bool found = false; - - // role= represents the instruction, so we can't filter on it - config item = cfg.get_config(); - item.remove_attribute("role"); - vconfig filter(item); - - // try to match units on the gamemap before the recall lists - std::vector types = utils::split(filter["type"]); - const bool has_any_types = !types.empty(); - std::vector::iterator ti = types.begin(), - ti_end = types.end(); - // loop to give precedence based on type order - const unit_filter ufilt(filter, resources::filter_con); - do { - if (has_any_types) { - item["type"] = *ti; - } - BOOST_FOREACH(unit &u, *resources::units) { - if ( ufilt(u) ) { - u.set_role(cfg["role"]); - found = true; - break; - } - } - } while(!found && has_any_types && ++ti != ti_end); - if(!found) { - // next try to match units on the recall lists - std::set player_ids; - std::vector sides = utils::split(cfg["side"]); - const bool has_any_sides = !sides.empty(); - BOOST_FOREACH(std::string const& side_str, sides) { - size_t side_num = lexical_cast_default(side_str,0); - if(side_num > 0 && side_num <= resources::teams->size()) { - player_ids.insert((resources::teams->begin() + (side_num - 1))->save_id()); - } - } - // loop to give precedence based on type order - std::vector::iterator ti = types.begin(); - const unit_filter ufilt(filter, resources::filter_con); - do { - if (has_any_types) { - item["type"] = *ti; - } - std::vector::iterator pi, - pi_end = resources::teams->end(); - for (pi = resources::teams->begin(); pi != pi_end; ++pi) - { - std::string const& player_id = pi->save_id(); - // Verify the filter's side= includes this player - if(has_any_sides && !player_ids.count(player_id)) { - continue; - } - // Iterate over the player's recall list to find a match - for(size_t i=0; i < pi->recall_list().size(); ++i) { - unit_ptr u = pi->recall_list()[i]; - scoped_recall_unit auto_store("this_unit", player_id, i); //TODO: Should this not be inside the if? Explain me. - if (ufilt( *u, map_location() )) { - u->set_role(cfg["role"]); - found=true; - break; - } - } - } - } while(!found && has_any_types && ++ti != ti_end); - } -} - /// Experimental data persistence /// @todo Finish experimenting. WML_HANDLER_FUNCTION(set_global_variable,/**/,pcfg)