#if defined(macintosh) #include <types.h> #else #include <sys/types.h> #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <unistd.h> #include <linux/unistd.h> #include <dirent.h> #include <sys/stat.h> #include "merc.h" #include "build.h" typedef struct arti_type ARTI_TYPE; sh_int top_artis; struct arti_type { ARTI_TYPE *next; AREA_DATA *pArea; OBJ_INDEX_DATA *pObjIndex; char * short_descr; char * name; char * player_name; sh_int vnum; }; ARTI_TYPE * artifact_list; #if defined(KEY) #undef KEY #endif #define KEY( literal, field, value ) \ if ( !str_cmp( word, literal ) ) \ { \ field = value; \ fMatch = TRUE; \ break; \ } #ifdef SKEY #undef SKEY #endif #define SKEY( string, field ) \ if ( !str_cmp( word, string ) ) \ { \ free_string( field ); \ field = fread_string( fp ); \ fMatch = TRUE; \ break; \ } void write_artifacts args ( ( void ) ); /* * Scans the artifact_list and see's if any of the vnums match * Returns true if it does, otherwise FALSE */ bool is_artifact( OBJ_INDEX_DATA *pObj ) { ARTI_TYPE * arti; for( arti = artifact_list; arti; arti = arti->next ) { if( arti->vnum == pObj->vnum ) return TRUE; } return FALSE; } /* * Replace the right artifact with the specified description * and player name */ void fix_artifact( OBJ_INDEX_DATA *pObj ) { ARTI_TYPE * arti; for( arti = artifact_list; arti; arti = arti->next ) { if( arti->vnum == pObj->vnum ) { free_string( arti->player_name ); arti->player_name = str_dup( "(not found)" ); return; } } bugf( "fix_artifact: not found %s (%d)", pObj->short_descr, pObj->vnum ); return; } void fix_artifact_pfile( OBJ_DATA *pObj, char * name, bool write ) { ARTI_TYPE * arti; for( arti = artifact_list; arti; arti = arti->next ) { if( arti->vnum == pObj->pIndexData->vnum ) { free_string( arti->player_name ); free_string( arti->short_descr ); free_string( arti->name ); arti->player_name = str_dup( name ); arti->short_descr = str_dup( pObj->short_descr ); arti->name = str_dup( pObj->name ); if( write ) write_artifacts( ); return; } } bugf( "Invalid artifact %s (%d)", pObj->short_descr, pObj->pIndexData->vnum ); return; } void write_artifacts( ) { ARTI_TYPE * arti; FILE * fp; if( !(fp = fopen( DATA_DIR ARTI_FILE, "w" ) ) ) { perror( DATA_DIR ARTI_FILE ); return; } fprintf( fp, "* This file contains a fairly updated list of artifacts\n" ); fprintf( fp, "* And who has them through the game\n" ); fprintf( fp, "*\n" ); for( arti = artifact_list; arti; arti = arti->next ) { fprintf( fp, "#ARTI\n" ); fprintf( fp, "V %d\n", arti->vnum ); fprintf( fp, "N %s~\n", strip_cr( arti->name) ); fprintf( fp, "S %s~\n", strip_cr( arti->short_descr) ); fprintf( fp, "P %s~\n", strip_cr( arti->player_name) ); fprintf( fp, "End\n\n" ); } fprintf( fp, "#END\n" ); fclose( fp ); return; } void fread_artifact ( FILE *fp ) { char * name; char * player_name; char * short_descr; char * word; int vnum; bool fMatch; vnum = 0; name = &str_empty[0]; player_name = &str_empty[0]; short_descr = &str_empty[0]; for( ; ; ) { word = feof( fp ) ? "End" : fread_word( fp ); fMatch = FALSE; switch ( UPPER(word[0]) ) { case '*': fMatch = TRUE; fread_to_eol( fp ); break; case 'N': SKEY( "N", name ); break; case 'P': SKEY( "P", player_name ); break; case 'S': SKEY( "S", short_descr ); break; case 'V': KEY( "V", vnum, fread_number( fp ) ); break; case 'E': if( !str_cmp( word, "End" ) ) { ARTI_TYPE * arti; fMatch = TRUE; for( arti = artifact_list; arti; arti = arti->next ) { if( arti->vnum == vnum ) { free_string( arti->player_name ); arti->player_name = str_dup( player_name ); free_string( arti->name ); arti->name = str_dup( name ); free_string( arti->short_descr ); arti->short_descr = str_dup( short_descr ); logf( NULL, "%d (%s) to %s", vnum, name, player_name ); break; } } free_string( player_name ); free_string( name ); free_string( short_descr ); return; } break; } if( !fMatch ) { bugf( "fread_artif: no match %s", word ); } } } void update_artifacts( char * fname ) { FILE * fp; bool fMatch; if( !(fp = fopen( fname, "r" ) ) ) return; fMatch = FALSE; for( ; ; ) { char letter; char * word; letter = fread_letter( fp ); if ( letter == '*' ) { fread_to_eol( fp ); continue; } if ( letter != '#' ) { bug( "update_artifacts: # not found.",0 ); break; } word = fread_word( fp ); if ( !str_cmp( word, "ARTI" ) ) { fread_artifact( fp ); continue; } else if ( !str_cmp( word, "END" ) ) break; else { bugf( "update_artifacts: bad section. %s", word ); break; } } fclose( fp ); return; } /* * Scan all the object index's for artifacts. */ void load_artifacts( ) { OBJ_INDEX_DATA *pObjIndex; ARTI_TYPE * arti; int vnum; int nMatch; nMatch = 0; top_artis = 0; artifact_list = NULL; for( vnum = 0; nMatch < top_obj_index; vnum++ ) { if( ( pObjIndex = get_obj_index( vnum ) ) ) { nMatch++; if( IS_SET(pObjIndex->quest, QUEST_ARTIFACT) && !is_artifact( pObjIndex ) ) { arti = alloc_perm( sizeof( ARTI_TYPE ) ); arti->next = NULL; arti->pObjIndex = pObjIndex; arti->pArea = pObjIndex->area; arti->player_name = str_dup( "(not found)" ); arti->short_descr = str_dup( pObjIndex->short_descr ); arti->name = str_dup( pObjIndex->name ); arti->vnum = pObjIndex->vnum; arti->next = artifact_list; artifact_list = arti; top_artis++; } } } logf( NULL, "Max Artifacts: %d", top_artis ); update_artifacts( DATA_DIR ARTI_FILE ); return; } char * check_date ( CHAR_DATA *ch, char * filename ) { char fname [ 256 ]; struct stat fst; time_t tdiff; time_t now_time; now_time = time(0); if( get_char_world( ch, filename ) ) return "{G"; sprintf( fname, "%s/%s", PLAYER_DIR, filename ); if ( stat( fname, &fst ) != -1 ) { tdiff = (now_time - fst.st_mtime) / 86400; if( tdiff > 14 ) return "{D"; else if( tdiff > 9 ) return "{R"; else if( tdiff > 4 ) return "{Y"; else return ""; } else return "{D"; } void do_show_artifacts( CHAR_DATA *ch, char *argument ) { ARTI_TYPE * arti; char arg [ MIL ]; bool found; if( IS_NPC( ch ) ) return; argument = one_argument( argument, arg ); if( IS_IMMORTAL( ch ) ) { if( arg[0] != '\0' ) { if( !str_cmp( arg, "save" ) ) { write_artifacts( ); stc( "Done.\n\r", ch ); return; } if( !str_cmp( arg, "clear" ) ) { for( arti = artifact_list; arti; arti = arti->next ) { if( !arti ) break; if( !str_prefix( arti->name, argument ) ) { free_string( arti->player_name ); arti->player_name =str_dup( "(not found)" ); stc( "Done.\n\r", ch); return; } } send_to_char( "Artifact not found.\n\r", ch ); return; } } ch_printf( ch, "There are %d artifacts.\n\r", top_artis ); ch_printf( ch, "%5.5s | %20.20s | %-10.10s | %s\n\r", "Vnum", "Name", "PlayerName", "ShortDescr" ); send_to_char( LINE_SEPERATOR, ch ); } found = FALSE; for( arti = artifact_list; arti; arti = arti->next ) { if( !arti ) break; found = TRUE; if( IS_IMMORTAL(ch) ) { ch_printf( ch, "%5d | %20.20s | %s%-10.10s{x | %s\n\r", arti->vnum, arti->name, check_date( ch, arti->player_name ), arti->player_name, arti->short_descr ); } else { if( str_cmp( arti->player_name, "(not found)" ) ) ch_printf( ch, "%s, which has been discovered by %s.\n\r", arti->short_descr, arti->player_name ); else ch_printf( ch, "%s, which has not yet been discovered.\n\r", arti->short_descr ); } } if( !found ) { if( IS_IMMORTAL(ch) ) send_to_char( "None found.\n\r", ch ); else send_to_char( "There are no artifacts in the game yet.\n\r", ch); } if( IS_IMMORTAL(ch) ) send_to_char( "{Rsee also:{x 'help arti_tracking'\n\r", ch ); return; }