summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/dbg-scan.cc
diff options
context:
space:
mode:
authorgammafunk <gammafunk@gmail.com>2014-06-23 00:11:59 -0500
committergammafunk <gammafunk@gmail.com>2014-06-25 20:50:43 -0500
commit544f0ae2f541e7ba4a8040d669daa8312c028298 (patch)
treea7606121afe6473d42df87fcd6f4e5d6a6deee20 /crawl-ref/source/dbg-scan.cc
parentf1909d2967591ffdf556ca62d31855aa09329ad8 (diff)
downloadcrawl-ref-544f0ae2f541e7ba4a8040d669daa8312c028298.tar.gz
crawl-ref-544f0ae2f541e7ba4a8040d669daa8312c028298.zip
Write object statistics in one file per branch
All output in a single file was difficult to view and work with. Each file uses a common prefix of "objstat_", and the file names are printed to stdout.
Diffstat (limited to 'crawl-ref/source/dbg-scan.cc')
-rw-r--r--crawl-ref/source/dbg-scan.cc895
1 files changed, 429 insertions, 466 deletions
diff --git a/crawl-ref/source/dbg-scan.cc b/crawl-ref/source/dbg-scan.cc
index 94380c3bbb..da0e0b4698 100644
--- a/crawl-ref/source/dbg-scan.cc
+++ b/crawl-ref/source/dbg-scan.cc
@@ -4,8 +4,10 @@
**/
#include "AppHdr.h"
+
#include "dbg-scan.h"
+#include <errno.h>
#include <sstream>
#include "artefact.h"
@@ -734,13 +736,11 @@ void check_map_validity()
#endif
}
-
#ifdef DEBUG_DIAGNOSTICS
-
static FILE *og_outf;
-const static char *og_out_file = "objects.txt";
+const static char *og_out_prefix = "objgen_";
+const static char *og_out_ext = ".txt";
#define OG_STAT_PRECISION 3
-static char og_stat_fmt[10] = "";
enum og_class_type {
OG_FOOD,
@@ -763,21 +763,35 @@ enum og_class_type {
OG_UNUSED = 100,
};
-enum og_summary_level {
- SUMMARY_ORD,
- SUMMARY_ARTE,
- SUMMARY_ALL,
+enum og_antiquity_level {
+ ANTIQ_ORDINARY,
+ ANTIQ_ARTEFACT,
+ ANTIQ_ALL,
+};
+
+class og_item
+{
+public:
+ og_item(og_class_type ct, int st) : base_type(ct), sub_type(st)
+ {
+ }
+ og_item(item_def &item);
+
+ og_class_type base_type;
+ int sub_type;
};
-static vector<level_id> og_levels;
-static map<branch_type, int> og_branches;
+static level_id og_all_lev(NUM_BRANCHES, -1);
+static map<branch_type, vector<level_id> > og_branches;
+static int og_num_branches = 0;
+static int og_num_levels = 0;
// og_items[level_id][item.base_type][item.sub_type][field]
static map<level_id, FixedVector<map<int, map<string, double> >, NUM_OG_CLASSES> > og_items;
-// og_weapon_brands[level_id][item.sub_type][type_ind][brand];
-// type_ind is 0 for ordinary, 1 for artefact, or 2 for all
-static map<level_id, vector< vector< vector< int> > > > og_weapon_brands;
+// og_weapon_brands[level_id][item.base_type][item.sub_type][arte_sum][brand];
+// arte_sum is 0 for ordinary, 1 for artefact, or 2 for all
+static map<level_id, vector <vector< vector< vector< int> > > > > og_equip_brands;
static map<level_id, vector< vector< vector< int> > > > og_armour_brands;
static map<level_id, vector< vector< int> > > og_missile_brands;
@@ -955,21 +969,53 @@ static int _og_orig_food_subtype(int sub_type)
return 0;
}
-static int _og_orig_sub_type(og_class_type item_type, int sub_type)
+static string _og_class_name(og_class_type item_type)
+{
+ string name;
+ switch (item_type)
+ {
+ case OG_DECKS:
+ name = "Decks";
+ break;
+ case OG_ARTEBOOKS:
+ name = "Artefact Spellbooks";
+ break;
+ case OG_MANUALS:
+ name = "Manuals";
+ break;
+ default:
+ name = item_class_name(_og_orig_base_type(item_type));
+ }
+ return name;
+}
+
+static int _og_orig_sub_type(og_item &item)
{
int type;
- if (item_type == OG_DECKS)
- type = sub_type + MISC_FIRST_DECK;
- else if (item_type == OG_MISCELLANY && sub_type >= MISC_FIRST_DECK)
- type = sub_type + MISC_LAST_DECK - MISC_FIRST_DECK + 1;
- else if (item_type == OG_FOOD)
- type = _og_orig_food_subtype(sub_type);
- else if (item_type == OG_ARTEBOOKS)
- type = sub_type + BOOK_RANDART_LEVEL;
- else if (item_type == OG_MANUALS)
+ switch (item.base_type)
+ {
+ case OG_DECKS:
+ type = item.sub_type + MISC_FIRST_DECK;
+ break;
+ case OG_MISCELLANY:
+ if (item.sub_type >= MISC_FIRST_DECK)
+ type = item.sub_type + MISC_LAST_DECK - MISC_FIRST_DECK + 1;
+ else
+ type = item.sub_type;
+ break;
+ case OG_FOOD:
+ type = _og_orig_food_subtype(item.sub_type);
+ break;
+ case OG_ARTEBOOKS:
+ type = item.sub_type + BOOK_RANDART_LEVEL;
+ break;
+ case OG_MANUALS:
type = BOOK_MANUAL;
- else
- type = sub_type;
+ break;
+ default:
+ type = item.sub_type;
+ break;
+ }
return type;
}
@@ -989,7 +1035,7 @@ static int _og_get_max_subtype(og_class_type item_type)
num = MISC_LAST_DECK - MISC_FIRST_DECK + 1;
break;
case OG_BOOKS:
- num = MAX_RARE_BOOK;
+ num = MAX_RARE_BOOK + 1;
break;
case OG_ARTEBOOKS:
num = 2;
@@ -1004,49 +1050,21 @@ static int _og_get_max_subtype(og_class_type item_type)
return num;
}
-static item_def _og_dummy_item(og_class_type base_type, int sub_type)
+static item_def _og_dummy_item(og_item &item)
{
- item_def item;
- item.base_type = _og_orig_base_type(base_type);
- item.sub_type = _og_orig_sub_type(base_type, sub_type);
+ item_def dummy_item;
+ dummy_item.base_type = _og_orig_base_type(item.base_type);
+ dummy_item.sub_type = _og_orig_sub_type(item);
// Deck name is reported as buggy if this is not done.
- if (base_type == OG_DECKS)
+ if (item.base_type == OG_DECKS)
{
- item.plus = 1;
- item.special = DECK_RARITY_COMMON;
- init_deck(item);
+ dummy_item.plus = 1;
+ dummy_item.special = DECK_RARITY_COMMON;
+ init_deck(dummy_item);
}
- return item;
+ return dummy_item;
}
-static string _og_class_name(og_class_type item_type)
-{
- string name;
- switch (item_type)
- {
- case OG_DECKS:
- name = "Decks";
- break;
- case OG_ARTEBOOKS:
- name = "Artefact Spellbooks";
- break;
- case OG_MANUALS:
- name = "Manuals";
- break;
- default:
- name = item_class_name(_og_orig_base_type(item_type));
- }
- return name;
-}
-
-class og_item
-{
-public:
- og_item(item_def &item);
- og_class_type base_type;
- int sub_type;
-};
-
og_item::og_item(item_def &item)
{
base_type = _og_base_type(item);
@@ -1113,359 +1131,353 @@ static void _og_init_fields()
"TotalGourmNutr");
}
-
static void _og_init_stats()
{
- vector<level_id>::const_iterator li;
- for (li = og_levels.begin(); li != og_levels.end(); li++)
+ map<branch_type, vector<level_id> >::const_iterator bi;
+ for (bi = og_branches.begin(); bi != og_branches.end(); bi++)
{
- for (int i = 0; i < NUM_OG_CLASSES; i++)
+ for (unsigned int l = 0; l <= bi->second.size(); l++)
{
- og_class_type item_type = static_cast<og_class_type>(i);
- for (int j = 0; j <= _og_get_max_subtype(item_type); j++)
+ level_id lev;
+ if (l == bi->second.size())
{
- for (unsigned int k = 0; k < og_item_fields[i].size(); k++)
- og_items[*li][i][j][og_item_fields[i][k]] = 0;
+ lev.branch = bi->first;
+ lev.depth = -1;
}
- }
- og_weapon_brands[*li] = vector< vector< vector<int> > >();
- for (int i = 0; i <= NUM_WEAPONS; i++)
- {
- og_weapon_brands[*li].push_back(vector< vector<int> >());
- for (int j = 0; j < 3; j++)
+ else
+ lev = (bi->second)[l];
+ for (int i = 0; i < NUM_OG_CLASSES; i++)
{
- og_weapon_brands[*li][i].push_back(vector<int>());
- for (int k = 0; k < NUM_SPECIAL_WEAPONS; k++)
- og_weapon_brands[*li][i][j].push_back(0);
+ og_class_type item_type = static_cast<og_class_type>(i);
+ for (int j = 0; j <= _og_get_max_subtype(item_type); j++)
+ {
+ for (unsigned int k = 0; k < og_item_fields[i].size(); k++)
+ og_items[lev][i][j][og_item_fields[i][k]] = 0;
+ }
}
- }
- og_armour_brands[*li] = vector< vector< vector<int> > >();
- for (int i = 0; i <= NUM_ARMOURS; i++)
- {
- og_armour_brands[*li].push_back(vector< vector<int> >());
- for (int j = 0; j < 3; j++)
+ og_equip_brands[lev] = vector< vector< vector< vector<int> > > >();
+ og_equip_brands[lev].push_back(vector< vector< vector<int> > >());
+ for (int i = 0; i <= NUM_WEAPONS; i++)
{
- og_armour_brands[*li][i].push_back(vector<int>());
- for (int k = 0; k < NUM_SPECIAL_ARMOURS; k++)
- og_armour_brands[*li][i][j].push_back(0);
+ og_equip_brands[lev][0].push_back(vector< vector<int> >());
+ for (int j = 0; j < 3; j++)
+ {
+ og_equip_brands[lev][0][i].push_back(vector<int>());
+ for (int k = 0; k < NUM_SPECIAL_WEAPONS; k++)
+ og_equip_brands[lev][0][i][j].push_back(0);
+ }
+ }
+
+ og_equip_brands[lev].push_back(vector< vector< vector<int> > >());
+ for (int i = 0; i <= NUM_ARMOURS; i++)
+ {
+ og_equip_brands[lev][1].push_back(vector< vector<int> >());
+ for (int j = 0; j < 3; j++)
+ {
+ og_equip_brands[lev][1][i].push_back(vector<int>());
+ for (int k = 0; k < NUM_SPECIAL_ARMOURS; k++)
+ og_equip_brands[lev][1][i][j].push_back(0);
+ }
+ }
+
+ og_missile_brands[lev] = vector< vector<int> >();
+ for (int i = 0; i <= NUM_MISSILES; i++)
+ {
+ og_missile_brands[lev].push_back(vector<int>());
+ for (int j = 0; j < NUM_SPECIAL_ARMOURS; j++)
+ og_missile_brands[lev][i].push_back(0);
+ }
+
+ map<monster_type, int>::const_iterator mi;
+ for (mi = og_valid_monsters.begin(); mi != og_valid_monsters.end();
+ mi++)
+ {
+ for (unsigned int i = 0; i < og_monster_fields.size(); i++)
+ og_monsters[lev][mi->second][og_monster_fields[i]] = 0;
}
- }
- og_missile_brands[*li] = vector< vector<int> >();
- for (int i = 0; i <= NUM_MISSILES; i++)
- {
- og_missile_brands[*li].push_back(vector<int>());
- for (int j = 0; j < NUM_SPECIAL_ARMOURS; j++)
- og_missile_brands[*li][i].push_back(0);
- }
- map<monster_type, int>::const_iterator mi;
- for (mi = og_valid_monsters.begin(); mi != og_valid_monsters.end();
- mi++)
- {
- for (unsigned int i = 0; i < og_monster_fields.size(); i++)
- og_monsters[*li][mi->second][og_monster_fields[i]] = 0;
}
+ }
+}
+static void _og_record_item_stat(level_id &lev, og_item &item, string field,
+ double value)
+{
+ int class_sum = _og_get_max_subtype(item.base_type);
+ level_id br_lev(lev.branch, -1);
+
+ og_items[lev][item.base_type][item.sub_type][field] += value;
+ og_items[lev][item.base_type][class_sum][field] += value;
+ og_items[br_lev][item.base_type][item.sub_type][field] += value;
+ og_items[br_lev][item.base_type][class_sum][field] += value;
+ og_items[og_all_lev][item.base_type][item.sub_type][field] += value;
+ og_items[og_all_lev][item.base_type][class_sum][field] += value;
+}
+
+static void _og_record_brand(level_id &lev, og_item &item, int quantity,
+ bool is_arte, int brand)
+{
+ ASSERT(item.base_type == OG_WEAPONS || item.base_type == OG_ARMOUR
+ || item.base_type == OG_MISSILES);
+ int cst = _og_get_max_subtype(item.base_type);
+ int antiq = is_arte ? ANTIQ_ARTEFACT : ANTIQ_ORDINARY;
+ bool is_equip = item.base_type == OG_WEAPONS
+ || item.base_type == OG_ARMOUR;
+ int bt = item.base_type == OG_WEAPONS ? 0 : 1;
+ int st = item.sub_type;
+ level_id br_lev(lev.branch, -1);
+
+ if (is_equip)
+ {
+ og_equip_brands[lev][bt][st][antiq][brand] += quantity;
+ og_equip_brands[lev][bt][st][ANTIQ_ALL][brand] += quantity;
+ og_equip_brands[lev][bt][cst][antiq][brand] += quantity;
+ og_equip_brands[lev][bt][cst][ANTIQ_ALL][brand] += quantity;
+
+ og_equip_brands[br_lev][bt][st][antiq][brand] += quantity;
+ og_equip_brands[br_lev][bt][st][ANTIQ_ALL][brand] += quantity;
+ og_equip_brands[br_lev][bt][cst][antiq][brand] += quantity;
+ og_equip_brands[br_lev][bt][cst][ANTIQ_ALL][brand] += quantity;
+
+ og_equip_brands[og_all_lev][bt][st][antiq][brand] += quantity;
+ og_equip_brands[og_all_lev][bt][st][ANTIQ_ALL][brand] += quantity;
+ og_equip_brands[og_all_lev][bt][cst][antiq][brand] += quantity;
+ og_equip_brands[og_all_lev][bt][cst][ANTIQ_ALL][brand] += quantity;
+ }
+ else
+ {
+ og_missile_brands[lev][st][brand] += quantity;
+ og_missile_brands[lev][cst][brand] += quantity;
+ og_missile_brands[br_lev][st][brand] += quantity;
+ og_missile_brands[br_lev][cst][brand] += quantity;
+ og_missile_brands[og_all_lev][st][brand] += quantity;
+ og_missile_brands[og_all_lev][cst][brand] += quantity;
}
}
-void objgen_report_item(item_def &item)
+void objgen_record_item(item_def &item)
{
level_id cur_lev = level_id::current();
og_item ogi(item);
-
- if (ogi.base_type == OG_UNUSED)
- return;
-
bool is_arte = is_artefact(item);
- bool is_weapon = ogi.base_type == OG_WEAPONS;
- bool is_armour = ogi.base_type == OG_ARMOUR;
- bool is_missile = ogi.base_type == OG_MISSILES;
int brand = -1;
- int class_sum_ind = _og_get_max_subtype(ogi.base_type);
- og_summary_level sum_ind = is_arte ? SUMMARY_ARTE : SUMMARY_ORD;
string num_f = is_arte ? "ArteNum" : "OrdNum";
string cursed_f = is_arte ? "ArteNumCursed" : "OrdNumCursed";
string ench_f = is_arte ? "ArteEnch" : "OrdEnch";
- map<string, double> &item_stats =
- og_items[cur_lev][ogi.base_type][ogi.sub_type];
- map<string, double> &sum_stats =
- og_items[cur_lev][ogi.base_type][class_sum_ind];
-
- if (is_weapon)
- brand = get_weapon_brand(item);
- else if (is_armour)
- brand = get_armour_ego_type(item);
- else if (is_missile)
- brand = get_ammo_brand(item);
// The Some averages are calculated after all items are tallied.
switch (ogi.base_type)
{
case OG_MISSILES:
- og_missile_brands[cur_lev][ogi.sub_type][brand] += item.quantity;
- og_missile_brands[cur_lev][class_sum_ind][brand] += item.quantity;
- item_stats["NumBranded"] += brand > 0 ? item.quantity : 0;
- sum_stats["NumBranded"] += brand > 0 ? item.quantity : 0;
+ brand = get_ammo_brand(item);
+ _og_record_brand(cur_lev, ogi, item.quantity, is_arte, brand);
+ if (brand > 0)
+ _og_record_item_stat(cur_lev, ogi, "NumBranded", item.quantity);
//deliberate fallthrough
case OG_SCROLLS:
case OG_POTIONS:
case OG_GOLD:
- item_stats["Num"] += item.quantity;
- sum_stats["Num"] += item.quantity;
- item_stats["NumPiles"] += 1;
- sum_stats["NumPiles"] += 1;
+ _og_record_item_stat(cur_lev, ogi, "Num", item.quantity);
+ _og_record_item_stat(cur_lev, ogi, "NumPiles", 1);
break;
case OG_FOOD:
- item_stats["Num"] += item.quantity;
- sum_stats["Num"] += item.quantity;
- item_stats["NumPiles"] += 1;
- sum_stats["NumPiles"] += 1;
- item_stats["TotalNormNutr"] += food_value(item);
- sum_stats["TotalNormNutr"] += food_value(item);
+ _og_record_item_stat(cur_lev, ogi, "Num", item.quantity);
+ _og_record_item_stat(cur_lev, ogi, "NumPiles", 1);
+ _og_record_item_stat(cur_lev, ogi, "TotalNormNutr", food_value(item));
+ // Set these dietary mutations so we can get accurate nutrition.
you.mutation[MUT_CARNIVOROUS] = 3;
- item_stats["TotalCarnNutr"] += food_value(item)
- * food_is_meaty(item.sub_type);
- sum_stats["TotalCarnNutr"] += food_value(item)
- * food_is_meaty(item.sub_type);
+ _og_record_item_stat(cur_lev, ogi, "TotalCarnNutr",
+ food_value(item) * food_is_meaty(item.sub_type));
you.mutation[MUT_CARNIVOROUS] = 0;
you.mutation[MUT_HERBIVOROUS] = 3;
- item_stats["TotalHerbNutr"] += food_value(item)
- * food_is_veggie(item.sub_type);
- sum_stats["TotalHerbNutr"] += food_value(item)
- * food_is_veggie(item.sub_type);
+ _og_record_item_stat(cur_lev, ogi, "TotalHerbNutr",
+ food_value(item) * food_is_veggie(item.sub_type));
you.mutation[MUT_HERBIVOROUS] = 0;
break;
case OG_WANDS:
- item_stats["Num"] += 1;
- sum_stats["Num"] += 1;
- item_stats["WandCharges"] += item.plus;
- sum_stats["WandCharges"] += item.plus;
+ _og_record_item_stat(cur_lev, ogi, "Num", 1);
+ _og_record_item_stat(cur_lev, ogi, "WandCharges", item.plus);
break;
case OG_WEAPONS:
case OG_ARMOUR:
- item_stats[num_f] += 1;
- sum_stats[num_f] += 1;
- item_stats[cursed_f] += item.cursed();
- sum_stats[cursed_f] += item.cursed();
- item_stats[ench_f] += item.plus;
- sum_stats[ench_f] += item.plus;
- item_stats["OrdNumBranded"] += !is_arte && brand > 0;
- sum_stats["OrdNumBranded"] += !is_arte && brand > 0;
- item_stats["AllNum"] += 1;
- sum_stats["AllNum"] += 1;
- item_stats["AllNumCursed"] += item.cursed();
- sum_stats["AllNumCursed"] += item.cursed();
- item_stats["AllEnch"] += item.plus;
- sum_stats["AllEnch"] += item.plus;
- if (is_weapon)
- {
- og_weapon_brands[cur_lev][ogi.sub_type][sum_ind][brand] += 1;
- og_weapon_brands[cur_lev][class_sum_ind][sum_ind][brand] += 1;
- og_weapon_brands[cur_lev][ogi.sub_type][SUMMARY_ALL][brand] += 1;
- og_weapon_brands[cur_lev][class_sum_ind][SUMMARY_ALL][brand] += 1;
- }
+ if (ogi.base_type == OG_WEAPONS)
+ brand = get_weapon_brand(item);
else
+ brand = get_armour_ego_type(item);
+ _og_record_item_stat(cur_lev, ogi, num_f, 1);
+ _og_record_item_stat(cur_lev, ogi, "AllNum", 1);
+
+ if (item.cursed())
{
- og_armour_brands[cur_lev][ogi.sub_type][sum_ind][brand] += 1;
- og_armour_brands[cur_lev][class_sum_ind][sum_ind][brand] += 1;
- og_armour_brands[cur_lev][ogi.sub_type][SUMMARY_ALL][brand] += 1;
- og_armour_brands[cur_lev][class_sum_ind][SUMMARY_ALL][brand] += 1;
+ _og_record_item_stat(cur_lev, ogi, cursed_f, item.cursed());
+ _og_record_item_stat(cur_lev, ogi, "AllNumCursed", item.cursed());
}
+ _og_record_item_stat(cur_lev, ogi, ench_f, item.plus);
+ _og_record_item_stat(cur_lev, ogi, "AllEnch", item.plus);
+ if (!is_arte && brand > 0)
+ _og_record_item_stat(cur_lev, ogi, "OrdNumBranded", 1);
+ _og_record_brand(cur_lev, ogi, 1, is_arte, brand);
break;
case OG_STAVES:
- item_stats["Num"] += 1;
- sum_stats["Num"] += 1;
- item_stats["NumCursed"] += item.cursed();
- sum_stats["NumCursed"] += item.cursed();
+ _og_record_item_stat(cur_lev, ogi, "Num", 1);
+ _og_record_item_stat(cur_lev, ogi, "NumCursed", item.cursed());
break;
case OG_JEWELLERY:
- item_stats[num_f] += 1;
- sum_stats[num_f] += 1;
- item_stats[cursed_f] += item.cursed();
- sum_stats[cursed_f] += item.cursed();
- item_stats[ench_f] += item.plus;
- sum_stats[ench_f] += item.plus;
- item_stats["AllNum"] += 1;
- sum_stats["AllNum"] += 1;
- item_stats["AllNumCursed"] += item.cursed();
- sum_stats["AllNumCursed"] += item.cursed();
- item_stats["AllEnch"] += item.plus;
- sum_stats["AllEnch"] += item.plus;
+ _og_record_item_stat(cur_lev, ogi, num_f, 1);
+ _og_record_item_stat(cur_lev, ogi, "AllNum", 1);
+ if (item.cursed())
+ {
+ _og_record_item_stat(cur_lev, ogi, cursed_f, 1);
+ _og_record_item_stat(cur_lev, ogi, "AllNumCursed", 1);
+ }
+ _og_record_item_stat(cur_lev, ogi, ench_f, item.plus);
+ _og_record_item_stat(cur_lev, ogi, "AllEnch", item.plus);
break;
case OG_RODS:
- item_stats["Num"] += 1;
- sum_stats["Num"] += 1;
- item_stats["RodRecharge"] += item.plus2 / ROD_CHARGE_MULT;
- sum_stats["RodRecharge"] += item.plus2 / ROD_CHARGE_MULT;
- item_stats["RodMana"] += item.special;
- sum_stats["RodMana"] += item.special;
- item_stats["NumCursed"] += item.cursed();
- sum_stats["NumCursed"] += item.cursed();
+ _og_record_item_stat(cur_lev, ogi, "Num", 1);
+ _og_record_item_stat(cur_lev, ogi, "RodRecharge",
+ item.plus2 / ROD_CHARGE_MULT);
+ _og_record_item_stat(cur_lev, ogi, "RodMana", item.special);
+ _og_record_item_stat(cur_lev, ogi, "NumCursed", item.cursed());
break;
case OG_MISCELLANY:
- item_stats["Num"] += 1;
- sum_stats["Num"] += 1;
- item_stats["MiscPlus1"] += item.plus;
- sum_stats["MiscPlus1"] += item.plus;
- item_stats["MiscPlus2"] += item.plus2;
- sum_stats["MiscPlus2"] += item.plus2;
+ _og_record_item_stat(cur_lev, ogi, "Num", 1);
+ _og_record_item_stat(cur_lev, ogi, "MiscPlus1", item.plus);
+ _og_record_item_stat(cur_lev, ogi, "MiscPlus2", item.plus2);
break;
case OG_DECKS:
switch (deck_rarity(item))
{
case DECK_RARITY_COMMON:
- item_stats["PlainNum"] += 1;
- sum_stats["PlainNum"] += 1;
+ _og_record_item_stat(cur_lev, ogi, "PlainNum", 1);
break;
case DECK_RARITY_RARE:
- item_stats["OrnateNum"] += 1;
- sum_stats["OrnateNum"] += 1;
+ _og_record_item_stat(cur_lev, ogi, "OrnateNum", 1);
break;
case DECK_RARITY_LEGENDARY:
- item_stats["LegendaryNum"] += 1;
- sum_stats["LegendaryNum"] += 1;
+ _og_record_item_stat(cur_lev, ogi, "LegendaryNum", 1);
break;
default:
break;
}
- item_stats["AllNum"] += 1;
- sum_stats["AllNum"] += 1;
- item_stats["AllDeckCards"] += item.plus;
- sum_stats["AllDeckCards"] += item.plus;
+ _og_record_item_stat(cur_lev, ogi, "AllNum", 1);
+ _og_record_item_stat(cur_lev, ogi, "AllDeckCards", item.plus);
break;
case OG_BOOKS:
case OG_MANUALS:
case OG_ARTEBOOKS:
- item_stats["Num"] += 1;
- sum_stats["Num"] += 1;
+ _og_record_item_stat(cur_lev, ogi, "Num", 1);
break;
default:
- die("Buggy og_class_type");
break;
}
}
-void objgen_report_monster(monster *mons)
+static void _og_record_monster_stat(level_id &lev, int mons_ind, string field,
+ double value)
+{
+ level_id br_lev(lev.branch, -1);
+ int sum_ind = og_valid_monsters[NUM_MONSTERS];
+
+ og_monsters[lev][mons_ind][field] += value;
+ og_monsters[lev][sum_ind][field] += value;
+ og_monsters[br_lev][mons_ind][field] += value;
+ og_monsters[br_lev][sum_ind][field] += value;
+ og_monsters[og_all_lev][mons_ind][field] += value;
+ og_monsters[og_all_lev][sum_ind][field] += value;
+}
+
+void objgen_record_monster(monster *mons)
{
- level_id cur_lev = level_id::current();
if (!og_valid_monsters.count(mons->type))
return;
- int mons_id = og_valid_monsters[mons->type];
- int sum_ind = og_valid_monsters[NUM_MONSTERS];
- map<string, double> &mons_stats = og_monsters[cur_lev][mons_id];
- map<string, double> &sum_stats = og_monsters[cur_lev][sum_ind];
+ int mons_ind = og_valid_monsters[mons->type];
corpse_effect_type chunk_effect = mons_corpse_effect(mons->type);
-
- mons_stats["Num"] += 1;
- sum_stats["Num"] += 1;
- mons_stats["MonsXP"] += exper_value(mons);
- sum_stats["MonsXP"] += exper_value(mons);
- mons_stats["TotalXP"] += exper_value(mons);
- sum_stats["TotalXP"] += exper_value(mons);
- mons_stats["MonsHP"] += mons->max_hit_points;
- sum_stats["MonsHP"] += mons->max_hit_points;
- mons_stats["MonsHD"] += mons->hit_dice;
- sum_stats["MonsHD"] += mons->hit_dice;
- // copied from turn_corpse_into_chunks()
- double avg_chunks = (1 + stepdown_value(get_max_corpse_chunks(mons->type),
- 4, 4, 12, 12)) / 2.0;
- mons_stats["MonsNumChunks"] += avg_chunks;
- sum_stats["MonsNumChunks"] += avg_chunks;
bool is_contam = chunk_effect == CE_POISON_CONTAM
|| chunk_effect == CE_CONTAMINATED;
bool is_clean = chunk_effect == CE_CLEAN || chunk_effect == CE_POISONOUS;
+ // copied from turn_corpse_into_chunks()
+ double avg_chunks = (1 + stepdown_value(get_max_corpse_chunks(mons->type),
+ 4, 4, 12, 12)) / 2.0;
+ level_id lev = level_id::current();
+
+ _og_record_monster_stat(lev, mons_ind, "Num", 1);
+ _og_record_monster_stat(lev, mons_ind, "MonsXP", exper_value(mons));
+ _og_record_monster_stat(lev, mons_ind, "TotalXP", exper_value(mons));
+ _og_record_monster_stat(lev, mons_ind, "MonsHP", mons->max_hit_points);
+ _og_record_monster_stat(lev, mons_ind, "MonsHD", mons->hit_dice);
+ _og_record_monster_stat(lev, mons_ind, "MonsNumChunks", avg_chunks);
if (is_clean)
{
- mons_stats["TotalNormNutr"] += avg_chunks * CHUNK_BASE_NUTRITION;
- sum_stats["TotalNormNutr"] += avg_chunks * CHUNK_BASE_NUTRITION;
- }
- if (is_contam)
- {
- mons_stats["TotalNormNutr"] += avg_chunks * CHUNK_BASE_NUTRITION / 2.0;
- sum_stats["TotalNormNutr"] += avg_chunks * CHUNK_BASE_NUTRITION / 2.0;
+ _og_record_monster_stat(lev, mons_ind, "TotalNormNutr",
+ avg_chunks * CHUNK_BASE_NUTRITION);
}
+ else if (is_contam)
+ _og_record_monster_stat(lev, mons_ind, "TotalNormNutr",
+ avg_chunks * CHUNK_BASE_NUTRITION / 2.0);
if (is_clean || is_contam)
{
- mons_stats["TotalGourmNutr"] += avg_chunks * CHUNK_BASE_NUTRITION;
- sum_stats["TotalGourmNutr"] += avg_chunks * CHUNK_BASE_NUTRITION;
+ _og_record_monster_stat(lev, mons_ind, "TotalGourmNutr",
+ avg_chunks * CHUNK_BASE_NUTRITION);
}
}
-static void _og_write_level_headers(int num_fields)
+static void _og_write_level_headers(branch_type br, int num_fields)
{
- int level_count = 0;
- fprintf(og_outf, "Place");
+ unsigned int level_count = 0;
+ vector<level_id> &levels = og_branches[br];
vector<level_id>::const_iterator li;
- for (li = og_levels.begin(); li != og_levels.end(); li++)
+
+ fprintf(og_outf, "Place");
+ for (li = levels.begin(); li != levels.end(); li++)
{
- fprintf(og_outf, "\t%s", li->describe().c_str());
+ if (br == NUM_BRANCHES)
+ fprintf(og_outf, "\tAllLevels");
+ else
+ fprintf(og_outf, "\t%s", li->describe().c_str());
+
for (int i = 0; i < num_fields - 1; i++)
fprintf(og_outf, "\t");
- if (++level_count == og_branches[li->branch])
+ if (++level_count == levels.size() && level_count > 1)
{
- if (level_count == 1)
- {
- level_count = 0;
- continue;
- }
-
fprintf(og_outf, "\t%s", branches[li->branch].abbrevname);
for (int i = 0; i < num_fields - 1; i++)
fprintf(og_outf, "\t");
- level_count = 0;
}
}
- if (og_branches.size() > 1)
- {
- fprintf(og_outf, "\tAllLevels");
- for (int i = 0; i < num_fields - 1; i++)
- fprintf(og_outf, "\t");
- }
fprintf(og_outf, "\n");
}
-static void _og_write_stat_headers(vector<string> fields)
+static void _og_write_stat_headers(branch_type br, vector<string> fields)
{
- int level_count = 0;
- fprintf(og_outf, "Property");
+ unsigned int level_count = 0;
+ vector<level_id> &levels = og_branches[br];
vector<level_id>::const_iterator li;
- for (li = og_levels.begin(); li != og_levels.end(); li++)
+
+ fprintf(og_outf, "Property");
+ for (li = levels.begin(); li != levels.end(); li++)
{
for (unsigned int i = 0; i < fields.size(); i++)
fprintf(og_outf, "\t%s", fields[i].c_str());
- // Branch-level headers
- if (++level_count == og_branches[li->branch])
+ if (++level_count == levels.size() && level_count > 1)
{
- if (level_count == 1)
- {
- level_count = 0;
- continue;
- }
-
for (unsigned int i = 0; i < fields.size(); i++)
fprintf(og_outf, "\t%s", fields[i].c_str());
- level_count = 0;
}
}
- if (og_branches.size() > 1)
- {
- for (unsigned int i = 0; i < fields.size(); i++)
- fprintf(og_outf, "\t%s", fields[i].c_str());
- }
fprintf(og_outf, "\n");
}
-static void _og_write_stat(map<string, double> &item_stats, string field)
+static void _og_write_stat(map<string, double> &stats, string field)
{
ostringstream output;
double value = 0;
output.precision(OG_STAT_PRECISION);
if (field == "PileQuant")
- value = item_stats["Num"] / item_stats["NumPiles"];
+ value = stats["Num"] / stats["NumPiles"];
else if (field == "WandCharges"
|| field == "RodMana"
|| field == "RodRecharge"
@@ -1476,40 +1488,40 @@ static void _og_write_stat(map<string, double> &item_stats, string field)
|| field == "MonsXP"
|| field == "MonsNumChunks")
{
- value = item_stats[field] / item_stats["Num"];
+ value = stats[field] / stats["Num"];
}
else if (field == "AllEnch" || field == "AllDeckCards")
- value = item_stats[field] / item_stats["AllNum"];
+ value = stats[field] / stats["AllNum"];
else if (field == "ArteEnch")
- value = item_stats[field] / item_stats["ArteNum"];
+ value = stats[field] / stats["ArteNum"];
else if (field == "OrdEnch")
- value = item_stats[field] / item_stats["OrdNum"];
+ value = stats[field] / stats["OrdNum"];
else
- value = item_stats[field] / SysEnv.map_gen_iters;
+ value = stats[field] / SysEnv.map_gen_iters;
output << "\t" << value;
fprintf(og_outf, "%s", output.str().c_str());
}
-static string _og_brand_name(og_class_type base_type, int sub_type, int brand)
+static string _og_brand_name(og_item &item, int brand)
{
string brand_name = "";
- item_def item = _og_dummy_item(base_type, sub_type);
+ item_def dummy_item = _og_dummy_item(item);
if (!brand)
brand_name = "none";
else
{
- item.special = brand;
- switch (base_type)
+ dummy_item.special = brand;
+ switch (item.base_type)
{
case OG_WEAPONS:
- brand_name = weapon_brand_name(item, true);
+ brand_name = weapon_brand_name(dummy_item, true);
break;
case OG_ARMOUR:
- brand_name = armour_ego_name(item, true);
+ brand_name = armour_ego_name(dummy_item, true);
break;
case OG_MISSILES:
- brand_name = missile_brand_name(item, MBN_TERSE);
+ brand_name = missile_brand_name(dummy_item, MBN_TERSE);
break;
default:
break;
@@ -1518,14 +1530,11 @@ static string _og_brand_name(og_class_type base_type, int sub_type, int brand)
return brand_name;
}
-static void _og_write_brand_stats(vector<int> &brand_stats,
- og_class_type item_type, int sub_type,
- vector<int> *branch_stats = NULL,
- vector<int> *total_stats = NULL)
+static void _og_write_brand_stats(vector<int> &brand_stats, og_item &item)
{
- ASSERT(item_type == OG_WEAPONS || item_type == OG_ARMOUR
- || item_type == OG_MISSILES);
- item_def dummy_item = _og_dummy_item(item_type, sub_type);
+ ASSERT(item.base_type == OG_WEAPONS || item.base_type == OG_ARMOUR
+ || item.base_type == OG_MISSILES);
+ item_def dummy_item = _og_dummy_item(item);
unsigned int num_brands = brand_stats.size();
bool first_brand = true;
ostringstream brand_summary;
@@ -1543,219 +1552,127 @@ static void _og_write_brand_stats(vector<int> &brand_stats,
else
brand_summary << ",";
- brand_name = _og_brand_name(item_type, sub_type, i);
+ brand_name = _og_brand_name(item, i);
brand_summary << brand_name.c_str() << "(" << value << ")";
- if (branch_stats)
- (*branch_stats)[i] += brand_stats[i];
- if (total_stats)
- (*total_stats)[i] += brand_stats[i];
}
fprintf(og_outf, "\t%s", brand_summary.str().c_str());
}
-static string _og_item_name(og_class_type item_type, int sub_type)
+static string _og_item_name(og_item &item)
{
string name = "";
- if (item_type == OG_MANUALS)
+
+ if (item.sub_type == _og_get_max_subtype(item.base_type))
+ name = "All " + _og_class_name(item.base_type);
+ else if (item.base_type == OG_MANUALS)
name = "Manual";
- else if (item_type == OG_ARTEBOOKS)
+ else if (item.base_type == OG_ARTEBOOKS)
{
- name = _og_orig_sub_type(item_type, sub_type) == BOOK_RANDART_LEVEL
- ? "Level Artefact Book" : "Theme Artefact Book";
+ int orig_type = _og_orig_sub_type(item);
+ if (orig_type == BOOK_RANDART_LEVEL)
+ name = "Level Artefact Book";
+ else
+ name = "Theme Artefact Book";
}
- else if (sub_type == _og_get_max_subtype(item_type))
- name = "All " + item_class_name(_og_orig_base_type(item_type));
else
{
- item_def dummy_item = _og_dummy_item(item_type, sub_type);
+ item_def dummy_item = _og_dummy_item(item);
name = dummy_item.name(DESC_DBNAME, true, true);
}
return name;
}
-static void _og_write_item_stats(og_class_type item_type, int sub_type)
+static void _og_write_item_stats(branch_type br, og_item &item)
{
- map <string, double> branch_stats, total_stats;
- bool is_brand_equip = item_type == OG_WEAPONS || item_type == OG_ARMOUR;
- int num_brands = item_type == OG_WEAPONS ? NUM_SPECIAL_WEAPONS
- : item_type == OG_ARMOUR ? NUM_SPECIAL_ARMOURS
- : item_type == OG_MISSILES ? NUM_SPECIAL_MISSILES : 1;
- vector < vector<int> > branch_brand_stats(3, vector<int>(num_brands));
- vector < vector<int> > total_brand_stats(3, vector<int>(num_brands));
- int level_count = 0;
- vector <string> fields = og_item_fields[item_type];
-
- fprintf(og_outf, "%s", _og_item_name(item_type, sub_type).c_str());
+ bool is_brand_equip = item.base_type == OG_WEAPONS
+ || item.base_type == OG_ARMOUR;
+ int equip_ind = is_brand_equip
+ ? (item.base_type == OG_WEAPONS ? 0 : 1) : -1;
+ unsigned int level_count = 0;
+ vector <string> fields = og_item_fields[item.base_type];
vector<level_id>::const_iterator li;
- for (unsigned int i = 0; i < fields.size(); i++)
- total_stats[fields[i]] = 0;
- for (int i = 0; i < 3; i++)
- {
- for (int j = 0; j < num_brands; j++)
- total_brand_stats[i][j] = 0;
- }
- for (li = og_levels.begin(); li != og_levels.end(); li++)
+ fprintf(og_outf, "%s", _og_item_name(item).c_str());
+ for (li = og_branches[br].begin(); li != og_branches[br].end(); li++)
{
- if (!level_count)
- {
- for (unsigned int i = 0; i < fields.size(); i++)
- branch_stats[fields[i]] = 0;
- for (int i = 0; i < 3; i++)
- {
- for (int j = 0; j < num_brands; j++)
- branch_brand_stats[i][j] = 0;
- }
- }
-
- map <string, double> &item_stats = og_items[*li][item_type][sub_type];
+ map <string, double> &item_stats =
+ og_items[*li][item.base_type][item.sub_type];
for (unsigned int i = 0; i < fields.size(); i++)
- {
- branch_stats[fields[i]] += item_stats[fields[i]];
- total_stats[fields[i]] += item_stats[fields[i]];
_og_write_stat(item_stats, fields[i]);
- }
- vector<int> brand_stats;
+
if (is_brand_equip)
{
+ vector< vector<int> > &brand_stats =
+ og_equip_brands[*li][equip_ind][item.sub_type];
for (int j = 0; j < 3; j++)
- {
- if (item_type == OG_WEAPONS)
- brand_stats = og_weapon_brands[*li][sub_type][j];
- else
- brand_stats = og_armour_brands[*li][sub_type][j];
- _og_write_brand_stats(brand_stats, item_type, sub_type,
- &branch_brand_stats[j],
- &total_brand_stats[j]);
- }
- }
- else if (item_type == OG_MISSILES)
- {
- brand_stats = og_missile_brands[*li][sub_type];
- _og_write_brand_stats(brand_stats, item_type, sub_type,
- &branch_brand_stats[0],
- &total_brand_stats[0]);
+ _og_write_brand_stats(brand_stats[j], item);
}
+ else if (item.base_type == OG_MISSILES)
+ _og_write_brand_stats(og_missile_brands[*li][item.sub_type], item);
- if (++level_count == og_branches[li->branch])
+ if (++level_count == og_branches[li->branch].size() && level_count > 1)
{
- if (level_count == 1)
- {
- level_count = 0;
- continue;
- }
+ level_id br_lev(li->branch, -1);
+ map <string, double> &branch_stats =
+ og_items[br_lev][item.base_type][item.sub_type];
for (unsigned int i = 0; i < fields.size(); i++)
_og_write_stat(branch_stats, fields[i]);
if (is_brand_equip)
{
+ vector< vector<int> > &branch_brand_stats =
+ og_equip_brands[br_lev][equip_ind][item.sub_type];
for (int j = 0; j < 3; j++)
- {
- _og_write_brand_stats(branch_brand_stats[j], item_type,
- sub_type);
- }
+ _og_write_brand_stats(branch_brand_stats[j], item);
}
- else if (item_type == OG_MISSILES)
+ else if (item.base_type == OG_MISSILES)
{
- _og_write_brand_stats(branch_brand_stats[0], item_type,
- sub_type);
+ _og_write_brand_stats(og_missile_brands[br_lev][item.sub_type],
+ item);
}
- level_count = 0;
- }
- }
- // Only do grand summary if there are multiple branches.
- if (og_branches.size() > 1)
- {
- for (unsigned int i = 0; i < fields.size(); i++)
- _og_write_stat(total_stats, fields[i]);
-
- if (is_brand_equip)
- {
- for (int j = 0; j < 3; j++)
- _og_write_brand_stats(total_brand_stats[j], item_type, sub_type);
}
- else if (item_type == OG_MISSILES)
- _og_write_brand_stats(total_brand_stats[0], item_type, sub_type);
}
fprintf(og_outf, "\n");
}
-static void _og_write_monster_stats(int mons_id, monster_type mons_type)
+static void _og_write_monster_stats(branch_type br, monster_type mons_type,
+ int mons_ind)
{
- map <string, double> branch_stats, total_stats;
- int level_count = 0;
+ unsigned int level_count = 0;
vector <string> fields = og_monster_fields;
+ vector<level_id>::const_iterator li;
- if (mons_id == og_valid_monsters[NUM_MONSTERS])
+ if (mons_ind == og_valid_monsters[NUM_MONSTERS])
fprintf(og_outf, "All Monsters");
else
fprintf(og_outf, "%s", mons_type_name(mons_type, DESC_PLAIN).c_str());
- vector<level_id>::const_iterator li;
-
- for (unsigned int i = 0; i < fields.size(); i++)
- total_stats[fields[i]] = 0;
- for (li = og_levels.begin(); li != og_levels.end(); li++)
+ for (li = og_branches[br].begin(); li != og_branches[br].end(); li++)
{
- if (!level_count)
- {
- for (unsigned int i = 0; i < fields.size(); i++)
- branch_stats[fields[i]] = 0;
- }
-
- map <string, double> &mons_stats = og_monsters[*li][mons_id];
for (unsigned int i = 0; i < fields.size(); i++)
- {
- branch_stats[fields[i]] += mons_stats[fields[i]];
- total_stats[fields[i]] += mons_stats[fields[i]];
- _og_write_stat(mons_stats, fields[i]);
- }
+ _og_write_stat(og_monsters[*li][mons_ind], fields[i]);
- if (++level_count == og_branches[li->branch])
+ if (++level_count == og_branches[li->branch].size() && level_count > 1)
{
- if (level_count == 1)
- {
- level_count = 0;
- continue;
- }
-
+ level_id br_lev(li->branch, -1);
for (unsigned int i = 0; i < fields.size(); i++)
- _og_write_stat(branch_stats, fields[i]);
-
- level_count = 0;
+ _og_write_stat(og_monsters[br_lev][mons_ind], fields[i]);
}
}
- // Only do grand summary if there are multiple branches.
- if (og_branches.size() > 1)
- {
- for (unsigned int i = 0; i < fields.size(); i++)
- _og_write_stat(total_stats, fields[i]);
- }
fprintf(og_outf, "\n");
}
-static void _og_write_object_stats()
+static void _og_write_branch_stats(branch_type br)
{
- string range_desc = "";
- if (SysEnv.map_gen_range.get())
- range_desc = SysEnv.map_gen_range->describe();
- else
- range_desc = "Entire Dungeon";
- og_outf = fopen(og_out_file, "w");
- fprintf(og_outf, "Object Generation Stats\n"
- "Number of iterations: %d\n"
- "Levels generated: %s\n"
- "Version: %s\n", SysEnv.map_gen_iters, range_desc.c_str(),
- Version::Long);
fprintf(og_outf, "Item Generation Stats\n");
for (int i = 0; i < NUM_OG_CLASSES; i++)
{
og_class_type item_type = static_cast<og_class_type>(i);
int num_types = _og_get_max_subtype(item_type);
- fprintf(og_outf, "\n%s\n",
- _og_class_name(item_type).c_str());
vector<string> fields = og_item_fields[item_type];
+
+ fprintf(og_outf, "\n%s\n", _og_class_name(item_type).c_str());
if (item_type == OG_WEAPONS || item_type == OG_ARMOUR)
{
for (int j = 0; j < 3; j++)
@@ -1764,18 +1681,53 @@ static void _og_write_object_stats()
else if (item_type == OG_MISSILES)
fields.push_back(og_missile_brand_field);
- _og_write_level_headers(fields.size());
- _og_write_stat_headers(fields);
+ _og_write_level_headers(br, fields.size());
+ _og_write_stat_headers(br, fields);
for (int j = 0; j <= num_types; j++)
- _og_write_item_stats(item_type, j);
+ {
+ og_item item(item_type, j);
+ _og_write_item_stats(br, item);
+ }
}
- fprintf(og_outf, "Monster Generation Stats\n");
- _og_write_level_headers(og_monster_fields.size());
- _og_write_stat_headers(og_monster_fields);
+ fprintf(og_outf, "\n\nMonster Generation Stats\n");
+ _og_write_level_headers(br, og_monster_fields.size());
+ _og_write_stat_headers(br, og_monster_fields);
map<monster_type, int>::const_iterator mi;
for (mi = og_valid_monsters.begin(); mi != og_valid_monsters.end(); mi++)
- _og_write_monster_stats(mi->second, mi->first);
- fclose(og_outf);
+ _og_write_monster_stats(br, mi->first, mi->second);
+}
+
+static void _og_write_object_stats()
+{
+ map<branch_type, vector<level_id> >::const_iterator bi;
+
+ for (bi = og_branches.begin(); bi != og_branches.end(); bi++)
+ {
+ string branch_name;
+ if (bi->first == NUM_BRANCHES)
+ branch_name = "AllLevels";
+ else
+ branch_name = branches[bi->first].abbrevname;
+ ostringstream out_file;
+ out_file << og_out_prefix << branch_name << og_out_ext;
+ og_outf = fopen(out_file.str().c_str(), "w");
+ if (!og_outf)
+ {
+ fprintf(stderr, "Unable to open objgen output file: %s\n"
+ "Error: %s", out_file.str().c_str(), strerror(errno));
+ end(1);
+ }
+ fprintf(og_outf, "Object Generation Stats\n"
+ "Number of iterations: %d\n"
+ "Number of branches: %d\n"
+ "Number of levels: %d\n"
+ "Version: %s\n", SysEnv.map_gen_iters, og_num_branches,
+ og_num_levels, Version::Long);
+ _og_write_branch_stats(bi->first);
+ fclose(og_outf);
+ fprintf(stdout, "Wrote statistics for branch %s to %s.\n",
+ branch_name.c_str(), out_file.str().c_str());
+ }
}
void objgen_generate_stats()
@@ -1792,7 +1744,6 @@ void objgen_generate_stats()
run_map_global_preludes();
run_map_local_preludes();
- sprintf(og_stat_fmt, "%%1.%df", OG_STAT_PRECISION);
// Populate a vector of the levels ids we've made
for (int i = 0; i < NUM_BRANCHES; ++i)
{
@@ -1805,6 +1756,7 @@ void objgen_generate_stats()
if (br == BRANCH_FOREST)
continue;
#endif
+ vector<level_id> levels;
for (int dep = 1; dep <= brdepth[i]; ++dep)
{
const level_id lid(br, dep);
@@ -1813,13 +1765,24 @@ void objgen_generate_stats()
{
continue;
}
- if (!og_branches.count(br))
- og_branches[br] = 1;
- else
- og_branches[br] += 1;
- og_levels.push_back(lid);
+ levels.push_back(lid);
+ ++og_num_levels;
}
+ if (levels.size())
+ {
+ og_branches[br] = levels;
+ ++og_num_branches;
+ }
+ }
+ // For the all-level summary
+ if (og_num_branches > 1)
+ {
+ og_branches[NUM_BRANCHES] = vector<level_id>();
+ og_branches[NUM_BRANCHES].push_back(level_id(NUM_BRANCHES, -1));
}
+ fprintf(stdout, "Generating object statistics for %d iterations of %d "
+ "levels over %d branches.\n", SysEnv.map_gen_iters, og_num_levels,
+ og_num_branches);
_og_init_fields();
_og_init_foods();
_og_init_monsters();