The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
movetype.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 
15 /**
16  * @file
17  * Handle movement types.
18  */
19 
20 #include "movetype.hpp"
21 
22 #include "game_board.hpp"
23 #include "game_config_manager.hpp"
24 #include "log.hpp"
25 #include "map/map.hpp"
26 #include "terrain/translation.hpp"
27 #include "terrain/type_data.hpp"
28 #include "units/types.hpp" // for attack_type
29 
30 #include <boost/assign.hpp>
31 #include <boost/make_shared.hpp>
32 
33 
34 static lg::log_domain log_config("config");
35 #define ERR_CF LOG_STREAM(err, log_config)
36 #define WRN_CF LOG_STREAM(warn, log_config)
37 
38 
39 /* *** parameters *** */
40 
41 
42 namespace { // Some functions for use with parameters::eval.
43 
44  /// Converts config defense values to a "max" value.
45  int config_to_max(int value)
46  {
47  return value < 0 ? -value : value;
48  }
49 
50  /// Converts config defense values to a "min" value.
51  int config_to_min(int value)
52  {
53  return value < 0 ? -value : 0;
54  }
55 }
56 
57 
58 /// The parameters used when calculating a terrain-based value.
60 {
61  int min_value; /// The smallest allowable value.
62  int max_value; /// The largest allowable value.
63  int default_value; /// The default value (if no data is available).
64 
65  int (*eval)(int); /// Converter for values taken from a config. May be nullptr.
66 
67  bool use_move; /// Whether to look at underlying movement or defense terrains.
68  bool high_is_good; /// Whether we are looking for highest or lowest (unless inverted by the underlying terrain).
69 
70  parameters(int min, int max, int (*eval_fun)(int)=nullptr, bool move=true, bool high=false) :
71  min_value(min), max_value(max), default_value(high ? min : max),
72  eval(eval_fun), use_move(move), high_is_good(high)
73  {}
74 };
75 
76 
79 
81  movetype::terrain_defense::params_min_(0, 100, config_to_min, false, true);
83  movetype::terrain_defense::params_max_(0, 100, config_to_max, false, false);
84 
85 
86 /* *** data *** */
87 
88 
90 {
91 public:
92  /// Constructor.
93  /// @a params must be long-lived (typically a static variable).
94  explicit data(const parameters & params) :
95  cfg_(), cache_(), params_(params)
96  {}
97  /// Constructor.
98  /// @a params must be long-lived (typically a static variable).
99  data(const config & cfg, const parameters & params) :
100  cfg_(cfg), cache_(), params_(params)
101  {}
102 
103  // The copy constructor does not bother copying the cache since
104  // typically the cache will be cleared shortly after the copy.
105  data(const data & that) :
106  cfg_(that.cfg_), cache_(), params_(that.params_)
107  {}
108 
109  /// Clears the cached data (presumably our fallback has changed).
110  void clear_cache(const terrain_info * cascade) const;
111  /// Tests if merging @a new_values would result in changes.
112  bool config_has_changes(const config & new_values, bool overwrite) const;
113  /// Tests for no data in this object.
114  bool empty() const { return cfg_.empty(); }
115  /// Merges the given config over the existing costs.
116  void merge(const config & new_values, bool overwrite,
117  const terrain_info * cascade);
118  /// Read-only access to our parameters.
119  const parameters & params() const { return params_; }
120  /// Returns the value associated with the given terrain.
122  const terrain_info * fallback) const
123  { return value(terrain, fallback, 0); }
124  /// If there is data, writes it to the config.
125  void write(config & out_cfg, const std::string & child_name) const;
126  /// If there is (merged) data, writes it to the config.
127  void write(config & out_cfg, const std::string & child_name,
128  const terrain_info * fallback) const;
129 
130 private:
131  /// Calculates the value associated with the given terrain.
133  const terrain_info * fallback, unsigned recurse_count) const;
134  /// Returns the value associated with the given terrain (possibly cached).
136  const terrain_info * fallback, unsigned recurse_count) const;
137 
138 private:
139  typedef std::map<t_translation::t_terrain, int> cache_t;
140 
141  /// Config describing the terrain values.
143  /// Cache of values based on the config.
144  mutable cache_t cache_;
145  /// Various parameters used when calculating values.
147 };
148 
149 
150 /**
151  * Clears the cached data (presumably our fallback has changed).
152  * @param[in] cascade Cache clearing will be cascaded into this terrain_info.
153  */
155 {
156  cache_.clear();
157  // Cascade the clear to whichever terrain_info falls back on us.
158  if ( cascade )
159  cascade->clear_cache();
160 }
161 
162 
163 /**
164  * Tests if merging @a new_values would result in changes.
165  * This allows the shared data to actually work, as otherwise each unit created
166  * via WML (including unstored units) would "overwrite" its movement data with
167  * a usually identical copy and thus break the sharing.
168  */
170  bool overwrite) const
171 {
172  if ( overwrite ) {
173  for (const config::attribute & a : new_values.attribute_range())
174  if ( a.second != cfg_[a.first] )
175  return true;
176  }
177  else {
178  for (const config::attribute & a : new_values.attribute_range())
179  if ( a.second.to_int() != 0 )
180  return true;
181  }
182 
183  // If we make it here, new_values has no changes for us.
184  return false;
185 }
186 
187 
188 /**
189  * Merges the given config over the existing costs.
190  * @param[in] new_values The new values.
191  * @param[in] overwrite If true, the new values overwrite the old.
192  * If false, the new values are added to the old.
193  * @param[in] cascade Cache clearing will be cascaded into this terrain_info.
194  */
195 void movetype::terrain_info::data::merge(const config & new_values, bool overwrite,
196  const terrain_info * cascade)
197 {
198  if ( overwrite )
199  // We do not support child tags here, so do not copy any that might
200  // be in the input. (If in the future we need to support child tags,
201  // change "merge_attributes" to "merge_with".)
202  cfg_.merge_attributes(new_values);
203  else {
204  for (const config::attribute & a : new_values.attribute_range()) {
205  config::attribute_value & dest = cfg_[a.first];
206  int old = dest.to_int(params_.max_value);
207 
208  // The new value is the absolute value of the old plus the
209  // provided value, capped between minimum and maximum, then
210  // given the sign of the old value.
211  // (Think defenses for why we might have negative values.)
212  int value = abs(old) + a.second.to_int(0);
213  value = std::max(params_.min_value, std::min(value, params_.max_value));
214  if ( old < 0 )
215  value = -value;
216 
217  dest = value;
218  }
219  }
220 
221  // The new data has invalidated the cache.
222  clear_cache(cascade);
223 }
224 
225 
226 /**
227  * If there is data, writes it to a config.
228  * @param[out] out_cfg The config that will receive the data.
229  * @param[in] child_name If not empty, create and write to a child config with this tag.
230  * This child will *not* be created if there is no data to write.
231  */
233  config & out_cfg, const std::string & child_name) const
234 {
235  if ( cfg_.empty() )
236  return;
237 
238  if ( child_name.empty() )
239  out_cfg.merge_with(cfg_);
240  else
241  out_cfg.add_child(child_name, cfg_);
242 }
243 
244 
245 /**
246  * Writes merged data to a config.
247  * @param[out] out_cfg The config that will receive the data.
248  * @param[in] child_name If not empty, create and write to a child config with this tag.
249  * This *will* be created even if there is no data to write.
250  * @param[in] fallback If not nullptr, its data will be merged with ours for the write.
251  */
253  config & out_cfg, const std::string & child_name, const terrain_info * fallback) const
254 {
255  // Get a place to write to.
256  config & merged = child_name.empty() ? out_cfg : out_cfg.add_child(child_name);
257 
258  if ( fallback )
259  fallback->write(merged, "", true);
260  merged.merge_with(cfg_);
261 }
262 
263 
264 /**
265  * Calculates the value associated with the given terrain.
266  * This is separate from value() to separate the calculating of the
267  * value from the caching of it.
268  * @param[in] terrain The terrain whose value is requested.
269  * @param[in] fallback Consulted if we are missing data.
270  * @param[in] recurse_count Detects (probable) infinite recursion.
271  */
274  const terrain_info * fallback,
275  unsigned recurse_count) const
276 {
277  // Infinite recursion detection:
278  if ( recurse_count > 100 ) {
279  ERR_CF << "infinite terrain_info recursion on "
280  << (params_.use_move ? "movement" : "defense") << ": "
282  << " depth " << recurse_count << '\n';
283  return params_.default_value;
284  }
285 
286  tdata_cache tdata;
288  tdata = game_config_manager::get()->terrain_types(); //This permits to get terrain info in unit help pages from the help in title screen, even if there is no residual gamemap object
289  }
290  assert(tdata);
291 
292  // Get a list of underlying terrains.
293  const t_translation::t_list & underlying = params_.use_move ?
294  tdata->underlying_mvt_terrain(terrain) :
295  tdata->underlying_def_terrain(terrain);
296  assert(!underlying.empty());
297 
298 
299  if ( underlying.size() == 1 && underlying.front() == terrain )
300  {
301  // This is not an alias; get the value directly.
302  int result = params_.default_value;
303 
304  const std::string & id = tdata->get_terrain_info(terrain).id();
305  if (const config::attribute_value *val = cfg_.get(id)) {
306  // Read the value from our config.
307  result = val->to_int(params_.default_value);
308  if ( params_.eval != nullptr )
309  result = params_.eval(result);
310  }
311  else if ( fallback != nullptr ) {
312  // Get the value from our fallback.
313  result = fallback->value(terrain);
314  }
315 
316  // Validate the value.
317  if ( result < params_.min_value ) {
318  WRN_CF << "Terrain '" << terrain << "' has evaluated to " << result
319  << " (" << (params_.use_move ? "cost" : "defense")
320  << "), which is less than " << params_.min_value
321  << "; resetting to " << params_.min_value << ".\n";
322  result = params_.min_value;
323  }
324  if ( result > params_.max_value ) {
325  WRN_CF << "Terrain '" << terrain << "' has evaluated to " << result
326  << " (" << (params_.use_move ? "cost" : "defense")
327  << "), which is more than " << params_.max_value
328  << "; resetting to " << params_.max_value << ".\n";
329  result = params_.max_value;
330  }
331 
332  return result;
333  }
334  else
335  {
336  // This is an alias; select the best of all underlying terrains.
337  bool prefer_high = params_.high_is_good;
338  int result = params_.default_value;
339  if ( underlying.front() == t_translation::MINUS )
340  // Use the other value as the initial value.
341  result = result == params_.max_value ? params_.min_value :
342  params_.max_value;
343 
344  // Loop through all underlying terrains.
345  t_translation::t_list::const_iterator i;
346  for ( i = underlying.begin(); i != underlying.end(); ++i )
347  {
348  if ( *i == t_translation::PLUS ) {
349  // Prefer what is good.
350  prefer_high = params_.high_is_good;
351  }
352  else if ( *i == t_translation::MINUS ) {
353  // Prefer what is bad.
354  prefer_high = !params_.high_is_good;
355  }
356  else {
357  // Test the underlying terrain's value against the best so far.
358  const int num = value(*i, fallback, recurse_count + 1);
359 
360  if ( ( prefer_high && num > result) ||
361  (!prefer_high && num < result) )
362  result = num;
363  }
364  }
365 
366  return result;
367  }
368 }
369 
370 
371 /**
372  * Returns the value associated with the given terrain (possibly cached).
373  * @param[in] terrain The terrain whose value is requested.
374  * @param[in] fallback Consulted if we are missing data.
375  * @param[in] recurse_count Detects (probable) infinite recursion.
376  */
379  const terrain_info * fallback,
380  unsigned recurse_count) const
381 {
382  // Check the cache.
383  std::pair<cache_t::iterator, bool> cache_it =
384  cache_.insert(std::make_pair(terrain, -127)); // Bogus value that should never be seen.
385  if ( cache_it.second )
386  // The cache did not have an entry for this terrain, so calculate the value.
387  cache_it.first->second = calc_value(terrain, fallback, recurse_count);
388 
389  return cache_it.first->second;
390 }
391 
392 
393 /* *** terrain_info *** */
394 
395 
396 /**
397  * Constructor.
398  * @param[in] params The parameters to use when calculating values.
399  * This is stored as a reference, so it must be long-lived (typically a static variable).
400  * @param[in] fallback Used as a backup in case we are asked for data we do not have (think vision costs falling back to movement costs).
401  * @param[in] cascade A terrain_info that uses us as a fallback. (Needed to sync cache clearing.)
402  * @note The fallback/cascade mechanism is a bit fragile and really should only
403  * be used by movetype.
404  */
406  const terrain_info * fallback,
407  const terrain_info * cascade) :
408  data_(new data(params)),
409  merged_data_(),
410  fallback_(fallback),
411  cascade_(cascade)
412 {
413 }
414 
415 
416 /**
417  * Constructor.
418  * @param[in] cfg An initial data set.
419  * @param[in] params The parameters to use when calculating values.
420  * This is stored as a reference, so it must be long-lived (typically a static variable).
421  * @param[in] fallback Used as a backup in case we are asked for data we do not have (think vision costs falling back to movement costs).
422  * @param[in] cascade A terrain_info that uses us as a fallback. (Needed to sync cache clearing.)
423  * @note The fallback/cascade mechanism is a bit fragile and really should only
424  * be used by movetype.
425  */
427  const terrain_info * fallback,
428  const terrain_info * cascade) :
429  data_(new data(cfg, params)),
430  merged_data_(),
431  fallback_(fallback),
432  cascade_(cascade)
433 {
434 }
435 
436 
437 /**
438  * Copy constructor.
439  * @param[in] that The terran_info to copy.
440  * @param[in] fallback Used as a backup in case we are asked for data we do not have (think vision costs falling back to movement costs).
441  * @param[in] cascade A terrain_info that uses us as a fallback. (Needed to sync cache clearing.)
442  * @note The fallback/cascade mechanism is a bit fragile and really should only
443  * be used by movetype.
444  */
446  const terrain_info * fallback,
447  const terrain_info * cascade) :
448  // If we do not have a fallback, we need to incorporate that's fallback.
449  // (See also the assignment operator.)
450  data_(fallback ? that.data_ : that.get_merged()),
451  merged_data_(that.merged_data_),
452  fallback_(fallback),
453  cascade_(cascade)
454 {
455 }
456 
457 
458 /**
459  * Destructor
460  */
462 {
463  // While this appears to be simply the default destructor, it needs
464  // to be defined in this file so that it knows about ~data(), which
465  // is called from the smart pointers' destructor.
466 }
467 
468 
469 /**
470  * Assignment operator.
471  */
473 {
474  if ( this != &that ) {
475  // If we do not have a fallback, we need to incorporate that's fallback.
476  // (See also the copy constructor.)
477  data_ = fallback_ ? that.data_ : that.get_merged();
478  merged_data_ = that.merged_data_;
479  // We do not change our fallback nor our cascade.
480  }
481 
482  return *this;
483 }
484 
485 
486 /**
487  * Clears the cache of values.
488  */
490 {
491  merged_data_.reset();
492  data_->clear_cache(cascade_);
493 }
494 
495 
496 /**
497  * Returns whether or not our data is empty.
498  */
500 {
501  return data_->empty();
502 }
503 
504 
505 /**
506  * Merges the given config over the existing values.
507  * @param[in] new_values The new values.
508  * @param[in] overwrite If true, the new values overwrite the old.
509  * If false, the new values are added to the old.
510  */
511 void movetype::terrain_info::merge(const config & new_values, bool overwrite)
512 {
513  if ( !data_->config_has_changes(new_values, overwrite) )
514  // Nothing will change, so skip the copy-on-write.
515  return;
516 
517  // Reset merged_data_ before seeing if data_ is unique, since the two might
518  // point to the same thing.
519  merged_data_.reset();
520 
521  // Copy-on-write.
522  if ( !data_.unique() ) {
523  data_.reset(new data(*data_));
524  // We also need to make copies of our fallback and cascade.
525  // This is to keep the caching manageable, as this means each
526  // individual movetype will either share *all* of its cost data
527  // or not share *all* of its cost data. In particular, we avoid:
528  // 1) many sets of (unshared) vision costs whose cache would need
529  // to be cleared when a shared set of movement costs changes;
530  // 2) a caching nightmare when shared vision costs fallback to
531  // unshared movement costs.
532  if ( fallback_ )
533  fallback_->make_unique_fallback();
534  if ( cascade_ )
535  cascade_->make_unique_cascade();
536  }
537 
538  data_->merge(new_values, overwrite, cascade_);
539 }
540 
541 
542 /**
543  * Returns the value associated with the given terrain.
544  */
546 {
547  return data_->value(terrain, fallback_);
548 }
549 
550 
551 /**
552  * Writes our data to a config.
553  * @param[out] cfg The config that will receive the data.
554  * @param[in] child_name If not empty, create and write to a child config with this tag.
555  * @param[in] merged If true, our data will be merged with our fallback's, and it is possible an empty child will be created.
556  * If false, data will not be merged, and an empty child will not be created.
557  */
558 void movetype::terrain_info::write(config & cfg, const std::string & child_name,
559  bool merged) const
560 {
561  if ( !merged )
562  data_->write(cfg, child_name);
563  else
564  data_->write(cfg, child_name, fallback_);
565 }
566 
567 
568 /**
569  * Returns a pointer to data the incorporates our fallback.
570  */
573 {
574  // Create-on-demand.
575  if ( !merged_data_ )
576  {
577  if ( !fallback_ )
578  // Nothing to incorporate.
579  merged_data_ = data_;
580 
581  else if ( data_->empty() )
582  // Pure fallback.
583  merged_data_ = fallback_->get_merged();
584 
585  else {
586  // Need to merge data.
587  config merged;
588  write(merged, "", true);
589  merged_data_ = boost::make_shared<data>(merged, data_->params());
590  }
591  }
592  return merged_data_;
593 }
594 
595 
596 /**
597  * Ensures our data is not shared, and propagates to our cascade.
598  */
600 {
601  if ( !data_.unique() )
602  // Const hack because this is not really changing the data.
603  const_cast<terrain_info *>(this)->data_.reset(new data(*data_));
604 
605  if ( cascade_ )
606  cascade_->make_unique_cascade();
607 }
608 
609 
610 /**
611  * Ensures our data is not shared, and propagates to our fallback.
612  */
614 {
615  if ( !data_.unique() )
616  // Const hack because this is not really changing the data.
617  const_cast<terrain_info *>(this)->data_.reset(new data(*data_));
618 
619  if ( fallback_ )
620  fallback_->make_unique_fallback();
621 }
622 
623 
624 /* *** resistances *** */
625 
626 
627 /**
628  * Returns a map from attack types to resistances.
629  */
631 {
633 
634  for (const config::attribute & attrb : cfg_.attribute_range()) {
635  result[attrb.first] = attrb.second;
636  }
637 
638  return result;
639 }
640 
641 
642 /**
643  * Returns the resistance against the indicated attack.
644  */
646 {
647  return cfg_[attack.type()].to_int(100);
648 }
649 
650 
651 /**
652  * Returns the resistance against the indicated damage type.
653  */
655 {
656  return cfg_[damage_type].to_int(100);
657 }
658 
659 
660 /**
661  * Merges the given config over the existing costs.
662  * If @a overwrite is false, the new values will be added to the old.
663  */
664 void movetype::resistances::merge(const config & new_data, bool overwrite)
665 {
666  if ( overwrite )
667  // We do not support child tags here, so do not copy any that might
668  // be in the input. (If in the future we need to support child tags,
669  // change "merge_attributes" to "merge_with".)
670  cfg_.merge_attributes(new_data);
671  else
672  for (const config::attribute & a : new_data.attribute_range()) {
673  config::attribute_value & dest = cfg_[a.first];
674  dest = std::max(0, dest.to_int(100) + a.second.to_int(0));
675  }
676 }
677 
678 
679 /**
680  * Writes our data to a config, as a child if @a child_name is specified.
681  * (No child is created if there is no data.)
682  */
683 void movetype::resistances::write(config & out_cfg, const std::string & child_name) const
684 {
685  if ( cfg_.empty() )
686  return;
687 
688  if ( child_name.empty() )
689  out_cfg.merge_with(cfg_);
690  else
691  out_cfg.add_child(child_name, cfg_);
692 }
693 
694 
695 /* *** movetype *** */
696 
697 
698 /**
699  * Default constructor
700  */
702  movement_(nullptr, &vision_), // This is not access before initialization; the address is merely stored at this point.
703  vision_(&movement_, &jamming_), // This is not access before initialization; the address is merely stored at this point.
704  jamming_(&vision_, nullptr),
705  defense_(),
706  resist_(),
707  flying_(false)
708 {
709 }
710 
711 
712 /**
713  * Constructor from a config
714  */
716  movement_(cfg.child_or_empty("movement_costs"), nullptr, &vision_), // This is not access before initialization; the address is merely stored at this point.
717  vision_(cfg.child_or_empty("vision_costs"), &movement_, &jamming_), // This is not access before initialization; the address is merely stored at this point.
718  jamming_(cfg.child_or_empty("jamming_costs"), &vision_, nullptr),
719  defense_(cfg.child_or_empty("defense")),
720  resist_(cfg.child_or_empty("resistance")),
721  flying_(cfg["flies"].to_bool(false))
722 {
723 }
724 
725 
726 /**
727  * Copy constructor
728  */
730  movement_(that.movement_, nullptr, &vision_), // This is not access before initialization; the address is merely stored at this point.
731  vision_(that.vision_, &movement_, &jamming_), // This is not access before initialization; the address is merely stored at this point.
732  jamming_(that.jamming_, &vision_, nullptr),
733  defense_(that.defense_),
734  resist_(that.resist_),
735  flying_(that.flying_)
736 {
737 }
738 
739 /**
740  * Checks if we have a defense cap (nontrivial min value) for any of the given terrain types.
741  */
742 bool movetype::has_terrain_defense_caps(const std::set<t_translation::t_terrain> & ts) const {
743  for (const t_translation::t_terrain & t : ts) {
744  if (defense_.capped(t))
745  return true;
746  }
747  return false;
748 }
749 
750 /**
751  * Merges the given config over the existing data.
752  * If @a overwrite is false, the new values will be added to the old.
753  */
754 void movetype::merge(const config & new_cfg, bool overwrite)
755 {
756  for (const config & child : new_cfg.child_range("movement_costs")) {
757  movement_.merge(child, overwrite);
758  }
759 
760  for (const config & child : new_cfg.child_range("vision_costs")) {
761  vision_.merge(child, overwrite);
762  }
763 
764  for (const config & child : new_cfg.child_range("jamming_costs")) {
765  jamming_.merge(child, overwrite);
766  }
767 
768  for (const config & child : new_cfg.child_range("defense")) {
769  defense_.merge(child, overwrite);
770  }
771 
772  for (const config & child : new_cfg.child_range("resistance")) {
773  resist_.merge(child, overwrite);
774  }
775 
776  // "flies" is used when WML defines a movetype.
777  // "flying" is used when WML defines a unit.
778  // It's easier to support both than to track which case we are in.
779  flying_ = new_cfg["flies"].to_bool(flying_);
780  flying_ = new_cfg["flying"].to_bool(flying_);
781 }
782 
783 /**
784  * The set of strings defining effects which apply to movetypes.
785  */
786 const std::set<std::string> movetype::effects = {"movement_costs",
787  "vision_costs", "jamming_costs", "defense", "resistance"};
788 
789 /**
790  * Writes the movement type data to the provided config.
791  */
792 void movetype::write(config & cfg) const
793 {
794  movement_.write(cfg, "movement_costs", false);
795  vision_.write(cfg, "vision_costs", false);
796  jamming_.write(cfg, "jamming_costs", false);
797  defense_.write(cfg, "defense");
798  resist_.write(cfg, "resistance");
799 
800  if ( flying_ )
801  cfg["flying"] = true;
802 }
803 
child_itors child_range(const std::string &key)
Definition: config.cpp:613
const parameters & params() const
Read-only access to our parameters.
Definition: movetype.cpp:119
cache_t cache_
Cache of values based on the config.
Definition: movetype.cpp:144
parameters(int min, int max, int(*eval_fun)(int)=nullptr, bool move=true, bool high=false)
Whether we are looking for highest or lowest (unless inverted by the underlying terrain).
Definition: movetype.cpp:70
int calc_value(const t_translation::t_terrain &terrain, const terrain_info *fallback, unsigned recurse_count) const
Calculates the value associated with the given terrain.
Definition: movetype.cpp:272
config cfg_
Config describing the terrain values.
Definition: movetype.cpp:142
void clear_cache() const
Clears the cache of values.
Definition: movetype.cpp:489
data(const parameters &params)
Constructor.
Definition: movetype.cpp:94
const terrain_info *const fallback_
Created as needed.
Definition: movetype.hpp:77
const boost::shared_ptr< data > & get_merged() const
Returns a pointer to data the incorporates our fallback.
Definition: movetype.cpp:572
int max_value
The smallest allowable value.
Definition: movetype.cpp:62
void clear_cache(const terrain_info *cascade) const
Clears the cached data (presumably our fallback has changed).
Definition: movetype.cpp:154
void make_unique_fallback() const
Ensures our data is not shared, and propagates to our fallback.
Definition: movetype.cpp:613
void write(config &cfg, const std::string &child_name="", bool merged=true) const
Writes our data to a config.
Definition: movetype.cpp:558
static const int UNREACHABLE
Magic value that signifies a hex is unreachable.
Definition: movetype.hpp:85
boost::shared_ptr< data > merged_data_
Never nullptr.
Definition: movetype.hpp:76
movetype()
Default constructor.
Definition: movetype.cpp:701
data(const data &that)
Definition: movetype.cpp:105
attribute_map::value_type attribute
Definition: config.hpp:393
static const parameters params_
Definition: movetype.hpp:90
int resistance_against(const attack_type &attack) const
Returns the resistance against the indicated attack.
Definition: movetype.cpp:645
~terrain_info()
Destructor.
Definition: movetype.cpp:461
const t_terrain MINUS
boost::shared_ptr< data > data_
Definition: movetype.hpp:75
GLuint const GLfloat * val
Definition: glew.h:2614
void merge(const config &new_data, bool overwrite)
Merges the given config over the existing costs.
Definition: movetype.cpp:664
void write(config &cfg) const
Writes the movement type data to the provided config.
Definition: movetype.cpp:792
const GLfloat * params
Definition: glew.h:1499
void merge(const config &new_cfg, bool overwrite=true)
Merges the given config over the existing data.
Definition: movetype.cpp:754
The basic "size" of the unit - flying, small land, large land, etc.
Definition: movetype.hpp:28
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
Definition: glew.h:1347
bool empty() const
Definition: config.cpp:1105
GLdouble GLdouble t
Definition: glew.h:1366
bool capped(const t_translation::t_terrain &terrain) const
Returns whether there is a defense cap associated to this terrain.
Definition: movetype.hpp:134
utils::string_map damage_table() const
Returns a map from attack types to resistances.
Definition: movetype.cpp:630
Variant for storing WML attributes.
Definition: config.hpp:223
void write(config &out_cfg, const std::string &child_name) const
If there is data, writes it to the config.
Definition: movetype.cpp:232
void merge_with(const config &c)
Merge config 'c' into this config, overwriting this config's values.
Definition: config.cpp:1350
static game_config_manager * get()
const t_terrain PLUS
GLuint64EXT * result
Definition: glew.h:10727
std::map< std::string, t_string > string_map
const terrain_info *const cascade_
Definition: movetype.hpp:78
bool use_move
Converter for values taken from a config. May be nullptr.
Definition: movetype.cpp:67
static text_list cache_
Definition: font.cpp:772
GLsizei const GLfloat * value
Definition: glew.h:1817
static const std::set< std::string > effects
The set of applicable effects for movement types.
Definition: movetype.hpp:233
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:7319
Stores a set of data based on terrain.
Definition: movetype.hpp:31
GLuint num
Definition: glew.h:2552
config & add_child(const std::string &key)
Definition: config.cpp:743
bool empty() const
Tests for no data in this object.
Definition: movetype.cpp:114
terrain_costs jamming_
Definition: movetype.hpp:241
static const ::config * terrain
The terrain used to create the cache.
Definition: minimap.cpp:135
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
void merge(const config &new_data, bool overwrite)
Merges the given config over the existing costs.
Definition: movetype.hpp:138
const std::string & type() const
Definition: attack_type.hpp:37
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Definition: translation.hpp:47
terrain_costs movement_
Definition: movetype.hpp:239
int default_value
The largest allowable value.
Definition: movetype.cpp:63
bool config_has_changes(const config &new_values, bool overwrite) const
Tests if merging new_values would result in changes.
Definition: movetype.cpp:169
bool high_is_good
Whether to look at underlying movement or defense terrains.
Definition: movetype.cpp:68
void write(config &cfg, const std::string &child_name="") const
Writes our data to a config, as a child if child_name is specified.
Definition: movetype.hpp:142
terrain_info & operator=(const terrain_info &that)
Assignment operator.
Definition: movetype.cpp:472
int value(const t_translation::t_terrain &terrain) const
Returns the value associated with the given terrain.
Definition: movetype.cpp:545
bool flying_
Definition: movetype.hpp:245
const_attr_itors attribute_range() const
Definition: config.cpp:984
static const terrain_info::parameters params_max_
Definition: movetype.hpp:122
size_t i
Definition: function.cpp:1057
terrain_costs vision_
Definition: movetype.hpp:240
const parameters & params_
Various parameters used when calculating values.
Definition: movetype.cpp:146
const tdata_cache & terrain_types() const
#define ERR_CF
Definition: movetype.cpp:35
std::string write_terrain_code(const t_terrain &tcode)
Writes a single terrain code to a string.
#define WRN_CF
Definition: movetype.cpp:36
const formula_callable * fallback_
Definition: function.cpp:807
void merge(const config &new_values, bool overwrite, const terrain_info *cascade)
Merges the given config over the existing costs.
Definition: movetype.cpp:195
void write(config &out_cfg, const std::string &child_name="") const
Writes our data to a config, as a child if child_name is specified.
Definition: movetype.cpp:683
bool empty() const
Returns whether or not our data is empty.
Definition: movetype.cpp:499
static lg::log_domain log_config("config")
resistances resist_
Definition: movetype.hpp:243
bool has_terrain_defense_caps(const std::set< t_translation::t_terrain > &ts) const
Returns whether or not there are any terrain caps with respect to a set of terrains.
Definition: movetype.cpp:742
terrain_defense defense_
Definition: movetype.hpp:242
Standard logging facilities (interface).
int to_int(int def=0) const
Definition: config.cpp:308
std::map< t_translation::t_terrain, int > cache_t
Definition: movetype.cpp:139
int value(const t_translation::t_terrain &terrain, const terrain_info *fallback) const
Returns the value associated with the given terrain.
Definition: movetype.cpp:121
The parameters used when calculating a terrain-based value.
Definition: movetype.cpp:59
void make_unique_cascade() const
Ensures our data is not shared, and propagates to our cascade.
Definition: movetype.cpp:599
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
terrain_info(const parameters &params, const terrain_info *fallback=nullptr, const terrain_info *cascade=nullptr)
Constructor.
Definition: movetype.cpp:405
GLsizei const GLcharARB ** string
Definition: glew.h:4503
static const terrain_info::parameters params_min_
Definition: movetype.hpp:121
void merge(const config &new_values, bool overwrite)
Merges the given config over the existing values.
Definition: movetype.cpp:511
int(* eval)(int)
The default value (if no data is available).
Definition: movetype.cpp:65
data(const config &cfg, const parameters &params)
Constructor.
Definition: movetype.cpp:99
std::vector< t_terrain > t_list
Definition: translation.hpp:75