#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;
}