Skip to content

Commit

Permalink
Moved [role] to Lua
Browse files Browse the repository at this point in the history
This fixes indirectly bug #23630
  • Loading branch information
Elvish-Hunter committed Jun 10, 2015
1 parent 1b239aa commit 787bd1b
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 70 deletions.
44 changes: 44 additions & 0 deletions data/lua/wml-tags.lua
Expand Up @@ -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
70 changes: 0 additions & 70 deletions src/game_events/action_wml.cpp
Expand Up @@ -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<std::string> types = utils::split(filter["type"]);
const bool has_any_types = !types.empty();
std::vector<std::string>::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<std::string> player_ids;
std::vector<std::string> 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<size_t>(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<std::string>::iterator ti = types.begin();
const unit_filter ufilt(filter, resources::filter_con);
do {
if (has_any_types) {
item["type"] = *ti;
}
std::vector<team>::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)
Expand Down

0 comments on commit 787bd1b

Please sign in to comment.