/* * Hiscore code * Author: Cronel (cronel_kal@hotmail.com) * of FrozenMUD (empire.digiunix.net 4000) * nov 98 * * Permission to use and distribute this code is granted provided * this header is retained and unaltered, and the distribution * package contains all the original files unmodified. * If you modify this code and use/distribute modified versions * you must give credit to the original author(s). * */ #include <stdio.h> #include "mud.h" /* data */ typedef struct hiscore_entry HISCORE_ENTRY; typedef struct hiscore HISCORE; struct hiscore_entry { char *name; int score; long double score2; HISCORE_ENTRY *next; HISCORE_ENTRY *prev; }; struct hiscore { char *keyword; char *desc; int vnum; sh_int max_length; sh_int length; HISCORE_ENTRY *first_entry; /* first entry is number 1, highest score */ HISCORE_ENTRY *last_entry; /* last entry is number 10 or last, lowest */ HISCORE *next; HISCORE *prev; }; HISCORE *first_table; HISCORE *last_table; /* void do_hiscoset( CHAR_DATA *ch, char *argument ); void do_hiscore( CHAR_DATA *ch, char *argument ); char *is_hiscore_obj( OBJ_DATA *obj ); void show_hiscore( char *keyword, CHAR_DATA *victim ); void adjust_hiscore( char *keyword, CHAR_DATA *ch, int score ); */ /* local function declarations */ bool add_hiscore( char *keyword, char *name, int score ); bool add_hiscore_ld( char *keyword, char *name, long double score ); sh_int get_position( char *keyword, char *name ); void fix_table_length( HISCORE * table ); void create_hitable( char *keyword, char *desc ); bool destroy_hitable( char *keyword ); void save_hiscores( void ); void load_hiscores( void ); HISCORE *find_table( char *keyword ); HISCORE *load_hiscore_table( FILE * fp ); void do_hiscoset( CHAR_DATA * ch, char *argument ) /* Hiscoset command */ { char cmd[MAX_INPUT_LENGTH]; char kwd[MAX_INPUT_LENGTH]; char set_val[MAX_INPUT_LENGTH]; HISCORE *table; HISCORE_ENTRY *entry; sh_int i; bool cmd_found; if( sysdata.stall_hiscores ) { pager_printf( ch, "Hiscore tables are disabled." ); return; } if( argument[0] == '\0' ) { send_to_char( "Syntax: hiscoset <command> [table keyword] [field] [value]\n\r", ch ); send_to_char( "\n\r", ch ); send_to_char( " Command being one of:\n\r", ch ); send_to_char( " list Lists all hiscore tables.\n\r", ch ); send_to_char( " show <kwd> Shows the data for that table.\n\r", ch ); send_to_char( " create <kwd> Create new table with that keyword.\n\r", ch ); send_to_char( " destroy <kwd> Destroy table with that keyword.\n\r", ch ); send_to_char( " set <kwd> <field> <val> Sets data for that table.\n\r", ch ); send_to_char( "\n\r", ch ); send_to_char( " Field being one of:\n\r", ch ); send_to_char( " keyword <str> Set new keyword for the table.\n\r", ch ); send_to_char( " vnum <num> Set an object vnum for this table.\n\r", ch ); send_to_char( " desc <str> Set the description.\n\r", ch ); send_to_char( " maxlength <num> Set Max entries in the table.\n\r", ch ); send_to_char( " entry <name> <score> Change the score for a player.\n\r", ch ); send_to_char( "\n\r", ch ); send_to_char( " See HELP HISCOSET for more details.\n\r", ch ); return; } argument = one_argument( argument, cmd ); if( !str_cmp( cmd, "list" ) ) { send_to_char( "List of hiscore tables: \n\r", ch ); for( table = first_table; table; table = table->next ) { ch_printf( ch, " Table '%s' (%s), %d entries, vnum is %d\n\r", table->keyword, table->desc, table->length, table->vnum ); } if( !first_table ) send_to_char( " No tables found.\n\r", ch ); return; } argument = one_argument( argument, kwd ); if( kwd[0] != '\0' ) table = find_table( kwd ); else table = NULL; cmd_found = FALSE; if( !str_cmp( cmd, "create" ) && ( cmd_found = TRUE ) && kwd[0] != '\0' ) { if( table != NULL ) { send_to_char( "A table with that keyword already exists.\n\r", ch ); return; } create_hitable( kwd, "Description not set yet" ); ch_printf( ch, "Table '%s' created.\n\r", kwd ); save_hiscores( ); return; } else if( !str_cmp( cmd, "show" ) && ( cmd_found = TRUE ) && table != NULL ) { pager_printf( ch, "Hiscore table, keyword '%s':\n\r", kwd ); pager_printf( ch, "Description: %s\n\r", table->desc ); pager_printf( ch, "Vnum: %d MaxLength: %d Length: %d\n\r", table->vnum, table->max_length, table->length ); for( entry = table->first_entry, i = 1; entry; entry = entry->next, i++ ) { if( !strcmp( table->keyword, "powerlevel" ) || !strcmp( table->keyword, "plsaiyan" ) || !strcmp( table->keyword, "plhuman" ) || !strcmp( table->keyword, "plhalfbreed" ) || !strcmp( table->keyword, "plnamek" ) || !strcmp( table->keyword, "plandroid" ) || !strcmp( table->keyword, "plicer" ) || !strcmp( table->keyword, "plkaio" ) || !strcmp( table->keyword, "pldemon" ) || !strcmp( table->keyword, "plgenie" ) || !strcmp( table->keyword, "plbio-android" ) || !strcmp( table->keyword, "plsaibaman" ) || !strcmp( table->keyword, "januaryladder" ) || !strcmp( table->keyword, "februaryladder" ) || !strcmp( table->keyword, "marchladder" ) || !strcmp( table->keyword, "aprilladder" ) || !strcmp( table->keyword, "mayladder" ) || !strcmp( table->keyword, "juneladder" ) || !strcmp( table->keyword, "julyladder" ) || !strcmp( table->keyword, "augustladder" ) || !strcmp( table->keyword, "septemberladder" ) || !strcmp( table->keyword, "octoberladder" ) || !strcmp( table->keyword, "novemberladder" ) || !strcmp( table->keyword, "decemberladder" ) ) pager_printf( ch, "%d. Name: %-15.15s Score: %s\n\r", i, capitalize( entry->name ), num_punct_ld( entry->score2 ) ); else pager_printf( ch, "%d. Name: %-15.15s Score: %s\n\r", i, capitalize( entry->name ), num_punct( entry->score ) ); } return; } else if( !str_cmp( cmd, "destroy" ) && ( cmd_found = TRUE ) && table != NULL ) { if( destroy_hitable( kwd ) ) ch_printf( ch, "Table '%s' destroyed.\n\r", kwd ); else { ch_printf( ch, "ERROR: Couldn't destroy table '%s'.\n\r", kwd ); LINK( table, first_table, last_table, next, prev ); } save_hiscores( ); return; } else if( !str_cmp( cmd, "set" ) ) cmd_found = TRUE; if( !cmd_found ) { ch_printf( ch, "Invalid command '%s' for hiscoset.\n\r", cmd ); return; } if( kwd[0] == '\0' ) { send_to_char( "Please specify a table keyword.\n\r", ch ); return; } if( table == NULL ) { ch_printf( ch, "No such table '%s'.\n\r", kwd ); return; } /* * If it reached here, its "hiscoset set" and table is valid */ argument = one_argument( argument, cmd ); if( cmd[0] == '\0' ) { send_to_char( "Hiscoset set what?\n\r", ch ); return; } cmd_found = FALSE; if( !str_cmp( cmd, "desc" ) && ( cmd_found = TRUE ) && argument[0] != '\0' ) { STRFREE( table->desc ); table->desc = STRALLOC( argument ); ch_printf( ch, "Ok. Description for table '%s' is now '%s'.\n\r", kwd, argument ); save_hiscores( ); return; } argument = one_argument( argument, set_val ); if( !str_cmp( cmd, "keyword" ) && ( cmd_found = TRUE ) && set_val[0] != '\0' ) { STRFREE( table->keyword ); table->keyword = STRALLOC( set_val ); ch_printf( ch, "Ok. Keyword for table '%s' is now '%s'.\n\r", kwd, set_val ); save_hiscores( ); return; } else if( !str_cmp( cmd, "vnum" ) && ( cmd_found = TRUE ) && set_val[0] != '\0' ) { if( is_number( set_val ) ) { table->vnum = atoi( set_val ); ch_printf( ch, "Ok. Vnum for table '%s' is now '%d'.\n\r", kwd, table->vnum ); save_hiscores( ); } else send_to_char( "Argument for set vnum must be numeric.\n\r", ch ); return; } else if( !str_cmp( cmd, "maxlength" ) && ( cmd_found = TRUE ) && set_val[0] != '\0' ) { if( is_number( set_val ) ) { table->max_length = atoi( set_val ); ch_printf( ch, "Ok. Max length for table '%s' is now '%d'.\n\r", kwd, table->max_length ); fix_table_length( table ); save_hiscores( ); } else send_to_char( "Argument for set maxlength must be numeric.\n\r", ch ); return; } else if( !str_cmp( cmd, "entry" ) ) cmd_found = TRUE; if( !cmd_found ) { ch_printf( ch, "Invalid value '%s' for hiscoset set.\n\r", cmd ); return; } if( set_val[0] == '\0' ) { ch_printf( ch, "Hiscoset set %s to what?.\n\r", cmd ); return; } /* * at this point, its hiscoset set entry .. */ if( argument == '\0' || !is_number( argument ) ) { send_to_char( "Second argument to set entry must be numberic.\n\r", ch ); return; } ch_printf( ch, "New score for %s set to %s.\n\r", set_val, argument ); if( add_hiscore( kwd, set_val, atoi( argument ) ) ) { ch_printf( ch, "New position is %d.\n\r", get_position( kwd, set_val ) ); } else ch_printf( ch, "They are out of the table.\n\r" ); save_hiscores( ); } void do_hiscore( CHAR_DATA * ch, char *argument ) /* Hiscore command */ { HISCORE *table; bool some_table; OBJ_INDEX_DATA *oindex; if( sysdata.stall_hiscores ) { pager_printf( ch, "Hiscore tables are disabled, most likely due to a bug.\n\r" ); pager_printf( ch, "Please notify an Admin of this on the 'bug' message board.\n\r" ); return; } if( argument[0] == '\0' ) { sysdata.outBytesFlag = LOGBOUTINFORMATION; some_table = FALSE; send_to_char( "Hiscore tables in this game:\n\r", ch ); for( table = first_table; table; table = table->next ) { if( table->vnum == -1 ) { ch_printf( ch, " &W%40s&w: keyword '&W%s&w'\n\r", table->desc, table->keyword ); some_table = TRUE; } else { oindex = get_obj_index( table->vnum ); if( oindex != NULL ) { ch_printf( ch, " %s: in object %s\n\r", table->desc, oindex->short_descr ); some_table = TRUE; } } } if( !some_table ) send_to_char( " None.\n\r", ch ); sysdata.outBytesFlag = LOGBOUTNORM; return; } table = find_table( argument ); if( table == NULL ) { HISCORE_ENTRY *entry; int num = 0; bool tablefound = FALSE; sysdata.outBytesFlag = LOGBOUTINFORMATION; for( table = first_table; table; table = table->next ) { if( table->vnum == -1 ) { num = 1; for( entry = table->first_entry; entry; entry = entry->next ) { if( !strcmp( entry->name, capitalize( argument ) ) ) { pager_printf_color( ch, "&w%s\n\r", table->desc ); pager_printf_color( ch, "&W ---------------\n\r" ); if( !strcmp( table->keyword, "powerlevel" ) || !strcmp( table->keyword, "plsaiyan" ) || !strcmp( table->keyword, "plhuman" ) || !strcmp( table->keyword, "plhalfbreed" ) || !strcmp( table->keyword, "plnamek" ) || !strcmp( table->keyword, "plandroid" ) || !strcmp( table->keyword, "plkaio" ) || !strcmp( table->keyword, "pldemon" ) || !strcmp( table->keyword, "plicer" ) || !strcmp( table->keyword, "plbio-android" ) || !strcmp( table->keyword, "plgenie" ) || !strcmp( table->keyword, "plsaibaman" ) || !strcmp( table->keyword, "januaryladder" ) || !strcmp( table->keyword, "februaryladder" ) || !strcmp( table->keyword, "marchladder" ) || !strcmp( table->keyword, "aprilladder" ) || !strcmp( table->keyword, "mayladder" ) || !strcmp( table->keyword, "juneladder" ) || !strcmp( table->keyword, "julyladder" ) || !strcmp( table->keyword, "augustladder" ) || !strcmp( table->keyword, "septemberladder" ) || !strcmp( table->keyword, "octoberladder" ) || !strcmp( table->keyword, "novemberladder" ) || !strcmp( table->keyword, "decemberladder" ) ) pager_printf_color( ch, "%s #%2d) %s\n\r", num <= 3 ? "&R" : "&Y", num, entry->name ); else pager_printf_color( ch, "%s #%2d) %s %s\n\r", num <= 3 ? "&R" : "&Y", num, entry->name, num_punct( entry->score ) ); tablefound = TRUE; pager_printf_color( ch, "\n\r" ); break; } num++; } } } if( !tablefound ) send_to_char( "No such hiscore table.\n\r", ch ); sysdata.outBytesFlag = LOGBOUTNORM; return; } if( table->vnum != -1 && !IS_IMMORTAL( ch ) ) { send_to_char( "That hiscore table is attached to an object. Go see the object.\n\r", ch ); return; } sysdata.outBytesFlag = LOGBOUTINFORMATION; show_hiscore( table->keyword, ch ); sysdata.outBytesFlag = LOGBOUTNORM; } char *is_hiscore_obj( OBJ_DATA * obj ) /* If the given object is marked as a hiscore table object, it returns * a pointer to the keyword for that table; otherwise returns NULL */ { HISCORE *table; for( table = first_table; table; table = table->next ) { if( obj->pIndexData->vnum == table->vnum ) return table->keyword; } return NULL; } /* (@) (@) | |-------------------------------------------------| | | | | | | | Greatest Pkillers of Frozen Wasteland | | | | | | | | 1. Darklord ..........|.......... 1000 | | | | 2. Pepto .............|............ 50 | | | | 10. 12345678901234567890123456789012345 | | | | 1234 | | | |-------------------------------------------------| | (@) (@) width = 01234567890123456789012345678901234567890123456789012345678901234567890123456789 0 1 2 3 4 5 6 7 3 + 5 + text + 5 + 3 = 16 + text text = 4 + 20 + 15 = 39 39 + 16 = 49+6 = 55 */ /* this is width of text only, * add 13 to get actual width */ void show_hiscore( char *keyword, CHAR_DATA * ch ) /* Shows a hiscore table to a player in a (more or less) nicely formatted * way. */ { HISCORE *table; HISCORE_ENTRY *entry; sh_int num, len; char buf[MAX_STRING_LENGTH]; bool odd; table = find_table( keyword ); if( table == NULL ) { bug( "show_hiscore: no such table '%s'", keyword ); return; } pager_printf_color( ch, "\n\r&g(&r@&g) (&r@&g)&w\n\r" ); pager_printf_color( ch, "&g| |-------------------------------------------------| |&w\n\r" ); pager_printf_color( ch, "&g| | | |&w\n\r" ); sprintf( buf, "%s", table->desc ); len = strlen( buf ); len = ( 39 - len ); odd = ( len % 2 ) == 1; len /= 2; if( len < 0 ) len = 0; for( num = 0; num < len; num++ ) buf[num] = ' '; buf[num] = '\0'; pager_printf_color( ch, "&g| | &G%s%s%s%s &g| |&w\n\r", buf, table->desc, odd ? " " : "", buf ); pager_printf_color( ch, "&g| | | |&w\n\r" ); num = 1; for( entry = table->first_entry; entry; entry = entry->next ) { if( !strcmp( table->keyword, "powerlevel" ) || !strcmp( table->keyword, "plsaiyan" ) || !strcmp( table->keyword, "plhuman" ) || !strcmp( table->keyword, "plhalfbreed" ) || !strcmp( table->keyword, "plnamek" ) || !strcmp( table->keyword, "plandroid" ) || !strcmp( table->keyword, "plicer" ) || !strcmp( table->keyword, "plkaio" ) || !strcmp( table->keyword, "pldemon" ) || !strcmp( table->keyword, "plbio-android" ) || !strcmp( table->keyword, "plgenie" ) || !strcmp( table->keyword, "plsaibaman" ) || !strcmp( table->keyword, "januaryladder" ) || !strcmp( table->keyword, "februaryladder" ) || !strcmp( table->keyword, "marchladder" ) || !strcmp( table->keyword, "aprilladder" ) || !strcmp( table->keyword, "mayladder" ) || !strcmp( table->keyword, "juneladder" ) || !strcmp( table->keyword, "julyladder" ) || !strcmp( table->keyword, "augustladder" ) || !strcmp( table->keyword, "septemberladder" ) || !strcmp( table->keyword, "octoberladder" ) || !strcmp( table->keyword, "novemberladder" ) || !strcmp( table->keyword, "decemberladder" ) ) pager_printf_color( ch, "&g| | %s%2d. %-20.20s &g| |\n\r", num <= 3 ? "&R" : num <= 10 ? "&Y" : num <= 25 ? "&w" : "&p", num, capitalize( entry->name ) ); else pager_printf_color( ch, "&g| | %s%2d. %-20.20s%15s &g| |\n\r", num <= 3 ? "&R" : num <= 10 ? "&Y" : num <= 25 ? "&w" : "&p", num, capitalize( entry->name ), num_punct( entry->score ) ); num++; } pager_printf_color( ch, "&g| | | |&w\n\r" ); pager_printf_color( ch, "&g| |-------------------------------------------------| |&w\n\r" ); pager_printf_color( ch, "&g(&r@&g) (&r@&g)&w\n\r" ); } void adjust_hiscore( char *keyword, CHAR_DATA * ch, int score ) /* Adjusts the hiscore for that character in that table * and sends message to the character and to the whole mud * if the player entered the table */ { char buf[MAX_STRING_LENGTH]; sh_int pos, old_pos; HISCORE *table; if( IS_IMMORTAL( ch ) ) score = 0; if( xIS_SET( ch->act, PLR_NO_HISCORE ) ) score = 0; if( IS_HC( ch ) && str_cmp( keyword, "bounty" ) ) return; if( score == 0 ) return; old_pos = get_position( keyword, ch->name ); add_hiscore( keyword, ch->name, score ); pos = get_position( keyword, ch->name ); table = find_table( keyword ); if( pos != -1 && pos > old_pos && table != NULL ) { ch_printf( ch, "You have reached position %d in the table of '%s'.\n\r", pos, table->desc ); if( pos <= 10 ) { sprintf( buf, "%s has reached position %d in the table of '%s'", ch->name, pos, table->desc ); do_info( ch, buf ); } } } void adjust_hiscore_ld( char *keyword, CHAR_DATA * ch, long double score ) /* Adjusts the hiscore for that character in that table * and sends message to the character and to the whole mud * if the player entered the table */ { char buf[MAX_STRING_LENGTH]; sh_int pos, old_pos; HISCORE *table; if( IS_IMMORTAL( ch ) ) score = 0; if( xIS_SET( ch->act, PLR_NO_HISCORE ) ) score = 0; if( IS_HC( ch ) ) return; if( score == 0 ) return; old_pos = get_position( keyword, ch->name ); add_hiscore_ld( keyword, ch->name, score ); pos = get_position( keyword, ch->name ); table = find_table( keyword ); if( pos != -1 && pos > old_pos && table != NULL ) { ch_printf( ch, "You have reached position %d in the table of '%s'.\n\r", pos, table->desc ); /* * replace for info channel */ if( pos <= 10 ) { sprintf( buf, "%s has reached position %d in the table of '%s'", ch->name, pos, table->desc ); do_info( ch, buf ); } } } bool add_hiscore( char *keyword, char *name, int score ) /* Sets the score for 'name'. If name is already on the table, the old * score is discarded and the new one takes effect. * Returns TRUE if as a result of this call, name was added to the * table or remained there. */ { HISCORE *table; HISCORE_ENTRY *entry, *new_entry; sh_int i; bool added; if( sysdata.stall_hiscores ) return FALSE; table = find_table( keyword ); if( table == NULL ) { bug( "add_hiscore: table '%s' not found", keyword ); sysdata.stall_hiscores = TRUE; // do_ainfo(NULL, "&RError in hiscore tables. Hiscore tables are disabled."); return FALSE; } for( entry = table->first_entry; entry; entry = entry->next ) { if( !str_cmp( entry->name, name ) ) { UNLINK( entry, table->first_entry, table->last_entry, next, prev ); STRFREE( entry->name ); DISPOSE( entry ); table->length--; break; } } added = FALSE; new_entry = NULL; for( i = 1, entry = table->first_entry; i <= table->max_length; entry = entry->next, i++ ) { if( !entry ) /* * there are empty slots at end of list, add there */ { CREATE( new_entry, HISCORE_ENTRY, 1 ); new_entry->name = STRALLOC( name ); new_entry->score = score; LINK( new_entry, table->first_entry, table->last_entry, next, prev ); table->length++; added = TRUE; break; } else if( score > entry->score ) { CREATE( new_entry, HISCORE_ENTRY, 1 ); new_entry->name = STRALLOC( name ); new_entry->score = score; INSERT( new_entry, entry, table->first_entry, next, prev ); table->length++; added = TRUE; break; } } fix_table_length( table ); if( added ) save_hiscores( ); return added; } bool add_hiscore_ld( char *keyword, char *name, long double score ) /* Sets the score for 'name'. If name is already on the table, the old * score is discarded and the new one takes effect. * Returns TRUE if as a result of this call, name was added to the * table or remained there. */ { HISCORE *table; HISCORE_ENTRY *entry, *new_entry; sh_int i; bool added; if( sysdata.stall_hiscores ) return FALSE; table = find_table( keyword ); if( table == NULL ) { bug( "add_hiscore: table '%s' not found", keyword ); sysdata.stall_hiscores = TRUE; // do_ainfo(NULL, "&RError in hiscore tables. Hiscore tables are disabled."); return FALSE; } for( entry = table->first_entry; entry; entry = entry->next ) { if( !str_cmp( entry->name, name ) ) { UNLINK( entry, table->first_entry, table->last_entry, next, prev ); STRFREE( entry->name ); DISPOSE( entry ); table->length--; break; } } added = FALSE; new_entry = NULL; for( i = 1, entry = table->first_entry; i <= table->max_length; entry = entry->next, i++ ) { if( !entry ) /* * there are empty slots at end of list, add there */ { CREATE( new_entry, HISCORE_ENTRY, 1 ); new_entry->name = STRALLOC( name ); new_entry->score2 = score; LINK( new_entry, table->first_entry, table->last_entry, next, prev ); table->length++; added = TRUE; break; } else if( score > entry->score2 ) { CREATE( new_entry, HISCORE_ENTRY, 1 ); new_entry->name = STRALLOC( name ); new_entry->score2 = score; INSERT( new_entry, entry, table->first_entry, next, prev ); table->length++; added = TRUE; break; } } fix_table_length( table ); if( added ) save_hiscores( ); return added; } void fix_table_length( HISCORE * table ) /* Chops entries at the end of the table if the table * has exceeded its maximum length */ { HISCORE_ENTRY *entry; while( table->length > table->max_length ) { table->length--; entry = table->last_entry; UNLINK( entry, table->first_entry, table->last_entry, next, prev ); STRFREE( entry->name ); DISPOSE( entry ); } } sh_int get_position( char *keyword, char *name ) /* Returns the position of 'name' within the table of that keyword, or * -1 if 'name' is not in that table */ { sh_int i; HISCORE *table; HISCORE_ENTRY *entry; table = find_table( keyword ); if( !table ) return -1; i = 1; for( entry = table->first_entry; entry; entry = entry->next ) { if( !str_cmp( entry->name, name ) ) return i; i++; } return -1; } HISCORE *find_table( char *keyword ) /* Returns a pointer to the table for the given keyword * or NULL if there's no such table */ { HISCORE *table; for( table = first_table; table; table = table->next ) { if( !str_cmp( table->keyword, keyword ) ) return table; } return NULL; } void create_hitable( char *keyword, char *desc ) /* Creates a new hiscore table with the given keyword and description */ { HISCORE *new_table; CREATE( new_table, HISCORE, 1 ); new_table->keyword = STRALLOC( keyword ); new_table->desc = STRALLOC( desc ); new_table->vnum = -1; new_table->max_length = 10; new_table->length = 0; new_table->first_entry = NULL; new_table->last_entry = NULL; LINK( new_table, first_table, last_table, next, prev ); } bool destroy_hitable( char *keyword ) /* Destroyes a given hiscore table. Returns FALSE if error */ { HISCORE *table; HISCORE_ENTRY *entry, *nentry; table = find_table( keyword ); if( !table ) return FALSE; UNLINK( table, first_table, last_table, next, prev ); STRFREE( table->keyword ); STRFREE( table->desc ); for( entry = table->first_entry; entry; entry = nentry ) { nentry = entry->next; UNLINK( entry, table->first_entry, table->last_entry, next, prev ); STRFREE( entry->name ); DISPOSE( entry ); } DISPOSE( table ); return TRUE; } void save_hiscores( void ) /* Saves all hiscore tables */ { FILE *fp; char filename[MAX_INPUT_LENGTH]; HISCORE *table; HISCORE_ENTRY *entry; sprintf( filename, "%shiscores.dat", SYSTEM_DIR ); fclose( fpReserve ); fp = fopen( filename, "w" ); if( fp == NULL ) { bug( "save_hiscores: fopen" ); return; } fprintf( fp, "#HISCORES\n" ); for( table = first_table; table; table = table->next ) { fprintf( fp, "#TABLE\n" ); fprintf( fp, "Keyword %s\n", table->keyword ); fprintf( fp, "Desc %s~\n", table->desc ); fprintf( fp, "Vnum %d\n", table->vnum ); fprintf( fp, "MaxLength %d\n", table->max_length ); for( entry = table->first_entry; entry; entry = entry->next ) { if( entry->score == 0 && entry->score2 == 0 ) continue; if( !strcmp( table->keyword, "powerlevel" ) || !strcmp( table->keyword, "plsaiyan" ) || !strcmp( table->keyword, "plhuman" ) || !strcmp( table->keyword, "plhalfbreed" ) || !strcmp( table->keyword, "plnamek" ) || !strcmp( table->keyword, "plandroid" ) || !strcmp( table->keyword, "plicer" ) || !strcmp( table->keyword, "plkaio" ) || !strcmp( table->keyword, "pldemon" ) || !strcmp( table->keyword, "plgenie" ) || !strcmp( table->keyword, "plbio-android" ) || !strcmp( table->keyword, "plsaibaman" ) || !strcmp( table->keyword, "januaryladder" ) || !strcmp( table->keyword, "februaryladder" ) || !strcmp( table->keyword, "marchladder" ) || !strcmp( table->keyword, "aprilladder" ) || !strcmp( table->keyword, "mayladder" ) || !strcmp( table->keyword, "juneladder" ) || !strcmp( table->keyword, "julyladder" ) || !strcmp( table->keyword, "augustladder" ) || !strcmp( table->keyword, "septemberladder" ) || !strcmp( table->keyword, "octoberladder" ) || !strcmp( table->keyword, "novemberladder" ) || !strcmp( table->keyword, "decemberladder" ) ) fprintf( fp, "Entry2 %s %.0Lf\n", entry->name, entry->score2 ); else fprintf( fp, "Entry %s %d\n", entry->name, entry->score ); } fprintf( fp, "End\n\n" ); } fprintf( fp, "#END\n" ); fclose( fp ); fpReserve = fopen( NULL_FILE, "r" ); } void load_hiscores( void ) /* Loads all hiscore tables */ { char filename[MAX_INPUT_LENGTH]; FILE *fp; HISCORE *new_table; sprintf( filename, "%shiscores.dat", SYSTEM_DIR ); fp = fopen( filename, "r" ); if( fp == NULL ) return; for( ;; ) { char letter; char *word; letter = fread_letter( fp ); if( letter != '#' ) { bug( "load_hiscores: # not found" ); return; } word = fread_word( fp ); if( !str_cmp( word, "HISCORES" ) ) ; else if( !str_cmp( word, "END" ) ) break; else if( !str_cmp( word, "TABLE" ) ) { new_table = load_hiscore_table( fp ); if( !new_table ) continue; LINK( new_table, first_table, last_table, next, prev ); } else { bug( "load_hiscores: unknown field" ); break; } } fclose( fp ); return; } HISCORE *load_hiscore_table( FILE * fp ) /* Loads one hiscore table from the file and returns it */ { char *word; HISCORE *new_table; HISCORE_ENTRY *new_entry; sh_int entry_count; CREATE( new_table, HISCORE, 1 ); entry_count = 0; for( ;; ) { word = fread_word( fp ); if( !str_cmp( word, "End" ) ) break; else if( !str_cmp( word, "Keyword" ) ) new_table->keyword = STRALLOC( fread_word( fp ) ); else if( !str_cmp( word, "Desc" ) ) new_table->desc = fread_string( fp ); else if( !str_cmp( word, "Vnum" ) ) new_table->vnum = fread_number( fp ); else if( !str_cmp( word, "MaxLength" ) ) new_table->max_length = fread_number( fp ); else if( !str_cmp( word, "Entry" ) ) { CREATE( new_entry, HISCORE_ENTRY, 1 ); new_entry->name = STRALLOC( fread_word( fp ) ); new_entry->score = fread_number( fp ); /* * LINK adds at the end of the table. */ LINK( new_entry, new_table->first_entry, new_table->last_entry, next, prev ); entry_count++; } else if( !str_cmp( word, "Entry2" ) ) { CREATE( new_entry, HISCORE_ENTRY, 1 ); new_entry->name = STRALLOC( fread_word( fp ) ); new_entry->score2 = fread_number_ld( fp ); /* * LINK adds at the end of the table. */ LINK( new_entry, new_table->first_entry, new_table->last_entry, next, prev ); entry_count++; } else { bug( "load_hiscore_table: unknown field" ); break; } } new_table->length = entry_count; if( entry_count > new_table->max_length ) { bug( "load_hiscore_table: extra entries in table. fixed max_length" ); new_table->max_length = entry_count; } if( new_table->keyword == NULL ) new_table->keyword = STRALLOC( "error" ); if( new_table->desc == NULL ) new_table->desc = STRALLOC( "Error: no description" ); return new_table; } void ladderTableClear( int mon ) { HISCORE *table; // HISCORE_ENTRY *entry; /* * new month, so wipe old ladder data for this month */ switch ( mon ) { default: case 0: table = find_table( "januaryladder" ); break; case 1: table = find_table( "februaryladder" ); break; case 2: table = find_table( "marchladder" ); break; case 3: table = find_table( "aprilladder" ); break; case 4: table = find_table( "mayladder" ); break; case 5: table = find_table( "juneladder" ); break; case 6: table = find_table( "julyladder" ); break; case 7: table = find_table( "augustladder" ); break; case 8: table = find_table( "septemberladder" ); break; case 9: table = find_table( "octoberladder" ); break; case 10: table = find_table( "novemberladder" ); break; case 11: table = find_table( "decemberladder" ); break; } /* if (table->length > 0) { for( entry = table->first_entry ; entry ; entry = entry->next ) { UNLINK( entry, table->first_entry, table->last_entry, next, prev ); STRFREE( entry->name ); DISPOSE( entry ); table->length--; } if (table->length != 0) bug("Error while reseting hiscore table: length was no 0"); } */ return; } void do_clearhiscore( CHAR_DATA * ch, char *argument ) { char kwd[MAX_INPUT_LENGTH]; HISCORE *table; HISCORE_ENTRY *entry; HISCORE_ENTRY *entry_next; int count = 0; if( IS_NPC( ch ) ) return; if( !IS_IMMORTAL( ch ) ) { ch_printf( ch, "Huh?" ); return; } argument = one_argument( argument, kwd ); if( ( table = find_table( kwd ) ) == NULL ) { ch_printf( ch, "No such hiscore.\n\r" ); return; } for( entry = table->first_entry; entry; entry = entry_next ) { entry_next = entry->next; UNLINK( entry, table->first_entry, table->last_entry, next, prev ); DISPOSE( entry ); count++; } if( count > 0 ) ch_printf( ch, "%d entries cleared.\n\r", count ); else ch_printf( ch, "There are no entries in that board.\n\r" ); return; } /*eof*/