experience/kills, with the section names being turns_by_place and kills_by_place. Also includes a "visits" dump section (included in the "misc" section") a brief description of the number of branches/levels/areas/etc you visited.
Breaks savefile compatibility.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2102 c06c8d41-db1a-0410-9941-cceddc491573
DOZORMA366M4HB5JKSS27BMCR6ET7QNZNND2B7KV3NVEEPR5H7EAC
IUZMNOXWL4ZUYPZIUV7ODZKBXOIECG5TDOKU4OIN6ZJEDCB72QQAC
6JG5G2K7WW4OTAD2NM2QUQZ3R4RDOC2VZIP4CIJF5EE3SLE7DCYAC
SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
5ASC3STDYCNLZFEBN6UTMUCGDETHBR2OCBZCF5VIAZ5RRWLOTDYQC
3PY3L3A4QRW3Z5Y7SHO4TMVOOP2VNCO27X2MX4DTOP2SADLBQUOAC
6L4EP4ZRWWYLT55PD5KTTJON5J2JB5VV5MWNHF5VPZQZ5BKEYZ4QC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
7NDXS36TE7QVXTXJWMYSVG5UHCCLPIO4VL6NXFGTDK3ZNKE3A2IAC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
7Y5HSDFKA5TPLS2TWTRFMQVX6UXUDHXU5MUMXQSDFAIY4THQ3BIQC
EOMCPVNQLX3IMLC46EAO67DPBH5KEG2FQTPBLGU62HIRWA3UQ7XQC
C5VA63WAQRWPENIMXRPUPZLZJMC77PL2B3A77HYFWDCZU5QDG7VQC
NNG27Y5ZQAZX6UD7F7M4F6KEZBEDFXPEEC3LFUSX4ESKT7K6UJQAC
B62ICMDTN5V7R7RBL4JALFVKEMVOOVLRSJASRNYS6CGFWBEEF5JQC
DODCHP2S4I6VZKQAVXX6D76OPNFI2YWZ4XH3HZTMAJZXA2RJ3XRQC
77H4BWWPPGLM3PLZH4QTAJRXIZTSDVNCOKZE223I437FN2UJ34RQC
X5WLJCJVW55SXZVP7IKP7ADCJIGNKN4PKAXFECVR6TNK7XSMZR7QC
BW3XFNOS6LDAQLHOZ6RXARCMKCY5JVLVDSXDSSAX4DSYM3FANQBAC
W5VEC2PBIM5DMU5233HOWAZUEPTGWJRZZIA3H35YYQQW6BTP6XUAC
ZJLJGSB2XSBQU42OFQMXL3EG4CXAQGOYAU6YTV2SAWZEJIPFH2CAC
GQL5SIGBHLU3FMCE54XVGLRY5AZHRM6DUEB722REA2DPLGJSN6EQC
KFULGQQOHWUTXOM3BXCCYPGGVGGY4Z6265XUFRCBPNLTZAEHJZSQC
RC6L3CIBLJEH4GWRFD7UQNGI6PZT74FRUVOYHSAN2XCC74NZUASQC
HNXKX6ZDQJV33E7UKZOLBYWJMRZ4QLEMXVXJZNRCTOIG2KVRTIEAC
4EWXDZSMYTEINQRUL4OHRUZVWMKCWEPYVJVGENQPBWUYU37SP63QC
3A537UMVZSYIFVKVO3SVK5JRSRLDN3YJKK3RKELHR2D4U6CMKM4QC
FLKXPXQ7SRFZPJPDM35D5CG6M52WP4SL32QNEZNSHGBNZYTKYGYAC
PTB7I4WQ3NTF7BE3O6WKXDSJD6QRWSZIEWPBSZGCJJZVNKT4OL5AC
SW3RLYFNRT3IJBK6LYKHKP2J2YDU7SXQWAJZX7U6S7ICYW43OMNQC
QDTVLBRGHDTRUVT7I3O72K6TMOYAUSAJBZUHGOEFU2RKJNUPWZSQC
ZHFUXYUHS6V47WK2NRH7OU6RX77NRKTXOZC3MND2GG7PEEWSGFTAC
7PRZJ6KZLG26YVTAMXT7YOTQLWZHGWGRTKXZZ52P4XYCQD4GT5WQC
EHSY6DVGUMI6C67WKET3GDJVLWJWGYBYQONNDK5JVT7BCTHBEZVAC
RVST2QHYJ757ZHK4AUJ5NGPDZ44AD6RVFVXYPKQIBJXZBDNUCHXQC
}
static void marshallPlaceInfo(struct tagHeader &th, PlaceInfo place_info)
{
marshallLong(th, place_info.level_type);
marshallLong(th, place_info.branch);
marshallLong(th, place_info.num_visits);
marshallLong(th, place_info.levels_seen);
marshallLong(th, place_info.mon_kill_exp);
marshallLong(th, place_info.mon_kill_exp_avail);
for (int i = 0; i < KC_NCATEGORIES; i++)
marshallLong(th, place_info.mon_kill_num[i]);
marshallLong(th, place_info.turns_total);
marshallLong(th, place_info.turns_explore);
marshallLong(th, place_info.turns_travel);
marshallLong(th, place_info.turns_interlevel);
marshallLong(th, place_info.turns_resting);
marshallLong(th, place_info.turns_other);
marshallFloat(th, place_info.elapsed_total);
marshallFloat(th, place_info.elapsed_explore);
marshallFloat(th, place_info.elapsed_travel);
marshallFloat(th, place_info.elapsed_interlevel);
marshallFloat(th, place_info.elapsed_resting);
marshallFloat(th, place_info.elapsed_other);
place_info.num_visits = (unsigned long) unmarshallLong(th);
place_info.levels_seen = (unsigned long) unmarshallLong(th);
place_info.mon_kill_exp = (unsigned long) unmarshallLong(th);
place_info.mon_kill_exp_avail = (unsigned long) unmarshallLong(th);
for (int i = 0; i < KC_NCATEGORIES; i++)
place_info.mon_kill_num[i] = (unsigned long) unmarshallLong(th);
place_info.turns_total = unmarshallLong(th);
place_info.turns_explore = unmarshallLong(th);
place_info.turns_travel = unmarshallLong(th);
place_info.turns_interlevel = unmarshallLong(th);
place_info.turns_resting = unmarshallLong(th);
place_info.turns_other = unmarshallLong(th);
place_info.elapsed_total = (double) unmarshallFloat(th);
place_info.elapsed_explore = (double) unmarshallFloat(th);
place_info.elapsed_travel = (double) unmarshallFloat(th);
place_info.elapsed_interlevel = (double) unmarshallFloat(th);
place_info.elapsed_resting = (double) unmarshallFloat(th);
place_info.elapsed_other = (double) unmarshallFloat(th);
return place_info;
}
std::vector<PlaceInfo> list = you.get_all_place_info();
count_p = (unsigned short) unmarshallShort(th);
// Use "<=" so that adding more branches or non-dungeon places
// won't break save-file compatibility.
ASSERT(count_p <= list.size());
for (i = 0; i < count_p; i++)
{
place_info = unmarshallPlaceInfo(th);
ASSERT(!place_info.is_global());
you.set_place_info(place_info);
}
global_info.make_global();
global_info.assert_validity();
for (int i = 0; i < NUM_BRANCHES; i++)
{
branch_info[i].level_type = LEVEL_DUNGEON;
branch_info[i].branch = i;
branch_info[i].assert_validity();
}
for (int i = 0; i < (NUM_LEVEL_AREA_TYPES - 1); i++)
{
non_branch_info[i].level_type = i + 1;
non_branch_info[i].branch = -1;
non_branch_info[i].assert_validity();
}
}
////////////////////////////////////////////////////////////////////////////
PlaceInfo::PlaceInfo()
: level_type(-2), branch(-2), num_visits(0),
levels_seen(0), mon_kill_exp(0), mon_kill_exp_avail(0),
turns_total(0), turns_explore(0), turns_travel(0), turns_interlevel(0),
turns_resting(0), turns_other(0), elapsed_total(0.0),
elapsed_explore(0.0), elapsed_travel(0.0), elapsed_interlevel(0.0),
elapsed_resting(0.0), elapsed_other(0.0)
{
for (int i = 0; i < KC_NCATEGORIES; i++)
mon_kill_num[i] = 0;
}
bool PlaceInfo::is_global() const
{
return (level_type == -1 && branch == -1);
}
void PlaceInfo::make_global()
{
level_type = -1;
branch = -1;
}
void PlaceInfo::assert_validity() const
{
// Check that level_type and branch match up
ASSERT(is_global() ||
(level_type == LEVEL_DUNGEON && branch >= BRANCH_MAIN_DUNGEON &&
branch < NUM_BRANCHES) ||
(level_type > LEVEL_DUNGEON && level_type < NUM_LEVEL_AREA_TYPES &&
branch == -1));
// Can't have visited a place without seeing any of its levels, and
// visa versa
ASSERT((num_visits == 0 && levels_seen == 0) ||
(num_visits > 0 && levels_seen > 0));
if (level_type == LEVEL_LABYRINTH || level_type == LEVEL_ABYSS)
ASSERT(num_visits == levels_seen);
else if (level_type == LEVEL_PANDEMONIUM)
ASSERT(num_visits <= levels_seen);
else if (level_type == LEVEL_DUNGEON && branches[branch].depth > 0)
ASSERT(levels_seen <= (unsigned long) branches[branch].depth);
ASSERT(turns_total == (turns_explore + turns_travel + turns_interlevel +
turns_resting + turns_other));
ASSERT(elapsed_total == (elapsed_explore + elapsed_travel +
elapsed_interlevel + elapsed_resting +
elapsed_other));
}
const std::string PlaceInfo::short_name() const
{
if (level_type == LEVEL_DUNGEON)
return branches[branch].shortname;
else
{
switch (level_type)
{
case LEVEL_ABYSS:
return "Abyss";
case LEVEL_PANDEMONIUM:
return "Pandemonium";
case LEVEL_LABYRINTH:
return "Labyrinth";
default:
return "Bug";
}
}
}
const PlaceInfo &PlaceInfo::operator += (const PlaceInfo &other)
{
num_visits += other.num_visits;
levels_seen += other.levels_seen;
mon_kill_exp += other.mon_kill_exp;
mon_kill_exp_avail += other.mon_kill_exp_avail;
for (int i = 0; i < KC_NCATEGORIES; i++)
mon_kill_num[i] += other.mon_kill_num[i];
turns_total += other.turns_total;
turns_explore += other.turns_explore;
turns_travel += other.turns_travel;
turns_interlevel += other.turns_interlevel;
turns_resting += other.turns_resting;
turns_other += other.turns_other;
elapsed_total += other.elapsed_total;
elapsed_explore += other.elapsed_explore;
elapsed_travel += other.elapsed_travel;
elapsed_interlevel += other.elapsed_interlevel;
elapsed_resting += other.elapsed_resting;
elapsed_other += other.elapsed_other;
return (*this);
const PlaceInfo &PlaceInfo::operator -= (const PlaceInfo &other)
{
num_visits -= other.num_visits;
levels_seen -= other.levels_seen;
mon_kill_exp -= other.mon_kill_exp;
mon_kill_exp_avail -= other.mon_kill_exp_avail;
for (int i = 0; i < KC_NCATEGORIES; i++)
mon_kill_num[i] -= other.mon_kill_num[i];
turns_total -= other.turns_total;
turns_explore -= other.turns_explore;
turns_travel -= other.turns_travel;
turns_interlevel -= other.turns_interlevel;
turns_resting -= other.turns_resting;
turns_other -= other.turns_other;
elapsed_total -= other.elapsed_total;
elapsed_explore -= other.elapsed_explore;
elapsed_travel -= other.elapsed_travel;
elapsed_interlevel -= other.elapsed_interlevel;
elapsed_resting -= other.elapsed_resting;
elapsed_other -= other.elapsed_other;
return (*this);
}
PlaceInfo PlaceInfo::operator + (const PlaceInfo &other) const
{
PlaceInfo copy = *this;
copy += other;
return copy;
}
PlaceInfo PlaceInfo::operator - (const PlaceInfo &other) const
{
PlaceInfo copy = *this;
copy -= other;
return copy;
}
PlaceInfo& player::get_place_info() const
{
return get_place_info(where_are_you, level_type);
}
PlaceInfo& player::get_place_info(branch_type branch) const
{
return get_place_info(branch, LEVEL_DUNGEON);
}
PlaceInfo& player::get_place_info(level_area_type level_type2) const
{
return get_place_info(NUM_BRANCHES, level_type2);
}
PlaceInfo& player::get_place_info(branch_type branch,
level_area_type level_type2) const
{
ASSERT((level_type2 == LEVEL_DUNGEON && branch >= BRANCH_MAIN_DUNGEON &&
branch < NUM_BRANCHES) ||
(level_type2 > LEVEL_DUNGEON && level_type < NUM_LEVEL_AREA_TYPES));
if (level_type2 == LEVEL_DUNGEON)
return (PlaceInfo&) branch_info[branch];
else
return (PlaceInfo&) non_branch_info[level_type2 - 1];
}
void player::set_place_info(PlaceInfo place_info)
{
place_info.assert_validity();
if (place_info.is_global())
global_info = place_info;
else if (place_info.level_type == LEVEL_DUNGEON)
branch_info[place_info.branch] = place_info;
else
non_branch_info[place_info.level_type - 1] = place_info;
}
std::vector<PlaceInfo> player::get_all_place_info(bool visited_only,
bool dungeon_only) const
{
std::vector<PlaceInfo> list;
for (int i = 0; i < NUM_BRANCHES; i++)
{
if ((visited_only && branch_info[i].num_visits == 0) ||
(dungeon_only && branch_info[i].level_type != LEVEL_DUNGEON))
continue;
list.push_back(branch_info[i]);
}
for (int i = 0; i < (NUM_LEVEL_AREA_TYPES - 1); i++)
{
if ((visited_only && non_branch_info[i].num_visits == 0) ||
(dungeon_only && non_branch_info[i].level_type != LEVEL_DUNGEON))
continue;
list.push_back(non_branch_info[i]);
}
return list;
}
if (!testbits(monster->flags, MF_CREATED_FRIENDLY))
give_adjusted_experience(monster, killer, pet_kill);
if (!created_friendly)
{
gain_exp(exper_value( monster ));
}
else
{
if (death_message)
mpr("That felt strangely unrewarding.");
}
if (created_friendly && death_message)
mpr("That felt strangely unrewarding.");
kill_category kc =
(killer == KILL_YOU || killer == KILL_YOU_MISSILE) ? KC_YOU :
(pet_kill)? KC_FRIENDLY :
KC_OTHER;
unsigned int exp_gain = 0, avail_gain = 0;
give_adjusted_experience(monster, killer, pet_kill,
&exp_gain, &avail_gain);
PlaceInfo& curr_PlaceInfo = you.get_place_info();
PlaceInfo delta;
delta.mon_kill_num[kc]++;
delta.mon_kill_exp += exp_gain;
delta.mon_kill_exp_avail += avail_gain;
you.global_info += delta;
you.global_info.assert_validity();
const branch_type old_where = you.where_are_you;
const bool was_a_labyrinth = you.level_type != LEVEL_DUNGEON;
const branch_type old_where = you.where_are_you;
const level_area_type old_level_type = you.level_type;
new_dump_fields("header,hiscore,stats,misc,inventory,skills,"
"spells,overview,mutations,messages,screenshot,"
"kills,notes");
new_dump_fields("header,hiscore,stats,misc,turns_by_place,inventory,"
"skills,spells,overview,mutations,messages,screenshot,"
"kills_by_place,kills,notes");
bool load( dungeon_feature_type stair_taken, load_mode_type load_mode,
bool was_a_labyrinth, int old_level, branch_type where_were_you2 );
bool load( dungeon_feature_type stair_taken, int load_mode,
level_area_type old_level_type, char old_level,
branch_type where_were_you2 );
bool load( dungeon_feature_type stair_taken, load_mode_type load_mode,
bool was_a_labyrinth, int old_level, branch_type old_branch )
bool load( dungeon_feature_type stair_taken, int load_mode,
level_area_type old_level_type, char old_level,
branch_type where_were_you2 )
if (load_mode != LOAD_RESTART_GAME)
{
// Update PlaceInfo entries
PlaceInfo& curr_PlaceInfo = you.get_place_info();
PlaceInfo delta;
if (load_mode == LOAD_START_GAME ||
(load_mode == LOAD_ENTER_LEVEL &&
(where_were_you2 != you.where_are_you ||
old_level_type != you.level_type)))
delta.num_visits++;
if (just_created_level)
delta.levels_seen++;
you.global_info += delta;
you.global_info.assert_validity();
curr_PlaceInfo += delta;
curr_PlaceInfo.assert_validity();
}
};
class PlaceInfo
{
public:
int level_type;
int branch;
unsigned long num_visits;
unsigned long levels_seen;
unsigned long mon_kill_exp;
unsigned long mon_kill_exp_avail;
unsigned long mon_kill_num[KC_NCATEGORIES];
long turns_total;
long turns_explore;
long turns_travel;
long turns_interlevel;
long turns_resting;
long turns_other;
double elapsed_total;
double elapsed_explore;
double elapsed_travel;
double elapsed_interlevel;
double elapsed_resting;
double elapsed_other;
public:
PlaceInfo();
bool is_global() const;
void make_global();
void assert_validity() const;
const std::string short_name() const;
const PlaceInfo &operator += (const PlaceInfo &other);
const PlaceInfo &operator -= (const PlaceInfo &other);
PlaceInfo operator + (const PlaceInfo &other) const;
PlaceInfo operator - (const PlaceInfo &other) const;
PlaceInfo& get_place_info() const ; // Current place info
PlaceInfo& get_place_info(branch_type branch,
level_area_type level_type2) const;
PlaceInfo& get_place_info(branch_type branch) const;
PlaceInfo& get_place_info(level_area_type level_type2) const;
void set_place_info(PlaceInfo info);
// Returns copies of the PlaceInfo; modifying the vector won't
// modify the player object.
std::vector<PlaceInfo> get_all_place_info(bool visited_only = false,
bool dungeon_only = false) const;
{ "header", sdump_header },
{ "stats", sdump_stats },
{ "location", sdump_location },
{ "religion", sdump_religion },
{ "burden", sdump_burden },
{ "hunger", sdump_hunger },
{ "transform", sdump_transform },
{ "misc", sdump_misc },
{ "notes", sdump_notes },
{ "inventory", sdump_inventory },
{ "skills", sdump_skills },
{ "spells", sdump_spells },
{ "mutations", sdump_mutations },
{ "messages", sdump_messages },
{ "screenshot", sdump_screenshot },
{ "kills", sdump_kills },
{ "overview", sdump_overview },
{ "hiscore", sdump_hiscore },
{ "header", sdump_header },
{ "stats", sdump_stats },
{ "location", sdump_location },
{ "religion", sdump_religion },
{ "burden", sdump_burden },
{ "hunger", sdump_hunger },
{ "transform", sdump_transform },
{ "visits", sdump_visits },
{ "misc", sdump_misc },
{ "turns_by_place", sdump_turns_by_place},
{ "notes", sdump_notes },
{ "inventory", sdump_inventory },
{ "skills", sdump_skills },
{ "spells", sdump_spells },
{ "mutations", sdump_mutations },
{ "messages", sdump_messages },
{ "screenshot", sdump_screenshot },
{ "kills_by_place", sdump_kills_by_place},
{ "kills", sdump_kills },
{ "overview", sdump_overview },
{ "hiscore", sdump_hiscore },
static void sdump_visits(dump_params &par)
{
std::string &text(par.text);
std::vector<PlaceInfo> branches_visited =
you.get_all_place_info(true, true);
PlaceInfo branches_total;
for (unsigned int i = 0; i < branches_visited.size(); i++)
branches_total += branches_visited[i];
text += make_stringf("You have visited %ld branch",
branches_visited.size());
if (branches_visited.size() > 1)
text += "es";
text += make_stringf(" of the dungeon, and seen %ld of its level",
branches_total.levels_seen);
if (branches_total.levels_seen > 1)
text += "s";
text += ".\n";
PlaceInfo place_info = you.get_place_info(LEVEL_PANDEMONIUM);
if (place_info.num_visits > 0)
{
text += make_stringf("You have visited Pandemonium %ld time",
place_info.num_visits);
if (place_info.num_visits > 1)
text += "s";
text += make_stringf(", and seen %ld of its levels.\n",
place_info.levels_seen);
if (place_info.levels_seen > 1)
text += "s";
text += ".\n";
}
place_info = you.get_place_info(LEVEL_ABYSS);
if (place_info.num_visits > 0)
{
text += make_stringf("You have visited the Abyss %ld time",
place_info.num_visits);
if (place_info.num_visits > 1)
text += "s";
text += ".\n";
}
place_info = you.get_place_info(LEVEL_LABYRINTH);
if (place_info.num_visits > 0)
{
text += make_stringf("You have visited %ld Labyrinth",
place_info.num_visits);
if (place_info.num_visits > 1)
text += "s";
text += ".\n";
}
place_info = you.get_place_info(LEVEL_PORTAL_VAULT);
if (place_info.num_visits > 0)
{
text += make_stringf("You have visited %ld portal chamber",
place_info.num_visits);
if (place_info.num_visits > 1)
text += "s";
text += " (including bazaars).\n";
}
text += "\n";
}
sdump_visits(par);
}
#define TO_PERCENT(x, y) (100.0 * ((float) (x)) / ((float) (y)))
static std::string sdump_turns_place_info(PlaceInfo place_info,
std::string name = "")
{
PlaceInfo gi = you.global_info;
std::string out;
if (name == "")
name = place_info.short_name();
float a, b, c, d, e, f;
unsigned int non_interlevel =
place_info.turns_total - place_info.turns_interlevel;
unsigned int global_non_interlevel =
gi.turns_total - gi.turns_interlevel;
a = TO_PERCENT(place_info.turns_total, gi.turns_total);
b = TO_PERCENT(non_interlevel, global_non_interlevel);
c = TO_PERCENT(place_info.turns_interlevel, place_info.turns_total);
d = TO_PERCENT(place_info.turns_resting, non_interlevel);
e = TO_PERCENT(place_info.turns_explore, non_interlevel);
f = (float) non_interlevel / (float) place_info.levels_seen;
out =
make_stringf("%14s | %5.1f | %5.1f | %5.1f | %5.1f | %5.1f | %13.1f\n",
name.c_str(), a, b, c , d, e, f);
out = replace_all(out, " nan ", " N/A ");
return out;
static void sdump_turns_by_place(dump_params &par)
{
std::string &text(par.text);
std::vector<PlaceInfo> all_visited =
you.get_all_place_info(true);
text +=
"Table legend:\n"
" A = Turns spent in this place as a percentage of turns spent in the\n"
" entire game.\n"
" B = Non-inter-level travel turns spent in this place as a perecentage of\n"
" non-inter-level travel turns spent in the entire game.\n"
" C = Inter-level travel turns spent in this place as a perecentage of\n"
" turns spent in this place.\n"
" D = Turns resting spent in this place as a percentage of non-inter-level\n"
" travel turns spent in this place.\n"
" E = Turns spent auto-exloring this place as a percentage of\n"
" non-inter-level travel turns spent in this place.\n"
" F = Non-inter-level travel turns spent in this place divided by the\n"
" number of levels of this place that you've seen.\n\n";
text += " ";
text += " A B C D E F\n";
text += " ";
text += "+-------+-------+-------+-------+-------+----------------------\n";
text += sdump_turns_place_info(you.global_info, "Total");
for (unsigned int i = 0; i < all_visited.size(); i++)
{
PlaceInfo pi = all_visited[i];
text += sdump_turns_place_info(pi);
}
text += " ";
text += "+-------+-------+-------+-------+-------+----------------------\n";
text += "\n";
}
static std::string sdump_kills_place_info(PlaceInfo place_info,
std::string name = "")
{
PlaceInfo gi = you.global_info;
std::string out;
if (name == "")
name = place_info.short_name();
unsigned int global_total_kills = 0;
for (int i = 0; i < KC_NCATEGORIES; i++)
global_total_kills += you.global_info.mon_kill_num[i];
unsigned int total_kills = 0;
for (int i = 0; i < KC_NCATEGORIES; i++)
total_kills += place_info.mon_kill_num[i];
// Skip places where nothing was killed.
if (total_kills == 0)
return "";
float a, b, c, d, e, f, g;
a = TO_PERCENT(total_kills, global_total_kills);
b = TO_PERCENT(place_info.mon_kill_num[KC_YOU],
you.global_info.mon_kill_num[KC_YOU]);
c = TO_PERCENT(place_info.mon_kill_num[KC_FRIENDLY],
you.global_info.mon_kill_num[KC_FRIENDLY]);
d = TO_PERCENT(place_info.mon_kill_num[KC_OTHER],
you.global_info.mon_kill_num[KC_OTHER]);
e = TO_PERCENT(place_info.mon_kill_exp,
you.global_info.mon_kill_exp);
f = TO_PERCENT(place_info.mon_kill_exp_avail,
you.global_info.mon_kill_exp_avail);
g = (float) MAXIMUM(place_info.mon_kill_exp,
place_info.mon_kill_exp_avail) /
(float) place_info.levels_seen;
out =
make_stringf("%14s | %5.1f | %5.1f | %5.1f | %5.1f | %5.1f |"
" %5.1f | %13.1f\n",
name.c_str(), a, b, c , d, e, f, g);
out = replace_all(out, " nan ", " N/A ");
return out;
}
static void sdump_kills_by_place(dump_params &par)
{
std::string &text(par.text);
std::vector<PlaceInfo> all_visited =
you.get_all_place_info(true);
std::string result = "";
std::string header =
"Table legend:\n"
" A = Kills in this place as a percentage of kills in entire the game.\n"
" B = Kills by you in this place as a percentage of kills by you in\n"
" the entire game.\n"
" C = Kills by friends in this place as a percentage of kills by\n"
" friends in the entire game.\n"
" D = Other kills in this place as a percentage of other kills in the\n"
" entire game.\n"
" E = Character level experience gained in this place as a percentage of\n"
" character level experience gained in the entire game.\n"
" F = Skills experience gained in this place as a percentage of skills\n"
" experience gained in the entire game.\n"
" G = Experience gained in this place divided by the number of levels of\n"
" this place that you have seen.\n\n";
header += " ";
header += " A B C D E F G\n";
header += " ";
header += "+-------+-------+-------+-------+-------+-------+--------------\n";
std::string footer = " ";
footer += "+-------+-------+-------+-------+-------+-------+--------------\n";
result += sdump_kills_place_info(you.global_info, "Total");
for (unsigned int i = 0; i < all_visited.size(); i++)
{
PlaceInfo pi = all_visited[i];
result += sdump_kills_place_info(pi);
}
if (result.length() > 0)
{
text += header + result + footer + "\n";
}
}
if (you.num_turns != -1)
{
PlaceInfo& curr_PlaceInfo = you.get_place_info();
PlaceInfo delta;
delta.turns_total++;
delta.elapsed_total += you.time_taken;
switch(you.running)
{
case RMODE_INTERLEVEL:
delta.turns_interlevel++;
delta.elapsed_interlevel += you.time_taken;
break;
case RMODE_EXPLORE_GREEDY:
case RMODE_EXPLORE:
delta.turns_explore++;
delta.elapsed_explore += you.time_taken;
break;
case RMODE_TRAVEL:
delta.turns_travel++;
delta.elapsed_travel += you.time_taken;
break;
default:
// prev_was_rest is needed so that the turn in which
// a player is interrupted from resting is counted
// as a resting turn, rather than "other".
static bool prev_was_rest = false;
if (!you.delay_queue.empty() &&
you.delay_queue.front().type == DELAY_REST)
prev_was_rest = true;
if (prev_was_rest)
{
delta.turns_resting++;
delta.elapsed_resting += you.time_taken;
}
else
{
delta.turns_other++;
delta.elapsed_other += you.time_taken;
}
if (you.delay_queue.empty() ||
you.delay_queue.front().type != DELAY_REST)
prev_was_rest = false;
break;
}
you.global_info += delta;
you.global_info.assert_validity();
curr_PlaceInfo += delta;
curr_PlaceInfo.assert_validity();
}
# dump_order = header,hiscore,stats,misc,notes,inventory,skills
# dump_order += spells,overview,mutations,messages,screenshot,kills
# dump_order = header,hiscore,stats,misc,notes,inventory,turns_by_place,
# dump_order += skills,spells,overview,mutations,messages,screenshot
# dump_order += kills_by_place,,kills
dump_order = header,hiscore,stats,misc,notes,inventory,skills
dump_order += spells,overview,mutations,messages,screenshot,kills
dump_order = header,hiscore,stats,misc,notes,inventory,turns_by_place,
dump_order += skills,spells,overview,mutations,messages,screenshot
dump_order += kills_by_place,,kills