16 #include "formula/callable_objects.hpp" 38 #define LOG_SF LOG_STREAM(info, log_scripting_formula) 39 #define ERR_SF LOG_STREAM(err, log_scripting_formula) 48 }
else if(key ==
"y") {
64 if(loc_callable ==
nullptr) {
86 if(key ==
"id" || key ==
"name") {
88 }
else if(key ==
"description") {
90 }
else if(key ==
"type") {
92 }
else if(key ==
"icon") {
94 }
else if(key ==
"range") {
96 }
else if(key ==
"damage") {
98 }
else if(key ==
"number_of_attacks" || key ==
"number" || key ==
"num_attacks" || key ==
"attacks") {
100 }
else if(key ==
"attack_weight") {
102 }
else if(key ==
"defense_weight") {
104 }
else if(key ==
"accuracy") {
106 }
else if(key ==
"parry") {
108 }
else if(key ==
"movement_used") {
110 }
else if(key ==
"attacks_used") {
112 }
else if(key ==
"specials" || key ==
"special") {
113 std::vector<variant> res;
115 for(
const auto special :
att_->specials().all_children_range()) {
116 if(!special.cfg[
"id"].empty()) {
117 res.emplace_back(special.cfg[
"id"].str());
147 if(att_callable ==
nullptr) {
151 if(
att_->damage() != att_callable->
att_->damage()) {
152 return att_->damage() - att_callable->
att_->damage();
155 if(
att_->num_attacks() != att_callable->
att_->num_attacks()) {
156 return att_->num_attacks() - att_callable->
att_->num_attacks();
159 if(
att_->id() != att_callable->
att_->id()) {
160 return att_->id().compare(att_callable->
att_->id());
163 if(
att_->type() != att_callable->
att_->type()) {
164 return att_->type().compare(att_callable->
att_->type());
167 if(
att_->range() != att_callable->
att_->range()) {
168 return att_->range().compare(att_callable->
att_->range());
171 const auto self_specials =
att_->specials().all_children_range();
172 const auto other_specials = att_callable->
att_->specials().all_children_range();
173 if(self_specials.size() != other_specials.size()) {
174 return self_specials.size() < other_specials.size() ? -1 : 1;
176 for(std::size_t
i = 0;
i < self_specials.size(); ++
i) {
177 const auto&
s = self_specials[
i].cfg[
"id"];
178 const auto& o = other_specials[
i].cfg[
"id"];
180 return s.str().compare(o.str());
200 }
else if(key ==
"y") {
206 }
else if(key ==
"loc") {
211 return variant(std::make_shared<location_callable>(
loc_));
212 }
else if(key ==
"terrain") {
217 }
else if(key ==
"id") {
219 }
else if(key ==
"type") {
221 }
else if(key ==
"name") {
223 }
else if(key ==
"usage") {
225 }
else if(key ==
"leader" || key ==
"canrecruit") {
227 }
else if(key ==
"undead") {
229 }
else if(key ==
"attacks") {
230 std::vector<variant> res;
232 res.emplace_back(std::make_shared<attack_type_callable>(att));
236 }
else if(key ==
"abilities") {
238 }
else if(key ==
"hitpoints") {
240 }
else if(key ==
"max_hitpoints") {
242 }
else if(key ==
"experience") {
244 }
else if(key ==
"max_experience") {
246 }
else if(key ==
"level" || key ==
"full") {
249 }
else if(key ==
"total_movement" || key ==
"max_moves") {
251 }
else if(key ==
"movement_left" || key ==
"moves") {
253 }
else if(key ==
"attacks_left") {
255 }
else if(key ==
"max_attacks") {
257 }
else if(key ==
"traits") {
259 }
else if(key ==
"extra_recruit") {
261 }
else if(key ==
"advances_to") {
263 }
else if(key ==
"states" || key ==
"status") {
265 }
else if(key ==
"side") {
268 }
else if(key ==
"side_number") {
270 }
else if(key ==
"cost") {
272 }
else if(key ==
"upkeep") {
274 }
else if(key ==
"loyal") {
277 }
else if(key ==
"hidden") {
279 }
else if(key ==
"petrified") {
281 }
else if(key ==
"resting") {
283 }
else if(key ==
"role") {
285 }
else if(key ==
"race") {
287 }
else if(key ==
"gender") {
289 }
else if(key ==
"variation") {
291 }
else if(key ==
"zoc") {
293 }
else if(key ==
"alignment") {
295 }
else if(key ==
"facing") {
297 }
else if(key ==
"resistance" || key ==
"movement_cost" || key ==
"vision_cost" || key ==
"jamming_cost" || key ==
"defense") {
300 bool needs_flip =
false;
301 if(key ==
"resistance") {
302 mt.get_resistances().write(cfg);
304 }
else if(key ==
"movement_cost") {
305 mt.get_movement().write(cfg);
306 }
else if(key ==
"vision_cost") {
307 mt.get_vision().write(cfg);
308 }
else if(key ==
"jamming_cost") {
309 mt.get_vision().write(cfg);
310 }
else if(key ==
"defense") {
311 mt.get_defense().write(cfg);
314 std::map<variant, variant> res;
324 }
else if(key ==
"flying") {
326 }
else if(key ==
"vars") {
332 }
else if(key ==
"wml_vars") {
334 }
else if(key ==
"n" || key ==
"s" || key ==
"ne" || key ==
"se" || key ==
"nw" || key ==
"sw" ||
335 key ==
"lawful" || key ==
"neutral" || key ==
"chaotic" || key ==
"liminal" ||
336 key ==
"male" || key ==
"female")
397 if(u_callable ==
nullptr) {
408 }
else if(key ==
"type") {
410 }
else if(key ==
"alignment") {
412 }
else if(key ==
"race") {
414 }
else if(key ==
"abilities") {
416 }
else if(key ==
"traits") {
417 std::vector<variant> res;
418 for(
const auto&
config :
u_.possible_traits()) {
419 res.emplace_back(
config[
"id"].str());
423 }
else if(key ==
"attacks") {
424 std::vector<variant> res;
426 res.emplace_back(std::make_shared<attack_type_callable>(att));
430 }
else if(key ==
"hitpoints" || key ==
"max_hitpoints") {
432 }
else if(key ==
"experience" || key ==
"max_experience") {
433 return variant(
u_.experience_needed(
true));
434 }
else if(key ==
"level") {
436 }
else if(key ==
"total_movement" || key ==
"max_moves" || key ==
"moves") {
438 }
else if(key ==
"unpoisonable") {
439 return variant(
u_.musthave_status(
"unpoisonable"));
440 }
else if(key ==
"unslowable") {
441 return variant(
u_.musthave_status(
"unslowable"));
442 }
else if(key ==
"unpetrifiable") {
443 return variant(
u_.musthave_status(
"unpetrifiable"));
444 }
else if(key ==
"undrainable") {
445 return variant(
u_.musthave_status(
"undrainable"));
446 }
else if(key ==
"unplagueable") {
447 return variant(
u_.musthave_status(
"unplagueable"));
448 }
else if(key ==
"cost") {
450 }
else if(key ==
"recall_cost") {
452 }
else if(key ==
"usage") {
481 if(u_callable ==
nullptr) {
485 return u_.
id().compare(u_callable->
u_.
id());
489 #ifdef USING_BOOST_VARIANT
490 :
public boost::static_visitor<variant>
507 if(cfg_.has_attribute(key)) {
509 }
else if(cfg_.has_child(key)) {
510 std::vector<variant> result;
511 for(
const auto& child : cfg_.child_range(key)) {
512 result.emplace_back(std::make_shared<config_callable>(child));
516 }
else if(key ==
"__all_children") {
517 std::vector<variant> result;
518 for(
const auto child : cfg_.all_children_range()) {
519 const variant cfg_child(std::make_shared<config_callable>(child.cfg));
520 const variant kv(std::make_shared<key_value_pair>(
variant(child.key), cfg_child));
521 result.push_back(kv);
525 }
else if(key ==
"__children") {
526 std::map<std::string, std::vector<variant>>
build;
527 for(
const auto child : cfg_.all_children_range()) {
528 const variant cfg_child(std::make_shared<config_callable>(child.cfg));
529 build[child.key].push_back(cfg_child);
532 std::map<variant,variant> result;
533 for(
auto&
p : build) {
538 }
else if(key ==
"__attributes") {
539 std::map<variant,variant> result;
540 for(
const auto& val : cfg_.attribute_range()) {
556 for(
const auto& val : cfg_.attribute_range()) {
566 if(cfg_callable ==
nullptr) {
586 }
else if(key ==
"y") {
588 }
else if(key ==
"loc") {
589 return variant(std::make_shared<location_callable>(
loc_));
590 }
else if(key ==
"id") {
592 }
else if(key ==
"name") {
594 }
else if(key ==
"editor_name") {
596 }
else if(key ==
"description") {
598 }
else if(key ==
"icon") {
600 }
else if(key ==
"light") {
602 }
else if(key ==
"village") {
604 }
else if(key ==
"castle") {
606 }
else if(key ==
"keep") {
608 }
else if(key ==
"healing") {
610 }
else if(key ==
"owner") {
613 }
else if(key ==
"owner_side") {
641 if(terr_callable ==
nullptr) {
661 if(key ==
"terrain") {
662 int w = get_gamemap().w();
663 int h = get_gamemap().h();
665 std::vector<variant> vars;
666 for(
int i = 0;
i <
w;
i++) {
667 for(
int j = 0; j <
h; j++) {
669 vars.emplace_back(std::make_shared<terrain_callable>(board_, loc));
674 }
else if(key ==
"gamemap") {
675 int w = get_gamemap().w();
676 int h = get_gamemap().h();
678 std::map<variant, variant> vars;
679 for(
int i = 0;
i <
w;
i++) {
680 for(
int j = 0; j <
h; j++) {
682 vars.emplace(std::make_shared<location_callable>(loc), std::make_shared<terrain_callable>(board_, loc));
687 }
else if(key ==
"w") {
689 }
else if(key ==
"h") {
722 add_input(inputs,
"carryover_percentage");
733 }
else if(key ==
"side_number") {
735 }
else if(key ==
"id") {
736 return variant(team_.save_id());
737 }
else if(key ==
"save_id") {
738 return variant(team_.save_id());
739 }
else if(key ==
"gold") {
741 }
else if(key ==
"start_gold") {
742 return variant(team_.start_gold());
743 }
else if(key ==
"base_income") {
744 return variant(team_.base_income());
745 }
else if(key ==
"total_income") {
746 return variant(team_.total_income());
747 }
else if(key ==
"village_gold") {
748 return variant(team_.village_gold());
749 }
else if(key ==
"village_support") {
750 return variant(team_.village_support());
751 }
else if(key ==
"recall_cost") {
752 return variant(team_.recall_cost());
753 }
else if(key ==
"is_human") {
754 return variant(team_.is_local_human());
755 }
else if(key ==
"is_ai") {
756 return variant(team_.is_local_ai());
757 }
else if(key ==
"is_network") {
758 return variant(team_.is_network());
759 }
else if(key ==
"fog") {
760 return variant(team_.uses_fog());
761 }
else if(key ==
"shroud") {
762 return variant(team_.uses_shroud());
763 }
else if(key ==
"hidden") {
764 return variant(team_.hidden());
765 }
else if(key ==
"flag") {
767 }
else if(key ==
"flag_icon") {
768 return variant(team_.flag_icon());
769 }
else if(key ==
"team_name") {
770 return variant(team_.team_name());
771 }
else if(key ==
"color") {
773 }
else if(key ==
"share_vision") {
775 }
else if(key ==
"carryover_bonus") {
777 }
else if(key ==
"carryover_percentage") {
778 return variant(team_.carryover_percentage());
779 }
else if(key ==
"carryover_add") {
780 return variant(team_.carryover_add());
781 }
else if(key ==
"recruit") {
782 std::vector<variant> result;
783 for(
const auto& recruit : team_.recruits()) {
784 result.emplace_back(recruit);
787 }
else if(key ==
"recall") {
788 std::vector<variant> result;
789 for(
const auto& u : team_.recall_list()) {
790 result.push_back(std::make_shared<unit_callable>(*u));
793 }
else if(key ==
"wml_vars") {
794 return variant(std::make_shared<config_callable>(team_.variables()));
804 }
else if(key ==
"value") {
821 LOG_SF <<
"Setting variable: " << key_ <<
" -> " << value_.to_debug_string();
822 obj->mutate_value(key_, value_);
827 ERR_SF <<
"ERROR #" << 5001 <<
" while executing 'set_var' formula function";
836 }
else if(key ==
"backup") {
853 res = action->execute_self(ctxt);
863 callable.
add(
"error", res);
868 backup_ = get_backup()->evaluate(callable);
876 if(key ==
"status") {
878 }
else if(key ==
"object") {
879 if(failed_callable_) {
880 return variant(failed_callable_);
884 }
else if(key ==
"current_loc" && current_unit_location_ !=
map_location()) {
885 return variant(std::make_shared<location_callable>(current_unit_location_));
913 if(key ==
"turn_number") {
915 }
else if(key ==
"time_of_day") {
917 }
else if(key ==
"side_number") {
919 }
else if(key ==
"sides") {
920 std::vector<variant> vars;
922 vars.emplace_back(std::make_shared<team_callable>(
team));
925 }
else if(key ==
"units") {
926 std::vector<variant> vars;
928 vars.emplace_back(std::make_shared<unit_callable>(
unit));
931 }
else if(key ==
"map") {
954 return variant(event_info.name);
955 }
else if(key ==
"event_id") {
957 }
else if(key ==
"loc") {
958 return variant(std::make_shared<location_callable>(event_info.loc1));
959 }
else if(key ==
"second_loc") {
960 return variant(std::make_shared<location_callable>(event_info.loc2));
961 }
else if(key ==
"event_data") {
962 return variant(std::make_shared<config_callable>(event_info.data));
963 }
else if(key ==
"unit") {
964 if(
auto u1 = event_info.loc1.get_unit()) {
965 return variant(std::make_shared<unit_callable>(*u1));
967 }
else if(key ==
"second_unit") {
968 if(
auto u2 = event_info.loc2.get_unit()) {
969 return variant(std::make_shared<unit_callable>(*u2));
971 }
else if(key ==
"weapon") {
972 if(event_info.data.has_child(
"first")) {
973 first_weapon = std::make_shared<attack_type>(event_info.data.child(
"first"));
974 return variant(std::make_shared<attack_type_callable>(*first_weapon));
976 }
else if(key ==
"second_weapon") {
977 if(event_info.data.has_child(
"second")) {
978 second_weapon = std::make_shared<attack_type>(event_info.data.child(
"second"));
979 return variant(std::make_shared<attack_type_callable>(*second_weapon));
const map_location & loc() const
variant execute_variant(const variant &to_exec)
play_controller * controller
variant get_value(const std::string &key) const override
int attacks_left() const
Gets the remaining number of attacks this unit can perform this turn.
::tod_manager * tod_manager
void get_inputs(formula_input_vector &inputs) const override
const t_string & description() const
void get_inputs(formula_input_vector &inputs) const override
This class represents a single unit of a specific type.
const std::string & type_id() const
The id of this unit's type.
variant get_value(const std::string &key) const override
Interfaces for manipulating version numbers of engine, add-ons, etc.
bool is_flying() const
Check if the unit is a flying unit.
const std::string & id() const
bool get_state(const std::string &state) const
Check if the unit is affected by a status effect.
variant get_value(const std::string &key) const override
unit_race::GENDER gender() const
The gender of this unit.
const movetype & movement_type() const
Get the unit's movement type.
int hitpoints() const
The current number of hitpoints this unit has.
config & variables()
Gets any user-defined variables this unit 'owns'.
variant get_value(const std::string &key) const override
int do_compare(const map_location &a) const
three-way comparator
const std::string & variation() const
The ID of the variation of this unit's type.
std::vector< formula_input > formula_input_vector
map_location::DIRECTION facing() const
The current direction this unit is facing within its hex.
void get_inputs(formula_input_vector &inputs) const override
void get_inputs(formula_input_vector &inputs) const override
bool resting() const
Checks whether this unit is 'resting'.
void get_inputs(formula_input_vector &inputs) const override
bool get_emit_zoc() const
Gets the raw zone-of-control flag, disregarding incapacitated.
bool get_hidden() const
Gets whether this unit is currently hidden on the map.
Definitions for the interface to Wesnoth Markup Language (WML).
int cost() const
How much gold is required to recruit this unit.
const_attr_itors attribute_range() const
variant operator()(const t_string &s) const
variant get_value(const std::string &key) const override
variant operator()(int i) const
variant get_value(const std::string &key) const override
int light_bonus(int base) const
Returns the light (lawful) bonus for this terrain when the time of day gives a base bonus...
void get_inputs(formula_input_vector &inputs) const override
variant execute_self(variant ctxt) override
This class stores all the data for a single 'side' (in game nomenclature).
const t_string & editor_name() const
const std::string & id() const
Gets this unit's id.
int do_compare(const formula_callable *callable) const override
std::string deprecated_message(const std::string &elem_name, DEP_LEVEL level, const version_info &version, const std::string &detail)
const config & get_config() const
attack_type_callable(const attack_type &attack)
int do_compare(const formula_callable *callable) const override
Encapsulates the map of the game.
int do_compare(const formula_callable *callable) const override
const t_string & name() const
Gets this unit's translatable display name.
int upkeep() const
Gets the amount of gold this unit costs a side per turn.
int max_experience() const
The max number of experience points this unit can have.
int level() const
The current level of this unit.
const std::string & id() const
The id for this unit_type.
void serialize_to_string(std::string &str) const override
const t_string & type_name() const
Gets the translatable name of this unit's type.
int gives_healing() const
variant get_value(const std::string &key) const override
unit_alignments::type alignment() const
The alignment of this unit.
void get_inputs(formula_input_vector &inputs) const override
const map_location & loc_
variant get_value(const std::string &key) const override
const std::string & gender_string(unit_race::GENDER gender)
void get_inputs(formula_input_vector &inputs) const override
Encapsulates the map of the game.
const_formula_callable_ptr as_callable() const
const gamemap & get_gamemap() const
variant operator()(bool b) const
int max_hitpoints() const
The max number of hitpoints this unit can have.
const std::string & get_role() const
Gets this unit's role.
variant operator()(double i) const
static std::string get_location(const std::string &loc)
int do_compare(const formula_callable *callable) const override
static map_location::DIRECTION s
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
variant operator()(const std::string &s) const
bool can_recruit() const
Whether this unit can recruit other units - ie, are they a leader unit.
std::string usage() const
Gets this unit's usage.
variant get_value(const std::string &key) const override
Define the game's event mechanism.
attack_itors attacks()
Gets an iterator over this unit's attacks.
unit_callable(const map_location &loc, const unit &u)
variant operator()(utils::monostate) const
std::vector< std::string > get_traits_list() const
Gets a list of the traits this unit currently has.
const unit_race * race() const
Gets this unit's race.
variant get_value(const std::string &key) const override
Represents version numbers.
const t_string & name() const
const std::vector< std::string > & recruits() const
The type IDs of the other units this unit may recruit, if possible.
unit_formula_manager & formula_manager() const
Get the unit formula manager.
std::shared_ptr< T > try_convert() const
int experience() const
The current number of experience points this unit has.
int do_compare(const formula_callable *callable) const override
void get_inputs(formula_input_vector &inputs) const override
variant get_value(const std::string &key) const override
Standard logging facilities (interface).
const std::string & id() const
variant execute_self(variant ctxt) override
static const map_location & null_location()
bool incapacitated() const
Check if the unit has been petrified.
int total_movement() const
The maximum moves this unit has.
terrain_callable(const display_context &m, const map_location &loc)
int side() const
The side this unit belongs to.
std::unique_ptr< window > build(const builder_window::window_resolution &definition)
Builds a window.
std::vector< std::string > get_ability_list() const
Get a list of all abilities by ID.
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
A config object defines a single node in a WML file, with access to child nodes.
const std::string & str() const
const std::set< std::string > get_states() const
Get the status effects currently affecting the unit.
const advances_to_t & advances_to() const
Gets the possible types this unit can advance to on level-up.
int recall_cost() const
How much gold it costs to recall this unit, or -1 if the side's default recall cost is used...
static std::string write_direction(DIRECTION dir)
int movement_left() const
Gets how far a unit can move, considering the incapacitated flag.
std::size_t underlying_id() const
This unit's unique internal ID.
variant operator()(unsigned long long i) const
int max_attacks() const
The maximum number of attacks this unit may perform per turn, usually 1.
const std::string & icon_image() const
void get_inputs(formula_input_vector &inputs) const override
static std::string get_string(enum_type key)
Converts a enum to its string equivalent.