1 /*
2    Copyright (C) 2014 - 2018 by David White <dave@whitevine.net>
3    Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY.
11 
12    See the COPYING file for more details.
13 */
14 
15 #pragma once
16 
17 #include "formula/callable.hpp"
18 #include "formula/formula.hpp"
19 #include "map/location.hpp"
20 #include "units/ptr.hpp"
21 
22 class display_context;
23 class gamemap;
24 class team;
25 class terrain_type;
26 class unit;
27 class unit_type;
28 
29 namespace wfl
30 {
31 
32 class terrain_callable : public formula_callable
33 {
34 public:
35 	terrain_callable(const display_context& m, const map_location& loc);
36 
37 	variant get_value(const std::string& key) const override;
38 	void get_inputs(formula_input_vector& inputs) const override;
39 
40 	int do_compare(const formula_callable* callable) const override;
41 
42 private:
43 	const map_location loc_;
44 	const terrain_type& t_;
45 	const int owner_;
46 };
47 
48 class gamemap_callable : public formula_callable
49 {
50 public:
gamemap_callable(const display_context & g)51 	explicit gamemap_callable(const display_context& g) : board_(g)
52 	{}
53 
54 	void get_inputs(formula_input_vector& inputs) const override;
55 	variant get_value(const std::string& key) const override;
56 
57 	const gamemap& get_gamemap() const;
58 
59 private:
60 	const display_context& board_;
61 };
62 
63 class location_callable : public formula_callable
64 {
65 public:
location_callable(const map_location & loc)66 	explicit location_callable(const map_location& loc) : loc_(loc)
67 	{
68 		type_ = LOCATION_C;
69 	}
70 
71 	void serialize_to_string(std::string& str) const override;
72 
loc() const73 	const map_location& loc() const { return loc_; }
74 
75 private:
76 	map_location loc_;
77 
78 	variant get_value(const std::string& key) const override;
79 
80 	void get_inputs(formula_input_vector& inputs) const override;
81 	int do_compare(const formula_callable* callable) const override;
82 };
83 
84 class attack_type_callable : public formula_callable
85 {
86 public:
87 	explicit attack_type_callable(const attack_type& attack);
88 
89 	variant get_value(const std::string& key) const override;
90 	void get_inputs(formula_input_vector& inputs) const override;
91 
92 	int do_compare(const formula_callable* callable) const override;
93 
get_attack_type() const94 	const attack_type& get_attack_type() const { return *att_; }
95 
96 private:
97 	const_attack_ptr att_;
98 };
99 
100 class unit_callable : public formula_callable
101 {
102 public:
unit_callable(const map_location & loc,const unit & u)103 	unit_callable(const map_location& loc, const unit& u) : loc_(loc), u_(u)
104 	{
105 		type_ = UNIT_C;
106 	}
107 
108 	explicit unit_callable(const unit &u);
109 
110 	variant get_value(const std::string& key) const override;
111 	void get_inputs(formula_input_vector& inputs) const override;
112 
113 	int do_compare(const formula_callable* callable) const override;
114 
get_unit() const115 	const unit& get_unit() const { return u_; }
get_location() const116 	const map_location& get_location() const { return loc_; }
117 
118 private:
119 	const map_location& loc_;
120 	const unit& u_;
121 };
122 
123 class unit_type_callable : public formula_callable
124 {
125 public:
unit_type_callable(const unit_type & u)126 	explicit unit_type_callable(const unit_type& u) : u_(u)
127 	{
128 		type_ = UNIT_TYPE_C;
129 	}
130 
131 	variant get_value(const std::string& key) const override;
132 	void get_inputs(formula_input_vector& inputs) const override;
133 
134 	int do_compare(const formula_callable* callable) const override;
135 
get_unit_type() const136 	const unit_type& get_unit_type() const { return u_; }
137 
138 private:
139 	const unit_type& u_;
140 };
141 
142 class config_callable : public formula_callable
143 {
144 public:
config_callable(const config & c)145 	explicit config_callable(const config& c) : cfg_(c) {}
146 
147 	variant get_value(const std::string& key) const override;
148 	void get_inputs(formula_input_vector& inputs) const override;
149 	int do_compare(const formula_callable* callable) const override;
150 
get_config() const151 	const config& get_config() const { return cfg_; }
152 
153 private:
154 	const config& cfg_;
155 };
156 
157 class team_callable : public formula_callable
158 {
159 public:
team_callable(const team & t)160 	explicit team_callable(const team& t) : team_(t) {}
161 
162 	void get_inputs(formula_input_vector& inputs) const override;
163 	variant get_value(const std::string& key) const override;
164 
get_team() const165 	const team& get_team() const { return team_; }
166 
167 private:
168 	const team& team_;
169 };
170 
171 class set_var_callable : public action_callable
172 {
173 public:
set_var_callable(const std::string & key,const variant & value)174 	set_var_callable(const std::string& key, const variant& value)
175 		: key_(key), value_(value)
176 	{}
177 
key() const178 	const std::string& key() const { return key_; }
value() const179 	variant value() const { return value_; }
180 	variant execute_self(variant ctxt) override;
181 
182 private:
183 	std::string key_;
184 	variant value_;
185 	variant get_value(const std::string& key) const override;
186 
187 	void get_inputs(formula_input_vector& inputs) const override;
188 };
189 
190 class safe_call_callable : public action_callable
191 {
192 
193 public:
safe_call_callable(const variant & main,const expression_ptr & backup)194 	safe_call_callable(const variant& main, const expression_ptr& backup)
195 		: main_(main)
196 		, backup_()
197 		, backup_formula_(backup)
198 	{}
199 
get_main() const200 	const variant& get_main() const { return main_; }
get_backup() const201 	const expression_ptr& get_backup() const { return backup_formula_; }
202 
set_backup_result(const variant & v)203 	void set_backup_result(const variant& v)
204 	{
205 		backup_ = v;
206 	}
207 
208 	variant execute_self(variant ctxt) override;
209 
210 private:
211 	variant main_;
212 	variant backup_;
213 	expression_ptr backup_formula_;
214 	variant get_value(const std::string& key) const override;
215 
216 	void get_inputs(formula_input_vector& inputs) const override;
217 };
218 
219 class safe_call_result : public formula_callable
220 {
221 public:
safe_call_result(const_formula_callable_ptr callable,int status,const map_location & loc=map_location ())222 	safe_call_result(const_formula_callable_ptr callable, int status, const map_location& loc = map_location())
223 		: failed_callable_(callable)
224 		, current_unit_location_(loc)
225 		, status_(status)
226 	{}
227 
228 private:
229 	const_formula_callable_ptr failed_callable_;
230 	const map_location current_unit_location_;
231 	const int status_;
232 
233 	variant get_value(const std::string& key) const override;
234 
235 	void get_inputs(formula_input_vector& inputs) const override;
236 };
237 
238 } // namespace wfl
239