ai/formula/stage_unit_formulas.cpp

Go to the documentation of this file.
00001 /* $Id: stage_unit_formulas.cpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
00002 /*
00003    Copyright (C) 2009 - 2012 by Yurii Chernyi <terraninfo@terraninfo.net>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 /**
00017  * @file
00018  * Defines formula ai unit formulas stage
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     //execute units formulas first
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     //we have no state on our own
00147 }
00148 
00149 
00150 config stage_unit_formulas::to_config() const
00151 {
00152     config cfg = stage::to_config();
00153     //we have no state on our own
00154     return cfg;
00155 }
00156 
00157 } // end of namespace ai
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:02:44 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs