Target code by Whiskey of Myth! [ncoast.lia.net 5000 Alpha version pending]
(graham@kestrel.is.und.ac.za).
With help by Blade of -E- and various suggestions on the rom mailing list.

You may use this code however you wish. Hack it up, use it as is, build more
into it, or even print it out and make origami flowers out of it.. whatever.
Just acknowledge yer sources. Sending me email is a nice touch.

note : This code hasn't been well tested. There SHOULDN'T be any memory
leakage or string bleeding, but management does not take any responsibility
for damage caused. ALWAYS make a backup before making changes. You'll want
to do a clean remake after putting this in, as it adds to PC_DATA.

EXPLANATION
^^^^^^^^^^^
This code allows replacement of the letters '$$' with a user-defined string.
This can be very helpful with aliases, as on most muds, the MAX_ALIAS is
very limiting.

Example :
untarget
'Your current target has been removed.'
alias atslap at $$ slap $$
'atslap is now aliased to "at $$ slap $$"'
target billy
'You are now targetting : "billy"'
atslap
'You send Billy REELING with a powerful SLAP!'

I have noticed that players especially like to alias "c sleep $$" or "backstab
$$' and change their targets when the opportunity arises.

CHANGES
^^^^^^^

Ok, firstly, in merc.h, add the following

UNDER >> struct	pc_data

FIND >>>
char *		bamfin;
char *		bamfout;
char *		title;

AND ADD >>>
char *		target;

- END of merc.h alterations -

Now, in save.c

UNDER >> void fwrite_char( CHAR_DATA *ch, FILE *fp )
AFTER >>>
    fprintf( fp, "Titl %s~\n",	ch->pcdata->title	);
ADD >>>
    if ( ch->pcdata->target[0] != '\0' )
    	fprintf( fp, "Targ %s~\n",	ch->pcdata->target	);

UNDER >> bool load_char_obj( whatever )
AFTER >>>
    ch->pcdata->title			= str_dup( "" );
ADD >>>
    ch->pcdata->target			= str_dup( "" );

UNDER >> void fread_char( CHAR_DATA *ch, FILE *fp )
AFTER >>>
	case 'T':
ADD >>>
            KEY( "Targ",	ch->pcdata->target,	fread_string( fp ) );

- END of save.c adjustments -

Next, in act_info.c

UNDER >> void do_score
AFTER >>> anywhere, really. It's a matter of individual taste.
	  We have it just above gold, silver and whatnot.
ADD >>>

    if ( !IS_NPC(ch) )
    {
    	if (ch->pcdata->target[0] != '\0' )
    	{
    		sprintf( buf,
    		"Your current target is : %s.\n\r", ch->pcdata->target);
    		send_to_char( buf, ch );
    	}
    	else 
    	send_to_char( "You have no current target.\n\r", ch);
    }

AT THE END OF THE FILE
ADD >>>

void set_target( CHAR_DATA *ch, char *target )
{
    char buf[MAX_STRING_LENGTH];

    strcpy( buf, target );

    if (ch->pcdata->target[0] != '\0')
     	free_string( ch->pcdata->target ); 
    ch->pcdata->target = str_dup( buf );
    return;
}



void do_target( CHAR_DATA *ch, char *argument)
{
  char arg[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH];
  
  smash_tilde(argument);
  one_argument( argument, arg );
  
  if ( IS_NPC(ch) )
  {
    send_to_char("Targets are for players!\n\r", ch);
    return;
  }
  
  if ( arg[0] == '\0' )
  {
  	
  	if ( ch->pcdata->target[0] != '\0' ) 
  	{
  		sprintf( buf, "Your current target is : %s\n\r", ch->pcdata->target);
  		send_to_char(buf,ch);
  		return;
  	}
 
  	send_to_char("You have no current target.\n\r",ch);
  	return;
  	
  }
  else
  {
  	set_target( ch, arg );
  	sprintf( buf, "Your new target is : %s\n\r", ch->pcdata->target);
  	send_to_char( buf, ch );
  	return;
  }
}

void do_untarget(CHAR_DATA *ch, char *argument)
{
   if ( IS_NPC(ch) )
   {
   	send_to_char("Only players can have targets!\n\r", ch);
   	return;
   }
   
   if ( ch->pcdata->target[0] == '\0' )
   {
   	send_to_char("Your target is not defined at the moment.\n\r", ch);
   	return;
   }
   
   send_to_char("You remove your current target.\n\r", ch);
   ch->pcdata->target = strdup("");
   return;
}

- END of alterations to act_info.c -

We're almost finished now. Open interp.h and add
DECLARE_DO_FUN( do_target );
 and
DECLARE_DO_FUN( do_untarget );

Make sure they go in alphabetical order. :)

- END of alterations to interp.h -

Lastly, in interp.c

UNDER >> the command table
AFTER >>> place it wherever it is relevant for your mud, probably after time
          but before weather.
ADD >>>
    { "target",		do_target,	POS_DEAD,	 0,  LOG_NORMAL, 1 },
    { "untarget",	do_untarget,	POS_DEAD,	 0,  LOG_NORMAL, 1 },

AFTER >>> at the end of the list, we have an entirely new function. Add it
	  just before do_interpret
ADD >>>

    /*  Targetting by Whiskey of Myth!, with help from
     *  Blade of -E-
     *  $$ converts into ch->pcdata->target
     */

char  * parse_target( CHAR_DATA *ch, char *oldstring )
{  
    	const 	char 	*str;
    	int		count = 0;
    	char 		*i = NULL; 
    	char 		*point;
    	char 		buf[ MAX_INPUT_LENGTH   ];
    	
        buf[0]  = '\0';
        str     = oldstring;
        point   = buf;
        while( *str != '\0' )
        {
            if( *str != '$' )
            {
                count++;
                *point++ = *str++;
                continue;
            }

	    ++str;
            if ( *str == '$' && ch->pcdata->target[0] != '\0' )
            {
               i = strdup(ch->pcdata->target); 
            	++str;
                while ( ( *point = *i ) != '\0' )
                	{
                	   ++point, ++i;
                	   count++;
                	   if (count > MAX_INPUT_LENGTH)
	    		   {
				send_to_char("Target substitution too long; not processed.\r\n",ch);
				return oldstring;
	    		   }
			}
            }
            else 
            {
            	*point++ = '$'; 
         	count++;
            }
         }
    buf[count] = '\0';
    oldstring = strdup( buf );
    return oldstring;
}

UNDER >> do_interpret
AFTER >>>
    if ( !IS_NPC(ch) && IS_SET(ch->act, PLR_FREEZE) )
    {
	send_to_char( "You're totally frozen!\n\r", ch );
	return;
    }
ADD >>>
    if ( !IS_NPC(ch) && ch->pcdata->target[0] != '\0')
    	argument = parse_target(ch, argument);

- END of alterations to interp.c -

HELPFILE
^^^^^^^^
1 TARGET UNTARGET~
Usage :   target
          target <name>
          untarget

Typing target alone will tell you what your current target is. Typing
untarget will remove whatever target you have; and typing target followed by
anything will set your target to whatever you typed.

The mud will replace a double dollar sign ('$$') with whatever your target
is, provided that you have a target. 

Example : untarget
          'Your current target has been removed.'
          alias 1 backstab $$
          '1 is now aliased to backstab $$.'
          target anthalas
          'Your current target is now anthalas.'
          1
          '<computer reads 1 as 'backstab $$', then reads $$ as 'anthalas'>'  
          'Your legendary backstab lightly tickles Anthalas.'

Note that you'll have to untarget before you can go moggy with aliases, or
you'll simply hardcode your aliases to whatever the computer reads $$ as.

Target code provided by Whiskey of Myth! with help from Blade of -E-
~
