The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
recruit.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010 - 2016 by Gabriel Morin <gabrielmorin (at) gmail (dot) com>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13  */
14 
15 /**
16  * @file
17  */
18 
19 #include "recruit.hpp"
20 
21 #include "manager.hpp"
22 #include "side_actions.hpp"
23 #include "utility.hpp"
24 #include "visitor.hpp"
25 
26 #include "fake_unit_manager.hpp"
27 #include "fake_unit_ptr.hpp"
28 #include "menu_events.hpp"
29 #include "play_controller.hpp"
30 #include "resources.hpp"
31 #include "units/unit.hpp"
33 #include "units/map.hpp"
34 #include "units/types.hpp"
35 
36 namespace wb
37 {
38 
39 std::ostream& operator<<(std::ostream& s, recruit_ptr recruit)
40 {
41  assert(recruit);
42  return recruit->print(s);
43 }
44 std::ostream& operator<<(std::ostream& s, recruit_const_ptr recruit)
45 {
46  assert(recruit);
47  return recruit->print(s);
48 }
49 
50 std::ostream& recruit::print(std::ostream &s) const
51 {
52  s << "Recruiting " << unit_name_ << " on hex " << recruit_hex_;
53  return s;
54 }
55 
56 recruit::recruit(size_t team_index, bool hidden, const std::string& unit_name, const map_location& recruit_hex):
57  action(team_index,hidden),
58  unit_name_(unit_name),
59  recruit_hex_(recruit_hex),
60  temp_unit_(create_corresponding_unit()), //auto-ptr ownership transfer
61  fake_unit_(unit_ptr(new unit(*temp_unit_))), //temp_unit_ *copied* into new fake unit
62  cost_(0)
63 {
64  this->init();
65 }
66 
67 recruit::recruit(config const& cfg, bool hidden)
68  : action(cfg,hidden)
69  , unit_name_(cfg["unit_name_"])
70  , recruit_hex_(cfg.child("recruit_hex_")["x"],cfg.child("recruit_hex_")["y"])
71  , temp_unit_()
72  , fake_unit_()
73  , cost_(0)
74 {
75  // Validate unit_name_
77  throw action::ctor_err("recruit: Invalid recruit unit type");
78 
79  // Construct temp_unit_ and fake_unit_
80  temp_unit_ = create_corresponding_unit(); //auto-ptr ownership transfer
81  fake_unit_.reset(unit_ptr (new unit(*temp_unit_))), //temp_unit_ copied into new fake_unit
82 
83  this->init();
84 }
85 
87 {
88  fake_unit_->set_location(recruit_hex_);
89  fake_unit_->set_movement(0, true);
90  fake_unit_->set_attacks(0);
91  fake_unit_->anim_comp().set_ghosted(false);
93 
94  cost_ = fake_unit_->type().cost();
95 }
96 
98 {
99 }
100 
102 {
103  v.visit(shared_from_this());
104 }
105 
106 void recruit::execute(bool& success, bool& complete)
107 {
108  assert(valid());
109  temporary_unit_hider const raii(*fake_unit_);
110  int const side_num = team_index() + 1;
111  //Give back the spent gold so we don't get "not enough gold" message
112  resources::teams->at(team_index()).get_side_actions()->change_gold_spent_by(-cost_);
114  //If it failed, take back the gold
115  if (!result) {
116  resources::teams->at(team_index()).get_side_actions()->change_gold_spent_by(cost_);
117  }
118  success = complete = result;
119 }
120 
122 {
123  assert(valid());
124  temp_unit_->set_location(recruit_hex_);
125 
126  DBG_WB << "Inserting future recruit [" << temp_unit_->id()
127  << "] at position " << temp_unit_->get_location() << ".\n";
128 
129  // Add cost to money spent on recruits.
130  resources::teams->at(team_index()).get_side_actions()->change_gold_spent_by(cost_);
131 
132  // Temporarily insert unit into unit_map
133  // unit map takes ownership of temp_unit
134  unit_map.insert(temp_unit_);
135 
136  // Update gold in the top bar
138 }
139 
141 {
142  //Unit map gives back ownership of temp_unit_
143  temp_unit_ = unit_map.extract(recruit_hex_);
144  assert(temp_unit_.get());
145 }
146 
148 {
149  if (hex == recruit_hex_)
150  {
151  const double x_offset = 0.5;
152  const double y_offset = 0.7;
153  //position 0,0 in the hex is the upper left corner
154  std::stringstream number_text;
155  number_text << utils::unicode_minus << cost_;
156  size_t font_size = 16;
157  SDL_Color color; color.r = 255; color.g = 0; color.b = 0; //red
159  number_text.str(), font_size, color, x_offset, y_offset);
160  }
161 }
162 
164 {
166 }
167 
168 
170 {
172  assert(type);
173  int side_num = team_index() + 1;
174  //real_unit = false needed to avoid generating random traits and causing OOS
175  bool real_unit = false;
176  unit_ptr result(new unit(*type, side_num, real_unit));
177  result->set_movement(0, true);
178  result->set_attacks(0);
179  return result; //ownership gets transferred to returned unique_ptr copy
180 }
181 
183 {
184  //Check that destination hex is still free
186  return LOCATION_OCCUPIED;
187  }
188  //Check that unit to recruit is still in side's recruit list
189  //FIXME: look at leaders extra_recruit too.
190  const std::set<std::string>& recruits = (*resources::teams)[team_index()].recruits();
191  if(recruits.find(unit_name_) == recruits.end()) {
192  return UNIT_UNAVAILABLE;
193  }
194  //Check that there is still enough gold to recruit this unit
195  if(temp_unit_->cost() > (*resources::teams)[team_index()].gold()) {
196  return NOT_ENOUGH_GOLD;
197  }
198  //Check that there is a leader available to recruit this unit
200  return NO_LEADER;
201  }
202 
203  return OK;
204 }
205 
207 {
208  config final_cfg = action::to_config();
209 
210  final_cfg["type"] = "recruit";
211  final_cfg["unit_name_"] = unit_name_;
212 // final_cfg["temp_cost_"] = temp_cost_; //Unnecessary
213 
214  config loc_cfg;
215  loc_cfg["x"]=recruit_hex_.x;
216  loc_cfg["y"]=recruit_hex_.y;
217  final_cfg.add_child("recruit_hex_",loc_cfg);
218 
219  return final_cfg;
220 }
221 
222 void recruit::do_hide() {fake_unit_->set_hidden(true);}
223 void recruit::do_show() {fake_unit_->set_hidden(false);}
224 
225 }
play_controller * controller
Definition: resources.cpp:21
void reset()
Reset the internal unit pointer, and deregister from the manager. This fake_unit_ptr is now dissassoc...
void invalidate_game_status()
Function to invalidate the game status displayed on the sidebar.
Definition: display.hpp:299
virtual ~recruit()
Definition: recruit.cpp:97
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
Definition: display.cpp:3536
Definition: unit.hpp:95
virtual config to_config() const
Constructs and returns a config object representing this object.
Definition: recruit.cpp:206
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1221
void place_on_fake_unit_manager(fake_unit_manager *d)
Place this on manager's fake_units_ dequeue.
void init()
Definition: recruit.cpp:86
game_display * screen
Definition: resources.cpp:27
boost::shared_ptr< recruit > shared_from_this()
Definition: recruit.hpp:80
unit * find_recruiter(size_t team_index, map_location const &hex)
Definition: utility.cpp:78
map_location const get_recruit_hex() const
Definition: recruit.hpp:74
virtual void visit(move_ptr move)=0
unit_type_data unit_types
Definition: types.cpp:1314
virtual void execute(bool &success, bool &complete)
Output parameters: success: Whether or not to continue an execute-all after this execution complete: ...
Definition: recruit.cpp:106
virtual void apply_temp_modifier(unit_map &unit_map)
Applies temporarily the result of this action to the specified unit map.
Definition: recruit.cpp:121
void draw_text_in_hex(const map_location &loc, const tdrawing_layer layer, const std::string &text, size_t font_size, SDL_Color color, double x_in_hex=0.5, double y_in_hex=0.5)
Draw text on a hex.
Definition: display.cpp:1668
virtual void do_hide()
Called by the non-virtual hide() and show(), respectively.
Definition: recruit.cpp:222
static config unit_name(const unit *u)
Definition: reports.cpp:133
unit_ptr temp_unit_
Definition: recruit.hpp:87
virtual void draw_hex(map_location const &hex)
Gets called by display when drawing a hex, to allow actions to draw to the screen.
Definition: recruit.cpp:147
const std::string unicode_minus
bool valid()
Returns whether this action is valid or not.
Definition: action.hpp:133
fake_unit_ptr fake_unit_
Definition: recruit.hpp:88
size_t team_index() const
Returns the index of the team that owns this action.
Definition: action.hpp:82
GLuint GLuint end
Definition: glew.h:1221
GLuint64EXT * result
Definition: glew.h:10727
std::vector< team > * teams
Definition: resources.cpp:29
std::pair< unit_iterator, bool > insert(unit_ptr p)
Adds the unit to the map.
Definition: map.cpp:126
error
Possible errors.
Definition: action.hpp:104
unit_ptr create_corresponding_unit()
Definition: recruit.cpp:169
const GLdouble * v
Definition: glew.h:1359
config & add_child(const std::string &key)
Definition: config.cpp:743
fake_unit_manager * fake_units
Definition: resources.cpp:32
virtual void do_show()
Definition: recruit.cpp:223
virtual void accept(visitor &v)
Definition: recruit.cpp:101
GLuint color
Definition: glew.h:5801
std::string unit_name_
Definition: recruit.hpp:84
bool do_recruit(const std::string &name, int side_num, const map_location &last_hex)
Encapsulates the map of the game.
Definition: location.hpp:38
Move numbering for the whiteboard.
Definition: display.hpp:895
virtual void redraw()
Redrawing function, called each time the action situation might have changed.
Definition: recruit.cpp:163
virtual std::ostream & print(std::ostream &s) const
Definition: recruit.cpp:50
map_location recruit_hex_
Definition: recruit.hpp:85
recruit(size_t team_index, bool hidden, const std::string &unit_name, const map_location &recruit_hex)
Definition: recruit.cpp:56
bool find(E event, F functor)
Tests whether an event handler is available.
events::menu_handler & get_menu_handler()
virtual config to_config() const
Constructs and returns a config object representing this object.
Definition: action.cpp:50
#define DBG_WB
Definition: typedefs.hpp:29
unit_ptr extract(const map_location &loc)
Extracts a unit from the map.
Definition: map.cpp:249
Container associating units to locations.
Definition: map.hpp:90
std::ostream & operator<<(std::ostream &s, action_ptr action)
Definition: action.cpp:33
const unit_type * find(const std::string &key, unit_type::BUILD_STATUS status=unit_type::FULL) const
Finds a unit_type by its id() and makes sure it is built to the specified level.
Definition: types.cpp:1155
visitor is an abstract interface : action.accept(visitor) calls visitor.visit(action) ...
Abstract base class for all the whiteboard planned actions.
Definition: action.hpp:33
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
GLdouble s
Definition: glew.h:1358
const int font_size
virtual void remove_temp_modifier(unit_map &unit_map)
Removes the result of this action from the specified unit map.
Definition: recruit.cpp:140
GLsizei const GLcharARB ** string
Definition: glew.h:4503
unit_map * units
Definition: resources.cpp:35
Definition: display.hpp:47
virtual error check_validity() const
Check the validity of the action.
Definition: recruit.cpp:182
Abstract base class for all the visitors (cf GoF Visitor Design Pattern) the whiteboard uses...
Definition: visitor.hpp:32