1 /**
2  * @file
3  * @brief Scorefile manipulation functions
4 **/
5 
6 #pragma once
7 
8 #include <vector>
9 
10 #include "god-type.h"
11 #include "score-format-type.h"
12 
13 using std::vector;
14 
15 class scorefile_entry;
16 
17 int hiscores_new_entry(const scorefile_entry &se);
18 
19 void logfile_new_entry(const scorefile_entry &se);
20 
21 void hiscores_read_to_memory();
22 
23 string hiscores_print_list(int display_count, int format, int newest_entry, int& start_out);
24 void hiscores_print_all(int display_count = -1, int format = SCORE_TERSE);
25 void show_hiscore_table();
26 
27 string hiscores_format_single(const scorefile_entry &se);
28 string hiscores_format_single_long(const scorefile_entry &se,
29                                    bool verbose = false);
30 
31 void mark_milestone(const string &type, const string &milestone,
32                     const string &origin_level = "", time_t t = 0);
33 
34 #ifdef DGL_WHEREIS
35 string xlog_status_line();
36 #endif
37 
38 class xlog_fields
39 {
40 public:
41     xlog_fields();
42     xlog_fields(const string &line);
43 
44     void init(const string &line);
45     string xlog_line() const;
46 
47     void add_field(const string &key, PRINTF(2, ));
48 
49     string str_field(const string &) const;
50     int int_field(const string &) const;
51 
52 private:
53     void map_fields() const;
54 
55 private:
56     typedef vector< pair<string, string> > xl_fields;
57     typedef map<string, string> xl_map;
58 
59     xl_fields fields;
60     mutable xl_map fieldmap;
61 };
62 
63 class scorefile_entry
64 {
65 private:
66     string      raw_line;
67 
68     string      version;
69     string      save_rcs_version;
70     string      save_tag_version;
71     uint8_t     tiles;
72     int         points;
73     string      name;
74     int         race;               // species_type + legacy values
75     int         job;                // job_type + legacy values
76     string      race_class_name;    // overrides race & cls if non-empty.
77     uint8_t     lvl;                // player level.
78     skill_type  best_skill;         // best skill #
79     uint8_t     best_skill_lvl;     // best skill level
80     string      title;              // title
81     int         death_type;
82     mid_t       death_source;       // killer (maybe be MID_NOBODY)
83     string      death_source_name;  // overrides death_source
84     set<string> death_source_flags; // misc flags about killer
85     string      auxkilldata;        // weapon wielded, spell cast, etc
86     string      indirectkiller;     // the effect or real monster that summoned
87     string      killerpath;         // colon-separated intermediate killers
88     string      last_banisher;      // the name of the last thing that banished
89                                     // the player
90     uint8_t     dlvl;               // dungeon level (relative)
91     short       absdepth;           // 1-based absolute depth
92     branch_type branch;             // dungeon branch
93     string      map;                // the vault (if any) the player is in
94     string      mapdesc;            // DESC: of the vault the player is in.
95     string      killer_map;         // the vault (if any) that placed the killer
96     int         final_hp;           // actual current HPs (probably <= 0)
97     int         final_max_hp;       // net HPs after drain
98     int         final_max_max_hp;   // gross HPs before drain
99     int         final_mp;           // actual current MP
100     int         final_max_mp;       // max MP
101     int         final_base_max_mp;  // max MP ignoring equipped items
102     int         damage;             // damage of final attack
103     int         source_damage;      // total damage done by death_source
104     int         turn_damage;        // total damage done last turn
105     int         str;                // final str (useful for nickname)
106     int         intel;              // final int
107     int         dex;                // final dex (useful for nickname)
108     int         ac;                 // AC
109     int         ev;                 // EV
110     int         sh;                 // SH
111     god_type    god;                // god
112     int         piety;              // piety
113     int         penance;            // penance
114     uint8_t     wiz_mode;           // character used wiz mode
115     uint8_t     explore_mode;       // character used explore mode
116     time_t      birth_time;         // start time of character
117     time_t      death_time;         // end time of character
118     time_t      real_time;          // real playing time in seconds
119     int         num_turns;          // number of turns taken
120     int         num_aut;            // quantity of aut taken
121     int         num_diff_runes;     // number of rune types in inventory
122     int         num_runes;          // total number of runes in inventory
123     int         kills;              // number of monsters killed
124     string      maxed_skills;       // comma-separated list of skills
125                                     // at level 27
126     string      fifteen_skills;     // comma-separated list of skills
127                                     // at level >= 15
128     string      status_effects;     // comma-separated list of status effects
129     int         gold;               // Remaining gold.
130     int         gold_found;         // Gold found.
131     int         gold_spent;         // Gold spent shopping.
132 
133     int         zigs;               // Ziggurats completed.
134     int         zigmax;             // Max level reached in a ziggurat.
135 
136     int         scrolls_used;       // Number of scrolls used.
137     int         potions_used;       // Number of potions used.
138     string      seed;               // Game seed: use string here for simplicity
139                                     // even though the seed is really uint64_t
140 
141     mutable unique_ptr<xlog_fields> fields;
142 
143 public:
144     scorefile_entry();
145     scorefile_entry(int damage, mid_t death_source, int death_type,
146                     const char *aux, bool death_cause_only = false,
147                     const char *death_source_name = nullptr,
148                     time_t death_time = 0);
149     scorefile_entry(const scorefile_entry &se);
150 
151     scorefile_entry &operator = (const scorefile_entry &other);
152 
153     void init_death_cause(int damage, mid_t death_source, int death_type,
154                           const char *aux, const char *death_source_name);
155     void init(time_t death_time = 0);
156     void reset();
157 
158     enum death_desc_verbosity
159     {
160         DDV_TERSE,
161         DDV_ONELINE,
162         DDV_NORMAL,
163         DDV_VERBOSE,
164         DDV_LOGVERBOSE     // Semi-verbose for logging purposes
165     };
166 
167     string raw_string() const;
168     bool parse(const string &line);
169 
170     string hiscore_line(death_desc_verbosity verbosity) const;
171 
172     string character_description(death_desc_verbosity) const;
173     // Full description of death: Killed by an xyz wielding foo
174     string death_description(death_desc_verbosity) const;
175     string death_place(death_desc_verbosity) const;
176     string game_time(death_desc_verbosity) const;
177 
get_name()178     string get_name() const       { return name; }
get_score()179     int    get_score() const      { return points; }
get_death_type()180     int    get_death_type() const { return death_type; }
get_death_time()181     time_t get_death_time() const { return death_time; }
182     actor* killer() const; // Obviously does not work across games.
183     xlog_fields get_fields() const;
184 
185     void set_base_xlog_fields() const;
186     string short_kill_message() const;
187     string long_kill_message() const;
188 
189 private:
190     string single_cdesc() const;
191     string strip_article_a(const string &s) const;
192     string terse_missile_cause() const;
193     string terse_missile_name() const;
194     string terse_beam_cause() const;
195     string terse_wild_magic() const;
196     const char *damage_verb() const;
197     string death_source_desc() const;
198     string damage_string(bool terse = false) const;
199 
200     bool parse_scoreline(const string &line);
201 
202     void init_with_fields();
203     void add_auxkill_field() const;
204     void set_score_fields() const;
205     void fixup_char_name();
206 
207     string make_oneline(const string &s) const;
208 
209     void init_from(const scorefile_entry &other);
210 };
211