The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
synced_commands.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 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 #include "synced_commands.hpp"
15 #include <cassert>
16 
17 #include "log.hpp"
18 #include "resources.hpp"
19 #include "map/location.hpp"
20 #include "game_data.hpp"
21 #include "units/unit.hpp"
22 #include "team.hpp"
23 #include "play_controller.hpp"
24 #include "actions/create.hpp"
25 #include "actions/attack.hpp"
26 #include "actions/move.hpp"
27 #include "actions/undo.hpp"
28 #include "preferences.hpp"
29 #include "game_preferences.hpp"
30 #include "game_events/manager.hpp"
31 #include "game_events/pump.hpp"
32 #include "units/helper.hpp"
33 #include "recall_list_manager.hpp"
34 #include "resources.hpp"
36 #include "formula/string_utils.hpp"
37 #include "units/types.hpp"
38 #include "units/udisplay.hpp"
39 
40 static lg::log_domain log_replay("replay");
41 #define DBG_REPLAY LOG_STREAM(debug, log_replay)
42 #define LOG_REPLAY LOG_STREAM(info, log_replay)
43 #define WRN_REPLAY LOG_STREAM(warn, log_replay)
44 #define ERR_REPLAY LOG_STREAM(err, log_replay)
45 
46 
47 /**
48  * @param[in] tag The replay tag for this action.
49  * @param[in] function The callback for this action.
50  */
52 {
53  assert(registry().find( tag ) == registry().end());
54  registry()[tag] = function;
55 }
56 
58 {
59  //Use a pointer to ensure that this object is not destructed when the programm ends.
60  static map* instance = new map();
61  return *instance;
62 }
63 
64 
65 SYNCED_COMMAND_HANDLER_FUNCTION(recruit, child, use_undo, show, error_handler)
66 {
67  int current_team_num = resources::controller->current_side();
68  team &current_team = (*resources::teams)[current_team_num - 1];
69 
71  map_location from(child.child_or_empty("from"), resources::gamedata);
72  // Validate "from".
73  if ( !from.valid() ) {
74  // This will be the case for AI recruits in replays saved
75  // before 1.11.2, so it is not more severe than a warning.
76  // EDIT: we borke compability with 1.11.2 anyway so we should give an error.
77  error_handler("Missing leader location for recruitment.\n", false);
78  }
79  else if ( resources::units->find(from) == resources::units->end() ) {
80  // Sync problem?
81  std::stringstream errbuf;
82  errbuf << "Recruiting leader not found at " << from << ".\n";
83  error_handler(errbuf.str(), false);
84  }
85 
86  // Get the unit_type ID.
87  std::string type_id = child["type"];
88  if ( type_id.empty() ) {
89  error_handler("Recruitment is missing a unit type.", true);
90  return false;
91  }
92 
93  const unit_type *u_type = unit_types.find(type_id);
94  if (!u_type) {
95  std::stringstream errbuf;
96  errbuf << "Recruiting illegal unit: '" << type_id << "'.\n";
97  error_handler(errbuf.str(), true);
98  return false;
99  }
100 
101  const std::string res = actions::find_recruit_location(current_team_num, loc, from, type_id);
102  if(!res.empty())
103  {
104  std::stringstream errbuf;
105  errbuf << "cannot recruit unit: " << res << "\n";
106  error_handler(errbuf.str(), true);
107  return false;
108  //we are already oos because the unit wasn't created, no need to keep the bookkeeping right...
109  }
110  const int beginning_gold = current_team.gold();
111 
112 
113 
114  if ( u_type->cost() > beginning_gold ) {
115  std::stringstream errbuf;
116  errbuf << "unit '" << type_id << "' is too expensive to recruit: "
117  << u_type->cost() << "/" << beginning_gold << "\n";
118  error_handler(errbuf.str(), false);
119  }
120 
121  actions::recruit_unit(*u_type, current_team_num, loc, from, show, use_undo);
122 
123  LOG_REPLAY << "recruit: team=" << current_team_num << " '" << type_id << "' at (" << loc
124  << ") cost=" << u_type->cost() << " from gold=" << beginning_gold << ' '
125  << "-> " << current_team.gold() << "\n";
126  return true;
127 }
128 
129 SYNCED_COMMAND_HANDLER_FUNCTION(recall, child, use_undo, show, error_handler)
130 {
131 
132  int current_team_num = resources::controller->current_side();
133  team &current_team = (*resources::teams)[current_team_num - 1];
134 
135  const std::string& unit_id = child["value"];
136  map_location loc(child, resources::gamedata);
137  map_location from(child.child_or_empty("from"), resources::gamedata);
138 
139  if ( !actions::recall_unit(unit_id, current_team, loc, from, show, use_undo) ) {
140  error_handler("illegal recall: unit_id '" + unit_id + "' could not be found within the recall list.\n", true);
141  //when recall_unit returned false nothing happend so we can safety return false;
142  return false;
143  }
144  return true;
145 }
146 
147 SYNCED_COMMAND_HANDLER_FUNCTION(attack, child, /*use_undo*/, show, error_handler)
148 {
149  const config &destination = child.child("destination");
150  const config &source = child.child("source");
151  //check_checksums(*cfg);
152 
153  if (!destination) {
154  error_handler("no destination found in attack\n", true);
155  return false;
156  }
157 
158  if (!source) {
159  error_handler("no source found in attack \n", true);
160  return false;
161  }
162 
163  //we must get locations by value instead of by references, because the iterators
164  //may become invalidated later
165  const map_location src(source, resources::gamedata);
166  const map_location dst(destination, resources::gamedata);
167 
168  int weapon_num = child["weapon"];
169  // having defender_weapon in the replay fixes a bug (OOS) where one player (or observer) chooses a different defensive weapon.
170  // Xan pointed out this was a possibility: we calculate defense weapon
171  // now based on attack_prediction code, but this uses floating point
172  // calculations, which means that in the case where results are close,
173  // rounding differences can mean that both ends choose different weapons.
174  int def_weapon_num = child["defender_weapon"].to_int(-2);
175  if (def_weapon_num == -2) {
176  // Let's not gratuitously destroy backwards compatibility.
177  LOG_REPLAY << "Old data, having to guess weapon\n";
178  def_weapon_num = -1;
179  }
180 
182  if (!u.valid()) {
183  error_handler("unfound location for source of attack\n", true);
184  return false;
185  }
186 
187  if (child.has_attribute("attacker_type")) {
188  const std::string &att_type_id = child["attacker_type"];
189  if (u->type_id() != att_type_id) {
190  WRN_REPLAY << "unexpected attacker type: " << att_type_id << "(game state gives: " << u->type_id() << ")" << std::endl;
191  }
192  }
193 
194  if (size_t(weapon_num) >= u->attacks().size()) {
195  error_handler("illegal weapon type in attack\n", true);
196  return false;
197  }
198 
200 
201  if (!tgt.valid()) {
202  std::stringstream errbuf;
203  errbuf << "unfound defender for attack: " << src << " -> " << dst << '\n';
204  error_handler(errbuf.str(), true);
205  return false;
206  }
207 
208  if (child.has_attribute("defender_type")) {
209  const std::string &def_type_id = child["defender_type"];
210  if (tgt->type_id() != def_type_id) {
211  WRN_REPLAY << "unexpected defender type: " << def_type_id << "(game state gives: " << tgt->type_id() << ")" << std::endl;
212  }
213  }
214 
215  if (def_weapon_num >= static_cast<int>(tgt->attacks().size())) {
216 
217  error_handler("illegal defender weapon type in attack\n", true);
218  return false;
219  }
220 
221  DBG_REPLAY << "Attacker XP (before attack): " << u->experience() << "\n";
222 
224  attack_unit_and_advance(src, dst, weapon_num, def_weapon_num, show);
225  return true;
226 }
227 
228 SYNCED_COMMAND_HANDLER_FUNCTION(disband, child, /*use_undo*/, /*show*/, error_handler)
229 {
230 
231  int current_team_num = resources::controller->current_side();
232  team &current_team = (*resources::teams)[current_team_num - 1];
233 
234  const std::string& unit_id = child["value"];
235  size_t old_size = current_team.recall_list().size();
236 
237  // Find the unit in the recall list.
238  unit_ptr dismissed_unit = current_team.recall_list().find_if_matches_id(unit_id);
239  assert(dismissed_unit);
240  //add dismissal to the undo stack
241  resources::undo_stack->add_dismissal(dismissed_unit);
242 
243  current_team.recall_list().erase_if_matches_id(unit_id);
244 
245  if (old_size == current_team.recall_list().size()) {
246  error_handler("illegal disband\n", true);
247  return false;
248  }
249  return true;
250 }
251 
252 SYNCED_COMMAND_HANDLER_FUNCTION(move, child, use_undo, show, error_handler)
253 {
254  int current_team_num = resources::controller->current_side();
255  team &current_team = (*resources::teams)[current_team_num - 1];
256 
257  std::vector<map_location> steps;
258 
259  try {
260  read_locations(child,steps);
261  } catch (bad_lexical_cast &) {
262  WRN_REPLAY << "Warning: Path data contained something which could not be parsed to a sequence of locations:" << "\n config = " << child.debug() << std::endl;
263  return false;
264  }
265 
266  if(steps.empty())
267  {
268  WRN_REPLAY << "Warning: Missing path data found in [move]" << std::endl;
269  return false;
270  }
271 
272  const map_location& src = steps.front();
273  const map_location& dst = steps.back();
274 
275  if (src == dst) {
276  WRN_REPLAY << "Warning: Move with identical source and destination. Skipping..." << std::endl;
277  return false;
278  }
279 
280  // The nominal destination should appear to be unoccupied.
282  if ( u.valid() ) {
283  WRN_REPLAY << "Warning: Move destination " << dst << " appears occupied." << std::endl;
284  // We'll still proceed with this movement, though, since
285  // an event might intervene.
286  // 'event' doesn't mean wml event but rather it means 'hidden' units form the movers point of view.
287  }
288 
289  u = resources::units->find(src);
290  if (!u.valid()) {
291  std::stringstream errbuf;
292  errbuf << "unfound location for source of movement: "
293  << src << " -> " << dst << '\n';
294  error_handler(errbuf.str(), true);
295  return false;
296  }
297  bool skip_sighted = false;
298  bool skip_ally_sighted = false;
299  if(child["skip_sighted"] == "all")
300  {
301  skip_sighted = true;
302  }
303  else if(child["skip_sighted"] == "only_ally")
304  {
305  skip_ally_sighted = true;
306  }
307 
308  bool show_move = show;
309  if ( current_team.is_local_ai() || current_team.is_network_ai())
310  {
311  show_move = show_move && preferences::show_ai_moves();
312  }
313  actions::move_unit_from_replay(steps, use_undo ? resources::undo_stack : nullptr, skip_sighted, skip_ally_sighted, show_move);
314 
315  return true;
316 }
317 
318 SYNCED_COMMAND_HANDLER_FUNCTION(fire_event, child, use_undo, /*show*/, /*error_handler*/)
319 {
320  bool undoable = true;
321 
322  if(const config &last_select = child.child("last_select"))
323  {
324  //the select event cannot clear the undo stack.
326  }
327  const std::string &event_name = child["raise"];
328  if (const config &source = child.child("source")) {
329  undoable = undoable & !resources::game_events->pump().fire(event_name, map_location(source, resources::gamedata));
330  } else {
331  undoable = undoable & !resources::game_events->pump().fire(event_name);
332  }
333 
334  // Not clearing the undo stack here casues OOS because we added an entry to the replay but no entry to the undo stack.
335  if(use_undo) {
336  if(!undoable) {
338  } else {
340  }
341  }
342  return true;
343 }
344 
345 SYNCED_COMMAND_HANDLER_FUNCTION(lua_ai, child, /*use_undo*/, /*show*/, /*error_handler*/)
346 {
347  const std::string &lua_code = child["code"];
348  assert(resources::lua_kernel);
349  resources::lua_kernel->run(lua_code.c_str());
350  return true;
351 }
352 
353 SYNCED_COMMAND_HANDLER_FUNCTION(auto_shroud, child, use_undo, /*show*/, /*error_handler*/)
354 {
355  assert(use_undo);
356  team &current_team = resources::controller->current_team();
357 
358  bool active = child["active"].to_bool();
359  // We cannot update shroud here like 'if(active) resources::undo_stack->commit_vision();'.
360  // Becasue the undo.cpp code assumes exactly 1 entry in the undo stack per entry in the replay.
361  // And doing so would create a second entry in the undo stack for this 'auto_shroud' entry.
362  current_team.set_auto_shroud_updates(active);
364  return true;
365 }
366 
367 /** from resources::undo_stack->commit_vision(bool is_replay):
368  * Updates fog/shroud based on the undo stack, then updates stack as needed.
369  * Call this when "updating shroud now".
370  * This may fire events and change the game state.
371  * @param[in] is_replay Set to true when this is called during a replay.
372  *
373  * this means it ia synced command liek any other.
374  */
375 
376 SYNCED_COMMAND_HANDLER_FUNCTION(update_shroud, /*child*/, use_undo, /*show*/, error_handler)
377 {
378  assert(use_undo);
379  team &current_team = resources::controller->current_team();
380  if(current_team.auto_shroud_updates()) {
381  error_handler("Team has DSU disabled but we found an explicit shroud update", false);
382  }
385  return true;
386 }
387 namespace
388 {
389  void debug_notification(const char* message)
390  {
391  utils::string_map symbols;
392  symbols["player"] = resources::controller->current_team().current_player();
394  }
395 }
396 SYNCED_COMMAND_HANDLER_FUNCTION(debug_unit, child, use_undo, /*show*/, /*error_handler*/)
397 {
398  if(use_undo) {
400  }
401  debug_notification(":unit debug command was used during turn of $player");
402  map_location loc(child);
403  const std::string name = child["name"];
404  const std::string value = child["value"];
405 
407  if (i == resources::units->end()) {
408  return false;
409  }
410  if (name == "advances" ) {
411  int int_value = lexical_cast<int>(value);
412  for (int levels=0; levels<int_value; levels++) {
413  i->set_experience(i->max_experience());
414 
415  advance_unit_at(advance_unit_params(loc).force_dialog(true));
416  i = resources::units->find(loc);
417  if (!i.valid()) {
418  break;
419  }
420  }
421  } else if (name == "status" ) {
422  config cfg;
423  i->write(cfg);
424  resources::units->erase(loc);
425  config& statuses = cfg.child_or_add("status");
426  for (std::string status : utils::split(value)) {
427  bool add = true;
428  if (status.length() >= 1 && status[0] == '-') {
429  add = false;
430  status = status.substr(1);
431  }
432  if (status.empty()) {
433  continue;
434  }
435  statuses[status] = add;
436  }
437  unit new_u(cfg, true);
438  resources::units->add(loc, new_u);
439  } else {
440  config cfg;
441  i->write(cfg);
442  resources::units->erase(loc);
443  cfg[name] = value;
444  unit new_u(cfg, true);
445  resources::units->add(loc, new_u);
446  }
447  if (name == "fail") { //testcase for bug #18488
448  assert(i.valid());
449  }
452 
453  return true;
454 }
455 SYNCED_COMMAND_HANDLER_FUNCTION(debug_create_unit, child, use_undo, /*show*/, error_handler)
456 {
457  if(use_undo) {
459  }
460 
461  debug_notification("A unit was created using debug command during turn of $player");
462  map_location loc(child);
463  const unit_race::GENDER gender = string_gender(child["gender"], unit_race::NUM_GENDERS);
464  const unit_type *u_type = unit_types.find(child["type"]);
465  if (!u_type) {
466  error_handler("Invalid unit type", true);
467  return false;
468  }
469 
470  const int side_num = resources::controller
472 
473  // Create the unit.
474  unit created(*u_type, side_num, true, gender);
475  created.new_turn();
476 
477  // Add the unit to the board.
478  std::pair<unit_map::iterator, bool> add_result = resources::units->replace(loc, created);
480  resources::game_events->pump().fire("unit placed", loc);
482 
483  // Village capture?
484  if ( resources::gameboard->map().is_village(loc) )
485  actions::get_village(loc, created.side());
486 
487  // Update fog/shroud.
488  actions::shroud_clearer clearer;
489  clearer.clear_unit(loc, created);
490  clearer.fire_events();
491  if ( add_result.first.valid() ) // In case sighted events messed with the unit.
492  actions::actor_sighted(*add_result.first);
493 
494  return true;
495 }
496 
497 SYNCED_COMMAND_HANDLER_FUNCTION(debug_lua, child, use_undo, /*show*/, /*error_handler*/)
498 {
499  if(use_undo) {
501  }
502  debug_notification(":lua debug command was used during turn of $player");
503  resources::lua_kernel->run(child["code"].str().c_str());
505 
506  return true;
507 }
508 
509 SYNCED_COMMAND_HANDLER_FUNCTION(debug_next_level, child, use_undo, /*show*/, /*error_handler*/)
510 {
511  if(use_undo) {
513  }
514 
515  debug_notification(":next_level debug command was used during turn of $player");
516 
517  std::string next_level = child["next_level"];
518  if (!next_level.empty())
519  resources::gamedata->set_next_scenario(next_level);
521  e.transient.carryover_report = false;
522  e.prescenario_save = true;
523  e.transient.linger_mode = false;
524  e.proceed_to_next_level = true;
525  e.is_victory = true;
526 
529 
530  return true;
531 }
532 
533 SYNCED_COMMAND_HANDLER_FUNCTION(debug_turn_limit, child, use_undo, /*show*/, /*error_handler*/)
534 {
535  if(use_undo) {
537  }
538 
539  debug_notification(":turn_limit debug command was used during turn of $player");
540 
541  resources::tod_manager->set_number_of_turns(child["turn_limit"].to_int(-1));
543  return true;
544 }
545 
546 SYNCED_COMMAND_HANDLER_FUNCTION(debug_turn, child, use_undo, /*show*/, /*error_handler*/)
547 {
548  if(use_undo) {
550  }
551 
552  debug_notification(":turn debug command was used during turn of $player");
553 
554  resources::tod_manager->set_turn(child["turn"].to_int(1), resources::gamedata);
555 
558 
559  return true;
560 }
561 
562 SYNCED_COMMAND_HANDLER_FUNCTION(debug_set_var, child, use_undo, /*show*/, /*error_handler*/)
563 {
564  if(use_undo) {
566  }
567 
568  debug_notification(":set_var debug command was used during turn of $player");
569 
570  try {
571  resources::gamedata->set_variable(child["name"],child["value"]);
572  }
573  catch(const invalid_variablename_exception&) {
574  // command_failed(_("Variable not found"));
575  return false;
576  }
577  return true;
578 }
579 
580 SYNCED_COMMAND_HANDLER_FUNCTION(debug_gold, child, use_undo, /*show*/, /*error_handler*/)
581 {
582  if(use_undo) {
584  }
585 
586  debug_notification(":gold debug command was used during turn of $player");
587 
588  resources::controller->current_team().spend_gold(-child["gold"].to_int(0));
590  return true;
591 }
592 
593 
594 SYNCED_COMMAND_HANDLER_FUNCTION(debug_event, child, use_undo, /*show*/, /*error_handler*/)
595 {
596  if(use_undo) {
598  }
599 
600  debug_notification(":throw debug command was used during turn of $player");
601 
602  resources::controller->pump().fire(child["eventname"]);
604 
605  return true;
606 }
607 
608 
609 SYNCED_COMMAND_HANDLER_FUNCTION(debug_fog, /*child*/, use_undo, /*show*/, /*error_handler*/)
610 {
611  if(use_undo) {
613  }
614 
615  debug_notification(":fog debug command was used during turn of $player");
616 
617  team& current_team = resources::controller->current_team();
618  current_team.set_fog(!current_team.uses_fog());
619  actions::recalculate_fog(current_team.side());
620 
623 
624  return true;
625 }
626 
627 
628 SYNCED_COMMAND_HANDLER_FUNCTION(debug_shroud, /*child*/, use_undo, /*show*/, /*error_handler*/)
629 {
630  if(use_undo) {
632  }
633 
634  debug_notification(":shroud debug command was used during turn of $player");
635 
636  team& current_team = resources::controller->current_team();
637  current_team.set_shroud(!current_team.uses_shroud());
638  actions::clear_shroud(current_team.side());
639 
642 
643  return true;
644 }
645 
void clear()
Clears the stack of undoable (and redoable) actions.
Definition: undo.cpp:226
play_controller * controller
Definition: resources.cpp:21
bool uses_shroud() const
Definition: team.hpp:315
bool is_local_ai() const
Definition: team.hpp:268
void read_locations(const config &cfg, std::vector< map_location > &locs)
Parse x,y keys of a config into a vector of locations.
Definition: location.cpp:413
static thandler * handler
Definition: handler.cpp:60
::tod_manager * tod_manager
Definition: resources.cpp:31
void set_shroud(bool shroud)
Definition: team.hpp:323
const std::string & current_player() const
Definition: team.hpp:238
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
Definition: display.cpp:3536
Definition: unit.hpp:95
bool clear_unit(const map_location &view_loc, team &view_team, size_t viewer_id, int sight_range, bool slowed, const movetype::terrain_costs &costs, const map_location &real_loc, const std::set< map_location > *known_units=nullptr, size_t *enemy_count=nullptr, size_t *friend_count=nullptr, move_unit_spectator *spectator=nullptr, bool instant=true)
Clears shroud (and fog) around the provided location for view_team based on sight_range, costs, and slowed.
Definition: vision.cpp:331
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
Various functions that implement attacks and attack calculations.
size_t size() const
Get the number of units on the list.
void advance_unit_at(const advance_unit_params &params)
Definition: attack.cpp:1478
void set_turn(const int num, game_data *vars=nullptr, const bool increase_limit_if_needed=true)
Dynamically change the current turn number.
static map & registry()
using static function variable instead of static member variable to prevent static initialization fia...
config & child_or_add(const std::string &key)
Returns a reference to the first child with the given key.
Definition: config.cpp:734
game_display * screen
Definition: resources.cpp:27
void redraw_everything()
Invalidates entire screen, including all tiles and sidebar.
Definition: display.cpp:2650
void invalidate_unit()
Function to invalidate that unit status displayed on the sidebar.
bool actor_sighted(const unit &target, const std::vector< int > *cache)
Fires sighted events for the sides that can see target.
Definition: vision.cpp:623
synced_command(const std::string &tag, handler function)
unit_type_data unit_types
Definition: types.cpp:1314
std::map< std::string, handler > map
bool prescenario_save
Should a prescenario be created the next game?
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
void flush_messages()
Flushes WML messages and errors.
Definition: pump.cpp:577
GLenum src
Definition: glew.h:2392
#define WRN_REPLAY
-file sdl_utils.hpp
To lexical_cast(From value)
Lexical cast converts one type to another.
const SDL_Color NORMAL_COLOR
Definition: font.cpp:564
void new_turn()
Update lighting settings.
std::vector< std::pair< const std::string *, const stats * > > levels
Stats (and name) for each scenario. The pointers are never nullptr.
Definition: statistics.hpp:115
game_data * gamedata
Definition: resources.cpp:22
game_events::t_pump & pump()
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:50
void recruit_unit(const unit_type &u_type, int side_num, const map_location &loc, const map_location &from, bool show, bool use_undo)
Recruits a unit of the given type for the given side.
Definition: create.cpp:699
GLuint GLuint end
Definition: glew.h:1221
bool linger_mode
Should linger mode be invoked?
std::map< std::string, t_string > string_map
bool auto_shroud_updates() const
Definition: team.hpp:335
unit_ptr find_if_matches_id(const std::string &unit_id)
Find a unit by id. Null pointer if not found.
int current_side() const
Returns the number of the side whose turn it is.
#define LOG_REPLAY
void recalculate_minimap()
Schedule the minimap for recalculation.
Definition: display.hpp:623
GLsizei const GLfloat * value
Definition: glew.h:1817
GLenum GLenum dst
Definition: glew.h:2392
game_board * gameboard
Definition: resources.cpp:20
unit_race::GENDER string_gender(const std::string &str, unit_race::GENDER def)
Definition: race.cpp:161
void recalculate_fog(int side)
Function that recalculates the fog of war.
Definition: vision.cpp:705
void set_variable(const std::string &varname, const t_string &value)
does nothing if varname is no valid variable name.
Definition: game_data.cpp:92
void spend_gold(const int amount)
Definition: team.hpp:213
bool carryover_report
Should a summary of the scenario outcome be displayed?
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
void commit_vision()
Updates fog/shroud based on the undo stack, then updates stack as needed.
Definition: undo.cpp:249
#define DBG_REPLAY
void set_fog(bool fog)
Definition: team.hpp:324
std::pair< unit_iterator, bool > add(const map_location &l, const unit &u)
Adds a copy of unit u at location l of the map.
Definition: map.cpp:70
game_events::manager * game_events
Definition: resources.cpp:24
SYNCED_COMMAND_HANDLER_FUNCTION(recruit, child, use_undo, show, error_handler)
void erase_if_matches_id(const std::string &unit_id)
Erase any unit with this id.
advances the unit at loc if it has enough experience, maximum 20 times.
Definition: attack.hpp:214
virtual void force_end_turn()=0
int cost() const
Definition: types.hpp:134
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.
void run(char const *prog, int nArgs=0)
Runs a plain script.
Various functions related to the creation of units (recruits, recalls, and placed units)...
void set_end_level_data(const end_level_data &data)
GLuint res
Definition: glew.h:9258
void add_dismissal(const unit_const_ptr u)
Adds a dismissal to the undo stack.
Definition: undo.cpp:171
transient_end_level transient
size_t move_unit_from_replay(const std::vector< map_location > &steps, undo_list *undo_stack, bool continued_move, bool skip_ally_sighted, bool show_move)
Moves a unit across the board.
Definition: move.cpp:1271
void set_number_of_turns(int num)
Define the game's event mechanism.
Information on a WML variable.
void new_turn()
Definition: unit.cpp:1215
size_t i
Definition: function.cpp:1057
bool proceed_to_next_level
whether to proceed to the next scenario, equals is_victory in sp.
Additional information on the game outcome which can be provided by WML.
int side() const
Definition: team.hpp:193
bool fire_event(const tevent event, std::vector< std::pair< twidget *, tevent > > &event_chain, twidget *dispatcher, twidget *widget, F functor)
Helper function for fire_event.
game_events::t_pump & pump()
Definition: manager.cpp:194
std::string vgettext(const char *msgid, const utils::string_map &symbols)
GLuint const GLchar * name
Definition: glew.h:1782
size_t erase(const map_location &l)
Erases the unit at location l, if any.
Definition: map.cpp:277
bool clear_shroud(int side, bool reset_fog, bool fire_events)
Function that will clear shroud (and fog) based on current unit positions.
Definition: vision.cpp:754
void add_update_shroud()
Adds a shroud update to the undo stack.
Definition: undo.cpp:211
int gold() const
Definition: team.hpp:194
bool find(E event, F functor)
Tests whether an event handler is available.
bool uses_fog() const
Definition: team.hpp:316
config & child(const std::string &key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
Definition: config.cpp:658
void unit_recruited(const map_location &loc, const map_location &leader_loc)
Definition: udisplay.cpp:703
Various functions that implement the undoing (and redoing) of in-game commands.
std::string find_recruit_location(const int side, map_location &recruit_location, map_location &recruited_from, const std::string &unit_type)
Finds a location on which to place a unit.
Definition: create.cpp:464
Standard logging facilities (interface).
bool is_network_ai() const
Definition: team.hpp:270
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
void add_dummy()
Adds an auto-shroud toggle to the undo stack.
Definition: undo.cpp:160
recall_list_manager & recall_list()
Definition: team.hpp:220
game_lua_kernel * lua_kernel
Definition: resources.cpp:25
GLsizei GLenum GLuint GLuint GLsizei char * message
Definition: glew.h:2499
Class to encapsulate fog/shroud clearing and the resultant sighted events.
Definition: vision.hpp:58
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
void set_auto_shroud_updates(bool value)
Definition: team.hpp:336
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.
#define e
void add_auto_shroud(bool turned_on)
Adds an auto-shroud toggle to the undo stack.
Definition: undo.cpp:152
actions::undo_list * undo_stack
Definition: resources.cpp:34
static lg::log_domain log_replay("replay")
unit_iterator find(size_t id)
Definition: map.cpp:285
bool valid() const
Definition: map.hpp:229
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
void announce(const std::string &msg, const SDL_Color &color=font::GOOD_COLOR)
Announce a message prominently.
Definition: display.cpp:1950
Thrown when a lexical_cast fails.
GLsizei const GLcharARB ** string
Definition: glew.h:4503
GLsizei GLsizei GLchar * source
Definition: glew.h:1800
unit_map * units
Definition: resources.cpp:35
unit_map::iterator find_visible_unit(const map_location &loc, const team &current_team, bool see_all=false)
Definition: game_board.cpp:173
Display units performing various actions: moving, attacking, and dying.
void attack_unit_and_advance(const map_location &attacker, const map_location &defender, int attack_with, int defend_with, bool update_display, const ai::unit_advancements_aspect &ai_advancement)
Performs an attack, and advanced the units afterwards.
Definition: attack.cpp:1524