18 #define _GNU_SOURCE // strcasestr() is a GNU extension in string.h 25 #include <sys/types.h> 70 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');
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]));
301 memset(hiscore_tables,0,
sizeof(hiscore_tables));
316 if (!name || !*name)
continue;
320 for (
char *c = hiscore_tables[subtype].fname; *c; ++c ) {
324 strncpy(hiscore_tables[subtype].skill_name, name,
sizeof(hiscore_tables[subtype].skill_name));
328 if (hiscore_tables[0].entry[0].
exp == 0) {
350 if (op->stats.exp == 0 || !op->contr->name_changed)
356 "Since you have been in wizard mode, " 357 "you can't enter the high-score list.");
360 if (!op->stats.exp) {
363 "You don't deserve to save your character yet.");
371 if (new_score.
killer[0] ==
'\0') {
372 strcpy(new_score.
killer,
"a dungeon collapse");
375 if (op->map == NULL) {
378 strncpy(new_score.
maplevel, op->map->name ? op->map->name : op->map->path,
BIG_NAME-1);
381 new_score.
maxhp = (int)op->stats.maxhp;
382 new_score.
maxsp = (
int)op->stats.maxsp;
383 new_score.
maxgrace = (int)op->stats.maxgrace;
385 if (tmp->type != SKILL)
continue;
386 if (!tmp->stats.exp)
continue;
387 new_score.
exp = tmp->stats.exp;
390 if (!quiet && new_score.
exp > old_score.
exp) {
392 "You improved your rating in %s: %" FMT64, tmp->name, new_score.
exp);
401 new_score.
exp = op->stats.exp;
402 add_score(&hiscore_tables[0], &new_score, &old_score);
413 message =
"You didn't enter the highscore list:";
415 message =
"You entered the highscore list:";
418 message =
"You left the highscore list:";
419 else if (new_score.
exp > old_score.
exp)
420 message =
"You beat your last score:";
422 message =
"You didn't beat your last score:";
449 int skill_min,skill_max;
453 if (match && strncmp(match,
"-s", 2) == 0 ) {
457 if (strchr(match,
' ')) {
458 len = strchr(match,
' ') - match;
463 if (strncmp(match,hiscore_tables[i].skill_name, len) == 0) {
470 "Could not match '%.*s' to a skill", len, match);
477 if ( max < 100 && max > 10 ) max = 10;
480 while (*match ==
' ') ++match;
482 skill_min = skill_max = skill_match;
483 if (skill_match == -1) {
494 if (skill < skill_min || skill > skill_max)
continue;
496 if (hiscore_tables[skill].skill_name[0] == 0) {
499 if (hiscore_tables[skill].entry[0].
exp == 0) {
504 "Overall high scores:");
507 "High scores for the skill [color=red]%s[/color]:", hiscore_tables[skill].skill_name);
510 "[fixed]Rank Score [print]Who <max hp><max sp><max grace>");
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
const char * skill_names[MAX_SKILLS]
void hiscore_display(object *op, int max, const char *match)
static void hiscore_save(const score_table *table)
void player_get_title(const struct pl *pl, char *buf, size_t bufsize)
static char * draw_one_high_score(const score *sc, char *buf, size_t size)
#define MSG_TYPE_ADMIN_HISCORE
static int get_score(char *bp, score *sc)
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
static void hiscore_load(score_table *table)
int get_skill_client_code(const char *skill_name)
#define MSG_TYPE_COMMAND_ERROR
#define MSG_TYPE_APPLY_ERROR
int of_close(OutputFile *of)
score entry[HIGHSCORE_LENGTH]
#define QUERY_FLAG(xyz, p)
static void put_score(const score *sc, char *buf, size_t size)
static score_table hiscore_tables[MAX_SKILLS+1]
static void add_score(score_table *table, score *new_score, score *old_score)
FILE * of_open(OutputFile *of, const char *fname)
size_t split_string(char *str, char *array[], size_t array_size, char sep)
void LOG(LogLevel logLevel, const char *format,...)
void hiscore_check(object *op, int quiet)
#define FOR_INV_PREPARE(op_, it_)