Skip to content

Commit

Permalink
Allow modifying dead units in last_breath and die event handlers
Browse files Browse the repository at this point in the history
Fixes an unintentional API change from commit 3c344e8, discussed in
comments of #3042.
  • Loading branch information
jyrkive committed May 14, 2018
1 parent ed46bc1 commit 15446ac
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/actions/attack.cpp
Expand Up @@ -1291,6 +1291,8 @@ void attack::unit_killed(unit_info& attacker,

std::string undead_variation = defender.get_unit().undead_variation();

unit::dying_unit_loc = defender.loc_;

fire_event("attack_end");
refresh_bc();

Expand All @@ -1315,6 +1317,7 @@ void attack::unit_killed(unit_info& attacker,

// WML has invalidated the dying unit, abort.
if(!defender.valid() || defender.get_unit().hitpoints() > 0) {
unit::dying_unit_loc = map_location::null_location();
return;
}

Expand All @@ -1339,6 +1342,8 @@ void attack::unit_killed(unit_info& attacker,
resources::game_events->pump().fire("die", death_loc, attacker_loc, dat);
refresh_bc();

unit::dying_unit_loc = map_location::null_location();

if(!defender.valid() || defender.get_unit().hitpoints() > 0) {
// WML has invalidated the dying unit, abort
return;
Expand Down
6 changes: 5 additions & 1 deletion src/units/unit.cpp
Expand Up @@ -207,6 +207,8 @@ namespace
}
} // end anon namespace

map_location unit::dying_unit_loc;

/**
* Intrusive Pointer interface
*
Expand Down Expand Up @@ -630,7 +632,9 @@ void unit::init(const config& cfg, bool use_traits, const vconfig* vcfg)
}

if(const config::attribute_value* v = cfg.get("hitpoints")) {
VALIDATE(*v > 0, _("Unit with negative HP found"));
if(loc_ != dying_unit_loc) {
VALIDATE(*v > 0, _("Unit with negative HP found"));
}
hit_points_ = *v;
} else {
hit_points_ = max_hit_points_;
Expand Down
9 changes: 9 additions & 0 deletions src/units/unit.hpp
Expand Up @@ -1598,6 +1598,15 @@ class unit
void set_appearance_changed(bool value) { appearance_changed_ = value; }
bool appearance_changed() const { return appearance_changed_; }

/**
* The location of the dying unit for the duration of last_breath and die events.
* Null location when neither of those events is running.
* This exists in order to detect at unit creation time whether the WML/Lua code is unstoring a unit
* that was already dead (e.g. as a result of [modify_unit], which is implemented with unstoring
* under the hood). That's the only situation where creating a unit with negative HP is allowed.
*/
static map_location dying_unit_loc;

protected:
mutable long ref_count_; // used by intrusive_ptr

Expand Down

0 comments on commit 15446ac

Please sign in to comment.