1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
|
/**
* @file
* @brief Tracks monsters the player has killed.
**/
#pragma once
#include <cstdio>
#include <map>
#include <string>
#include <vector>
#include "enum.h"
class monster;
struct monster_info;
class reader;
class writer;
// Not intended for external use!
struct kill_monster_desc
{
kill_monster_desc(const monster*);
kill_monster_desc(const monster_info&);
kill_monster_desc() { }
void save(writer&) const;
void load(reader&);
enum name_modifier
{
M_NORMAL, M_ZOMBIE, M_SKELETON, M_SIMULACRUM, M_SPECTRE,
M_SHAPESHIFTER, // A shapeshifter pretending to be 'monnum'
};
monster_type monnum; // Number of the beast
name_modifier modifier; // Nature of the beast
struct less_than
{
bool operator () (const kill_monster_desc &m1,
const kill_monster_desc &m2) const
{
return m1.monnum < m2.monnum
|| (m1.monnum == m2.monnum && m1.modifier < m2.modifier);
}
};
};
#define PLACE_LIMIT 5 // How many unique kill places we're prepared to track
class kill_def
{
public:
kill_def(const monster* mon);
kill_def() : kills(0), exp(0)
{
// This object just says to the world that it's uninitialised
}
void save(writer&) const;
void load(reader&);
void add_kill(const monster* mon, level_id place);
void add_place(level_id place, bool force = false);
void merge(const kill_def &k, bool unique_monster);
string info(const kill_monster_desc &md) const;
string base_name(const kill_monster_desc &md) const;
unsigned short kills; // How many kills does the player have?
int exp; // Experience gained for slaying the beast.
// Only set *once*, even for shapeshifters.
vector<level_id> places; // Places where we've killed the beast.
private:
string append_places(const kill_monster_desc &md, const string &name) const;
};
// Ghosts and random Pandemonium demons.
class kill_ghost
{
public:
kill_ghost(const monster* mon);
kill_ghost() { }
void save(writer&) const;
void load(reader&);
string info() const;
string ghost_name;
int exp;
level_id place;
};
// This is the structure that Lua sees.
struct kill_exp
{
int nkills;
int exp;
string base_name;
string desc;
monster_type monnum; // Number of the beast
int modifier; // Nature of the beast
vector<level_id> places;
kill_exp(const kill_def &k, const kill_monster_desc &md)
: nkills(k.kills), exp(k.exp), base_name(k.base_name(md)),
desc(k.info(md)),
monnum(md.monnum), modifier(md.modifier), places(k.places)
{
}
kill_exp(const kill_ghost &kg)
: nkills(1), exp(kg.exp), base_name(), desc(kg.info()),
monnum(MONS_PROGRAM_BUG), modifier(0)
{
places.push_back(kg.place);
}
// operator< is implemented for a descending sort.
bool operator < (const kill_exp &b) const
{
return exp == b.exp? (base_name < b.base_name) : (exp > b.exp);
}
};
class Kills
{
public:
void record_kill(const monster* mon);
void merge(const Kills &k);
bool empty() const;
void save(writer&) const;
void load(reader&);
int get_kills(vector<kill_exp> &v) const;
int num_kills(const monster* mon) const;
int num_kills(const monster_info& mon) const;
private:
int num_kills(kill_monster_desc desc) const;
typedef map<kill_monster_desc, kill_def,
kill_monster_desc::less_than> kill_map;
typedef vector<kill_ghost> ghost_vec;
kill_map kills;
ghost_vec ghosts;
void record_ghost_kill(const monster* mon);
};
class KillMaster
{
public:
void record_kill(const monster* mon, int killer, bool ispet);
bool empty() const;
void save(writer&) const;
void load(reader&);
// Number of kills, by category.
int num_kills(const monster* mon, kill_category cat) const;
int num_kills(const monster_info& mon, kill_category cat) const;
// Number of kills, any category.
int num_kills(const monster* mon) const;
int num_kills(const monster_info& mon) const;
int total_kills() const;
string kill_info() const;
private:
const char *category_name(kill_category kc) const;
Kills categorized_kills[KC_NCATEGORIES];
private:
void add_kill_info(string &, vector<kill_exp> &,
int count, const char *c, bool separator) const;
};
enum KILL_DUMP_OPTIONS
{
KDO_NO_PLACES, // Don't dump places at all
KDO_ONE_PLACE, // Show places only for single kills and uniques.
KDO_ALL_PLACES, // Show all available place information
};
|