The Battle for Wesnoth  1.15.1+dev
tod_manager.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2018 by Eugen Jiresch
3  Part of the Battle for Wesnoth Project https://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 #include "tod_manager.hpp"
16 
17 #include "display_context.hpp"
19 #include "game_data.hpp"
20 #include "gettext.hpp"
21 #include "log.hpp"
22 #include "map/map.hpp"
23 #include "play_controller.hpp"
24 #include "random.hpp"
25 #include "units/unit.hpp"
26 #include "units/abilities.hpp"
27 #include "resources.hpp"
28 
29 #include <algorithm>
30 #include <iterator>
31 #include "utils/functional.hpp"
32 #include "actions/attack.hpp"
33 
34 static lg::log_domain log_engine("engine");
35 #define LOG_NG LOG_STREAM(info, log_engine)
36 
37 tod_manager::tod_manager(const config& scenario_cfg):
38  currentTime_(0),
39  times_(),
40  areas_(),
41  liminal_bonus_(25),
42  turn_(scenario_cfg["turn_at"].to_int(1)),
43  num_turns_(scenario_cfg["turns"].to_int(-1)),
44  has_turn_event_fired_(!scenario_cfg["it_is_a_new_turn"].to_bool(true)),
45  has_tod_bonus_changed_ (false),
46  has_cfg_liminal_bonus_ (false)
47 {
48  // ? : operator doesn't work in this case.
49  if (scenario_cfg["current_time"].to_int(-17403) == -17403)
50  random_tod_ = scenario_cfg["random_start_time"];
51  else
52  random_tod_ = false;
53 
54  time_of_day::parse_times(scenario_cfg,times_);
56  if (scenario_cfg.has_attribute("liminal_bonus")) {
57  liminal_bonus_ = scenario_cfg["liminal_bonus"].to_int(liminal_bonus_);
59  }
60  //We need to call parse_times before calculate_current_time because otherwise the first parameter will always be 0.
61  currentTime_ = calculate_current_time(times_.size(), turn_, scenario_cfg["current_time"].to_int(0), true);
62 
63 }
64 
66 {
67  if(this == &manager) {
68  return *this;
69  }
70 
71  currentTime_ = manager.currentTime_;
72  times_ = manager.times_;
73  areas_ = manager.areas_;
75 
76  turn_ = manager.turn_;
77  num_turns_ = manager.num_turns_;
78 
82 
83  random_tod_ = manager.random_tod_;
84 
85  return *this;
86 }
87 
89 {
90  //process the random_start_time string, which can be boolean yes/no true/false or a
91  //comma-separated string of integers >= 1 referring to the times_ array indices
92  std::vector<std::string> output_strings = utils::split(random_tod_.str());
93  std::vector<int> output;
94 
95  try
96  {
97  std::transform(output_strings.begin(), output_strings.end(), std::back_inserter(output),
98  [](const std::string& str)
99  {
100  return std::stoi(str);
101  });
102  }
103  catch (const std::invalid_argument&)
104  {
105  // This happens if the random_start_time string is a boolean.
106  // Simply ignore the exception.
107  }
108 
109  // Remove non-positive times
110  output.erase(
111  std::remove_if(
112  output.begin(),
113  output.end(),
114  [](int time){ return time <= 0; }),
115  output.end());
116 
117  if(!output.empty())
118  {
119  int chosen = output[r.next_random() % output.size()];
120  currentTime_ = calculate_current_time(times_.size(), turn_, chosen, true);
121  r.next_random();
122  }
123  else if (random_tod_.to_bool(false))
124  {
126  }
127  random_tod_ = false;
128 }
130 {
131  config cfg;
132  cfg["turn_at"] = turn_;
133  cfg["turns"] = num_turns_;
134  cfg["current_time"] = currentTime_;
135  cfg["random_start_time"] = random_tod_;
136  cfg["it_is_a_new_turn"] = !has_turn_event_fired_;
138  cfg["liminal_bonus"] = liminal_bonus_;
139 
140  for(const time_of_day& tod : times_) {
141  // Don't write the stub default ToD if it happens to be present.
142  if(tod.id != "nulltod") {
143  tod.write(cfg.add_child("time"));
144  }
145  }
146 
147  for(const area_time_of_day& a_tod : areas_) {
148  config& area = cfg.add_child("time_area");
149 
150  // If no ranges, then use hexes to generate ranges
151  if(a_tod.xsrc.empty() && a_tod.ysrc.empty()) {
152  write_location_range(a_tod.hexes, area);
153  } else {
154  area["x"] = a_tod.xsrc;
155  area["y"] = a_tod.ysrc;
156  }
157 
158  for(const time_of_day& tod : a_tod.times) {
159  // Don't write the stub default ToD if it happens to be present.
160  if(tod.id != "nulltod") {
161  tod.write(area.add_child("time"));
162  }
163  }
164 
165  area["current_time"] = a_tod.currentTime;
166 
167  if(!a_tod.id.empty()) {
168  area["id"] = a_tod.id;
169  }
170  }
171 
172  return cfg;
173 }
174 
176 {
178 }
179 
181  assert(index < static_cast<int>(areas_.size()) );
182  return areas_[index].currentTime;
183 }
184 
186 {
187  if ( loc != map_location::null_location() ) {
188  for ( std::vector<area_time_of_day>::const_reverse_iterator
189  i = areas_.rbegin(), i_end = areas_.rend(); i != i_end; ++i )
190  {
191  if (i->hexes.find(loc) != i->hexes.end())
192  return i->currentTime;
193  }
194  }
195 
196  return currentTime_;
197 }
198 
199 const std::vector<time_of_day>& tod_manager::times(const map_location& loc) const
200 {
201  if ( loc != map_location::null_location() ) {
202  for ( std::vector<area_time_of_day>::const_reverse_iterator
203  i = areas_.rbegin(), i_end = areas_.rend(); i != i_end; ++i )
204  {
205  if (i->hexes.find(loc) != i->hexes.end())
206  return i->times;
207  }
208  }
209 
210  return times_;
211 }
212 
213 const time_of_day& tod_manager::get_time_of_day(const map_location& loc, int n_turn) const
214 {
215  if(n_turn == 0)
216  n_turn = turn_;
217 
218  if ( loc != map_location::null_location() )
219  {
220  for ( std::vector<area_time_of_day>::const_reverse_iterator
221  i = areas_.rbegin(), i_end = areas_.rend(); i != i_end; ++i )
222  {
223  if (i->hexes.find(loc) != i->hexes.end())
224  return get_time_of_day_turn(i->times, n_turn, i->currentTime);
225  }
226  }
227 
228  return get_time_of_day_turn(times_, n_turn, currentTime_);
229 }
230 
231 const time_of_day tod_manager::get_illuminated_time_of_day(const unit_map & units, const gamemap & map, const map_location& loc, int for_turn) const
232 {
233  // get ToD ignoring illumination
234  time_of_day tod = get_time_of_day(loc, for_turn);
235 
236  if ( map.on_board_with_border(loc) )
237  {
238  // Now add terrain illumination.
239  const int terrain_light = map.get_terrain_info(loc).light_bonus(tod.lawful_bonus);
240 
241  std::vector<int> mod_list;
242  std::vector<int> max_list;
243  std::vector<int> min_list;
244  int most_add = 0;
245  int most_sub = 0;
246 
247  // Find the "illuminates" effects from units that can affect loc.
248  std::array<map_location, 7> locs;
249  locs[0] = loc;
250  get_adjacent_tiles(loc, locs.data() + 1); // start at [1]
251  for ( std::size_t i = 0; i < locs.size(); ++i ) {
252  const unit_map::const_iterator itor = units.find(locs[i]);
253  if (itor != units.end() &&
254  itor->get_ability_bool("illuminates") &&
255  !itor->incapacitated())
256  {
257  unit_ability_list illum = itor->get_abilities("illuminates");
258  unit_abilities::effect illum_effect(illum, terrain_light, false);
259  const int unit_mod = illum_effect.get_composite_value();
260 
261  // Record this value.
262  mod_list.push_back(unit_mod);
263  max_list.push_back(illum.highest("max_value").first);
264  min_list.push_back(illum.lowest("min_value").first);
265  if ( unit_mod > most_add )
266  most_add = unit_mod;
267  else if ( unit_mod < most_sub )
268  most_sub = unit_mod;
269  }
270  }
271  const bool net_darker = most_add < -most_sub;
272 
273  // Apply each unit's effect, tracking the best result.
274  int best_result = terrain_light;
275  const int base_light = terrain_light + (net_darker ? most_add : most_sub);
276  for ( std::size_t i = 0; i != mod_list.size(); ++i ) {
277  int result = bounded_add( base_light, mod_list[i], max_list[i], min_list[i] );
278 
279  if ( net_darker && result < best_result )
280  best_result = result;
281  else if ( !net_darker && result > best_result )
282  best_result = result;
283  }
284 
285  // Update the object we will return.
286  tod.bonus_modified = best_result - tod.lawful_bonus;
287  tod.lawful_bonus = best_result;
288  }
289 
290  return tod;
291 }
292 
293 
295 {
296  return !random_start_time.empty()
297  && utils::string_bool(random_start_time, true);
298 }
299 
301 {
302  int bonus = times_[currentTime_].lawful_bonus;
303  times_.clear();
305  currentTime_ = time_cfg["current_time"].to_int(0);
306  if (bonus != times_[currentTime_].lawful_bonus) {
307  has_tod_bonus_changed_ = true;
308  }
309 }
310 
311 void tod_manager::replace_schedule(const std::vector<time_of_day>& schedule)
312 {
313  int bonus = times_[currentTime_].lawful_bonus;
314  times_ = schedule;
315 
316  if(schedule.empty()) {
317  // Make sure that there is at least one ToD
318  times_.emplace_back();
319  }
320 
321  currentTime_ = 0;
322  if (bonus != times_[currentTime_].lawful_bonus) {
323  has_tod_bonus_changed_ = true;
324  }
325 }
326 
327 void tod_manager::replace_area_locations(int area_index, const std::set<map_location>& locs) {
328  assert(area_index < static_cast<int>(areas_.size()));
329  areas_[area_index].hexes = locs;
330  has_tod_bonus_changed_ = true;
331 }
332 
333 void tod_manager::replace_local_schedule(const std::vector<time_of_day>& schedule, int area_index)
334 {
335  assert(area_index < static_cast<int>(areas_.size()));
336  area_time_of_day& area = areas_[area_index];
337  int bonus = area.times[area.currentTime].lawful_bonus;
338  area.times = schedule;
339  area.currentTime = 0;
340  if (bonus != area.times[area.currentTime].lawful_bonus) {
341  has_tod_bonus_changed_ = true;
342  }
343 }
344 
345 void tod_manager::set_area_id(int area_index, const std::string& id) {
346  assert(area_index < static_cast<int>(areas_.size()));
347  areas_[area_index].id = id;
348 }
349 
350 std::vector<std::string> tod_manager::get_area_ids() const
351 {
352  std::vector<std::string> areas;
353  for (const area_time_of_day& area : areas_) {
354  areas.push_back(area.id);
355  }
356  return areas;
357 }
358 
359 const std::set<map_location>& tod_manager::get_area_by_id(const std::string& id) const
360 {
361  for (const area_time_of_day& area : areas_) {
362  if (area.id == id)
363  return area.hexes;
364  }
365  static const std::set<map_location> res;
366  return res;
367 }
368 
369 const std::set<map_location>& tod_manager::get_area_by_index(int index) const
370 {
371  return areas_[index].hexes;
372 }
373 
374 void tod_manager::add_time_area(const gamemap & map, const config& cfg)
375 {
376  areas_.emplace_back();
377  area_time_of_day &area = areas_.back();
378  area.id = cfg["id"].str();
379  area.xsrc = cfg["x"].str();
380  area.ysrc = cfg["y"].str();
381  area.currentTime = cfg["current_time"].to_int(0);
382  const std::vector<map_location>& locs (map.parse_location_range(area.xsrc, area.ysrc, true));
383  area.hexes.insert(locs.begin(), locs.end());
384  time_of_day::parse_times(cfg, area.times);
385  has_tod_bonus_changed_ = true;
386 }
387 
388 void tod_manager::add_time_area(const std::string& id, const std::set<map_location>& locs,
389  const config& time_cfg)
390 {
391  areas_.emplace_back();
392  area_time_of_day& area = areas_.back();
393  area.id = id;
394  area.hexes = locs;
395  area.currentTime = time_cfg["current_time"].to_int(0);
396  time_of_day::parse_times(time_cfg, area.times);
397  has_tod_bonus_changed_ = true;
398 }
399 
400 void tod_manager::remove_time_area(const std::string& area_id)
401 {
402  if(area_id.empty()) {
403  areas_.clear();
404  } else {
405  // search for all time areas that match the id.
407  while(i != areas_.end()) {
408  if((*i).id == area_id) {
409  i = areas_.erase(i);
410  } else {
411  ++i;
412  }
413  }
414  }
415  has_tod_bonus_changed_ = true;
416 }
417 
418 void tod_manager::remove_time_area(int area_index)
419 {
420  assert(area_index < static_cast<int>(areas_.size()));
421  areas_.erase(areas_.begin() + area_index);
422  has_tod_bonus_changed_ = true;
423 }
424 
425 const time_of_day& tod_manager::get_time_of_day_turn(const std::vector<time_of_day>& times, int nturn, const int current_time) const
426 {
427  const int time = calculate_current_time(times.size(), nturn, current_time);
428  return times[time];
429 }
430 
431 void tod_manager::modify_turns(const std::string& mod)
432 {
433  num_turns_ = std::max<int>(utils::apply_modifier(num_turns_,mod,0),-1);
434 }
436 {
437  num_turns_ = std::max<int>(num, -1);
438 }
439 
441 {
442  if(resources::controller->current_team().is_local()) {
443  //the currently active side informs the mp server about the turn change.
444  //NOTE: The current implementation does not guarnateee that the server gets informed
445  // about those changes in 100% of cases. But that is ok because the information is only
446  // used to display the turn limit in the lobby (as opposed to things that cause OOS).
448  "change_turns_wml", config {
449  "current", turn_,
450  "max", num_turns_,
451  },
452  });
453  }
454 }
455 void tod_manager::modify_turns_by_wml(const std::string& mod)
456 {
457  modify_turns(mod);
459 }
461 {
462  set_number_of_turns(num);
464 }
465 
466 void tod_manager::set_turn(const int num, game_data* vars, const bool increase_limit_if_needed)
467 {
468  has_tod_bonus_changed_ = false;
469  const int new_turn = std::max<int>(num, 1);
470  LOG_NG << "changing current turn number from " << turn_ << " to " << new_turn << '\n';
471  // Correct ToD
472  set_new_current_times(new_turn);
473 
474  if(increase_limit_if_needed && (new_turn > num_turns_) && num_turns_ != -1) {
475  set_number_of_turns(new_turn);
476  }
477  turn_ = new_turn;
478  if (vars)
479  vars->get_variable("turn_number") = new_turn;
480 }
481 
482 void tod_manager::set_turn_by_wml(const int num, game_data* vars, const bool increase_limit_if_needed)
483 {
484  set_turn(num, vars, increase_limit_if_needed);
486 }
487 void tod_manager::set_new_current_times(const int new_current_turn_number)
488 {
489  set_current_time(calculate_current_time(times_.size(), new_current_turn_number, currentTime_));
490  for (area_time_of_day& area : areas_) {
492  area.times.size(),
493  new_current_turn_number,
494  area.currentTime),
495  area);
496  }
497 }
498 
500  const int number_of_times,
501  const int for_turn_number,
502  const int current_time,
503  const bool only_to_allowed_range) const
504 {
505  if (number_of_times == 0) return 0;
506  int new_current_time = 0;
507  if(only_to_allowed_range) new_current_time = current_time % number_of_times;
508  else new_current_time = (current_time + for_turn_number - turn_) % number_of_times;
509  while(new_current_time < 0) { new_current_time += number_of_times; }
510  return new_current_time;
511 }
512 
514  if (times_[time].lawful_bonus != times_[currentTime_].lawful_bonus) {
515  has_tod_bonus_changed_ = true;
516  }
517  currentTime_ = time;
518 }
519 
520 void tod_manager::set_current_time(int time, int area_index) {
521  assert(area_index < static_cast<int>(areas_.size()));
522  set_current_time(time, areas_[area_index]);
523 }
524 
525 void tod_manager::set_current_time(int time, const std::string& area_id) {
526  for (area_time_of_day& area : areas_) {
527  if (area.id == area_id)
528  set_current_time(time, area);
529  }
530 }
531 
533  assert(time < static_cast<int>(area.times.size()) );
534  if (area.times[time].lawful_bonus != area.times[area.currentTime].lawful_bonus) {
535  has_tod_bonus_changed_ = true;
536  }
537  area.currentTime = time;
538 }
539 
541 {
542  set_turn(turn_ + 1, vars, false);
543  has_turn_event_fired_ = false;
544  return is_time_left();
545 }
546 
547 
549 {
550  return num_turns_ == -1 || turn_ <= num_turns_;
551 }
552 
553 int tod_manager::calculate_best_liminal_bonus(const std::vector<time_of_day>& schedule) const
554 {
555  int fearless_chaotic = 0;
556  int fearless_lawful = 0;
557  std::set<int> bonuses;
558  for (const auto& tod : schedule) {
559  fearless_chaotic += generic_combat_modifier(tod.lawful_bonus, unit_type::ALIGNMENT::CHAOTIC, true, 0);
560  fearless_lawful += generic_combat_modifier(tod.lawful_bonus, unit_type::ALIGNMENT::LAWFUL, true, 0);
561  bonuses.insert(std::abs(tod.lawful_bonus));
562  }
563  int target = std::max(fearless_chaotic, fearless_lawful);
564  int delta = target;
565  int result = 0;
566  for (int bonus : bonuses) {
567  int liminal_effect = 0;
568  for (const auto& tod : schedule) {
569  liminal_effect += generic_combat_modifier(tod.lawful_bonus, unit_type::ALIGNMENT::LIMINAL, false, bonus);
570  }
571  if (std::abs(target - liminal_effect) < delta) {
572  result = bonus;
573  delta = std::abs(target - liminal_effect);
574  }
575  }
576  return result;
577 }
play_controller * controller
Definition: resources.cpp:21
void set_new_current_times(const int new_current_turn_number)
For a change of the current turn number, sets the current times of the main time and all time areas...
void replace_local_schedule(const std::vector< time_of_day > &schedule, int area_index)
tod_manager & operator=(const tod_manager &manager)
Definition: tod_manager.cpp:65
unit_iterator end()
Definition: map.hpp:415
bool has_turn_event_fired_
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
Definition: location.cpp:517
void replace_schedule(const config &time_cfg)
Replace the time of day schedule.
const time_of_day & get_previous_time_of_day() const
Various functions that implement attacks and attack calculations.
bool has_attribute(config_key_type key) const
Definition: config.cpp:213
void set_turn(const int num, game_data *vars=nullptr, const bool increase_limit_if_needed=true)
Dynamically change the current turn number.
std::string id
Definition: time_of_day.hpp:91
int get_current_time(const map_location &loc=map_location::null_location()) const
void set_area_id(int area_index, const std::string &id)
bool has_tod_bonus_changed_
void resolve_random(randomness::rng &r)
handles random_start_time, should be called before the game starts.
Definition: tod_manager.cpp:88
int lawful_bonus
The % bonus lawful units receive.
Definition: time_of_day.hpp:84
void modify_turns_by_wml(const std::string &mod)
const terrain_type & get_terrain_info(const t_translation::terrain_code &terrain) const
Definition: map.cpp:97
std::set< map_location > hexes
int generic_combat_modifier(int lawful_bonus, unit_type::ALIGNMENT alignment, bool is_fearless, int max_liminal_bonus)
Returns the amount that a unit&#39;s damage should be multiplied by due to a given lawful_bonus.
Definition: attack.cpp:1783
void write(config &cfg) const
Definition: time_of_day.cpp:54
const std::set< map_location > & get_area_by_id(const std::string &id) const
int calculate_best_liminal_bonus(const std::vector< time_of_day > &schedule) const
Computes the maximum absolute value of lawful_bonus in the schedule.
std::vector< std::string > split(const std::string &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
config::attribute_value & get_variable(const std::string &varname)
throws invalid_variablename_exception if varname is no valid variable name.
Definition: game_data.cpp:62
void modify_turns(const std::string &mod)
Object which defines a time of day with associated bonuses, image, sounds etc.
Definition: time_of_day.hpp:57
void set_current_time(int time)
int light_bonus(int base) const
Returns the light (lawful) bonus for this terrain when the time of day gives a base bonus...
Definition: terrain.hpp:56
std::vector< map_location > parse_location_range(const std::string &xvals, const std::string &yvals, bool with_border=false) const
Parses ranges of locations into a vector of locations, using this map&#39;s dimensions as bounds...
Definition: map.cpp:416
static std::ostream & output()
Definition: log.cpp:51
void set_number_of_turns_by_wml(int num)
std::vector< time_of_day > times
bool on_board_with_border(const map_location &loc) const
Definition: map.cpp:382
const time_of_day & get_time_of_day(int for_turn=0) const
Returns global time of day for the passed turn.
Definition: tod_manager.hpp:54
config::attribute_value random_tod_
void remove_time_area(const std::string &id)
Removes a time area from config, making it follow the scenario&#39;s normal time-of-day sequence...
std::vector< time_of_day > times_
Encapsulates the map of the game.
Definition: map.hpp:36
tod_manager(const config &scenario_cfg=config())
Definition: tod_manager.cpp:37
config to_config() const
void update_server_information() const
std::vector< std::string > get_area_ids() const
void set_turn_by_wml(const int num, game_data *vars=nullptr, const bool increase_limit_if_needed=true)
Dynamically change the current turn number.
Encapsulates the map of the game.
Definition: location.hpp:42
std::pair< int, map_location > lowest(const std::string &key, int def=0) const
Definition: unit.hpp:60
unit_iterator find(std::size_t id)
Definition: map.cpp:311
const time_of_day get_illuminated_time_of_day(const unit_map &units, const gamemap &map, const map_location &loc, int for_turn=0) const
Returns time of day object for the passed turn at a location.
int calculate_current_time(const int number_of_times, const int for_turn_number, const int current_time, const bool only_to_allowed_range=false) const
Computes for the main time or a time area the index of its times where we&#39;re currently at...
std::size_t i
Definition: function.cpp:933
void write_location_range(const std::set< map_location > &locs, config &cfg)
Write a set of locations into a config using ranges, adding keys x=x1,..,xn and y=y1a-y1b,..,yna-ynb.
Definition: location.cpp:441
void set_number_of_turns(int num)
const std::vector< time_of_day > & times(const map_location &loc=map_location::null_location()) const
static void parse_times(const config &cfg, std::vector< time_of_day > &normal_times)
Parse config and add time of day entries into passed vector.
Definition: time_of_day.cpp:70
int get_composite_value() const
Definition: abilities.hpp:49
bool string_bool(const std::string &str, bool def)
Convert no, false, off, 0, 0.0 to false, empty to def, and others to true.
bool is_time_left() const
Function to check the end of turns.
bool to_bool(bool def=false) const
#define LOG_NG
Definition: tod_manager.cpp:35
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:71
bool has_cfg_liminal_bonus_
static lg::log_domain log_engine("engine")
config & add_child(config_key_type key)
Definition: config.cpp:476
static bool is_start_ToD(const std::string &)
void replace_area_locations(int index, const std::set< map_location > &locs)
void add_time_area(const gamemap &map, const config &cfg)
Adds a new local time area from config, making it follow its own time-of-day sequence.
int apply_modifier(const int number, const std::string &amount, const int minimum)
Standard logging facilities (interface).
static const map_location & null_location()
Definition: location.hpp:85
Container associating units to locations.
Definition: map.hpp:99
uint32_t next_random()
Provides the next random draw.
Definition: random.cpp:84
const std::set< map_location > & get_area_by_index(int index) const
std::vector< area_time_of_day > areas_
int bounded_add(int base, int increment, int max_sum, int min_sum=0)
Returns base + increment, but will not increase base above max_sum, nor decrease it below min_sum...
Definition: math.hpp:46
int get_current_area_time(int index) const
const time_of_day & get_time_of_day_turn(const std::vector< time_of_day > &times, int nturn, const int current_time) const
Returns time of day object in the turn "nturn".
bool next_turn(game_data *vars)
Function to move to the next turn.
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:92
bool random_start_time()
Definition: game.cpp:542
int bonus_modified
Definition: time_of_day.hpp:85
std::string::const_iterator iterator
Definition: tokenizer.hpp:24
virtual void send_to_wesnothd(const config &, const std::string &="unknown") const
std::pair< int, map_location > highest(const std::string &key, int def=0) const
Definition: unit.hpp:56
std::string str(const std::string &fallback="") const
this class does not give synced random results derived classes might do.
Definition: random.hpp:27