Throw a Lua exception when creating a negative-HP unit in a Lua context

Instead of throwing a WML error. This allows the UMC author to get a stack
trace if the unit creation was triggered from Lua.

Requested by @gfgtdf in a comment of #3042.
This commit is contained in:
Jyrki Vesterinen 2018-05-15 20:20:41 +03:00
parent ddaf9f5a87
commit 258a0e4689
3 changed files with 19 additions and 3 deletions

View file

@ -647,6 +647,11 @@ std::size_t wml_event_pump::wml_tracking()
return impl_->internal_wml_tracking;
}
bool wml_event_pump::running() const
{
return impl_->instance_count > 0u;
}
wml_event_pump::wml_event_pump(manager& man)
: impl_(new pump_impl(man))
{

View file

@ -144,6 +144,9 @@ public:
/** This function can be used to detect when no WML/Lua has been executed. */
std::size_t wml_tracking();
/** Returns true if we're currently executing an event handler. */
bool running() const;
private:
bool filter_event(const event_handler& handler, const queued_event& ev);

View file

@ -22,13 +22,15 @@
#include "color.hpp"
#include "deprecation.hpp"
#include "display.hpp"
#include "filter_context.hpp"
#include "formatter.hpp"
#include "formula/string_utils.hpp" // for VGETTEXT
#include "game_board.hpp" // for game_board
#include "game_config.hpp" // for add_color_info, etc
#include "game_data.hpp"
#include "game_errors.hpp" // for game_error
#include "game_events/manager.hpp" // for add_events
#include "game_events/manager.hpp" // for add_events, pump
#include "game_events/pump.hpp" // for running
#include "preferences/game.hpp" // for encountered_units
#include "gettext.hpp" // for N_
#include "lexical_cast.hpp"
@ -55,6 +57,7 @@
#include "utils/functional.hpp"
#include <boost/dynamic_bitset.hpp>
#include <boost/function_output_iterator.hpp>
#include "lua/lauxlib.h"
#ifdef _MSC_VER
#pragma warning (push)
@ -632,8 +635,13 @@ void unit::init(const config& cfg, bool use_traits, const vconfig* vcfg)
}
if(const config::attribute_value* v = cfg.get("hitpoints")) {
if(loc_ != dying_unit_loc) {
VALIDATE(*v > 0, _("Unit with negative HP found"));
if(!(*v > 0 || loc_ == dying_unit_loc)) {
if(resources::game_events->pump().running()) {
// This function throws an exception, it doesn't return
luaL_error(resources::filter_con->get_lua_kernel()->get_state(), "Attempted to create a unit with negative HP");
} else {
VALIDATE(false, _("Unit with negative HP found"));
}
}
hit_points_ = *v;
} else {