30 #define DBG_NG LOG_STREAM(debug, log_engine)
31 #define ERR_NG LOG_STREAM(err, log_engine)
37 bool mid_scenario =
false;
40 typedef std::map<std::string,stats> team_stats_t;
55 explicit scenario_stats(
const config& cfg);
60 team_stats_t team_stats;
64 scenario_stats::scenario_stats(
const config& cfg) :
66 scenario_name(cfg[
"scenario"])
69 team_stats[
team[
"save_id"]] = stats(team);
76 res[
"scenario"] = scenario_name;
77 for(team_stats_t::const_iterator
i = team_stats.begin();
i != team_stats.end(); ++
i) {
87 for(team_stats_t::const_iterator
i = team_stats.begin();
i != team_stats.end(); ++
i) {
94 std::vector<scenario_stats> master_stats;
100 if(master_stats.empty()) {
101 master_stats.push_back(scenario_stats(
std::string()));
104 team_stats_t& team_stats = master_stats.back().team_stats;
105 return team_stats[save_id];
111 for(stats::str_int_map::const_iterator
i = m.begin();
i != m.end(); ++
i) {
112 res[
i->first] =
i->second;
120 for(stats::str_int_map::const_iterator
i = m.begin();
i != m.end(); ++
i) {
127 stats::str_int_map
m;
129 m[
i.first] =
i.second;
138 for(stats::battle_result_map::const_iterator
i = m.begin();
i != m.end(); ++
i) {
141 new_cfg[
"_num"] =
i->first;
149 for(stats::battle_result_map::const_iterator
i = m.begin();
i != m.end(); ++
i) {
159 stats::battle_result_map
m;
163 int key = item[
"_num"];
173 for(stats::str_int_map::const_iterator
i = b.begin();
i != b.end(); ++
i) {
174 a[
i->first] +=
i->second;
180 for(stats::battle_result_map::const_iterator
i = b.begin();
i != b.end(); ++
i) {
187 DBG_NG <<
"Merging statistics\n";
197 a.recruit_cost += b.recruit_cost;
198 a.recall_cost += b.recall_cost;
200 a.damage_inflicted += b.damage_inflicted;
201 a.damage_taken += b.damage_taken;
202 a.expected_damage_inflicted += b.expected_damage_inflicted;
203 a.expected_damage_taken += b.expected_damage_taken;
205 a.turn_damage_inflicted = b.turn_damage_inflicted;
206 a.turn_damage_taken = b.turn_damage_taken;
207 a.turn_expected_damage_inflicted = b.turn_expected_damage_inflicted;
208 a.turn_expected_damage_taken = b.turn_expected_damage_taken;
226 turn_damage_inflicted(0),
227 turn_damage_taken(0),
228 expected_damage_inflicted(0),
229 expected_damage_taken(0),
230 turn_expected_damage_inflicted(0),
231 turn_expected_damage_taken(0),
247 turn_damage_inflicted(0),
248 turn_damage_taken(0),
249 expected_damage_inflicted(0),
250 expected_damage_taken(0),
251 turn_expected_damage_inflicted(0),
252 turn_expected_damage_taken(0),
367 save_id = cfg[
"save_id"].str();
372 if(!mid_scenario || master_stats.empty()) {
373 master_stats.push_back(scenario_stats(name));
381 mid_scenario =
false;
385 const unit&
d,
int a_cth,
int d_cth) :
386 attacker_type(a.type_id()),
387 defender_type(d.type_id()),
388 attacker_side(get_team_save_id(a)),
389 defender_side(get_team_save_id(d)),
390 chance_to_hit_defender(a_cth),
391 chance_to_hit_attacker(d_cth),
419 int defender_inflict =
round_double(defender_inflict_ * stats::decimal_shift);
423 def_stats.expected_damage_inflicted += defender_inflict;
424 def_stats.expected_damage_taken += attacker_inflict;
427 def_stats.turn_expected_damage_inflicted += defender_inflict;
428 def_stats.turn_expected_damage_taken += attacker_inflict;
440 def_stats.damage_inflicted -= drain;
442 def_stats.turn_damage_inflicted -= drain;
445 def_stats.damage_taken += damage;
447 def_stats.turn_damage_taken += damage;
463 def_stats.damage_taken -= drain;
465 def_stats.turn_damage_taken -= drain;
469 def_stats.damage_inflicted += damage;
471 def_stats.turn_damage_inflicted += damage;
536 DBG_NG <<
"calculate_stats, side: " << save_id <<
" master_stats.size: " << master_stats.size() <<
"\n";
539 for (
size_t i = 0;
i != master_stats.size(); ++
i ) {
540 team_stats_t::const_iterator find_it = master_stats[
i].team_stats.find(save_id);
541 if ( find_it != master_stats[
i].team_stats.end() )
561 static const stats null_stats;
567 const team_stats_t & team_stats = master_stats[
level].team_stats;
569 team_stats_t::const_iterator find_it = team_stats.find(save_id);
570 if ( find_it != team_stats.end() )
571 level_list.push_back(make_pair(&master_stats[
level].scenario_name,
577 if ( level_list.empty() )
578 level_list.push_back(make_pair(&null_name, &null_stats));
587 res[
"mid_scenario"] = mid_scenario;
589 for(std::vector<scenario_stats>::const_iterator
i = master_stats.begin();
i != master_stats.end(); ++
i) {
598 out.
write_key_val(
"mid_scenario", mid_scenario ?
"yes" :
"no");
600 for(std::vector<scenario_stats>::const_iterator
i = master_stats.begin();
i != master_stats.end(); ++
i) {
610 mid_scenario = cfg[
"mid_scenario"].to_bool();
613 master_stats.push_back(scenario_stats(
s));
619 master_stats.clear();
620 mid_scenario =
false;
625 if(master_stats.empty() ==
false) {
626 master_stats.pop_back();
627 mid_scenario =
false;
634 for(stats::str_int_map::const_iterator
i = m.begin();
i != m.end(); ++
i) {
644 for (stats::str_int_map::const_iterator
i = m.begin();
i != m.end(); ++
i) {
647 ERR_NG <<
"Statistics refer to unknown unit type '" <<
i->first <<
"'. Discarding." << std::endl;
649 cost +=
i->second * t->
cost();
child_itors child_range(const std::string &key)
int chance_to_hit_defender
void remove_attribute(const std::string &key)
static stats::battle_result_map read_battle_result_map(const config &cfg)
long long damage_inflicted
scenario_context(const std::string &name)
battle_result_map defends
int sum_str_int_map(const stats::str_int_map &m)
void un_recall_unit(const unit &u)
attribute_map::value_type attribute
long long turn_damage_taken
int sum_cost_str_int_map(const stats::str_int_map &m)
unit_type_data unit_types
std::string attacker_type
void defend_result(hit_result res, int damage, int drain)
int round_double(double d)
void reset_turn_stats(const std::string &save_id)
void recruit_unit(const unit &u)
std::vector< std::pair< const std::string *, const stats * > > levels
Stats (and name) for each scenario. The pointers are never nullptr.
long long expected_damage_taken
const unit_type & type() const
The type of the unit (accounting for gender and variation).
GLdouble GLdouble GLdouble b
long long turn_expected_damage_inflicted
const std::string & type_id() const
The id of the type of the unit.
This class stores all the data for a single 'side' (in game nomenclature).
void write_key_val(const std::string &key, const T &value)
This template function will work with any type that can be assigned to an attribute_value.
std::string defender_side
int chance_to_hit_attacker
static void merge_str_int_map(stats::str_int_map &a, const stats::str_int_map &b)
std::vector< team > * teams
void close_child(const std::string &key)
static const int decimal_shift
Class for writing a config out to a file in pieces.
int un_recall_unit_cost(const unit &u)
void open_child(const std::string &key)
GLboolean GLboolean GLboolean GLboolean a
static stats & get_stats(const std::string &save_id)
levels level_stats(const std::string &save_id)
Returns a list of names and stats for each scenario in the current campaign.
static config write_battle_result_map(const stats::battle_result_map &m)
config & add_child(const std::string &key)
void read_stats(const config &cfg)
void read(const config &cfg)
Templates and utility-routines for strings and numbers.
void advance_unit(const unit &u)
static lg::log_domain log_engine("engine")
stats calculate_stats(const std::string &save_id)
const_attr_itors attribute_range() const
static stats::str_int_map read_str_int_map(const config &cfg)
long long turn_damage_inflicted
static void merge_battle_result_maps(stats::battle_result_map &a, const stats::battle_result_map &b)
std::string attacker_side
void recall_unit(const unit &u)
attack_context(const unit &a, const unit &d, int a_cth, int d_cth)
GLuint const GLchar * name
long long expected_damage_inflicted
std::string defender_type
const std::string & base_id() const
The id of the original type from which this (variation) descended.
static void merge_stats(stats &a, const stats &b)
void attack_expected_damage(double attacker_inflict, double defender_inflict)
std::map< std::string, int > str_int_map
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...
Standard logging facilities (interface).
void attack_result(hit_result res, int damage, int drain)
long long turn_expected_damage_taken
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.
battle_result_map attacks
void un_recruit_unit(const unit &u)
A config object defines a single node in a WML file, with access to child nodes.
void clear_current_scenario()
static config write_str_int_map(const stats::str_int_map &m)
void write(std::ostream &out, configr_of const &cfg, unsigned int level)
GLsizei const GLcharARB ** string