37 #define LOG_SF LOG_STREAM(info, log_scripting_formula)
38 #define ERR_SF LOG_STREAM(err, log_scripting_formula)
47 }
else if(key ==
"y") {
63 if(loc_callable ==
nullptr) {
73 std::ostringstream ss;
85 if(key ==
"id" || key ==
"name") {
87 }
else if(key ==
"description") {
89 }
else if(key ==
"base_type") {
91 }
else if(key ==
"type") {
92 return variant(
att_->effective_damage_type().first);
93 }
else if(key ==
"icon") {
95 }
else if(key ==
"range") {
97 }
else if(key ==
"alignment") {
99 }
else if(key ==
"damage") {
101 }
else if(key ==
"number_of_attacks" || key ==
"number" || key ==
"num_attacks" || key ==
"attacks") {
103 }
else if(key ==
"attack_weight") {
105 }
else if(key ==
"defense_weight") {
107 }
else if(key ==
"accuracy") {
109 }
else if(key ==
"parry") {
111 }
else if(key ==
"movement_used") {
113 }
else if(key ==
"attacks_used") {
115 }
else if(key ==
"min_range") {
117 }
else if(key ==
"max_range") {
119 }
else if(key ==
"specials" || key ==
"special") {
120 std::vector<variant> res;
122 for(
const auto& p_ab :
att_->specials()) {
123 if(!p_ab->id().empty()) {
124 res.emplace_back(p_ab->id());
127 return variant(std::move(res));
158 if(att_callable ==
nullptr) {
162 if(
att_->damage() != att_callable->
att_->damage()) {
163 return att_->damage() - att_callable->
att_->damage();
166 if(
att_->num_attacks() != att_callable->
att_->num_attacks()) {
167 return att_->num_attacks() - att_callable->
att_->num_attacks();
170 if(
att_->id() != att_callable->
att_->id()) {
171 return att_->id().compare(att_callable->
att_->id());
174 if(
att_->type() != att_callable->
att_->type()) {
175 return att_->type().compare(att_callable->
att_->type());
178 if(
att_->range() != att_callable->
att_->range()) {
179 return att_->range().compare(att_callable->
att_->range());
182 if(
att_->alignment_str() != att_callable->
att_->alignment_str()) {
183 return att_->alignment_str().compare(att_callable->
att_->alignment_str());
186 const auto& self_specials =
att_->specials();
187 const auto& other_specials = att_callable->
att_->specials();
188 if(self_specials.size() != other_specials.size()) {
189 return self_specials.size() < other_specials.size() ? -1 : 1;
191 for(std::size_t
i = 0;
i < self_specials.size(); ++
i) {
192 const auto&
s = self_specials[
i]->id();
193 const auto& o = other_specials[
i]->id();
216 }
else if(key ==
"y") {
222 }
else if(key ==
"loc") {
227 return make_callable<location_callable>(
loc_);
228 }
else if(key ==
"terrain") {
233 }
else if(key ==
"id") {
235 }
else if(key ==
"type") {
237 }
else if(key ==
"name") {
239 }
else if(key ==
"usage") {
241 }
else if(key ==
"leader" || key ==
"canrecruit") {
243 }
else if(key ==
"undead") {
245 }
else if(key ==
"attacks") {
246 std::vector<variant> res;
248 res.emplace_back(std::make_shared<attack_type_callable>(att));
251 return variant(std::move(res));
252 }
else if(key ==
"abilities") {
255 }
else if(key ==
"ability_ids") {
257 }
else if(key ==
"hitpoints") {
259 }
else if(key ==
"max_hitpoints") {
261 }
else if(key ==
"experience") {
263 }
else if(key ==
"max_experience") {
265 }
else if(key ==
"level" || key ==
"full") {
268 }
else if(key ==
"total_movement" || key ==
"max_moves") {
270 }
else if(key ==
"movement_left" || key ==
"moves") {
272 }
else if(key ==
"attacks_left") {
274 }
else if(key ==
"max_attacks") {
276 }
else if(key ==
"traits") {
278 }
else if(key ==
"advancements_taken") {
280 }
else if(key ==
"objects") {
282 }
else if(key ==
"traits_count") {
284 }
else if(key ==
"advancements_taken_count") {
286 }
else if(key ==
"objects_count") {
288 }
else if(key ==
"extra_recruit") {
290 }
else if(key ==
"advances_to") {
292 }
else if(key ==
"states" || key ==
"status") {
294 }
else if(key ==
"side_number") {
296 }
else if(key ==
"cost") {
298 }
else if(key ==
"upkeep") {
300 }
else if(key ==
"loyal") {
303 }
else if(key ==
"hidden") {
305 }
else if(key ==
"petrified") {
307 }
else if(key ==
"resting") {
309 }
else if(key ==
"role") {
311 }
else if(key ==
"race") {
313 }
else if(key ==
"gender") {
315 }
else if(key ==
"variation") {
317 }
else if(key ==
"zoc") {
319 }
else if(key ==
"alignment") {
321 }
else if(key ==
"facing") {
323 }
else if(key ==
"resistance" || key ==
"movement_cost" || key ==
"vision_cost" || key ==
"jamming_cost" || key ==
"defense") {
326 bool needs_flip =
false;
327 if(key ==
"resistance") {
328 mt.get_resistances().write(
cfg);
330 }
else if(key ==
"movement_cost") {
331 mt.get_movement().write(
cfg);
332 }
else if(key ==
"vision_cost") {
333 mt.get_vision().write(
cfg);
334 }
else if(key ==
"jamming_cost") {
335 mt.get_jamming().write(
cfg);
336 }
else if(key ==
"defense") {
337 mt.get_defense().write(
cfg);
340 std::map<variant, variant> res;
342 int val = value.to_int();
349 return variant(std::move(res));
350 }
else if(key ==
"flying") {
352 }
else if(key ==
"fearless") {
354 }
else if(key ==
"healthy") {
356 }
else if(key ==
"wml_vars") {
357 return make_callable<config_callable>(
u_.
variables());
358 }
else if(key ==
"n" || key ==
"s" || key ==
"ne" || key ==
"se" || key ==
"nw" || key ==
"sw" ||
359 key ==
"lawful" || key ==
"neutral" || key ==
"chaotic" || key ==
"liminal" ||
360 key ==
"male" || key ==
"female")
429 if(u_callable ==
nullptr) {
440 }
else if(key ==
"type") {
442 }
else if(key ==
"alignment") {
444 }
else if(key ==
"race") {
446 }
else if(key ==
"abilities") {
449 }
else if(key ==
"ability_ids") {
451 }
else if(key ==
"traits") {
452 std::vector<variant> res;
454 res.emplace_back(
config[
"id"].str());
457 return variant(std::move(res));
458 }
else if(key ==
"attacks") {
459 std::vector<variant> res;
461 res.emplace_back(std::make_shared<attack_type_callable>(att));
464 return variant(std::move(res));
465 }
else if(key ==
"hitpoints" || key ==
"max_hitpoints") {
467 }
else if(key ==
"experience" || key ==
"max_experience") {
469 }
else if(key ==
"level") {
471 }
else if(key ==
"total_movement" || key ==
"max_moves" || key ==
"moves") {
473 }
else if(key ==
"undead") {
475 }
else if(key ==
"unpoisonable") {
477 }
else if(key ==
"unslowable") {
479 }
else if(key ==
"unpetrifiable") {
481 }
else if(key ==
"undrainable") {
483 }
else if(key ==
"unplagueable") {
485 }
else if(key ==
"cost") {
487 }
else if(key ==
"recall_cost") {
489 }
else if(key ==
"usage") {
519 if(u_callable ==
nullptr) {
523 return u_.
id().compare(u_callable->
u_.
id());
527 #ifdef USING_BOOST_VARIANT
528 :
public boost::static_visitor<variant>
548 std::vector<variant> result;
550 result.emplace_back(std::make_shared<config_callable>(child));
553 return variant(std::move(result));
554 }
else if(key ==
"__all_children") {
555 std::vector<variant> result;
557 const variant cfg_child(std::make_shared<config_callable>(child_cfg));
558 const variant kv(std::make_shared<key_value_pair>(
variant(child_key), cfg_child));
559 result.push_back(kv);
562 return variant(std::move(result));
563 }
else if(key ==
"__children") {
564 std::map<std::string, std::vector<variant>> build;
566 const variant cfg_child(std::make_shared<config_callable>(child_cfg));
567 build[child_key].push_back(cfg_child);
570 std::map<variant, variant> result;
571 for(
auto&
p : build) {
575 return variant(std::move(result));
576 }
else if(key ==
"__attributes") {
577 std::map<variant, variant> result;
582 return variant(std::move(result));
604 if(cfg_callable ==
nullptr) {
624 }
else if(key ==
"y") {
626 }
else if(key ==
"loc") {
627 return make_callable<location_callable>(
loc_);
628 }
else if(key ==
"id") {
630 }
else if(key ==
"name") {
632 }
else if(key ==
"editor_name") {
634 }
else if(key ==
"description") {
636 }
else if(key ==
"icon") {
638 }
else if(key ==
"light") {
640 }
else if(key ==
"village") {
642 }
else if(key ==
"castle") {
644 }
else if(key ==
"keep") {
646 }
else if(key ==
"healing") {
648 }
else if(key ==
"owner_side") {
676 if(terr_callable ==
nullptr) {
696 if(key ==
"terrain") {
700 std::vector<variant> vars;
701 for(
int i = 0;
i <
w;
i++) {
702 for(
int j = 0; j <
h; j++) {
704 vars.emplace_back(std::make_shared<terrain_callable>(
board_,
loc));
708 return variant(std::move(vars));
709 }
else if(key ==
"gamemap") {
713 std::map<variant, variant> vars;
714 for(
int i = 0;
i <
w;
i++) {
715 for(
int j = 0; j <
h; j++) {
717 vars.emplace(std::make_shared<location_callable>(
loc), std::make_shared<terrain_callable>(
board_,
loc));
721 return variant(std::move(vars));
722 }
else if(key ==
"w") {
724 }
else if(key ==
"h") {
767 }
else if(key ==
"side_number") {
769 }
else if(key ==
"id") {
771 }
else if(key ==
"save_id") {
773 }
else if(key ==
"gold") {
775 }
else if(key ==
"start_gold") {
777 }
else if(key ==
"base_income") {
779 }
else if(key ==
"total_income") {
781 }
else if(key ==
"village_gold") {
783 }
else if(key ==
"village_support") {
785 }
else if(key ==
"recall_cost") {
787 }
else if(key ==
"is_human") {
789 }
else if(key ==
"is_ai") {
791 }
else if(key ==
"is_network") {
793 }
else if(key ==
"fog") {
795 }
else if(key ==
"shroud") {
797 }
else if(key ==
"hidden") {
799 }
else if(key ==
"flag") {
801 }
else if(key ==
"flag_icon") {
803 }
else if(key ==
"team_name") {
805 }
else if(key ==
"faction") {
807 }
else if(key ==
"faction_name") {
809 }
else if(key ==
"color") {
811 }
else if(key ==
"share_vision") {
813 }
else if(key ==
"carryover_bonus") {
815 }
else if(key ==
"carryover_percentage") {
817 }
else if(key ==
"carryover_add") {
819 }
else if(key ==
"recruit") {
820 std::vector<variant> result;
822 result.emplace_back(recruit);
824 return variant(std::move(result));
825 }
else if(key ==
"recall") {
826 std::vector<variant> result;
828 result.emplace_back(std::make_shared<unit_callable>(*u));
830 return variant(std::move(result));
831 }
else if(key ==
"wml_vars") {
842 }
else if(
key ==
"value") {
857 if(
auto obj = callable_cast<formula_callable*>(ctxt)) {
859 std::const_pointer_cast<formula_callable>(obj)->mutate_value(
key_,
value_);
863 ERR_SF <<
"ERROR #" << 5001 <<
" while executing 'set_var' formula function";
864 return make_callable<safe_call_result>(
fake_ptr(), 5001);
871 }
else if(key ==
"backup") {
887 if(
auto action = callable_cast<action_callable*>(
main_)) {
888 res = std::const_pointer_cast<action_callable>(action)->execute_self(ctxt);
891 if(callable_cast<safe_call_result*>(res)) {
898 callable.
add(
"error", res);
911 if(key ==
"status") {
913 }
else if(key ==
"object") {
948 if(key ==
"turn_number") {
950 }
else if(key ==
"time_of_day") {
952 }
else if(key ==
"side_number") {
954 }
else if(key ==
"sides") {
955 std::vector<variant> vars;
957 vars.emplace_back(std::make_shared<team_callable>(
team));
959 return variant(std::move(vars));
960 }
else if(key ==
"units") {
961 std::vector<variant> vars;
963 vars.emplace_back(std::make_shared<unit_callable>(
unit));
965 return variant(std::move(vars));
966 }
else if(key ==
"map") {
990 }
else if(key ==
"event_id") {
992 }
else if(key ==
"loc") {
994 }
else if(key ==
"second_loc") {
996 }
else if(key ==
"event_data") {
998 }
else if(key ==
"unit") {
1000 return make_callable<unit_callable>(*u1);
1002 }
else if(key ==
"second_unit") {
1004 return make_callable<unit_callable>(*u2);
1006 }
else if(key ==
"weapon") {
1009 return make_callable<attack_type_callable>(*
first_weapon);
1011 }
else if(key ==
"second_weapon") {
1033 }
else if(key ==
"green") {
1035 }
else if(key ==
"blue") {
1037 }
else if(key ==
"alpha") {
static lg::log_domain log_scripting_formula("scripting/formula")
A config object defines a single node in a WML file, with access to child nodes.
const_attr_itors attribute_range() const
auto all_children_view() const
In-order iteration over all children.
child_itors child_range(std::string_view key)
bool has_attribute(std::string_view key) const
bool has_child(std::string_view key) const
Determine whether a config has a child or not.
config & mandatory_child(std::string_view key, int n=0)
Returns the nth child with the given key, or throws an error if there is none.
Abstract class for exposing game data that doesn't depend on the GUI, however which for historical re...
virtual const gamemap & map() const =0
int w() const
Effective map width.
int h() const
Effective map height.
Encapsulates the map of the game.
This class stores all the data for a single 'side' (in game nomenclature).
const std::string & color() const
const std::string & faction() const
int village_support() const
const std::string & team_name() const
bool is_local_human() const
team_shared_vision::type share_vision() const
const t_string & faction_name() const
bool carryover_add() const
int carryover_percentage() const
const std::string & save_id() const
double carryover_bonus() const
const std::string & flag_icon() const
const std::string & flag() const
recall_list_manager & recall_list()
const std::set< std::string > & recruits() const
const std::string & icon_image() const
const t_string & name() const
const std::string & id() const
const t_string & description() const
int light_bonus(int base) const
Returns the light (lawful) bonus for this terrain when the time of day gives a base bonus.
const t_string & editor_name() const
int gives_healing() const
const std::string & id() const
std::string race_id() const
Returns the ID of this type's race without the need to build the type.
std::vector< std::string > get_ability_id_list() const
const std::string & id() const
The id for this unit_type.
const_attack_itors attacks() const
const std::string & usage() const
int experience_needed(bool with_acceleration=true) const
bool musthave_status(const std::string &status) const
const t_string & type_name() const
The name of the unit in the current language setting.
config::const_child_itors possible_traits() const
unit_alignments::type alignment() const
This class represents a single unit of a specific type.
Represents version numbers.
int do_compare(const formula_callable *callable) const override
variant get_value(const std::string &key) const override
attack_type_callable(const attack_type &attack)
void get_inputs(formula_input_vector &inputs) const override
variant get_value(const std::string &key) const override
void get_inputs(formula_input_vector &inputs) const override
void get_inputs(formula_input_vector &inputs) const override
variant get_value(const std::string &key) const override
int do_compare(const formula_callable *callable) const override
const config & get_config() const
void get_inputs(formula_input_vector &inputs) const override
variant get_value(const std::string &key) const override
std::shared_ptr< attack_type > second_weapon
const game_events::queued_event & event_info
std::shared_ptr< attack_type > first_weapon
const display_context & board_
const gamemap & get_gamemap() const
void get_inputs(formula_input_vector &inputs) const override
variant get_value(const std::string &key) const override
variant get_value(const std::string &key) const override
void get_inputs(formula_input_vector &inputs) const override
const map_location & loc() const
void get_inputs(formula_input_vector &inputs) const override
std::string serialize_to_string() const override
Inherited from formula_callable.
int do_compare(const formula_callable *callable) const override
variant get_value(const std::string &key) const override
const expression_ptr & get_backup() const
variant execute_self(variant ctxt) override
variant get_value(const std::string &key) const override
void get_inputs(formula_input_vector &inputs) const override
const map_location current_unit_location_
void get_inputs(formula_input_vector &inputs) const override
const_formula_callable_ptr failed_callable_
variant get_value(const std::string &key) const override
void get_inputs(formula_input_vector &inputs) const override
variant get_value(const std::string &key) const override
const std::string & key() const
variant execute_self(variant ctxt) override
void get_inputs(formula_input_vector &inputs) const override
variant get_value(const std::string &key) const override
variant get_value(const std::string &key) const override
terrain_callable(const display_context &m, const map_location &loc)
void get_inputs(formula_input_vector &inputs) const override
int do_compare(const formula_callable *callable) const override
variant get_value(const std::string &key) const override
const map_location & loc_
void get_inputs(formula_input_vector &inputs) const override
unit_callable(const map_location &loc, const unit &u)
int do_compare(const formula_callable *callable) const override
variant get_value(const std::string &key) const override
int do_compare(const formula_callable *callable) const override
void get_inputs(formula_input_vector &inputs) const override
const_formula_callable_ptr as_callable() const
std::string to_debug_string(bool verbose=false, formula_seen_stack *seen=nullptr) const
Definitions for the interface to Wesnoth Markup Language (WML).
std::string deprecated_message(const std::string &elem_name, DEP_LEVEL level, const version_info &version, const std::string &detail)
Interfaces for manipulating version numbers of engine, add-ons, etc.
static std::string _(const char *str)
std::vector< std::string > get_ability_id_list() const
Get a list of all abilities by ID.
int max_hitpoints() const
The max number of hitpoints this unit can have.
unit_alignments::type alignment() const
The alignment of this unit.
bool incapacitated() const
Check if the unit has been petrified.
int level() const
The current level of this unit.
std::string usage() const
Gets this unit's usage.
const std::string & get_role() const
Gets this unit's role.
const std::set< std::string > & recruits() const
The type IDs of the other units this unit may recruit, if possible.
const std::string & variation() const
The ID of the variation of this unit's type.
int hitpoints() const
The current number of hitpoints this unit has.
int cost() const
How much gold is required to recruit this unit.
bool get_state(const std::string &state) const
Check if the unit is affected by a status effect.
const std::string & type_id() const
The id of this unit's type.
bool get_hidden() const
Gets whether this unit is currently hidden on the map.
const std::set< std::string > get_states() const
Get the status effects currently affecting the unit.
const unit_race * race() const
Gets this unit's race.
int experience() const
The current number of experience points this unit has.
bool can_recruit() const
Whether this unit can recruit other units - ie, are they a leader unit.
const std::string & id() const
Gets this unit's id.
int side() const
The side this unit belongs to.
config & variables()
Gets any user-defined variables this unit 'owns'.
std::size_t underlying_id() const
This unit's unique internal ID.
int max_experience() const
The max number of experience points this unit can have.
unit_race::GENDER gender() const
The gender of this unit.
const t_string & name() const
Gets this unit's translatable display name.
const advances_to_t & advances_to() const
Gets the possible types this unit can advance to on level-up.
attack_itors attacks()
Gets an iterator over this unit's attacks.
int max_attacks() const
The maximum number of attacks this unit may perform per turn, usually 1.
int attacks_left() const
Gets the remaining number of attacks this unit can perform this turn.
std::size_t advancements_count() const
std::size_t traits_count() const
std::size_t objects_count() const
bool get_emit_zoc() const
Gets the raw zone-of-control flag, disregarding incapacitated.
const movetype & movement_type() const
Get the unit's movement type.
int movement_left() const
Gets how far a unit can move, considering the incapacitated flag.
int total_movement() const
The maximum moves this unit has.
map_location::direction facing() const
The current direction this unit is facing within its hex.
bool resting() const
Checks whether this unit is 'resting'.
bool is_flying() const
Check if the unit is a flying unit.
std::vector< std::string > get_advancements_list() const
std::vector< std::string > get_objects_list() const
int upkeep() const
Gets the amount of gold this unit costs a side per turn.
bool is_healthy() const
Gets whether this unit is healthy - ie, always rest heals.
bool is_fearless() const
Gets whether this unit is fearless - ie, unaffected by time of day.
std::vector< std::string > get_traits_list() const
Gets a list of the traits this unit currently has, including hidden traits.
Standard logging facilities (interface).
::tod_manager * tod_manager
play_controller * controller
std::vector< formula_input > formula_input_vector
variant execute_actions(const variant &execute, const variant &context)
Executes all action_callables in execute using the provided context.
static std::string get_location(const std::string &loc)
Define the game's event mechanism.
const std::string & gender_string(unit_race::GENDER gender)
unit_const_ptr get_unit() const
Encapsulates the map of the game.
static std::string write_direction(direction dir)
static const map_location & null_location()
int do_compare(const map_location &a) const
three-way comparator
static std::string get_string(enum_type key)
Converts a enum to its string equivalent.
variant operator()(double i) const
variant operator()(int i) const
variant operator()(const std::string &s) const
variant operator()(unsigned long long i) const
variant operator()(const t_string &s) const
variant operator()(utils::monostate) const
variant operator()(bool b) const
static map_location::direction s