whiteboard/recall.cpp

Go to the documentation of this file.
00001 /* $Id: recall.cpp 53876 2012-04-09 12:30:04Z jamit $ */
00002 /*
00003  Copyright (C) 2010 - 2012 by Gabriel Morin <gabrielmorin (at) gmail (dot) com>
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  */
00019 
00020 #include "recall.hpp"
00021 
00022 #include "manager.hpp"
00023 #include "side_actions.hpp"
00024 #include "utility.hpp"
00025 #include "visitor.hpp"
00026 
00027 #include "foreach.hpp"
00028 #include "game_display.hpp"
00029 #include "menu_events.hpp"
00030 #include "play_controller.hpp"
00031 #include "resources.hpp"
00032 #include "team.hpp"
00033 #include "unit.hpp"
00034 
00035 namespace wb
00036 {
00037 
00038 std::ostream& operator<<(std::ostream& s, recall_ptr recall)
00039 {
00040     assert(recall);
00041     return recall->print(s);
00042 }
00043 std::ostream& operator<<(std::ostream& s, recall_const_ptr recall)
00044 {
00045     assert(recall);
00046     return recall->print(s);
00047 }
00048 
00049 std::ostream& recall::print(std::ostream &s) const
00050 {
00051     s << "Recalling " << fake_unit_->name() << " [" << fake_unit_->id() << "] on hex " << recall_hex_;
00052     return s;
00053 }
00054 
00055 recall::recall(size_t team_index, bool hidden, const unit& unit, const map_location& recall_hex):
00056         action(team_index,hidden),
00057         temp_unit_(new class unit(unit)),
00058         recall_hex_(recall_hex),
00059         valid_(true),
00060         fake_unit_(new game_display::fake_unit(unit) )
00061 {
00062     this->init();
00063 }
00064 
00065 recall::recall(config const& cfg, bool hidden)
00066     : action(cfg,hidden)
00067     , temp_unit_()
00068     , recall_hex_(cfg.child("recall_hex_")["x"],cfg.child("recall_hex_")["y"])
00069     , valid_(true)
00070     , fake_unit_()
00071 {
00072     // Construct and validate temp_unit_
00073     size_t underlying_id = cfg["temp_unit_"];
00074     foreach(unit const& recall_unit, resources::teams->at(team_index()).recall_list())
00075     {
00076         if(recall_unit.underlying_id()==underlying_id)
00077         {
00078             temp_unit_.reset(new unit(recall_unit));
00079             break;
00080         }
00081     }
00082     if(!temp_unit_.get()) {
00083         throw action::ctor_err("recall: Invalid underlying_id");
00084     }
00085 
00086     fake_unit_.reset(new game_display::fake_unit(*temp_unit_)); //makes copy of temp_unit_
00087 
00088     this->init();
00089 }
00090 
00091 void recall::init()
00092 {
00093     temp_unit_->set_movement(0);
00094     temp_unit_->set_attacks(0);
00095 
00096     fake_unit_->set_location(recall_hex_);
00097     fake_unit_->set_movement(0);
00098     fake_unit_->set_attacks(0);
00099     fake_unit_->set_ghosted(false);
00100     fake_unit_->place_on_game_display( resources::screen);
00101 }
00102 
00103 recall::~recall()
00104 {
00105 }
00106 
00107 void recall::accept(visitor& v)
00108 {
00109     v.visit(shared_from_this());
00110 }
00111 
00112 void recall::execute(bool& success, bool& complete)
00113 {
00114     assert(valid_);
00115     assert(temp_unit_.get());
00116     temporary_unit_hider const raii(*fake_unit_);
00117     //Give back the spent gold so we don't get "not enough gold" message
00118     int cost = resources::teams->at(team_index()).recall_cost();
00119     resources::teams->at(team_index()).get_side_actions()->change_gold_spent_by(-cost);
00120     bool const result = resources::controller->get_menu_handler().do_recall(*temp_unit_, team_index() + 1, recall_hex_, map_location::null_location);
00121     if (!result) {
00122         resources::teams->at(team_index()).get_side_actions()->change_gold_spent_by(cost);
00123     }
00124     success = complete = result;
00125 }
00126 
00127 void recall::apply_temp_modifier(unit_map& unit_map)
00128 {
00129     assert(valid_);
00130     temp_unit_->set_location(recall_hex_);
00131 
00132     DBG_WB << "Inserting future recall " << temp_unit_->name() << " [" << temp_unit_->id()
00133             << "] at position " << temp_unit_->get_location() << ".\n";
00134 
00135     //temporarily remove unit from recall list
00136     std::vector<unit>& recalls = resources::teams->at(team_index()).recall_list();
00137     std::vector<unit>::iterator it = find_if_matches_id(recalls, temp_unit_->id());
00138     assert(it != recalls.end());
00139     recalls.erase(it);
00140 
00141     // Temporarily insert unit into unit_map
00142     //unit map takes ownership of temp_unit
00143     unit_map.insert(temp_unit_.release());
00144 
00145     //Add cost to money spent on recruits.
00146     int cost = resources::teams->at(team_index()).recall_cost();
00147     resources::teams->at(team_index()).get_side_actions()->change_gold_spent_by(cost);
00148 
00149     // Update gold in top bar
00150     resources::screen->invalidate_game_status();
00151 }
00152 
00153 void recall::remove_temp_modifier(unit_map& unit_map)
00154 {
00155     temp_unit_.reset(unit_map.extract(recall_hex_));
00156     assert(temp_unit_.get());
00157 
00158     //Put unit back into recall list
00159     resources::teams->at(team_index()).recall_list().push_back(*temp_unit_);
00160 }
00161 
00162 void recall::draw_hex(map_location const& hex)
00163 {
00164     if (hex == recall_hex_)
00165     {
00166         const double x_offset = 0.5;
00167         const double y_offset = 0.7;
00168         //position 0,0 in the hex is the upper left corner
00169         std::stringstream number_text;
00170         number_text << utils::unicode_minus << resources::teams->at(team_index()).recall_cost();
00171         size_t font_size = 16;
00172         SDL_Color color; color.r = 255; color.g = 0; color.b = 0; //red
00173         resources::screen->draw_text_in_hex(hex, display::LAYER_ACTIONS_NUMBERING,
00174                         number_text.str(), font_size, color, x_offset, y_offset);
00175     }
00176 }
00177 
00178 ///@todo Find a better way to serialize unit_ because underlying_id isn't cutting it
00179 config recall::to_config() const
00180 {
00181     config final_cfg = action::to_config();
00182 
00183     final_cfg["type"] = "recall";
00184     final_cfg["temp_unit_"] = static_cast<int>(temp_unit_->underlying_id());
00185 //  final_cfg["temp_cost_"] = temp_cost_; //Unnecessary
00186 
00187     config loc_cfg;
00188     loc_cfg["x"]=recall_hex_.x;
00189     loc_cfg["y"]=recall_hex_.y;
00190     final_cfg.add_child("recall_hex_",loc_cfg);
00191 
00192     return final_cfg;
00193 }
00194 
00195 void recall::do_hide() {fake_unit_->set_hidden(true);}
00196 void recall::do_show() {fake_unit_->set_hidden(false);}
00197 
00198 } //end namespace wb
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

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