The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
unit_creator.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2016 by David White <[email protected]>
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  * Recruiting, recalling.
18  */
19 
20 #include "unit_creator.hpp"
21 
22 #include "move.hpp" //for actions::get_village
23 
24 #include "config.hpp"
25 #include "filter_context.hpp"
26 #include "game_board.hpp"
27 #include "game_events/manager.hpp"
28 #include "game_events/pump.hpp"
29 #include "game_preferences.hpp"
30 #include "game_data.hpp" // for resources::gamedata conversion variable_set
31 #include "gettext.hpp"
32 #include "log.hpp"
33 #include "map/map.hpp"
34 #include "pathfind/pathfind.hpp"
35 #include "resources.hpp" // for resources::screen, resources::gamedata
36 #include "team.hpp" //for team
37 #include "units/unit.hpp" // for unit
38 #include "units/udisplay.hpp" // for unit_display
39 #include "variable.hpp" // for vconfig
40 
41 #include "game_display.hpp" // for resources::screen
42 
43 #include <boost/scoped_ptr.hpp>
44 
45 static lg::log_domain log_engine("engine");
46 #define DBG_NG LOG_STREAM(debug, log_engine)
47 #define LOG_NG LOG_STREAM(info, log_engine)
48 #define ERR_NG LOG_STREAM(err, log_engine)
49 
51  : add_to_recall_(false)
52  , discover_(false)
53  , get_village_(false)
54  , invalidate_(false)
55  , rename_side_(false)
56  , show_(false)
57  , start_pos_(start_pos)
58  , team_(tm)
59  , board_(board ? board : resources::gameboard)
60 {
61 }
62 
63 
65 {
66  show_ = b;
67  return *this;
68 }
69 
70 
72 {
73  get_village_ = b;
74  return *this;
75 }
76 
77 
79 {
80  rename_side_ = b;
81  return *this;
82 }
83 
85 {
86  invalidate_ = b;
87  return *this;
88 }
89 
90 
92 {
93  discover_ = b;
94  return *this;
95 }
96 
97 
99 {
100  add_to_recall_ = b;
101  return *this;
102 }
103 
104 
105 map_location unit_creator::find_location(const config &cfg, const unit* pass_check)
106 {
107 
108  DBG_NG << "finding location for unit with id=["<<cfg["id"]<<"] placement=["<<cfg["placement"]<<"] x=["<<cfg["x"]<<"] y=["<<cfg["y"]<<"] for side " << team_.side() << "\n";
109 
110  std::vector<std::string> placements = utils::split(cfg["placement"]);
111 
112  placements.push_back("map");
113  placements.push_back("recall");
114 
115  for (const std::string& place : placements)
116  {
117  map_location loc;
118 
119  if ( place == "recall" ) {
121  }
122 
123  else if ( place == "leader" || place == "leader_passable" ) {
125  //todo: take 'leader in recall list' possibility into account
126  if (leader.valid()) {
127  loc = leader->get_location();
128  } else {
129  loc = start_pos_;
130  }
131  }
132 
133  // "map", "map_passable", and "map_overwrite".
134  else if ( place == "map" || place.compare(0, 4, "map_") == 0 ) {
135  loc = map_location(cfg, resources::gamedata);
136  }
137  else {
138  loc = board_->map().special_location(place);
139  }
140 
141  if(loc.valid() && board_->map().on_board(loc)) {
142  const bool pass((place == "leader_passable") || (place == "map_passable"));
143  if ( place != "map_overwrite" ) {
145  pass ? pass_check : nullptr, nullptr, board_);
146  }
147  if(loc.valid() && board_->map().on_board(loc)) {
148  return loc;
149  }
150  }
151  }
152 
154 
155 }
156 
157 
158 void unit_creator::add_unit(const config &cfg, const vconfig* vcfg)
159 {
160  config temp_cfg(cfg);
161  temp_cfg["side"] = team_.side();
162 
163  const std::string& id =(cfg)["id"];
164  bool animate = temp_cfg["animate"].to_bool();
165  temp_cfg.remove_attribute("animate");
166 
167  unit_ptr recall_list_element = team_.recall_list().find_if_matches_id(id);
168 
169  if ( !recall_list_element ) {
170  //make the new unit
171  unit_ptr new_unit(new unit(temp_cfg, true, vcfg, &board_->unit_id_manager()));
172  map_location loc = find_location(temp_cfg, new_unit.get());
173  if ( loc.valid() ) {
174  //add the new unit to map
175  board_->units().replace(loc, *new_unit);
176  LOG_NG << "inserting unit for side " << new_unit->side() << "\n";
177  post_create(loc,*(board_->units().find(loc)),animate);
178  }
179  else if ( add_to_recall_ ) {
180  //add to recall list
181  team_.recall_list().add(new_unit);
182  DBG_NG << "inserting unit with id=["<<id<<"] on recall list for side " << new_unit->side() << "\n";
183  preferences::encountered_units().insert(new_unit->type_id());
184  }
185  } else {
186  //get unit from recall list
187  map_location loc = find_location(temp_cfg, recall_list_element.get());
188  if ( loc.valid() ) {
189  board_->units().replace(loc, *recall_list_element);
190  LOG_NG << "inserting unit from recall list for side " << recall_list_element->side()<< " with id="<< id << "\n";
191  post_create(loc,*(board_->units().find(loc)),animate);
192  //if id is not empty, delete units with this ID from recall list
194  }
195  else if ( add_to_recall_ ) {
196  LOG_NG << "wanted to insert unit on recall list, but recall list for side " << (cfg)["side"] << "already contains id=" <<id<<"\n";
197  return;
198  }
199  }
200 }
201 
202 
203 void unit_creator::post_create(const map_location &loc, const unit &new_unit, bool anim)
204 {
205 
206  if (discover_) {
207  preferences::encountered_units().insert(new_unit.type_id());
208  }
209 
210  bool show = show_ && (resources::screen !=nullptr) && !resources::screen->fogged(loc);
211  bool animate = show && anim;
212 
213  if (get_village_) {
214  assert(resources::gameboard);
215  if (board_->map().is_village(loc)) {
216  actions::get_village(loc, new_unit.side());
217  }
218  }
219 
220  // Only fire the events if it's safe; it's not if we're in the middle of play_controller::reset_gamestate()
221  if (resources::lua_kernel != nullptr) {
222  resources::game_events->pump().fire("unit placed", loc);
223  }
224 
225  if (resources::screen!=nullptr) {
226 
227  if (invalidate_ ) {
229  }
230 
231  if (animate) {
233  } else if (show) {
235  }
236  }
237 }
unit_creator & allow_rename_side(bool b)
void remove_attribute(const std::string &key)
Definition: config.cpp:534
Game board class.
Definition: game_board.hpp:55
virtual const unit_map & units() const
Definition: game_board.hpp:99
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
Definition: display.cpp:3536
Definition: unit.hpp:95
bool get_village(const map_location &loc, int side, bool *action_timebonus, bool fire_event)
Makes it so the village at the given location is owned by the given side.
Definition: move.cpp:140
static lg::log_domain log_engine("engine")
unit_creator & allow_invalidate(bool b)
unit_creator & allow_show(bool b)
unit_iterator find_leader(int side)
Definition: map.cpp:297
bool is_village(const map_location &loc) const
Definition: map.cpp:68
game_display * screen
Definition: resources.cpp:27
map_location find_vacant_tile(const map_location &loc, VACANT_TILE_TYPE vacancy, const unit *pass_check, const team *shroud_check, const game_board *board)
Function that will find a location on the board that is as near to loc as possible, but which is unoccupied by any units.
Definition: pathfind.cpp:56
unit_creator & allow_discover(bool b)
bool fire(const std::string &event, const entity_location &loc1=entity_location::null_entity, const entity_location &loc2=entity_location::null_entity, const config &data=config())
Function to fire an event.
Definition: pump.cpp:471
int side() const
Definition: unit.hpp:201
virtual void draw()
Draws invalidated items.
Definition: display.cpp:2706
-file sdl_utils.hpp
Definitions for the interface to Wesnoth Markup Language (WML).
unit_creator & allow_add_to_recall(bool b)
game_data * gamedata
Definition: resources.cpp:22
GLdouble GLdouble GLdouble b
Definition: glew.h:6966
const std::string & type_id() const
The id of the type of the unit.
Definition: unit.hpp:142
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:50
unit_ptr find_if_matches_id(const std::string &unit_id)
Find a unit by id. Null pointer if not found.
#define LOG_NG
bool valid() const
Definition: location.hpp:69
game_board * gameboard
Definition: resources.cpp:20
const map_location start_pos_
static const map_location & null_location()
Definition: location.hpp:195
std::pair< unit_iterator, bool > replace(const map_location &l, const unit &u)
Works like unit_map::add; but l is emptied first, if needed.
Definition: map.cpp:207
game_events::manager * game_events
Definition: resources.cpp:24
void erase_if_matches_id(const std::string &unit_id)
Erase any unit with this id.
void show(CVideo &video, const std::string &window_id, const t_string &message, const tpoint &mouse)
Shows a tip.
Definition: tip.cpp:133
Encapsulates the map of the game.
Definition: location.hpp:38
Various functions related to moving units.
map_location special_location(const std::string &id) const
Definition: map.cpp:409
unit_creator & allow_get_village(bool b)
Various functions related to the creation of units (recruits, recalls, and placed units)...
Define the game's event mechanism.
std::set< std::string > & encountered_units()
int side() const
Definition: team.hpp:193
game_events::t_pump & pump()
Definition: manager.cpp:194
virtual const gamemap & map() const
Definition: game_board.hpp:98
bool on_board(const map_location &loc) const
Tell if a location is on the map.
Definition: map.cpp:467
void add_unit(const config &cfg, const vconfig *vcfg=nullptr)
adds a unit on map without firing any events (so, usable during team construction in gamestatus) ...
n_unit::id_manager & unit_id_manager()
Definition: game_board.hpp:91
map_location find_location(const config &cfg, const unit *pass_check=nullptr)
finds a suitable location for unit
void unit_recruited(const map_location &loc, const map_location &leader_loc)
Definition: udisplay.cpp:703
A variable-expanding proxy for the config class.
Definition: variable.hpp:36
Standard logging facilities (interface).
recall_list_manager & recall_list()
Definition: team.hpp:220
void add(const unit_ptr &ptr)
Add a unit to the list.
game_lua_kernel * lua_kernel
Definition: resources.cpp:25
std::vector< std::string > split(std::string const &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
unit_iterator find(size_t id)
Definition: map.cpp:285
unit_creator(team &tm, const map_location &start_pos, game_board *board=nullptr)
bool valid() const
Definition: map.hpp:229
void post_create(const map_location &loc, const unit &new_unit, bool anim)
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
This module contains various pathfinding functions and utilities.
GLsizei const GLcharARB ** string
Definition: glew.h:4503
game_board * board_
Display units performing various actions: moving, attacking, and dying.
#define DBG_NG