00001 #ifndef CALLABLE_OBJECTS_HPP_INCLUDED
00002 #define CALLABLE_OBJECTS_HPP_INCLUDED
00003
00004 #include <map>
00005
00006 #include "formula_callable.hpp"
00007 #include "map.hpp"
00008 #include "unit.hpp"
00009 #include "foreach.hpp"
00010
00011 #define CALLABLE_WRAPPER_START(klass) \
00012 class klass##_callable : public game_logic::formula_callable { \
00013 const klass& object_; \
00014 public: \
00015 explicit klass##_callable(const klass& object) : object_(object) \
00016 {} \
00017 \
00018 const klass& get_##klass() const { return object_; } \
00019 void get_inputs(std::vector<game_logic::formula_input>* inputs) const \
00020 { \
00021 using game_logic::FORMULA_READ_ONLY;
00022
00023 #define CALLABLE_WRAPPER_INPUT(VAR) \
00024 inputs->push_back(game_logic::formula_input(#VAR, FORMULA_READ_ONLY));
00025
00026 #define CALLABLE_WRAPPER_INPUT_END \
00027 } \
00028 \
00029 variant get_value(const std::string& key) const {
00030
00031 #define CALLABLE_WRAPPER_VAR(VAR) \
00032 if(key == #VAR) { \
00033 return variant(object_.VAR); \
00034 } else
00035
00036 #define CALLABLE_WRAPPER_FN(VAR) \
00037 if(key == #VAR) { \
00038 return variant(object_.VAR()); \
00039 } else
00040
00041
00042
00043 #define CALLABLE_WRAPPER_END \
00044 { return variant(); } \
00045 } \
00046 };
00047
00048 class terrain_callable : public game_logic::formula_callable {
00049 public:
00050 typedef gamemap::location location;
00051 terrain_callable(const terrain_type& t, const location loc)
00052 : loc_(loc), t_(t)
00053 {}
00054
00055 variant get_value(const std::string& key) const;
00056 void get_inputs(std::vector<game_logic::formula_input>* inputs) const;
00057 private:
00058 const location loc_;
00059 const terrain_type &t_;
00060 };
00061
00062 CALLABLE_WRAPPER_START(gamemap)
00063 CALLABLE_WRAPPER_INPUT(terrain)
00064 CALLABLE_WRAPPER_INPUT(w)
00065 CALLABLE_WRAPPER_INPUT(h)
00066 CALLABLE_WRAPPER_INPUT_END
00067 if(key == "terrain") {
00068 int w = object_.w();
00069 int h = object_.h();
00070 std::vector<variant> vars;
00071 for(int i = 0;i < w; i++) {
00072 for(int j = 0;j < h; j++) {
00073 const gamemap::location loc(i,j);
00074 vars.push_back(variant(new terrain_callable(object_.get_terrain_info(loc), loc)));
00075 }
00076 }
00077 return variant(&vars);
00078 } else
00079 CALLABLE_WRAPPER_FN(w)
00080 CALLABLE_WRAPPER_FN(h)
00081 CALLABLE_WRAPPER_END
00082
00083 class location_callable : public game_logic::formula_callable {
00084 gamemap::location loc_;
00085
00086 variant get_value(const std::string& key) const;
00087
00088 void get_inputs(std::vector<game_logic::formula_input>* inputs) const;
00089 int do_compare(const game_logic::formula_callable* callable) const;
00090
00091 public:
00092 explicit location_callable(const gamemap::location& loc) : loc_(loc)
00093 {}
00094
00095 const gamemap::location& loc() const { return loc_; }
00096
00097 void serialize_to_string(std::string& str) const;
00098 };
00099
00100 class move_callable : public game_logic::formula_callable {
00101 gamemap::location src_, dst_;
00102 variant get_value(const std::string& key) const {
00103 if(key == "src") {
00104 return variant(new location_callable(src_));
00105 } else if(key == "dst") {
00106 return variant(new location_callable(dst_));
00107 } else {
00108 return variant();
00109 }
00110 }
00111 void get_inputs(std::vector<game_logic::formula_input>* inputs) const {
00112 inputs->push_back(game_logic::formula_input("src", game_logic::FORMULA_READ_ONLY));
00113 inputs->push_back(game_logic::formula_input("dst", game_logic::FORMULA_READ_ONLY));
00114 }
00115 public:
00116 move_callable(const gamemap::location& src, const gamemap::location& dst) :
00117 src_(src), dst_(dst)
00118 {}
00119
00120 const gamemap::location& src() const { return src_; }
00121 const gamemap::location& dst() const { return dst_; }
00122 };
00123
00124 class move_map_callable : public game_logic::formula_callable {
00125 typedef std::multimap<gamemap::location, gamemap::location> move_map;
00126 const move_map& srcdst_;
00127 const move_map& dstsrc_;
00128
00129 variant get_value(const std::string& key) const;
00130 void get_inputs(std::vector<game_logic::formula_input>* inputs) const;
00131 public:
00132 move_map_callable(const move_map& srcdst, const move_map& dstsrc)
00133 : srcdst_(srcdst), dstsrc_(dstsrc)
00134 {}
00135
00136 const move_map& srcdst() const { return srcdst_; }
00137 const move_map& dstsrc() const { return dstsrc_; }
00138 };
00139
00140 class unit_callable : public game_logic::formula_callable {
00141 public:
00142 typedef gamemap::location location;
00143 unit_callable(const std::pair<location, unit>& pair)
00144 : loc_(pair.first), u_(pair.second)
00145 {}
00146
00147 const unit& get_unit() const { return u_; }
00148 variant get_value(const std::string& key) const;
00149 void get_inputs(std::vector<game_logic::formula_input>* inputs) const;
00150 private:
00151 const location& loc_;
00152 const unit& u_;
00153 };
00154
00155 CALLABLE_WRAPPER_START(team)
00156 CALLABLE_WRAPPER_INPUT(gold)
00157 CALLABLE_WRAPPER_INPUT(start_gold)
00158 CALLABLE_WRAPPER_INPUT(base_income)
00159 CALLABLE_WRAPPER_INPUT(village_gold)
00160 CALLABLE_WRAPPER_INPUT(name)
00161 CALLABLE_WRAPPER_INPUT(is_human)
00162 CALLABLE_WRAPPER_INPUT(is_ai)
00163 CALLABLE_WRAPPER_INPUT(is_network)
00164 CALLABLE_WRAPPER_INPUT_END
00165 CALLABLE_WRAPPER_FN(gold)
00166 if(key == "start_gold") { \
00167 return variant(lexical_cast<int>(object_.start_gold())); \
00168 } else
00169 CALLABLE_WRAPPER_FN(base_income)
00170 CALLABLE_WRAPPER_FN(village_gold)
00171 CALLABLE_WRAPPER_FN(name)
00172 CALLABLE_WRAPPER_FN(is_human)
00173 CALLABLE_WRAPPER_FN(is_ai)
00174 CALLABLE_WRAPPER_FN(is_network)
00175 CALLABLE_WRAPPER_END
00176 #endif