Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "stage_unit_formulas.hpp"
00023 #include "ai.hpp"
00024
00025 #include "../../formula.hpp"
00026 #include "../../formula_function.hpp"
00027 #include "../../log.hpp"
00028 #include "../../resources.hpp"
00029 #include <boost/lexical_cast.hpp>
00030
00031 static lg::log_domain log_formula_ai("ai/stage/unit_formulas");
00032 #define LOG_AI LOG_STREAM(info, log_formula_ai)
00033 #define WRN_AI LOG_STREAM(warn, log_formula_ai)
00034 #define ERR_AI LOG_STREAM(err, log_formula_ai)
00035
00036 namespace ai {
00037
00038 stage_unit_formulas::stage_unit_formulas(ai_context &context, const config &cfg, formula_ai &fai)
00039 : stage(context,cfg), cfg_(cfg), fai_(fai)
00040 {
00041
00042 }
00043
00044
00045 stage_unit_formulas::~stage_unit_formulas()
00046 {
00047 }
00048
00049 bool stage_unit_formulas::do_play_stage()
00050 {
00051
00052 game_logic::unit_formula_set units_with_formulas;
00053
00054 unit_map &units_ = *resources::units;
00055
00056 for(unit_map::unit_iterator i = units_.begin() ; i != units_.end() ; ++i)
00057 {
00058 if (i->side() == get_side()) {
00059 if (i->has_formula() || i->has_loop_formula()) {
00060 int priority = 0;
00061 if (i->has_priority_formula()) {
00062 try {
00063 game_logic::const_formula_ptr priority_formula(fai_.create_optional_formula(i->get_priority_formula()));
00064 if (priority_formula) {
00065 game_logic::map_formula_callable callable(&fai_);
00066 callable.add_ref();
00067 callable.add("me", variant(new unit_callable(*i)));
00068 priority = (game_logic::formula::evaluate(priority_formula, callable)).as_int();
00069 } else {
00070 WRN_AI << "priority formula skipped, maybe it's empty or incorrect"<< std::endl;
00071 }
00072 } catch(game_logic::formula_error& e) {
00073 if(e.filename == "formula")
00074 e.line = 0;
00075 fai_.handle_exception( e, "Unit priority formula error for unit: '" + i->type_id() + "' standing at (" + str_cast(i->get_location().x + 1) + "," + str_cast(i->get_location().y + 1) + ")");
00076
00077 priority = 0;
00078 } catch(type_error& e) {
00079 priority = 0;
00080 ERR_AI << "formula type error while evaluating unit priority formula " << e.message << "\n";
00081 }
00082 }
00083
00084 units_with_formulas.insert( game_logic::unit_formula_pair( i, priority ) );
00085 }
00086 }
00087 }
00088
00089 for(game_logic::unit_formula_set::iterator pair_it = units_with_formulas.begin() ; pair_it != units_with_formulas.end() ; ++pair_it)
00090 {
00091 unit_map::iterator i = pair_it->first;
00092
00093 if( i.valid() ) {
00094
00095 if (i->has_formula()) {
00096 try {
00097 game_logic::const_formula_ptr formula(fai_.create_optional_formula(i->get_formula()));
00098 if (formula) {
00099 game_logic::map_formula_callable callable(&fai_);
00100 callable.add_ref();
00101 callable.add("me", variant(new unit_callable(*i)));
00102 fai_.make_action(formula, callable);
00103 } else {
00104 WRN_AI << "unit formula skipped, maybe it's empty or incorrect" << std::endl;
00105 }
00106 }
00107 catch(game_logic::formula_error& e) {
00108 if(e.filename == "formula") {
00109 e.line = 0;
00110 }
00111 fai_.handle_exception( e, "Unit formula error for unit: '" + i->type_id() + "' standing at (" + str_cast(i->get_location().x + 1) + "," + str_cast(i->get_location().y + 1) + ")");
00112 }
00113 }
00114 }
00115
00116 if( i.valid() ) {
00117 if (i->has_loop_formula())
00118 {
00119 try {
00120 game_logic::const_formula_ptr loop_formula(fai_.create_optional_formula(i->get_loop_formula()));
00121 if (loop_formula) {
00122 game_logic::map_formula_callable callable(&fai_);
00123 callable.add_ref();
00124 callable.add("me", variant(new unit_callable(*i)));
00125 while ( !fai_.make_action(loop_formula, callable).is_empty() && i.valid() )
00126 {
00127 }
00128 } else {
00129 WRN_AI << "Loop formula skipped, maybe it's empty or incorrect" << std::endl;
00130 }
00131 } catch(game_logic::formula_error& e) {
00132 if (e.filename == "formula") {
00133 e.line = 0;
00134 }
00135 fai_.handle_exception( e, "Unit loop formula error for unit: '" + i->type_id() + "' standing at (" + str_cast(i->get_location().x + 1) + "," + str_cast(i->get_location().y + 1) + ")");
00136 }
00137 }
00138 }
00139 }
00140 return false;
00141 }
00142
00143
00144 void stage_unit_formulas::on_create()
00145 {
00146
00147 }
00148
00149
00150 config stage_unit_formulas::to_config() const
00151 {
00152 config cfg = stage::to_config();
00153
00154 return cfg;
00155 }
00156
00157 }