30 #define ERR_CF LOG_STREAM(err, log_config) 31 #define WRN_CF LOG_STREAM(warn, log_config) 40 int config_to_max(
int value)
42 return value < 0 ? -value : value;
46 int config_to_min(
int value)
48 return value < 0 ? -value : 0;
71 parameters(
int min,
int max,
int (*eval_fun)(
int)=
nullptr,
bool move=
true,
bool high=
false) :
72 min_value(min), max_value(max), default_value(high ? min : max),
73 eval(eval_fun), use_move(move), high_is_good(high)
99 cfg_(), cache_(), params_(params)
106 cfg_(cfg), cache_(), params_(params)
112 cfg_(that.cfg_), cache_(), params_(that.params_)
116 void clear_cache()
const;
118 bool config_has_changes(
const config & new_values,
bool overwrite)
const;
120 bool empty()
const {
return cfg_.empty(); }
122 void merge(
const config & new_values,
bool overwrite);
128 {
return value(terrain, fallback, 0); }
130 void write(
config & out_cfg,
const std::string & child_name)
const;
132 void write(
config & out_cfg,
const std::string & child_name,
138 const terrain_info * fallback,
unsigned recurse_count)
const;
141 const terrain_info * fallback,
unsigned recurse_count)
const;
144 typedef std::map<t_translation::terrain_code, int>
cache_t;
171 bool overwrite)
const 175 if (
a.second != cfg_[
a.first] )
180 if (
a.second.to_int() != 0 )
205 cfg_.merge_attributes(new_values);
209 int old = dest.
to_int(params_.max_value);
215 int value = std::abs(old) +
a.second.to_int(0);
216 value = std::max(params_.min_value, std::min(value, params_.max_value));
236 config & out_cfg,
const std::string & child_name)
const 241 if ( child_name.empty() )
256 config & out_cfg,
const std::string & child_name,
const terrain_info * fallback)
const 262 fallback->
write(merged,
"",
true);
278 unsigned recurse_count)
const 281 if ( recurse_count > 100 ) {
282 ERR_CF <<
"infinite terrain_info recursion on " 283 << (params_.use_move ?
"movement" :
"defense") <<
": " 285 <<
" depth " << recurse_count <<
'\n';
286 return params_.default_value;
289 std::shared_ptr<terrain_type_data> tdata;
297 tdata->underlying_mvt_terrain(terrain) :
298 tdata->underlying_def_terrain(terrain);
303 int result = params_.default_value;
305 const std::string &
id = tdata->get_terrain_info(terrain).id();
308 result = val->to_int(params_.default_value);
309 if ( params_.eval !=
nullptr )
310 result = params_.eval(result);
312 else if ( fallback !=
nullptr ) {
314 result = fallback->
value(terrain);
318 if ( result < params_.min_value ) {
319 WRN_CF <<
"Terrain '" << terrain <<
"' has evaluated to " << result
320 <<
" (" << (params_.use_move ?
"cost" :
"defense")
321 <<
"), which is less than " << params_.min_value
322 <<
"; resetting to " << params_.min_value <<
".\n";
323 result = params_.min_value;
325 if ( result > params_.max_value ) {
326 WRN_CF <<
"Terrain '" << terrain <<
"' has evaluated to " << result
327 <<
" (" << (params_.use_move ?
"cost" :
"defense")
328 <<
"), which is more than " << params_.max_value
329 <<
"; resetting to " << params_.max_value <<
".\n";
330 result = params_.max_value;
338 bool prefer_high = params_.high_is_good;
339 int result = params_.default_value;
342 result = result == params_.max_value ? params_.min_value :
346 t_translation::ter_list::const_iterator
i;
347 for (
i = underlying.begin();
i != underlying.end(); ++
i )
351 prefer_high = params_.high_is_good;
355 prefer_high = !params_.high_is_good;
359 const int num =
value(*
i, fallback, recurse_count + 1);
361 if ( ( prefer_high && num > result) ||
362 (!prefer_high && num < result) )
381 unsigned recurse_count)
const 384 std::pair<cache_t::iterator, bool> cache_it =
385 cache_.emplace(terrain, -127);
386 if ( cache_it.second )
388 cache_it.first->second = calc_value(terrain, fallback, recurse_count);
390 return cache_it.first->second;
553 const std::vector<movetype::terrain_info * > & dependants)
555 if ( !
get_data().config_has_changes(new_values, overwrite) )
566 for (
auto & dependant : dependants) {
568 dependant->make_data_writable();
611 std::unique_ptr<terrain_costs>
t;
614 t = std::make_unique<terrain_info>(*
this,
nullptr);
623 write(merged,
"",
true);
624 t = std::make_unique<terrain_info>(merged,
get_data().
params(),
nullptr);
657 t->shared_data_.reset();
681 t->shared_data_ = std::move(
t->unique_data_);
687 min_(that.min_, nullptr),
688 max_(that.max_, nullptr)
732 result[attrb.first] = attrb.second;
744 return cfg_[attack.
type()].to_int(100);
753 return cfg_[damage_type].to_int(100);
767 cfg_.merge_attributes(new_data);
771 dest = std::max(0, dest.
to_int(100) +
a.second.to_int(0));
785 if ( child_name.empty() )
816 defense_(cfg.child_or_empty(
"defense")),
817 resist_(cfg.child_or_empty(
"resistance")),
818 flying_(cfg[
"flies"].to_bool(false))
870 merge(child, applies_to, overwrite);
884 if(applies_to ==
"movement_costs") {
887 else if(applies_to ==
"vision_costs") {
890 else if(applies_to ==
"jamming_costs") {
893 else if(applies_to ==
"defense") {
896 else if(applies_to ==
"resistance") {
900 ERR_CF <<
"movetype::merge with unknown applies_to: " << applies_to << std::endl;
908 "vision_costs",
"jamming_costs",
"defense",
"resistance"};
922 cfg[
"flying"] =
true;
bool is_indivisible() const
Returns true if this terrain has no underlying types other than itself.
void write(config &cfg, const std::string &child_name="") const
Writes our data to a config, as a child if child_name is specified.
cache_t cache_
Cache of values based on the config.
parameters(int min, int max, int(*eval_fun)(int)=nullptr, bool move=true, bool high=false)
bool empty() const
Returns whether or not our data is empty.
config cfg_
Config describing the terrain values.
void merge(const config &new_values, bool overwrite, const std::vector< movetype::terrain_info *> &dependants)
Merges the given config over the existing values.
void merge(const config &new_values, bool overwrite)
Merges the given config over the existing costs.
std::map< std::string, t_string > string_map
void write(config &cfg, const std::string &child_name="", bool merged=true) const override
Writes our data to a config.
data(const parameters ¶ms)
Constructor.
void swap_data(movetype::terrain_info &that)
Swap function for the terrain_info class.
const terrain_info *const fallback_
std::map< t_translation::terrain_code, int > cache_t
movetype & operator=(const movetype &that)
std::unique_ptr< data > unique_data_
int max_value
The largest allowable value.
Variant for storing WML attributes.
terrain_info(const parameters ¶ms, const terrain_info *fallback)
Constructor.
static const int UNREACHABLE
Magic value that signifies a hex is unreachable.
movetype()
Default constructor.
child_itors child_range(config_key_type key)
attribute_map::value_type attribute
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
const data & get_data() const
Returns either *unique_data_ or *shared_data_, choosing the one that currently holds the data...
void merge(const config &new_data, bool overwrite)
Merges the given config over the existing costs.
const std::string & type() const
int to_int(int def=0) const
bool empty() const
Tests for no data in this object.
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...
The basic "size" of the unit - flying, small land, large land, etc.
void write(config &cfg) const
Writes the movement type data to the provided config.
bool capped(const t_translation::terrain_code &terrain) const
Returns whether there is a defense cap associated to this terrain.
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_attr_itors attribute_range() const
void clear_cache() const
Clears the cached data (presumably our fallback has changed).
int resistance_against(const attack_type &attack) const
Returns the resistance against the indicated attack.
const std::shared_ptr< terrain_type_data > & terrain_types() const
void merge_with(const config &c)
Merge config 'c' into this config, overwriting this config's values.
static game_config_manager * get()
void make_data_writable() const
Copy the immutable data back to unique_data_, no-op if the data is already in unique_data_.
bool use_move
Whether to look at underlying movement or defense terrains.
void write(config &out_cfg, const std::string &child_name) const
If there is data, writes it to the config.
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.
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'...
static const std::set< std::string > effects
The set of applicable effects for movement types.
Stores a set of data based on terrain, in some cases with raw pointers to other instances of terrain_...
int value(const t_translation::terrain_code &terrain) const override
Returns the value associated with the given terrain.
std::shared_ptr< const data > shared_data_
void merge(const config &new_data, bool overwrite)
Merges the given config over the existing costs.
std::string write_terrain_code(const terrain_code &tcode)
Writes a single terrain code to a string.
~terrain_info() override
Destructor.
int default_value
The default value (if no data is available).
bool high_is_good
Whether we are looking for highest or lowest (unless inverted by the underlying terrain).
bool config_has_changes(const config &new_values, bool overwrite) const
Tests if merging new_values would result in changes.
static const terrain_info::parameters params_max_
int min_value
The smallest allowable value.
const parameters & params_
Various parameters used when calculating values.
config & add_child(config_key_type key)
int(* eval)(int)
Converter for values taken from a config.
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, as happens when terrain_defense is copied, or 2) all of the siblings are being copied, as happens when movetype is copied.
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.
void swap(movetype::terrain_defense &a, movetype::terrain_defense &b)
Swap function for the terrain_defense class.
static lg::log_domain log_config("config")
utils::string_map damage_table() const
Returns a map from attack types to resistances.
Standard logging facilities (interface).
std::vector< terrain_code > ter_list
static const terrain_info::parameters mvj_params_
Limits for movement, vision and jamming.
const parameters & params() const
Read-only access to our parameters.
The parameters used when calculating a terrain-based value.
friend void swap(movetype &a, movetype &b)
Swap function for the movetype class, including its terrain_info members.
A config object defines a single node in a WML file, with access to child nodes.
terrain_defense & operator=(const terrain_defense &that)
static std::unique_ptr< terrain_costs > read_terrain_costs(const config &cfg)
Reverse of terrain_costs::write.
Stores a set of defense levels.
static const terrain_info::parameters params_min_
data(const config &cfg, const parameters ¶ms)
Constructor.
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.
int value(const t_translation::terrain_code &terrain, const terrain_info *fallback) const
Returns the value associated with the given terrain.