I. Disclaimer
--------------

First I want apologize for my english.

Do you have playerd any advanced PK MUD? Emlen? MUME? There is "trophy" system.
If you kill any enemy (enemy race usually), you got his tropy - his name, race
and level is saved in your trophy list. For example:


> do_trophy

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                                                                 |
    | Cnt Name         Race    Level  Cnt Name         Race    Level  |
    |                                                                 |
    |   1 Lagoona      Demon   1       |   2 Tasuja       Elf     9   |
    |   1 Astra        Half-Orc 34      |   1 Test         Troll   100 |
    |   2 Liisu        Orc     49      |   1 Ihtel        Ghost   8   |
    |                                                                 |
    |                  Trophies : Total 8  , Different 6              |
    \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/  
                                  //\\
                                  \\//
                                   \/

It Means this player has been killed eight times enemy players and six
of them is different name. 


II. Credits

No credit required! If you are so kind or something is 'messy' then:
Mail to me: rainer_roomet@hotmail.com
Msn to me : rainer_roomet@hotmail.com
Or in MUD : carlnet.ee 4242


III. Code


// Open the file 'merc.h'
typedef	struct	trophy_data		TROPHY_DATA;		// trophies

// Now find the 'struct char_data' and add:
TROPHY_DATA *	trophy;

// Add in somewhere to merch.
struct trophy_data
{
    TROPHY_DATA *	next;
    char *		name;	// victim name
    sh_int		count;  // how many times
    sh_int		level;  // victim level
    sh_int		race;   // victim race
};

/* trophy.c */
void	add_to_trophy	args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );

// Close the file 'merc.h'

// Open the file 'fight.c'
// And find the place where victim is dying (usually IMMLogged)
// Blablabla "killed by" or "got toasted by" blabalbal
// And and add after that:


           if (ch != victim)
	      add_to_trophy( ch, victim ); 

// Also you may add some kind of check before that, for example we are using
// if (!is_same_detiy(ch, victim)) - it means that if victim and char is not
// in same deity (different kingdoms) then they are enemies and trophy will 
// be added. If you don't add any similar checks, then each player what you
// killed is saved into your trophy list.
// Close the file 'fight.c'

// Open the file 'interp.c' and 'interp.h'
// And define command 'do_trophy'  
// Close 'interp.c' and 'interp.h'

// Open the file 'recycle.c'
// Add the top of the file after defines:

TROPHY_DATA *           trophy_free = NULL;

// Find function: 'void free_char (CHAR_DATA *ch)'
// and after:
//   for (paf = ch->affected; paf != NULL; paf = paf_next)
//   {
//      paf_next = paf->next;
//      affect_remove(ch,paf);
//   }
// 
// Add the following:

   if ( !IS_NPC(ch) && ch->trophy != NULL )
   {
	TROPHY_DATA *tro;
	TROPHY_DATA *tro_next;

	for ( tro = ch->trophy; tro != NULL; tro = tro_next )
	{
	    tro_next    = tro->next;

	    free_string( tro->name );
	    ch->trophy  = tro->next;
	    tro->next   = trophy_free;
	    trophy_free = tro;
	}
    }

// Close the 'recycle.c'

// Open file the 'save.c'
// find the function: void fwrite_char( CHAR_DATA *ch, FILE *fp )
// And add into variables section:

TROPHY_DATA *tro;

// Find the following in fwrite_char:
//   for ( sn = 0; sn < MAX_SKILL; sn++ )
//   {
//      if ( skill_table[sn].name != NULL && ch->pcdata->learned[sn] > 0 )
//      {
//         fprintf( fp, "Sk %d '%s'\n",
//            ch->pcdata->learned[sn], 
//	    skill_table[sn].name );
//      }
//   }

// And add the following:

       if ( ch->level < LEVEL_IMMORTAL ) // Immortal's don't need trophies
	for ( tro = ch->trophy; tro != NULL; tro = tro->next )
	{
	    int length;
 
	    length = strlen( tro->name );

	    if ( tro->count < 1 || length < 2 || length > 12 )
	    {
		if ( length > 12 )
		    free_string( tro->name );
		continue;
	    }
	    
	    fprintf( fp, "Trophy '%s' %3d %3d %3d\n",
	      tro->name,
		tro->race,
		tro->count,
		tro->level );
	}


// Now find the function: bool load_char_obj( DESCRIPTOR_DATA *d, char *name )
// And add in resetting part the following:

ch->trophy	= NULL;

// Now find the function: void fread_char( CHAR_DATA *ch, FILE *fp )
// And add after variables:

ch->trophy = NULL;

// Find the following:
//	 case 'T':
//	    KEY( "Tru",		ch->trust,		fread_number( fp ) );
//
//	    if (!str_cmp( word, "Titl"))
//	    {
//	       ch->pcdata->title = fread_string( fp );
//  		
//               if (ch->pcdata->title[0] != '.' && ch->pcdata->title[0] != ',' 
//	       &&  ch->pcdata->title[0] != '!' && ch->pcdata->title[0] != '?')
//	       {
//	          sprintf( buf, "%s", ch->pcdata->title );
//		  free_string( ch->pcdata->title );
//		  ch->pcdata->title = str_dup( buf );
//	       } 
//               fMatch = TRUE;
//	       break;
//	    }

// And add:

 if ( !str_cmp(word,"Trophy") )
            {
		TROPHY_DATA *trop;
		char *tname;
 
                if ( trophy_free == NULL )
                {
                    trop        = alloc_perm( sizeof(*trop) );
                }
                else
                {
                    trop        = trophy_free;
                    trophy_free = trophy_free->next;
                }
		{
		    char *buf=  (char*)calloc( 1, MAX_INPUT_LENGTH );
		    tname		= fread_word2( fp,buf );
		    if( tname == NULL )
		    {
			bug( "Fread_char: fread_word error (trophy name).", 0 );
			return;
		    }
		    trop->name	= str_dup( tname );
		    free(buf);
		}

 		                   trop->race	= fread_number( fp );
                trop->count	= fread_number( fp );
                trop->level	= fread_number( fp );


                if ( trop->count < 1 )
                {
                    fprintf(stderr,"%s", trop->name);
                    bug( "Fread_char: trophy count less than 0. ", 0 );
		    trop->count = 1;
                }
		else if ( trop->level < 1 || trop->level > MAX_LEVEL )
		    trop->level = 1;
		else if ( trop->race < 0 || trop->race > MAX_PC_RACE )
		    trop->race = 0;

                trop->next	= ch->trophy;
                ch->trophy	= trop;
                fMatch = TRUE;
		break;
            }


// Close the save.c

// Make the new file named as: trophy.c
// And copy the following:
#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>

#include "merc.h"
#include "interp.h"
#include "magic.h"
#include "recycle.h"
#include "tables.h"

/*
 * Show trophy list to char
 */
void do_trophy( CHAR_DATA *ch, char *argument )
{
    TROPHY_DATA *trop;
    char arg[MAX_INPUT_LENGTH];
    char buf[MAX_INPUT_LENGTH];
    int col;
    int nTrop;
    int nTotal;
    int race = 0;

    one_argument( argument, arg );
    col = 0;
    nTrop = 0;
    nTotal = 0;

    send_to_char("\n\r\n\r", ch);
    send_to_char("    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\r", ch);
    send_to_char("    |                                                                 |\n\r", ch);
    send_to_char("    | Cnt Name         Race    Level  Cnt Name         Race    Level  |\n\r", ch );
    send_to_char("    |                                                                 |\n\r", ch );

    if (arg[0] != '\0')
    {
    	    if (!str_cmp(arg, "man"))		race = 1;
       else if (!str_cmp(arg, "woman"))		race = 2;	
       else if (!str_cmp(arg, "elf"))		race = 3;
       else if (!str_cmp(arg, "dwarf"))		race = 4;
       else if (!str_cmp(arg, "hobbit"))	race = 5;
       else if (!str_cmp(arg, "half-elf"))	race = 6;
       else if (!str_cmp(arg, "giant"))		race = 7;
       else if (!str_cmp(arg, "gremlin"))	race = 8;
       else if (!str_cmp(arg, "numenorean"))	race = 9;
       else if (!str_cmp(arg, "orc"))		race = 10; 
       else if (!str_cmp(arg, "demon"))		race = 11;
       else if (!str_cmp(arg, "half-orc"))	race = 12;
       else if (!str_cmp(arg, "troll"))		race = 13;
       else if (!str_cmp(arg, "ghost"))		race = 14;
       else if (!str_cmp(arg, "fallen-man"))	race = 15;
       else if (!str_cmp(arg, "fallen-woman"))	race = 16;
       else if (!str_cmp(arg, "dark-elf"))	race = 17;
       else if (!str_cmp(arg, "dark-half-elf"))	race = 18;
       else if (!str_cmp(arg, "gollum"))	race = 19;
       else if (!str_cmp(arg, "forsaked-dwarf"))race = 20;
    }

 

    for( trop = ch->trophy; trop != NULL; trop = trop->next )
    {
	if( arg[0] == '\0'
	|| ( arg[0] != '\0' && (trop->race == race 
	|| is_name( arg, trop->name ))) )
	{

	    nTotal += trop->count;
	    nTrop++;	   

	    sprintf( buf, "    | %3d %-12s %-7s %-4d",
		trop->count,
		trop->name,
		race_table[trop->race].name,
		trop->level );
	    send_to_char( buf, ch );
	    if( ++col % 2 == 0 )
		send_to_char( "|\n\r", ch );
	}
    }

    if( col % 2 != 0 )
	send_to_char( "    |                              |\n\r", ch );


    send_to_char("    |                                                                 |\n\r", ch );
    sprintf( buf,"    |                  Trophies : Total %-3d, Different %-3d            |\n\r", nTotal, nTrop );
    send_to_char( buf, ch );
    send_to_char("    \\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/  \n\r", ch);
    send_to_char("                                  //\\\\\n\r", ch );
    send_to_char("                                  \\\\//\n\r", ch );
    send_to_char("                                   \\/\n\r", ch );

 //   ch->different = nTrop;
    return;
}

void add_to_trophy( CHAR_DATA *ch, CHAR_DATA *victim )
{
    TROPHY_DATA *ptro;
   
    if( ch == NULL || victim == NULL || IS_NPC(ch) || IS_NPC(victim))
        return;
 
    for( ptro = ch->trophy; ptro != NULL; ptro = ptro->next )
        if( !strcmp( victim->name, ptro->name ) )
        {
	    ptro->level = (( ptro->count * ptro->level ) + victim->level ) / (++ptro->count );
            ptro->race  = victim->race;
            return;
        }
 
    if( trophy_free == NULL )
    {
        ptro		= alloc_perm( sizeof(*ptro) );
    }
    else
    {
        ptro		= trophy_free;
        trophy_free	= trophy_free->next;
    }
 
    ptro->name		= str_dup( victim->name );
    ptro->race		= victim->race;
    ptro->level		= victim->level;
    ptro->count		= 1;
    ptro->next		= ch->trophy;
    ch->trophy		= ptro;
    
    return;
}


// Now save this file, close it, make clean and make again.
// Maybe you have using some different definition (LEVEL_IMMORTAL) for example
// then you change it. Also this snippet is 'UNTESTED' - code is tested - 1 year
// already but I mean "installing the snipper" is not tested - if you notice some
// big bugs at this snippet - if you aren't so lazy please contact to me:
// MAIL/MSN: rainer_roomet@hotmail.com
// Or in MUD: telnet carlnet.ee 4242
// Or send feedback in mudmagic.com
//


Thank you for downloading My Snippet.

Ranka