Skip to content

Commit

Permalink
Properly port [heal_unit] to Lua
Browse files Browse the repository at this point in the history
  • Loading branch information
CelticMinstrel committed Dec 11, 2016
1 parent f00e2e1 commit eb369ff
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 84 deletions.
2 changes: 2 additions & 0 deletions changelog
Expand Up @@ -29,6 +29,8 @@ Version 1.13.6+dev:
* WML Engine:
* Removed LOW_MEM option when building.
* Add color= attribute to [floating_text]
* New ability_type key in standard unit filters matches if the unit has any
ability of the specified type (tag name).

Version 1.13.6:
* AI:
Expand Down
62 changes: 61 additions & 1 deletion data/lua/wml-tags.lua
Expand Up @@ -632,7 +632,67 @@ function wml_actions.unpetrify(cfg)
end

function wml_actions.heal_unit(cfg)
wesnoth.heal_unit(cfg)
local healers = helper.get_child("filter_second")
if healers then
healers = wesnoth.get_units{
ability_type = "heals",
T["and"](healers)
}
else
healers = {}
end

local who = helper.get_child("filter")
if who then
who = wesnoth.get_units(who)
else
who = wesnoth.get_units{
x = wesnoth.current.event_context.x1,
y = wesnoth.current.event_context.y1
}
end

local heal_full = cfg.amount == "full"
local moves_full = cfg.moves == "full"
local heal_amount_set = false
for i,u in ipairs(who) do
local heal_amount = u.max_hitpoints - u.hitpoints
if heal_full then
u.hitpoints = u.max_hitpoints
else
heal_amount = math.min(math.max(1, cfg.amount), heal_amount)
u.hitpoints = u.hitpoints + heal_amount
end

if moves_full then
u.moves = u.max_moves
else
u.moves = math.min(u.max_moves, u.moves + (cfg.moves or 0))
end

if cfg.restore_attacks then
u.attacks_left = u.max_attacks
end

if cfg.restore_statuses then
u.status.poisoned = false
u.status.petrified = false
u.status.slowed = false
u.status.unhealable = false
end

if ~heal_amount_set then
heal_amount_set = true
wesnoth.set_variable("heal_amount", heal_amount)
end

if cfg.animate then
wesnoth.animate_unit{
T.filter(healers),
flag = "healing"
}
end
end
end

function wml_actions.transform_unit(cfg)
Expand Down
83 changes: 0 additions & 83 deletions src/scripting/game_lua_kernel.cpp
Expand Up @@ -1790,88 +1790,6 @@ int game_lua_kernel::intf_find_cost_map(lua_State *L)
return 1;
}

int game_lua_kernel::intf_heal_unit(lua_State *L)
{
vconfig cfg(luaW_checkvconfig(L, 1));

const game_events::queued_event &event_info = get_event_info();

unit_map & temp = units();
unit_map* units = & temp;

const vconfig & healers_filter = cfg.child("filter_second");
std::vector<unit*> healers;
if (!healers_filter.null()) {
const unit_filter ufilt(healers_filter, &game_state_);
for (unit& u : *units) {
if ( ufilt(u) && u.has_ability_type("heals") ) {
healers.push_back(&u);
}
}
}

const config::attribute_value amount = cfg["amount"];
const config::attribute_value moves = cfg["moves"];
const bool restore_attacks = cfg["restore_attacks"].to_bool(false);
const bool restore_statuses = cfg["restore_statuses"].to_bool(true);
const bool animate = cfg["animate"].to_bool(false);

const vconfig & healed_filter = cfg.child("filter");
bool only_unit_at_loc1 = healed_filter.null();
bool heal_amount_to_set = true;

const unit_filter ufilt(healed_filter, &game_state_);
for(unit_map::unit_iterator u = units->begin(); u != units->end(); ++u) {
if (only_unit_at_loc1)
{
u = units->find(event_info.loc1);
if(!u.valid()) return 0;
}
else if ( !ufilt(*u) ) continue;

int heal_amount = u->max_hitpoints() - u->hitpoints();
if(amount.blank() || amount == "full") u->set_hitpoints(u->max_hitpoints());
else {
heal_amount = lexical_cast_default<int, config::attribute_value> (amount, heal_amount);
const int new_hitpoints = std::max(1, std::min(u->max_hitpoints(), u->hitpoints() + heal_amount));
heal_amount = new_hitpoints - u->hitpoints();
u->set_hitpoints(new_hitpoints);
}

if(!moves.blank()) {
if(moves == "full") u->set_movement(u->total_movement());
else {
// set_movement doesn't set below 0
u->set_movement(std::min<int>(
u->total_movement(),
u->movement_left() + lexical_cast_default<int, config::attribute_value> (moves, 0)
));
}
}

if(restore_attacks) u->set_attacks(u->max_attacks());

if(restore_statuses)
{
u->set_state(unit::STATE_POISONED, false);
u->set_state(unit::STATE_SLOWED, false);
u->set_state(unit::STATE_PETRIFIED, false);
u->set_state(unit::STATE_UNHEALABLE, false);
u->anim_comp().set_standing();
}

if (heal_amount_to_set)
{
heal_amount_to_set = false;
gamedata().get_variable("heal_amount") = heal_amount;
}

if(animate) unit_display::unit_healing(*u, healers, heal_amount);
if(only_unit_at_loc1) return 0;
}
return 0;
}

int game_lua_kernel::intf_print(lua_State *L) {
vconfig cfg(luaW_checkvconfig(L, 1));

Expand Down Expand Up @@ -4025,7 +3943,6 @@ game_lua_kernel::game_lua_kernel(game_state & gs, play_controller & pc, reports
{ "get_villages", &dispatch<&game_lua_kernel::intf_get_villages > },
{ "get_village_owner", &dispatch<&game_lua_kernel::intf_get_village_owner > },
{ "get_displayed_unit", &dispatch<&game_lua_kernel::intf_get_displayed_unit > },
{ "heal_unit", &dispatch<&game_lua_kernel::intf_heal_unit > },
{ "highlight_hex", &dispatch<&game_lua_kernel::intf_highlight_hex > },
{ "is_enemy", &dispatch<&game_lua_kernel::intf_is_enemy > },
{ "kill", &dispatch<&game_lua_kernel::intf_kill > },
Expand Down
13 changes: 13 additions & 0 deletions src/units/filter.cpp
Expand Up @@ -377,6 +377,19 @@ bool basic_unit_filter_impl::internal_matches_filter(const unit & u, const map_l
if (!match) return false;
}

if (!vcfg["ability_type"].empty())
{
bool match = false;

for (const std::string& ability : utils::split(vcfg["ability_type"])) {
if (u.has_ability_type(ability)) {
match = true;
break;
}
}
if (!match) return false;
}

if (!vcfg["race"].empty()) {
std::vector<std::string> races = utils::split(vcfg["race"]);
if (std::find(races.begin(), races.end(), u.race()->id()) == races.end()) {
Expand Down

0 comments on commit eb369ff

Please sign in to comment.