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 191 192 193 194 195 196 197
|
/*
* File: kills.h
* Summary: Tracks monsters the player has killed.
* Written by: Darshan Shaligram
*/
#ifndef KILLS_H
#define KILLS_H
#include <vector>
#include <string>
#include <map>
#include <stdio.h>
#include "enum.h"
std::string apostrophise(const std::string &name);
std::string apostrophise_fixup(const std::string &sentence);
class monsters;
class reader;
class writer;
// Not intended for external use!
struct kill_monster_desc
{
kill_monster_desc(const monsters *);
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'
};
int 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 monsters *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 monsters *mon, unsigned short place);
void add_place(unsigned short place, bool force = false);
void merge(const kill_def &k, bool unique_monster);
std::string info(const kill_monster_desc &md) const;
std::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.
std::vector<unsigned short> places; // Places where we've killed the beast.
private:
std::string append_places(const kill_monster_desc &md,
const std::string &name) const;
};
// Ghosts and random Pandemonium demons.
class kill_ghost
{
public:
kill_ghost(const monsters *mon);
kill_ghost() { }
void save(writer&) const;
void load(reader&);
std::string info() const;
std::string ghost_name;
int exp;
unsigned short place;
};
// This is the structure that Lua sees.
struct kill_exp
{
int nkills;
int exp;
std::string base_name;
std::string desc;
int monnum; // Number of the beast
int modifier; // Nature of the beast
std::vector<unsigned short> 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(-1), 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 monsters *mon);
void merge(const Kills &k);
bool empty() const;
void save(writer&) const;
void load(reader&);
int get_kills(std::vector<kill_exp> &v) const;
int num_kills(const monsters *mon) const;
private:
typedef std::map<kill_monster_desc,
kill_def,
kill_monster_desc::less_than> kill_map;
typedef std::vector<kill_ghost> ghost_vec;
kill_map kills;
ghost_vec ghosts;
void record_ghost_kill(const monsters *mon);
};
class KillMaster
{
public:
KillMaster();
KillMaster(const KillMaster& other);
~KillMaster();
void record_kill(const monsters *mon, int killer, bool ispet);
bool empty() const;
void save(writer&) const;
void load(reader&);
// Number of kills, by category.
int num_kills(const monsters *mon, kill_category cat) const;
// Number of kills, any category.
int num_kills(const monsters *mon) const;
int total_kills() const;
std::string kill_info() const;
private:
const char *category_name(kill_category kc) const;
Kills categorized_kills[KC_NCATEGORIES];
private:
void add_kill_info(std::string &, std::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
};
#endif
|