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 #include "recruit.hpp"
00021
00022 #include "manager.hpp"
00023 #include "side_actions.hpp"
00024 #include "utility.hpp"
00025 #include "visitor.hpp"
00026
00027 #include "game_display.hpp"
00028 #include "menu_events.hpp"
00029 #include "play_controller.hpp"
00030 #include "resources.hpp"
00031 #include "unit.hpp"
00032 #include "unit_map.hpp"
00033 #include "unit_types.hpp"
00034
00035 namespace wb
00036 {
00037
00038 std::ostream& operator<<(std::ostream& s, recruit_ptr recruit)
00039 {
00040 assert(recruit);
00041 return recruit->print(s);
00042 }
00043 std::ostream& operator<<(std::ostream& s, recruit_const_ptr recruit)
00044 {
00045 assert(recruit);
00046 return recruit->print(s);
00047 }
00048
00049 std::ostream& recruit::print(std::ostream &s) const
00050 {
00051 s << "Recruiting " << unit_name_ << " on hex " << recruit_hex_;
00052 return s;
00053 }
00054
00055 recruit::recruit(size_t team_index, bool hidden, const std::string& unit_name, const map_location& recruit_hex):
00056 action(team_index,hidden),
00057 unit_name_(unit_name),
00058 recruit_hex_(recruit_hex),
00059 temp_unit_(create_corresponding_unit()),
00060 valid_(true),
00061 fake_unit_(new game_display::fake_unit(*temp_unit_)),
00062 cost_(0)
00063 {
00064 this->init();
00065 }
00066
00067 recruit::recruit(config const& cfg, bool hidden)
00068 : action(cfg,hidden)
00069 , unit_name_(cfg["unit_name_"])
00070 , recruit_hex_(cfg.child("recruit_hex_")["x"],cfg.child("recruit_hex_")["y"])
00071 , temp_unit_()
00072 , valid_(true)
00073 , fake_unit_()
00074 , cost_(0)
00075 {
00076
00077 if(!unit_types.find(unit_name_))
00078 throw action::ctor_err("recruit: Invalid recruit unit type");
00079
00080
00081 temp_unit_ = create_corresponding_unit();
00082 fake_unit_.reset(new game_display::fake_unit(*temp_unit_)),
00083
00084 this->init();
00085 }
00086
00087 void recruit::init()
00088 {
00089 fake_unit_->set_location(recruit_hex_);
00090 fake_unit_->set_movement(0);
00091 fake_unit_->set_attacks(0);
00092 fake_unit_->set_ghosted(false);
00093 fake_unit_->place_on_game_display(resources::screen);
00094
00095 cost_ = fake_unit_->type()->cost();
00096 }
00097
00098 recruit::~recruit()
00099 {
00100 }
00101
00102 void recruit::accept(visitor& v)
00103 {
00104 v.visit(shared_from_this());
00105 }
00106
00107 void recruit::execute(bool& success, bool& complete)
00108 {
00109 assert(valid_);
00110 temporary_unit_hider const raii(*fake_unit_);
00111 int const side_num = team_index() + 1;
00112
00113 resources::teams->at(team_index()).get_side_actions()->change_gold_spent_by(-cost_);
00114 bool const result = resources::controller->get_menu_handler().do_recruit(unit_name_, side_num, recruit_hex_);
00115
00116 if (!result) {
00117 resources::teams->at(team_index()).get_side_actions()->change_gold_spent_by(cost_);
00118 }
00119 success = complete = result;
00120 }
00121
00122 void recruit::apply_temp_modifier(unit_map& unit_map)
00123 {
00124 assert(valid_);
00125 temp_unit_->set_location(recruit_hex_);
00126
00127 DBG_WB << "Inserting future recruit [" << temp_unit_->id()
00128 << "] at position " << temp_unit_->get_location() << ".\n";
00129
00130
00131 resources::teams->at(team_index()).get_side_actions()->change_gold_spent_by(cost_);
00132
00133
00134
00135 unit_map.insert(temp_unit_.release());
00136
00137
00138 resources::screen->invalidate_game_status();
00139 }
00140
00141 void recruit::remove_temp_modifier(unit_map& unit_map)
00142 {
00143
00144 temp_unit_.reset(unit_map.extract(recruit_hex_));
00145 assert(temp_unit_.get());
00146 }
00147
00148 void recruit::draw_hex(map_location const& hex)
00149 {
00150 if (hex == recruit_hex_)
00151 {
00152 const double x_offset = 0.5;
00153 const double y_offset = 0.7;
00154
00155 std::stringstream number_text;
00156 number_text << utils::unicode_minus << cost_;
00157 size_t font_size = 16;
00158 SDL_Color color; color.r = 255; color.g = 0; color.b = 0;
00159 resources::screen->draw_text_in_hex(hex, display::LAYER_ACTIONS_NUMBERING,
00160 number_text.str(), font_size, color, x_offset, y_offset);
00161 }
00162 }
00163
00164 std::auto_ptr<unit> recruit::create_corresponding_unit()
00165 {
00166 unit_type const* type = unit_types.find(unit_name_);
00167 assert(type);
00168 int side_num = team_index() + 1;
00169
00170 bool real_unit = false;
00171 std::auto_ptr<unit> result(new unit(type, side_num, real_unit));
00172 result->set_movement(0);
00173 result->set_attacks(0);
00174 return result;
00175 }
00176
00177 config recruit::to_config() const
00178 {
00179 config final_cfg = action::to_config();
00180
00181 final_cfg["type"] = "recruit";
00182 final_cfg["unit_name_"] = unit_name_;
00183
00184
00185 config loc_cfg;
00186 loc_cfg["x"]=recruit_hex_.x;
00187 loc_cfg["y"]=recruit_hex_.y;
00188 final_cfg.add_child("recruit_hex_",loc_cfg);
00189
00190 return final_cfg;
00191 }
00192
00193 void recruit::do_hide() {fake_unit_->set_hidden(true);}
00194 void recruit::do_show() {fake_unit_->set_hidden(false);}
00195
00196 }