The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
recall.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 "recall.hpp"
20 
21 #include "manager.hpp"
22 #include "side_actions.hpp"
23 #include "utility.hpp"
24 #include "visitor.hpp"
25 
26 #include "actions/create.hpp"
27 #include "fake_unit_manager.hpp"
28 #include "fake_unit_ptr.hpp"
29 #include "game_display.hpp"
30 #include "recall_list_manager.hpp"
31 #include "resources.hpp"
32 #include "replay_helper.hpp"
33 #include "statistics.hpp"
34 #include "synced_context.hpp"
35 #include "team.hpp"
36 #include "units/unit.hpp"
38 
39 namespace wb
40 {
41 
42 std::ostream& operator<<(std::ostream& s, recall_ptr recall)
43 {
44  assert(recall);
45  return recall->print(s);
46 }
47 std::ostream& operator<<(std::ostream& s, recall_const_ptr recall)
48 {
49  assert(recall);
50  return recall->print(s);
51 }
52 
53 std::ostream& recall::print(std::ostream &s) const
54 {
55  s << "Recalling " << fake_unit_->name() << " [" << fake_unit_->id() << "] on hex " << recall_hex_;
56  return s;
57 }
58 
59 recall::recall(size_t team_index, bool hidden, const unit& unit, const map_location& recall_hex):
60  action(team_index,hidden),
61  temp_unit_(new class unit(unit)),
62  recall_hex_(recall_hex),
63  fake_unit_(unit_ptr( new class unit(unit) ) )
64 {
65  this->init();
66 }
67 
68 recall::recall(config const& cfg, bool hidden)
69  : action(cfg,hidden)
70  , temp_unit_()
71  , recall_hex_(cfg.child("recall_hex_")["x"],cfg.child("recall_hex_")["y"])
72  , fake_unit_()
73 {
74  // Construct and validate temp_unit_
75  size_t underlying_id = cfg["temp_unit_"];
76  for(const unit_const_ptr & recall_unit : resources::teams->at(team_index()).recall_list())
77  {
78  if(recall_unit->underlying_id()==underlying_id)
79  {
80  temp_unit_.reset(new class unit(*recall_unit)); //TODO: is it necessary to make a copy?
81  break;
82  }
83  }
84  if(!temp_unit_.get()) {
85  throw action::ctor_err("recall: Invalid underlying_id");
86  }
87 
88  fake_unit_.reset(unit_ptr(new class unit(*temp_unit_))); //makes copy of temp_unit_
89 
90  this->init();
91 }
92 
94 {
95  temp_unit_->set_movement(0, true);
96  temp_unit_->set_attacks(0);
97 
98  fake_unit_->set_location(recall_hex_);
99  fake_unit_->set_movement(0, true);
100  fake_unit_->set_attacks(0);
101  fake_unit_->anim_comp().set_ghosted(false);
103 }
104 
106 {
107 }
108 
110 {
111  v.visit(shared_from_this());
112 }
113 
114 void recall::execute(bool& success, bool& complete)
115 {
116  team & current_team = resources::teams->at(team_index());
117 
118  assert(valid());
119  assert(temp_unit_.get());
120  temporary_unit_hider const raii(*fake_unit_);
121  //Give back the spent gold so we don't get "not enough gold" message
122  int cost = current_team.recall_cost();
123  if (temp_unit_->recall_cost() > -1) {
124  cost=temp_unit_->recall_cost();
125  }
126  current_team.get_side_actions()->change_gold_spent_by(-cost);
127  bool const result = synced_context::run_and_throw("recall",
129  true,
130  true,
132 
133  if (!result) {
134  current_team.get_side_actions()->change_gold_spent_by(cost);
135  }
136  success = complete = result;
137 }
138 
140 {
141  assert(valid());
142  temp_unit_->set_location(recall_hex_);
143 
144  DBG_WB << "Inserting future recall " << temp_unit_->name() << " [" << temp_unit_->id()
145  << "] at position " << temp_unit_->get_location() << ".\n";
146 
147  //temporarily remove unit from recall list
148  unit_ptr it = resources::teams->at(team_index()).recall_list().extract_if_matches_id(temp_unit_->id());
149  assert(it);
150 
151  //Add cost to money spent on recruits.
152  int cost = resources::teams->at(team_index()).recall_cost();
153  if (it->recall_cost() > -1) {
154  cost = it->recall_cost();
155  }
156 
157  // Temporarily insert unit into unit_map
158  //unit map takes ownership of temp_unit
159  unit_map.insert(temp_unit_);
160 
161  resources::teams->at(team_index()).get_side_actions()->change_gold_spent_by(cost);
162  // Update gold in top bar
164 }
165 
167 {
168  temp_unit_ = unit_map.extract(recall_hex_);
169  assert(temp_unit_.get());
170 
171  //Put unit back into recall list
172  resources::teams->at(team_index()).recall_list().add(temp_unit_);
173 }
174 
176 {
177  if (hex == recall_hex_)
178  {
179  const double x_offset = 0.5;
180  const double y_offset = 0.7;
181  //position 0,0 in the hex is the upper left corner
182  std::stringstream number_text;
183  unit &it = *get_unit();
184  int cost = statistics::un_recall_unit_cost(it);
185  if (cost < 0) {
186  number_text << utils::unicode_minus << resources::teams->at(team_index()).recall_cost();
187  }
188  else {
189  number_text << utils::unicode_minus << cost;
190  }
191  size_t font_size = 16;
192  SDL_Color color; color.r = 255; color.g = 0; color.b = 0; //red
194  number_text.str(), font_size, color, x_offset, y_offset);
195  }
196 }
197 
199 {
201 }
202 
204 {
205  //Check that destination hex is still free
207  return LOCATION_OCCUPIED;
208  }
209  //Check that unit to recall is still in side's recall list
210  if( !(*resources::teams)[team_index()].recall_list().find_if_matches_id(temp_unit_->id()) ) {
211  return UNIT_UNAVAILABLE;
212  }
213  //Check that there is still enough gold to recall this unit
214  if((*resources::teams)[team_index()].recall_cost() > (*resources::teams)[team_index()].gold()) {
215  return NOT_ENOUGH_GOLD;
216  }
217  //Check that there is a leader available to recall this unit
219  return NO_LEADER;
220  }
221 
222  return OK;
223 }
224 
225 ///@todo Find a better way to serialize unit_ because underlying_id isn't cutting it
227 {
228  config final_cfg = action::to_config();
229 
230  final_cfg["type"] = "recall";
231  final_cfg["temp_unit_"] = static_cast<int>(temp_unit_->underlying_id());
232 // final_cfg["temp_cost_"] = temp_cost_; //Unnecessary
233 
234  config loc_cfg;
235  loc_cfg["x"]=recall_hex_.x;
236  loc_cfg["y"]=recall_hex_.y;
237  final_cfg.add_child("recall_hex_",loc_cfg);
238 
239  return final_cfg;
240 }
241 
242 void recall::do_hide() {fake_unit_->set_hidden(true);}
243 void recall::do_show() {fake_unit_->set_hidden(false);}
244 
245 } //end namespace wb
void reset()
Reset the internal unit pointer, and deregister from the manager. This fake_unit_ptr is now dissassoc...
virtual unit_ptr get_unit() const
Definition: recall.hpp:65
boost::shared_ptr< wb::side_actions > get_side_actions() const
get the whiteboard planned actions for this team
Definition: team.hpp:382
virtual void do_show()
Definition: recall.cpp:243
void invalidate_game_status()
Function to invalidate the game status displayed on the sidebar.
Definition: display.hpp:299
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
Definition: display.cpp:3536
Definition: unit.hpp:95
fake_unit_ptr fake_unit_
Definition: recall.hpp:87
virtual error check_validity() const
Check the validity of the action.
Definition: recall.cpp:203
static config get_recall(const std::string &unit_id, const map_location &loc, const map_location &from)
virtual void do_hide()
Called by the non-virtual hide() and show(), respectively.
Definition: recall.cpp:242
void place_on_fake_unit_manager(fake_unit_manager *d)
Place this on manager's fake_units_ dequeue.
virtual void execute(bool &success, bool &complete)
Output parameters: success: Whether or not to continue an execute-all after this execution complete: ...
Definition: recall.cpp:114
game_display * screen
Definition: resources.cpp:27
boost::shared_ptr< recall > shared_from_this()
Definition: recall.hpp:75
virtual config to_config() const
Definition: recall.cpp:226
recall(size_t team_index, bool hidden, const unit &unit, const map_location &recall_hex)
Definition: recall.cpp:59
unit * find_recruiter(size_t team_index, map_location const &hex)
Definition: utility.cpp:78
virtual void accept(visitor &v)
Definition: recall.cpp:109
map_location const get_recall_hex() const
Definition: recall.hpp:69
virtual void remove_temp_modifier(unit_map &unit_map)
Removes the result of this action from the specified unit map.
Definition: recall.cpp:166
virtual void visit(move_ptr move)=0
virtual void apply_temp_modifier(unit_map &unit_map)
Applies temporarily the result of this action to the specified unit map.
Definition: recall.cpp:139
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
-file sdl_utils.hpp
virtual void draw_hex(const map_location &hex)
Gets called by display when drawing a hex, to allow actions to draw to the screen.
Definition: recall.cpp:175
const std::string unicode_minus
bool valid()
Returns whether this action is valid or not.
Definition: action.hpp:133
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:50
size_t team_index() const
Returns the index of the team that owns this action.
Definition: action.hpp:82
static std::string at(const std::string &file, int line)
int recall_cost() const
Definition: team.hpp:198
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
static void ignore_error_function(const std::string &message, bool heavy)
a function to be passed to run_in_synced_context to ignore the error.
const GLdouble * v
Definition: glew.h:1359
int un_recall_unit_cost(const unit &u)
Definition: statistics.cpp:508
config & add_child(const std::string &key)
Definition: config.cpp:743
fake_unit_manager * fake_units
Definition: resources.cpp:32
static const map_location & null_location()
Definition: location.hpp:195
map_location recall_hex_
Definition: recall.hpp:86
GLuint color
Definition: glew.h:5801
Encapsulates the map of the game.
Definition: location.hpp:38
Various functions related to the creation of units (recruits, recalls, and placed units)...
Move numbering for the whiteboard.
Definition: display.hpp:895
virtual void redraw()
Redrawing function, called each time the action situation might have changed.
Definition: recall.cpp:198
virtual std::ostream & print(std::ostream &s) const
Definition: recall.cpp:53
void init()
Definition: recall.cpp:93
static bool run_and_throw(const std::string &commandname, const config &data, bool use_undo=true, bool show=true, synced_command::error_handler_function error_handler=default_error_function)
boost::intrusive_ptr< unit > unit_ptr
Definition: ptr.hpp:29
bool find(E event, F functor)
Tests whether an event handler is available.
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
bool recall_unit(const std::string &id, team &current_team, const map_location &loc, const map_location &from, bool show, bool use_undo)
Recalls the unit with the indicated ID for the provided team.
Definition: create.cpp:731
Container associating units to locations.
Definition: map.hpp:90
virtual ~recall()
Definition: recall.cpp:105
std::ostream & operator<<(std::ostream &s, action_ptr action)
Definition: action.cpp:33
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
unit_ptr temp_unit_
Definition: recall.hpp:85
GLdouble s
Definition: glew.h:1358
const int font_size
unit_map * units
Definition: resources.cpp:35
Definition: display.hpp:47
Abstract base class for all the visitors (cf GoF Visitor Design Pattern) the whiteboard uses...
Definition: visitor.hpp:32