19 #define _GNU_SOURCE // strcasestr() is a GNU extension in string.h 27 #include <sys/types.h> 72 snprintf(buf, size,
"%s:%s:%" FMT64 ":%s:%s:%d:%d:%d", sc->
name, sc->
title, sc->
exp, sc->
killer, sc->
maplevel, sc->
maxhp, sc->
maxsp, sc->
maxgrace);
96 fprintf(fp,
"%s\n", buf);
117 cp = strchr(bp,
'\n');
130 sscanf(tmp[2],
"%" FMT64, &sc->
exp);
138 sscanf(tmp[5],
"%d", &sc->
maxhp);
140 sscanf(tmp[6],
"%d", &sc->
maxsp);
142 sscanf(tmp[7],
"%d", &sc->
maxgrace);
162 if (strcmp(sc->
killer,
"quit") == 0 || strcmp(sc->
killer,
"left") == 0) {
165 }
else if (strcmp(sc->
killer,
"a dungeon collapse") == 0) {
169 s1 =
"was killed by";
172 snprintf(buf, size,
"[fixed]%3d %10" FMT64 "[print] %s%s%s %s %s on map %s <%d><%d><%d>.",
173 sc->
position, sc->
exp, sc->
name, sc->
title[0]==
',' ?
"" :
" ", sc->
title, s1, s2, sc->
maplevel, sc->
maxhp, sc->
maxsp, sc->
maxgrace);
192 memset(old_score, 0,
sizeof(*old_score));
198 table->
entry[i] = *new_score;
203 *old_score = table->
entry[i];
205 table->
entry[i] = *new_score;
212 if (i >= HIGHSCORE_LENGTH) {
222 table->
entry[i] = *new_score;
227 while (i > 0 && new_score->
exp >= table->
entry[i-1].
exp) {
230 tmp = table->
entry[i-1];
232 table->
entry[i] = tmp;
256 fp = fopen(table->
fname,
"r");
258 if (errno == ENOENT) {
261 LOG(
llevError,
"Cannot open highscore file %s: %s\n", table->
fname, strerror(errno));
268 if (fgets(buf,
MAX_BUF, fp) == NULL) {
282 memset(&table->
entry[i], 0,
sizeof(table->
entry[i]));
305 memset(hiscore_tables,0,
sizeof(hiscore_tables));
320 if (!name || !*name)
continue;
324 for (
char *
c = hiscore_tables[subtype].fname; *
c; ++
c ) {
328 strncpy(hiscore_tables[subtype].skill_name, name,
sizeof(hiscore_tables[subtype].skill_name));
332 if (hiscore_tables[0].entry[0].
exp == 0) {
360 "Since you have been in wizard mode, " 361 "you can't enter the high-score list.");
367 "You don't deserve to save your character yet.");
376 if (new_score.
killer[0] ==
'\0') {
377 strcpy(new_score.
killer,
"a dungeon collapse");
380 if (op->
map == NULL) {
390 if (tmp->type !=
SKILL)
continue;
391 if (!tmp->stats.exp)
continue;
392 new_score.
exp = tmp->stats.exp;
395 if (!quiet && new_score.
exp > old_score.
exp) {
397 "You improved your rating in %s: %" FMT64, tmp->name, new_score.
exp);
407 add_score(&hiscore_tables[0], &new_score, &old_score);
419 message =
"You didn't enter the highscore list:";
421 message =
"You entered the highscore list:";
424 message =
"You left the highscore list:";
425 else if (new_score.
exp > old_score.
exp)
426 message =
"You beat your last score:";
428 message =
"You didn't beat your last score:";
455 int skill_min,skill_max;
459 if (strncmp(match,
"-s", 2) == 0 ) {
463 if (strchr(match,
' ')) {
464 len = strchr(match,
' ') - match;
469 if (strncmp(match,hiscore_tables[i].skill_name, len) == 0) {
476 "Could not match '%.*s' to a skill", len, match);
483 if ( max < 100 && max > 10 ) max = 10;
486 while (*match ==
' ') ++match;
488 skill_min = skill_max = skill_match;
489 if (skill_match == -1) {
500 if (skill < skill_min || skill > skill_max)
continue;
502 if (hiscore_tables[skill].skill_name[0] == 0) {
505 if (hiscore_tables[skill].entry[0].
exp == 0) {
510 "Overall high scores:");
513 "High scores for the skill [color=red]%s[/color]:", hiscore_tables[skill].skill_name);
516 "[fixed]Rank Score [print]Who <max hp><max sp><max grace>");
static event_registration c
static void add_score(score_table *table, score *new_score, score *old_score)
Adds the given score-structure to the high-score list, but only if it was good enough to deserve a pl...
const char * skill_names[MAX_SKILLS]
Will contain a number-name mapping for skills, initialized by init_skills().
#define PROFILE_BEGIN(expr)
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
char title[BIG_NAME]
Title.
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...) PRINTF_ARGS(6
int16_t maxgrace
Maximum grace.
char fname[MAX_BUF]
Filename of the backing file.
#define MSG_TYPE_ADMIN_HISCORE
Hiscore list.
void hiscore_display(object *op, int max, const char *match)
Displays the high score file.
int position
Position in the highscore list.
#define PROFILE_END(var, expr)
Global type definitions and header inclusions.
struct player * contr
Pointer to the player which control this object.
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Sends message to player(s).
#define MSG_TYPE_APPLY
Applying objects.
size_t split_string(char *str, char *array[], size_t array_size, char sep)
Splits a string delimited by passed in sep value into characters into an array of strings...
#define MSG_TYPE_COMMAND
Responses to commands, eg, who.
int get_skill_client_code(const char *skill_name)
Return the code of the skill for a client, the index in the skill_names array.
FILE * of_open(OutputFile *of, const char *fname)
Opens an output file.
static score_table hiscore_tables[MAX_SKILLS+1]
The highscore table.
char killer[BIG_NAME]
Name (+ title) or "left".
#define MSG_TYPE_COMMAND_ERROR
Bad syntax/can't use command.
char path[HUGE_BUF]
Filename of the map.
#define QUERY_FLAG(xyz, p)
Information on one title.
void player_get_title(const player *pl, char *buf, size_t bufsize)
Returns the player's title.
#define MSG_TYPE_APPLY_ERROR
#define FOR_INV_FINISH()
Finishes FOR_INV_PREPARE().
static void hiscore_save(const score_table *table)
Saves the highscore_table into the highscore file.
static char * draw_one_high_score(const score *sc, char *buf, size_t size)
Formats one score to display to a player.
static void put_score(const score *sc, char *buf, size_t size)
Writes the given score structure to specified buffer.
char killer[BIG_NAME]
Who killed this player.
The score structure is used when treating new high-scores.
struct Settings settings
Global settings.
score entry[HIGHSCORE_LENGTH]
The entries in decreasing exp order.
living stats
Str, Con, Dex, etc.
#define MAX_BUF
Used for all kinds of things.
struct mapstruct * map
Pointer to the map in which this object is present.
char maplevel[BIG_NAME]
Killed on what level.
Also see SKILL_TOOL (74) below.
uint32_t name_changed
If true, the player has set a name.
const char * localdir
Read/write data files.
#define HIGHSCORE_LENGTH
How many entries there are room for.
sstring name
The name of the object, obviously...
int maxgrace
Max grace when killed.
Only for debugging purposes.
int of_close(OutputFile *of)
Closes an output file.
static void hiscore_load(score_table *table)
Loads the hiscore_table from the highscore file.
int maxsp
Max sp when killed.
void hiscore_check(object *op, int quiet)
Checks if player should enter the hiscore, and if so writes her into the list.
Functions for creating text output files.
int16_t maxsp
Max spell points.
#define NDI_UNIQUE
Print immediately, don't buffer.
#define FLAG_WAS_WIZ
Player was once a wiz.
int16_t maxhp
Max hit points.
void hiscore_init(void)
Initializes the module.
#define MAX_SKILLS
This is the maximum number of skills the game may handle.
static int get_score(char *bp, score *sc)
The opposite of put_score(), get_score reads from the given buffer into a static score structure...
int maxhp
Max hp when killed.
#define FOR_INV_PREPARE(op_, it_)
Constructs a loop iterating over the inventory of an object.
char * name
Name of map as given by its creator.