28 #define ERR_CF LOG_STREAM(err, log_config)
29 #define WRN_CF LOG_STREAM(warn, log_config)
38 int config_to_max(
int value)
40 return value < 0 ? -value : value;
44 int config_to_min(
int value)
46 return value < 0 ? -value : 0;
69 parameters(
int min,
int max,
int (*eval_fun)(
int)=
nullptr,
bool move=
true,
bool high=
false) :
120 void merge(
const config & new_values,
bool overwrite);
126 {
return value(terrain, fallback, 0); }
128 void write(
config & out_cfg,
const std::string & child_name)
const;
130 void write(
config & out_cfg,
const std::string & child_name,
136 const terrain_info * fallback,
unsigned recurse_count)
const;
139 const terrain_info * fallback,
unsigned recurse_count)
const;
142 typedef std::map<t_translation::terrain_code, int>
cache_t;
169 bool overwrite)
const
173 if (
value != cfg_[key] )
178 if (
value.to_int() != 0 )
203 cfg_.merge_attributes(new_values);
207 int old = dest.
to_int(params_.max_value);
213 int value = std::abs(old) + new_value.to_int(0);
214 value = std::max(params_.min_value, std::min(
value, params_.max_value));
234 config & out_cfg,
const std::string & child_name)
const
239 if ( child_name.empty() )
254 config & out_cfg,
const std::string & child_name,
const terrain_info * fallback)
const
260 fallback->
write(merged,
"",
true);
276 unsigned recurse_count)
const
279 if ( recurse_count > 100 ) {
280 ERR_CF <<
"infinite terrain_info recursion on "
281 << (params_.use_move ?
"movement" :
"defense") <<
": "
283 <<
" depth " << recurse_count;
284 return params_.default_value;
287 std::shared_ptr<terrain_type_data> tdata;
295 tdata->underlying_mvt_terrain(terrain) :
296 tdata->underlying_def_terrain(terrain);
301 int result = params_.default_value;
303 const std::string &
id = tdata->get_terrain_info(terrain).id();
306 result = val->to_int(params_.default_value);
307 if ( params_.eval !=
nullptr )
308 result = params_.eval(result);
310 else if ( fallback !=
nullptr ) {
312 result = fallback->
value(terrain);
316 if ( result < params_.min_value ) {
317 WRN_CF <<
"Terrain '" << terrain <<
"' has evaluated to " << result
318 <<
" (" << (params_.use_move ?
"cost" :
"defense")
319 <<
"), which is less than " << params_.min_value
320 <<
"; resetting to " << params_.min_value <<
".";
321 result = params_.min_value;
323 if ( result > params_.max_value ) {
324 WRN_CF <<
"Terrain '" << terrain <<
"' has evaluated to " << result
325 <<
" (" << (params_.use_move ?
"cost" :
"defense")
326 <<
"), which is more than " << params_.max_value
327 <<
"; resetting to " << params_.max_value <<
".";
328 result = params_.max_value;
336 bool prefer_high = params_.high_is_good;
337 int result = params_.default_value;
340 result = result == params_.max_value ? params_.min_value :
344 t_translation::ter_list::const_iterator
i;
345 for (
i = underlying.begin();
i != underlying.end(); ++
i )
349 prefer_high = params_.high_is_good;
353 prefer_high = !params_.high_is_good;
357 const int num =
value(*
i, fallback, recurse_count + 1);
359 if ( ( prefer_high && num > result) ||
360 (!prefer_high && num < result) )
379 unsigned recurse_count)
const
382 std::pair<cache_t::iterator, bool> cache_it =
383 cache_.emplace(terrain, -127);
384 if ( cache_it.second )
386 cache_it.first->second = calc_value(terrain, fallback, recurse_count);
388 return cache_it.first->second;
418 unique_data_(new
data(cfg, params)),
474 this->unique_data_.reset();
540 return get_data().empty();
552 const std::vector<movetype::terrain_info * > & dependants)
554 if ( !get_data().config_has_changes(new_values, overwrite) )
564 make_data_writable();
565 for (
auto & dependant : dependants) {
567 dependant->make_data_writable();
570 unique_data_->merge(new_values, overwrite);
579 return get_data().value(terrain,
fallback_);
593 get_data().write(cfg, child_name);
595 get_data().write(cfg, child_name,
fallback_);
610 std::unique_ptr<terrain_costs>
t;
613 t = std::make_unique<terrain_info>(*
this,
nullptr);
615 else if(get_data().empty()) {
622 write(merged,
"",
true);
623 t = std::make_unique<terrain_info>(merged, get_data().params(),
nullptr);
630 assert(unique_data_ || shared_data_);
631 assert(! (unique_data_ && shared_data_));
633 return *unique_data_;
634 return *shared_data_;
655 t->unique_data_.reset(
new data(*shared_data_));
656 t->shared_data_.reset();
660 unique_data_->clear_cache();
680 t->shared_data_ = std::move(
t->unique_data_);
686 min_(that.min_, nullptr),
687 max_(that.max_, nullptr)
692 min_(std::move(that.min_), nullptr),
693 max_(std::move(that.max_), nullptr)
699 min_.copy_data(that.
min_);
700 max_.copy_data(that.
max_);
706 min_.swap_data(that.min_);
707 max_.swap_data(that.max_);
716 min_.merge(new_data, overwrite, {});
717 max_.merge(new_data, overwrite, {});
730 for(
const auto& [key, value] : cfg_.attribute_range()) {
742 return cfg_[damage_type].to_int(100);
756 cfg_.merge_attributes(new_data);
760 dest = std::max(0, dest.
to_int(100) + value.to_int(0));
774 if ( child_name.empty() )
803 movement_(cfg.child_or_empty(
"movement_costs"), mvj_params_, nullptr),
804 vision_(cfg.child_or_empty(
"vision_costs"), mvj_params_, &movement_),
805 jamming_(cfg.child_or_empty(
"jamming_costs"), mvj_params_, &vision_),
806 defense_(cfg.child_or_empty(
"defense")),
807 resist_(cfg.child_or_empty(
"resistance")),
808 flying_(cfg[
"flies"].to_bool(false))
823 movement_(that.movement_, nullptr),
824 vision_(that.vision_, &movement_),
825 jamming_(that.jamming_, &vision_),
826 defense_(that.defense_),
827 resist_(that.resist_),
828 flying_(that.flying_),
829 special_notes_(that.special_notes_)
837 movement_(std::move(that.movement_), nullptr),
838 vision_(std::move(that.vision_), &movement_),
839 jamming_(std::move(that.jamming_), &vision_),
840 defense_(std::move(that.defense_)),
841 resist_(std::move(that.resist_)),
842 flying_(std::move(that.flying_)),
843 special_notes_(std::move(that.special_notes_))
862 merge(child, applies_to, overwrite);
876 if(applies_to ==
"movement_costs") {
879 else if(applies_to ==
"vision_costs") {
882 else if(applies_to ==
"jamming_costs") {
885 else if(applies_to ==
"defense") {
888 else if(applies_to ==
"resistance") {
892 ERR_CF <<
"movetype::merge with unknown applies_to: " << applies_to;
900 "vision_costs",
"jamming_costs",
"defense",
"resistance"};
911 cfg[
"flying"] =
true;
Variant for storing WML attributes.
int to_int(int def=0) const
A config object defines a single node in a WML file, with access to child nodes.
const_attr_itors attribute_range() const
void merge_with(const config &c)
Merge config 'c' into this config, overwriting this config's values.
child_itors child_range(config_key_type key)
config & add_child(config_key_type key)
static game_config_manager * get()
const std::shared_ptr< terrain_type_data > & terrain_types() const
int resistance_against(const std::string &damage_type) const
Returns the vulnerability to the indicated damage type (higher means more damage).
void merge(const config &new_data, bool overwrite)
Merges the given config over the existing costs.
utils::string_map_res damage_table() const
Returns a map from damage types to resistances.
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.
Stores a set of defense levels.
terrain_defense & operator=(const terrain_defense &that)
void write(config &cfg, const std::string &child_name="") const
Writes our data to a config, as a child if child_name is specified.
bool capped(const t_translation::terrain_code &terrain) const
Returns whether there is a defense cap associated to this terrain.
static const terrain_info::parameters params_max_
static const terrain_info::parameters params_min_
void merge(const config &new_data, bool overwrite)
Merges the given config over the existing costs.
bool config_has_changes(const config &new_values, bool overwrite) const
Tests if merging new_values would result in changes.
const parameters & params() const
Read-only access to our parameters.
void write(config &out_cfg, const std::string &child_name) const
If there is data, writes it to the config.
data(const config &cfg, const parameters ¶ms)
Constructor.
config cfg_
Config describing the terrain values.
std::map< t_translation::terrain_code, int > cache_t
bool empty() const
Tests for no data in this object.
void merge(const config &new_values, bool overwrite)
Merges the given config over the existing costs.
cache_t cache_
Cache of values based on the config.
void clear_cache() const
Clears the cached data (presumably our fallback has changed).
int calc_value(const t_translation::terrain_code &terrain, const terrain_info *fallback, unsigned recurse_count) const
Calculates the value associated with the given terrain.
int value(const t_translation::terrain_code &terrain, const terrain_info *fallback) const
Returns the value associated with the given terrain.
data(const parameters ¶ms)
Constructor.
const parameters & params_
Various parameters used when calculating values.
Stores a set of data based on terrain, in some cases with raw pointers to other instances of terrain_...
void make_data_writable() const
Copy the immutable data back to unique_data_, no-op if the data is already in unique_data_.
const data & get_data() const
Returns either *unique_data_ or *shared_data_, choosing the one that currently holds the data.
std::unique_ptr< terrain_costs > make_standalone() const override
Does a sufficiently deep copy so that the returned object's lifespan is independent of other objects'...
std::shared_ptr< const data > shared_data_
void swap_data(movetype::terrain_info &that)
Swap function for the terrain_info class.
void copy_data(const movetype::terrain_info &that)
This is only expected to be called either when 1) both this and that have no siblings,...
bool empty() const
Returns whether or not our data is empty.
terrain_info(const parameters ¶ms, const terrain_info *fallback)
Constructor.
void write(config &cfg, const std::string &child_name="", bool merged=true) const override
Writes our data to a config.
int value(const t_translation::terrain_code &terrain) const override
Returns the value associated with the given terrain.
~terrain_info() override
Destructor.
void make_data_shareable() const
Move data to an immutable copy in shared_data_, no-op if the data is already in shared_data_.
const terrain_info *const fallback_
void merge(const config &new_values, bool overwrite, const std::vector< movetype::terrain_info * > &dependants)
Merges the given config over the existing values.
std::unique_ptr< data > unique_data_
The basic "size" of the unit - flying, small land, large land, etc.
static const int UNREACHABLE
Magic value that signifies a hex is unreachable.
void write(config &cfg, bool include_notes) const
Writes the movement type data to the provided config.
movetype()
Default constructor.
static const std::set< std::string > effects
The set of applicable effects for movement types.
void merge(const config &new_cfg, bool overwrite=true)
Merges the given config over the existing data, the config should have zero or more children named "m...
bool has_terrain_defense_caps(const std::set< t_translation::terrain_code > &ts) const
Returns whether or not there are any terrain caps with respect to a set of terrains.
movetype & operator=(const movetype &that)
static const terrain_info::parameters mvj_params_
Limits for movement, vision and jamming.
static std::unique_ptr< terrain_costs > read_terrain_costs(const config &cfg)
Reverse of terrain_costs::write.
friend void swap(movetype &a, movetype &b)
Swap function for the movetype class, including its terrain_info members.
std::vector< t_string > special_notes_
bool is_indivisible() const
Returns true if this terrain has no underlying types other than itself.
const formula_callable * fallback_
static std::string _(const char *str)
Standard logging facilities (interface).
void swap(movetype::terrain_defense &a, movetype::terrain_defense &b)
Swap function for the terrain_defense class.
static lg::log_domain log_config("config")
std::vector< terrain_code > ter_list
std::string write_terrain_code(const terrain_code &tcode)
Writes a single terrain code to a string.
std::map< std::string, t_string, res_compare > string_map_res
The parameters used when calculating a terrain-based value.
int default_value
The default value (if no data is available).
bool use_move
Whether to look at underlying movement or defense terrains.
parameters(int min, int max, int(*eval_fun)(int)=nullptr, bool move=true, bool high=false)
int max_value
The largest allowable value.
bool high_is_good
Whether we are looking for highest or lowest (unless inverted by the underlying terrain).
int(* eval)(int)
Converter for values taken from a config.
int min_value
The smallest allowable value.
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...