27 #include "formula/callable_objects.hpp"
43 #define DBG_NG LOG_STREAM(debug, log_engine)
44 #define LOG_NG LOG_STREAM(info, log_engine)
45 #define WRN_NG LOG_STREAM(warn, log_engine)
48 #define DBG_EH LOG_STREAM(debug, log_event_handler)
56 : first_time_only_(true)
57 , is_menu_item_(false)
60 , has_preloaded_(false)
76 std::vector<std::string> standardized_names;
87 for(
const std::string& subname :
utils::split(single_name)) {
92 return standardized_names;
102 assert(!
disabled_ &&
"Trying to disable a disabled event. Shouldn't happen!");
113 DBG_NG <<
"menu item " <<
id_ <<
" will now invoke the following command(s):\n" <<
args_;
126 return std::all_of(
filters_.begin(),
filters_.end(), [&ev](
const auto& filter) {
127 return (*filter)(ev);
134 WRN_NG <<
"Tried to serialize disabled event, skipping";
137 static const char* log_append_preload =
" - this will not break saves since it was registered during or before preload\n";
138 static const char* log_append_postload =
" - this will break saves because it was registered after preload\n";
140 if(include_nonserializable) {
141 cfg[
"nonserializable"] =
true;
142 cfg.
add_child(
"lua")[
"code"] =
"<function>";
144 static const char* log =
"Skipping serialization of an event with action bound to Lua code";
146 WRN_NG << log << log_append_postload;
149 LOG_NG << log << log_append_preload;
155 if(include_nonserializable) {
156 cfg[
"nonserializable"] =
true;
158 static const char* log =
"Skipping serialization of an event with filter bound to Lua code";
160 WRN_NG << log << log_append_postload;
163 LOG_NG << log << log_append_preload;
169 if(!
id_.empty()) cfg[
"id"] =
id_;
172 for(
const auto& filter :
filters_) {
173 filter->serialize(cfg);
180 WRN_NG <<
"Tried to serialize an event with a filter that cannot be serialized!";
230 return loc.matches_unit_filter(
unit,
suf_);
252 auto unit_a = units.
find(loc);
253 auto unit_d = units.
find(loc_d);
254 if(unit_a != units.
end() && loc.matches_unit(unit_a)) {
255 const auto u = unit_a->shared_from_this();
258 const_attack_ptr attack = std::make_shared<const attack_type>(*temp_weapon);
259 if(unit_d != units.
end() && loc_d.matches_unit(unit_d)) {
260 const auto opp = unit_d->shared_from_this();
262 const_attack_ptr second_attack = temp_other_weapon ? std::make_shared<const attack_type>(*temp_other_weapon) :
nullptr;
263 auto ctx = attack->specials_context(u, opp, loc, loc_d,
first_, second_attack);
264 utils::optional<decltype(ctx)> opp_ctx;
266 opp_ctx.emplace(second_attack->specials_context(opp, u, loc_d, loc, !
first_, attack));
270 auto ctx = attack->specials_context(u, loc,
first_);
304 code =
"(" + cfg[
"filter_formula"].str() +
") and (" + code +
")";
306 cfg[
"filter_formula"] = code;
318 if(key ==
"filter_condition") {
319 return std::make_unique<filter_condition>(contents);
320 }
else if(key ==
"filter_side") {
321 return std::make_unique<filter_side>(contents);
322 }
else if(key ==
"filter") {
323 return std::make_unique<filter_unit>(contents,
true);
324 }
else if(key ==
"filter_attack") {
325 return std::make_unique<filter_attack>(contents,
true);
326 }
else if(key ==
"filter_second") {
327 return std::make_unique<filter_unit>(contents,
false);
328 }
else if(key ==
"filter_second_attack") {
329 return std::make_unique<filter_attack>(contents,
false);
345 return (*filter)(event_info);
370 add_filter(std::make_unique<filter_dynamic>(vcfg[
"name"], vcfg[
"variable"]));
374 add_filter(std::make_unique<filter_formula>(cfg[
"filter_formula"]));
380 filters_.push_back(std::move(filter));
A config object defines a single node in a WML file, with access to child nodes.
void append(const config &cfg)
Append data from another config object to this one.
auto all_children_view() const
In-order iteration over all children.
bool has_attribute(config_key_type key) const
optional_config_impl< config > optional_child(config_key_type key, int n=0)
Equivalent to mandatory_child, but returns an empty optional if the nth child was not found.
config & add_child(config_key_type key)
virtual const unit_map & units() const override
bool has_preloaded_
Tracks whether the event was registered before or after the Lua preload event fired.
void register_wml_event(game_lua_kernel &lk)
void add_filter(std::unique_ptr< event_filter > &&filter)
void read_filters(const config &cfg)
void write_config(config &cfg, bool include_nonserializable=false) const
std::vector< std::string > names(const variable_set *vars) const
void set_event_ref(int idx, bool has_preloaded)
void disable()
Flag this handler as disabled.
event_handler(const std::string &types, const std::string &id="")
bool filter_event(const queued_event &event_info) const
bool is_lua_
Tracks whether the event was registered from the Lua API.
std::vector< std::shared_ptr< event_filter > > filters_
void handle_event(const queued_event &event_info, game_lua_kernel &lk)
Handles the queued event, according to our WML instructions.
static std::string standardize_name(const std::string &name)
Utility to standardize the event names used in by_name_.
int save_wml_event()
Store a WML event in the Lua registry, as a function.
bool run_wml_event(int ref, const vconfig &args, const game_events::queued_event &ev, bool *out=nullptr)
Run a WML stored in the Lua registry.
bool match(const team &t) const
const config & get_config() const
Container associating units to locations.
unit_iterator find(std::size_t id)
This class represents a single unit of a specific type.
Information on a WML variable.
bool exists_as_container() const
maybe_const_t< config, V > & as_container() const
If instantiated with vi_policy_const, the lifetime of the returned const attribute_value reference mi...
A variable-expanding proxy for the config class.
static vconfig empty_vconfig()
const config & get_config() const
config get_parsed_config() const
An object representing the state of the current event; equivalent to Lua's wesnoth....
An object representing the state of the game, providing access to the map and basic information.
bool as_bool() const
Returns a boolean state of the variant value.
Define conditionals for the game's events mechanism, a.k.a.
std::string id
Text to match against addon_info.tags()
static lg::log_domain log_engine("engine")
static lg::log_domain log_event_handler("event_handler")
Define the handlers for the game's events mechanism.
Standard logging facilities (interface).
bool conditional_passed(const vconfig &cond)
static std::unique_ptr< event_filter > make_filter(const std::string &key, const vconfig &contents)
std::stringstream & log_to_chat()
Use this to show WML errors in the ingame chat.
std::unique_ptr< filter, std::function< void(filter *)> > filter_ptr
std::string tag(const std::string &tag_name, Args &&... contents)
play_controller * controller
void commit_music_changes()
std::string interpolate_variables_into_string(const std::string &str, const string_map *const symbols)
Function which will interpolate variables, starting with '$' in the string 'str' with the equivalent ...
bool might_contain_variables(const std::string &str)
Determines if a string might contain variables to interpolate.
std::vector< std::string > split(const config_attribute_value &val)
std::shared_ptr< const attack_type > const_attack_ptr
Define the game's event mechanism.
Represents a single filter condition on an event.
virtual void serialize(config &cfg) const
Serializes the filter into a config, if possible.
virtual bool can_serialize() const
Returns true if it is possible to serialize the filter into a config.
bool operator()(const queued_event &event_info) const override
Runs the filter and returns whether it passes on the given event.
void serialize(config &cfg) const override
Serializes the filter into a config, if possible.
bool can_serialize() const override
Returns true if it is possible to serialize the filter into a config.
filter_attack(const vconfig &cfg, bool first)
bool operator()(const queued_event &) const override
Runs the filter and returns whether it passes on the given event.
void serialize(config &cfg) const override
Serializes the filter into a config, if possible.
filter_condition(const vconfig &cfg)
bool can_serialize() const override
Returns true if it is possible to serialize the filter into a config.
This is a dynamic wrapper for any filter type, specified via [insert_tag].
bool can_serialize() const override
Returns true if it is possible to serialize the filter into a config.
filter_dynamic(const std::string &tag, const std::string &var)
void serialize(config &cfg) const override
Serializes the filter into a config, if possible.
bool operator()(const queued_event &event_info) const override
Runs the filter and returns whether it passes on the given event.
bool can_serialize() const override
Returns true if it is possible to serialize the filter into a config.
void serialize(config &cfg) const override
Serializes the filter into a config, if possible.
bool operator()(const queued_event &) const override
Runs the filter and returns whether it passes on the given event.
filter_side(const vconfig &cfg)
bool can_serialize() const override
Returns true if it is possible to serialize the filter into a config.
bool operator()(const queued_event &event_info) const override
Runs the filter and returns whether it passes on the given event.
filter_unit(const vconfig &cfg, bool first)
void serialize(config &cfg) const override
Serializes the filter into a config, if possible.