The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
mapbuilder.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 "mapbuilder.hpp"
20 
21 #include "action.hpp"
22 #include "move.hpp"
23 #include "side_actions.hpp"
24 #include "utility.hpp"
25 
26 #include "game_board.hpp"
27 #include "play_controller.hpp"
28 #include "resources.hpp"
29 #include "units/unit.hpp"
30 #include "units/map.hpp"
31 
32 #include <boost/range/adaptor/reversed.hpp>
33 
34 namespace wb
35 {
36 
38  : unit_map_(unit_map)
39  , applied_actions_()
40  , applied_actions_this_turn_()
41  , resetters_()
42  , removers_()
43  , acted_this_turn_()
44  , has_invalid_actions_()
45  , invalid_actions_()
46 {
47 }
48 
50 {
51  try {
53  //Remember that the member variable resetters_ is destructed here
54  } catch (...) {}
55 }
56 
58 {
59  for (team& t : *resources::teams) {
60  //Reset spent gold to zero, it'll be recalculated during the map building
61  t.get_side_actions()->reset_gold_spent();
62  }
63 
64  int current_side = resources::controller->current_side();
65  for (unit& u : *resources::units) {
66  bool on_current_side = (u.side() == current_side);
67 
68  //Remove any unit the current side cannot see to avoid their detection by planning
69  //Units will be restored to the unit map by destruction of removers_
70 
71  if(!on_current_side && !u.is_visible_to_team((*resources::teams)[viewer_team()], resources::gameboard->map(), false)) {
72  removers_.push_back(new temporary_unit_remover(*resources::units, u.get_location()));
73 
74  //Don't do anything else to the removed unit!
75  continue;
76  }
77 
78  //Reset movement points, to be restored by destruction of resetters_
79 
80  //restore movement points only to units not on the current side
81  resetters_.push_back(new unit_movement_resetter(u,!on_current_side));
82  //make sure current side's units are not reset to full moves on first turn
83  if(on_current_side) {
84  acted_this_turn_.insert(&u);
85  }
86  }
87 }
88 
90 {
91  pre_build();
92  if(!wb::has_actions()) {
93  return;
94  }
95 
96  bool end = false;
97  for(size_t turn=0; !end; ++turn) {
98  end = true;
99  for (team &side : *resources::teams) {
100  side_actions &actions = *side.get_side_actions();
101  if(turn < actions.num_turns() && team_has_visible_plan(side)) {
102  end = false;
103  side_actions::iterator it = actions.turn_begin(turn), next = it, end = actions.turn_end(turn);
104  while(it != end) {
105  std::advance(next, 1);
106  process(actions, it);
107  it = next;
108  }
109 
110  post_visit_team(turn);
111  }
112  }
113  }
114 }
115 
117 {
118  action_ptr action = *action_it;
119  bool acted=false;
120  unit_ptr unit = action->get_unit();
121  if(!unit) {
122  return;
123  }
124 
125  if(acted_this_turn_.find(unit.get()) == acted_this_turn_.end()) {
126  //reset MP
127  unit->set_movement(unit->total_movement());
128  acted=true;
129  }
130 
131  // Validity check
132  action::error erval = action->check_validity();
133  action->redraw();
134 
135  if(erval != action::OK) {
136  // We do not delete obstructed moves, nor invalid actions caused by obstructed moves.
137  if(has_invalid_actions_.find(unit.get()) == has_invalid_actions_.end()) {
138  if(erval == action::TOO_FAR || (erval == action::LOCATION_OCCUPIED && boost::dynamic_pointer_cast<move>(action))) {
139  has_invalid_actions_.insert(unit.get());
140  invalid_actions_.push_back(action_it);
141  } else {
142  sa.remove_action(action_it, false);
143  return;
144  }
145  } else {
146  invalid_actions_.push_back(action_it);
147  }
148  return;
149  }
150 
151  // We do not keep invalid actions replaced by a valid one.
152  std::set<class unit const*>::iterator invalid_it = has_invalid_actions_.find(unit.get());
153  if(invalid_it != has_invalid_actions_.end()) {
155  if((**it)->get_unit().get() == unit.get()) {
156  sa.remove_action(*it, false);
157  it = invalid_actions_.erase(it);
158  } else {
159  ++it;
160  }
161  }
162  has_invalid_actions_.erase(invalid_it);
163  }
164 
165  if(acted) {
166  acted_this_turn_.insert(unit.get());
167  }
168 
169  action->apply_temp_modifier(unit_map_);
170  applied_actions_.push_back(action);
171  applied_actions_this_turn_.push_back(action);
172 }
173 
175 {
176  std::set<unit const*> seen;
177 
178  // Go backwards through the actions of this turn to identify
179  // which ones are moves that end a turn.
180  for(action_ptr action : boost::adaptors::reverse(applied_actions_this_turn_)) {
181  move_ptr move = boost::dynamic_pointer_cast<class move>(action);
182  if(move) {
183  move->set_turn_number(0);
184  if(move->get_route().steps.size() > 1 && seen.count(move->get_unit().get()) == 0) {
185  seen.insert(move->get_unit().get());
186  move->set_turn_number(turn + 1);
187  }
188  }
189  }
190 
191  // Clear list of planned actions applied this turn
193  // Clear the list of units of this team that have acted this turn
194  acted_this_turn_.clear();
195 }
196 
198 {
199  //applied_actions_ contain only the actions that we applied to the unit map
200  for(action_ptr act : boost::adaptors::reverse(applied_actions_)) {
201  act->remove_temp_modifier(unit_map_);
202  }
203 }
204 
205 } // end namespace wb
container::iterator iterator
play_controller * controller
Definition: resources.cpp:21
bool team_has_visible_plan(team &t)
Returns whether a given team's plan is visible.
Definition: utility.cpp:163
void process(side_actions &sa, side_actions::iterator action_it)
Function called on each action.
Definition: mapbuilder.cpp:116
Definition: unit.hpp:95
size_t viewer_team()
Definition: utility.cpp:39
iterator turn_begin(size_t turn_num)
bool has_actions()
Return whether the whiteboard has actions.
Definition: utility.cpp:153
std::set< unit const * > acted_this_turn_
Definition: mapbuilder.hpp:74
boost::ptr_vector< temporary_unit_remover > removers_
Definition: mapbuilder.hpp:71
std::set< unit const * > has_invalid_actions_
Definition: mapbuilder.hpp:75
GLdouble GLdouble t
Definition: glew.h:1366
void restore_normal_map()
Definition: mapbuilder.cpp:197
iterator remove_action(iterator position, bool validate_after_delete=true)
Deletes the action at the specified position.
void pre_build()
Does various preliminary actions on the unit map such as resetting moves for some units...
Definition: mapbuilder.cpp:57
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:50
GLuint GLuint end
Definition: glew.h:1221
size_t num_turns() const
Returns the number of turns that have plans.
int current_side() const
Returns the number of the side whose turn it is.
std::vector< team > * teams
Definition: resources.cpp:29
error
Possible errors.
Definition: action.hpp:104
boost::ptr_vector< unit_movement_resetter > resetters_
Definition: mapbuilder.hpp:70
game_board * gameboard
Definition: resources.cpp:20
unit_map & unit_map_
Definition: mapbuilder.hpp:64
Object which temporarily resets a unit's movement.
Definition: unit.hpp:561
mapbuilder(unit_map &unit_map)
Definition: mapbuilder.cpp:37
action_queue applied_actions_
Definition: mapbuilder.hpp:66
This object is used to temporary remove a unit from the unit map.
Definition: game_board.hpp:183
std::list< side_actions::iterator > invalid_actions_
Conserved invalid actions.
Definition: mapbuilder.hpp:76
iterator turn_end(size_t turn_num)
#define next(ls)
Definition: llex.cpp:27
virtual ~mapbuilder()
Definition: mapbuilder.cpp:49
action_queue applied_actions_this_turn_
Definition: mapbuilder.hpp:67
Container associating units to locations.
Definition: map.hpp:90
void build_map()
Builds every team's actions as far into the future as possible, in the correct order.
Definition: mapbuilder.cpp:89
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
Abstract base class for all the whiteboard planned actions.
Definition: action.hpp:33
This internal whiteboard class holds the planned action queues for a team, and offers many utility me...
unit_map * units
Definition: resources.cpp:35
A planned move, represented on the map by an arrow and a ghosted unit in the destination hex...
Definition: move.hpp:33
Definition: display.hpp:47
void post_visit_team(size_t turn)
Function called after visiting a team.
Definition: mapbuilder.cpp:174