/*******************************************************************************
 *         _               | File Name:   custom_slay.txt
 *        / \      _-'     | Description: A new customizable Slay
 *      _/|  \-''- _ /     |              It allows an immortal with the slay command
 * __-' |          \       |              to set hisown/herown slay messages. It allows
 *     /              \    |              for multiple generic and user specific slay
 *     /       "o.  |o |   |              messages.
 *     |            \ ;    |              
 *                   ',    |
 *        \_         __\   | (c) 2000-2001 TAKA 
 *          ''-_    \.//   | (c) 2000-2001 The GhostMud Project Team
 *            / '-____'    | 
 *           /             | You may use this code under ROM license restriction 
 *         _'  The Wolf    | 1) This header block remains in the code.          
 *       _-'   strikes!    | 2) You email me at a_ghost_dancer@excite.com
 *_________________________|    letting me know you are using this code
 *                              please incluse your name, your mud name
 * All rights reserved          your mud address, your email and this file
 * GhostMud is copyrighted      name.                                         
 * by TAKA                   3) In your help files mention me where appropriate 
 *                              IE: help snippets.
 *********************************************************************************/



VNUM.H
/*
 * 010501
 * (c) TAKA 2001
 * slay messages get saved here in this list file
 *
 * Most of these flags for your mud are not even used but my release V2.1 uses
 * all of them and will be at some point available to the general public. However
 * at this time i have not released that code.
 *
 * You should include them if you wish but becareful a few are used in my code
 * and the SLAY_MESSAGE_LIST should be used always.
 */
#define SLAY_MESSAGE_LIST	"../text/slay.txt" 	/* List of petitions to clans */
#define ALLOW_MULTI_SLAY	1 /* Allow Multi Slay */
#define ALLOW_CUSTOM_SLAY	1 /* Allow immortals to make their own custom slays */
#define CUSTOM_SLAY_COUNT	5 /* Number of custom slays per person */
#define CUSTOM_SLAY_LEVEL	118 /* Level to allow custom slays */
#define ALLOW_SHARE_CUSTOM	0 /* Allow other immortals to use someone elses custom slay */


MERC.H
find 
typedef struct    room_index_data   ROOM_INDEX_DATA;
add
typedef struct    slay_message   	SLAY_MESSAGE; /*010501 */

then somewhere after 
struct char_data

add this following the close of the structure above
/*
 * Custom Slay messages
 * (c) Taka 2001
 * 010501
 */
struct    slay_message
{
    SLAY_MESSAGE *    SMnext;
    SLAY_MESSAGE *    SMprev;
    int					Slay_Number;
	char *				Slay_Name;
	char *				Char_Name;
	char *				Show_Vict;
	char *				Show_Char;
	char *				Show_Room;
};

SLAY_MESSAGE *SMHead, *SMTail, *SMptr;
/* 010501 - end */


INTERP.H
DECLARE_DO_FUN(do_edit_slay		); /* 010501 */

INTERP.C
    { "editslay",	do_edit_slay,	POS_DEAD,		L3,  LOG_ALWAYS, 1 },
    



NEW_DBX.C (for rom muds place in DB.C)
/* at the top with other declarations */
void	load_slaym		(); /* 010501 */
void	save_slaym		(); /* 010501 */
void 	AppendSlayMsg		(SLAY_MESSAGE *SMptr); /* 010501 */


/* near the bottom */
/*
 * 010501
 * (c) 2001 Taka
 * Custom slay messages
 * load_slaym - Loads a slay message
 * AppendSlayMsg - Adds a new message to the linked list
 * save_slaym - saves the slay message file
 */
void load_slaym()
{
	char	*word;
	FILE	*fp;

	if ( ( fp = fopen( SLAY_MESSAGE_LIST, "r" ) ) == NULL )
	{
	    perror( SLAY_MESSAGE_LIST );
	    exit( 1 );
	}

	log_string( "Loading Slay Message File" );

	for (;;)
	{
		word = fread_word( fp );

		if(word[0] == '$')
			return;

		SMptr = malloc(sizeof(struct slay_message));

		word = fread_word( fp );
		SMptr->Slay_Number = fread_number( fp );
		word = fread_word( fp );
		SMptr->Slay_Name   = fread_string( fp );
		word = fread_word( fp );
		SMptr->Char_Name   = fread_string( fp );
		word = fread_word( fp );
		SMptr->Show_Vict   = fread_string( fp );
		word = fread_word( fp );
		SMptr->Show_Char   = fread_string( fp );
		word = fread_word( fp );
		SMptr->Show_Room   = fread_string( fp );

		AppendSlayMsg( SMptr );
	}

	return;
}

/*
 * Append to Slay Message Linked List
 */
void AppendSlayMsg(SLAY_MESSAGE *SMptr)
{

   if (SMHead == NULL)
   {
      SMHead = SMptr;
      SMptr->SMprev = NULL;
   }
   else
   {
      SMTail->SMnext = SMptr;
      SMptr->SMprev = SMTail;
   }

   SMTail = SMptr;
   SMptr->SMnext = NULL;

   return;
}


void save_slaym()
{
    FILE *fp;
    SLAY_MESSAGE *smIndex;

	/* loop through slays and save */
    if ( ( fp = fopen( SLAY_MESSAGE_LIST, "w" ) ) == NULL )
    {
	bug( "Save_slay_message_list: fopen", 0 );
	perror( SLAY_MESSAGE_LIST );
    }
    else
    {
	for(smIndex=SMHead; smIndex != NULL; smIndex=smIndex->SMnext)
	{
		fprintf( fp, "#\n" );
		fprintf( fp, "Snmbr %d\n",  smIndex->Slay_Number);
		fprintf( fp, "SName %s~\n", smIndex->Slay_Name);
		fprintf( fp, "PName %s~\n", smIndex->Char_Name);
		fprintf( fp, "TVict %s~\n", smIndex->Show_Vict);
		fprintf( fp, "TChar %s~\n", smIndex->Show_Char);
		fprintf( fp, "TRoom %s~\n", smIndex->Show_Room);
        }
	fprintf( fp, "$\n" );
	fclose( fp );
    }

    return;
}



ACT_NEWC.C (else rom ACT_INFO.C)
/* at the top with other declarations */
extern void 	AppendSlayMsg		(SLAY_MESSAGE *SMptr); /* 010501 */
extern void	save_slaym		(); /* 010501 */


/* at the bottom */
/*
 * (c) 2001 Taka
 * add/modify a custom slay message
 * 010501
 */
void do_edit_slay(CHAR_DATA *ch, char *argument)
{
    char arg1[MIL];
    char arg2[MIL];
    char arg3[MIL];
 	char buf[MSL];
	char const *sName;
	SLAY_MESSAGE *smIndex;

    argument = one_argument( argument, arg1);
    argument = one_argument( argument, arg2);

	/*
	 * validate command
	 */

    if ( arg1[0] == '\0' )
    {
		send_to_char("{RSyntax: {Geditslay  <slay message name>  <type>  <text>{x\n\r", ch);
		send_to_char("{M        Types = Name, Gerneral, victim, char, room{x\n\r", ch);
		send_to_char("        Name    = Name of the Slay (place the word new in text for a new slay message)\n\r", ch);
		send_to_char("        General = 1=user owned, 0=available all\n\r", ch);
		send_to_char("        Victim  = Victim display message\n\r", ch);
		send_to_char("        Char    = Character diplay message\n\r", ch);
		send_to_char("        Room    = Room display message\n\r", ch);
		return;
	}

	/*
	 * do not allow a mob to use this command
	 * not that it will crash the mud but hey for good measure
	 */
	if ( IS_NPC(ch) )
	{
		send_to_char("Mobs have no need for slay messages!\n\r", ch);
		return;
	}

	/* set the name */
	if(arg2[0] != '\0' && !str_prefix(arg2, "name"))
	{
	    argument = one_argument( argument, arg3);
	
		if(arg3[0] != '\0' && !str_prefix(arg3, "new"))
		{
			/* Ensure slay message does not already exist */
			for(smIndex=SMHead; smIndex != NULL; smIndex=smIndex->SMnext)
			{
				if(!str_cmp( smIndex->Slay_Name, arg1))
				{
					printf_to_char(ch, "Slay named %s already exists!\n\r", 
						smIndex->Slay_Name);
					return;
				}
			}

			/* 
			   Slay message does not exist
			   1) allocate the needed memory for the message
			   2) set the linked list to blanks except the message name
			 */
			smIndex = malloc(sizeof(struct slay_message));

			smIndex->Slay_Number = 0;
			smIndex->Slay_Name   = str_dup(arg1);
			smIndex->Char_Name   = str_dup("");
			smIndex->Show_Vict   = str_dup("");
			smIndex->Show_Char   = str_dup("");
			smIndex->Show_Room   = str_dup("");

			AppendSlayMsg( smIndex );

			printf_to_char(ch, "New slay named %s has been added.\n\r", 
				smIndex->Slay_Name);

			save_slaym();
			return;
		}
		
		/* validate message and rename the slay message */
		for(smIndex=SMHead; smIndex != NULL; smIndex=smIndex->SMnext)
		{
			if(!str_cmp( smIndex->Slay_Name, arg1))
			{
				printf_to_char(ch, "Slay named %s has been renamed to %s.\n\r", 
					smIndex->Slay_Name, arg1);
				smIndex->Slay_Name = str_dup(arg1);
				save_slaym();
				return;
			}
		}

		/* error has occured on the name prompt */
		send_to_char("That is not a slay name!\n\r", ch);
		send_to_char("To make a new one use this.\n\r", ch);
		printf_to_char(ch, "editslay %s %s new", arg1, arg2);
		return;

	}

	/*
	 * general flag is used for user specific slays
	 */
	if(arg2[0] != '\0' && !str_prefix(arg2, "general"))
	{
		int value;
	    argument = one_argument( argument, arg3);

		if ( arg3[0] == '\0' || !is_number(arg3) )
		{
			send_to_char("{RYou must enter a number also!{x\n\r", ch);
			return;
		}

		value = atoi(arg3);

		/* validate message and set general flag */
		for(smIndex=SMHead; smIndex != NULL; smIndex=smIndex->SMnext)
		{
			if(!str_cmp( smIndex->Slay_Name, arg1))
			{
				printf_to_char(ch, "Slay named %s set as general %d.\n\r", 
					smIndex->Slay_Name, value);
				if(!value)
					smIndex->Char_Name = str_dup("");
				else
					smIndex->Char_Name = str_dup(ch->name);
				save_slaym();
				return;
			}
		}

		send_to_char("That is not a slay name!\n\r", ch);
		send_to_char("To make a new one use this.\n\r", ch);
		printf_to_char(ch, "editslay %s %s new", arg1, arg2);
		return;

	}

	/*
	 * check and set show messages for slay commands
	 */
	if(arg2[0] != '\0' && !str_prefix(arg2, "victim")
		|| arg2[0] != '\0' && !str_prefix(arg2, "char")
		|| arg2[0] != '\0' && !str_prefix(arg2, "room"))
	{
		/* check show value */
		if ( argument[0] == '\0' )
		{
			send_to_char("{RYou must enter a text associated to be seen!{x\n\r", ch);
			return;
		}

		/* find the message in question */
		for(smIndex=SMHead; smIndex != NULL; smIndex=smIndex->SMnext)
		{
			if(!str_cmp( smIndex->Slay_Name, arg1))
			{
				/* victim sees */
				if (!str_cmp(arg2, "victim"))
				{
					printf_to_char(ch, "victim message set to: %s\n\r", argument);
					smIndex->Show_Vict = str_dup(argument);
				}
				/* slayor sees */
				else if (!str_cmp(arg2, "char"))
				{
					printf_to_char(ch, "char message set to: %s\n\r", argument);
					smIndex->Show_Char = str_dup(argument);
				}
				/* room sees */
				else if (!str_cmp(arg2, "room"))
				{
					printf_to_char(ch, "room message set to: %s\n\r", argument);
					smIndex->Show_Room = str_dup(argument);
				}
				else
				{
					/* error */
					send_to_char("Try again!\n\r victim, char or room\n\r", ch);
					return;
				}
				save_slaym();
				return;
			}
		}

		/* error slay name not found */
		send_to_char("That is not a slay name!\n\r", ch);
		send_to_char("To make a new one use this.\n\r", ch);
		printf_to_char(ch, "editslay %s %s new", arg1, arg2);
		return;

	}

	/* list all slay names */
	if(!str_cmp(arg1, "list"))
	{
		for(smIndex=SMHead; smIndex != NULL; smIndex=smIndex->SMnext)
		{
			sName = format_str_len(smIndex->Slay_Name, 14, ALIGN_LEFT);
			strcpy (buf, sName);

			printf_to_char(ch, "Slay Number: %3d Name: %s Owner: %s\n\r", 
				smIndex->Slay_Number, buf, smIndex->Char_Name);
			printf_to_char(ch, "Vict: %s\n\r", smIndex->Show_Vict);
			printf_to_char(ch, "Char: %s\n\r", smIndex->Show_Char);
			printf_to_char(ch, "Room: %s\n\r", smIndex->Show_Room);
			send_to_char("\n\r", ch);
		}
		return;
	}

	/* 
	 * Output a generic error message
	 */
	send_to_char("An error has occured!\n\r", ch);
	return;
}


FIGHT.C
find do_slay and replace with this one

void do_slay (CHAR_DATA * ch, char *argument)
{
	CHAR_DATA *victim;
	char arg[MAX_INPUT_LENGTH];
	char arg2[MAX_INPUT_LENGTH];

	argument = one_argument (argument, arg);
	argument = one_argument (argument, arg2);

	if (arg[0] == '\0') {
		send_to_char ("Slay whom?\n\r", ch);
		return;
	}

	if ((victim = get_char_room (ch, arg)) == NULL)
	{
		if (ch->level < ML)
		{
			send_to_char ("They aren't here.\n\r", ch);
			return;
		}
		else
		{
			if ((victim = get_char_world (ch, arg)) == NULL)
			{
				send_to_char ("They aren't here.\n\r", ch);
				return;
			}
		}

	}

	if (ch == victim) 
	{
		send_to_char ("Suicide is a mortal sin.\n\r", ch);
		return;
	}

	if (!IS_NPC (victim) && victim->level >= get_trust (ch)) 
	{
		send_to_char ("You failed.\n\r", ch);
		return;
	}

	/* check slay message list */
	if(arg2[0] != '\0' && ALLOW_MULTI_SLAY)
	{
		SLAY_MESSAGE *smIndex;
		char buf[MSL];
		char *sName;
		int cnt = 0;

		if(!str_cmp(arg2, "list"))
		{
			send_to_char("Available slay types to you are:\n\r", ch);
			/*
			 * Loop through the slay index
			 * Show all slays with Character name or no name
			 * Edit slay name to 19 characters excluding color
			 * Show list as 4 across
			 */
			for(smIndex=SMHead; smIndex != NULL; smIndex=smIndex->SMnext)
			{
				if(!str_cmp(smIndex->Char_Name, ch->name)
					|| smIndex->Char_Name[0] == '\0')
				{
					sName = format_str_len(smIndex->Slay_Name, 19, ALIGN_LEFT);
					strcpy (buf, sName);

					printf_to_char(ch, "%s ", smIndex->Slay_Name);
					cnt++;

					if(cnt >= 4)
					{
						send_to_char("\n\r", ch);
						cnt = 0;
					}
				}
			}
			send_to_char("\n\r", ch);
			return;
		}


		for(smIndex=SMHead; smIndex != NULL; smIndex=smIndex->SMnext)
		{
			if(!str_cmp(arg2, smIndex->Slay_Name)
				&& smIndex->Char_Name[0] == '\0'
				|| !str_cmp(arg2, smIndex->Slay_Name)
				&& !str_cmp(smIndex->Char_Name, ch->name))
			{
				act (smIndex->Show_Char, ch, NULL, victim, TO_CHAR);
				act (smIndex->Show_Vict, ch, NULL, victim, TO_VICT);
				act (smIndex->Show_Room, ch, NULL, victim, TO_NOTVICT);

				if(!IS_NPC(victim))
					victim->pcdata->slay_cnt += 1;
				raw_kill (victim);
				return;
			}
		}
	}

	act ("{1You slay $M in cold blood!{x", ch, NULL, victim, TO_CHAR);
	act ("{1$n slays you in cold blood!{x", ch, NULL, victim, TO_VICT);
	act ("{1$n slays $N in cold blood!{x", ch, NULL, victim, TO_NOTVICT);

	if(!IS_NPC(victim))
		victim->pcdata->slay_cnt += 1;

	raw_kill (victim);
	return;
}



Place the code between the snips here into a file named slay.txt and place that file in a directory
called text. This file is your new custom slay messages file and is where all the slay messages will
be stored. I have provided a basic slay message OLC type editor in my do_edit_slay command found
above. If you wish to not use this command then either disable it or ignore it.

Below this slay.txt file i have provided you a help entry for these new functions

Last the command format_str_len is another one of my snippets and should be installed with or before
this code. printf_to_char is by another author though i am not sure of his name.

--------------SNIP   create slay.txt by cutting the lines that follow and placing into a file slay.txt
#
Snmbr 0
SName ribcage~
PName ~
TVict {W$n {Gfound the quickest way to your {rheart{G, through your {RRIBCAGE{G! Then $e shows it to you.{x~
TChar {GYou rip through {W$N's {RRIBCAGE {Gand tear out $S still beating {rheart{G!{x~
TRoom {W$n {rrips {Gthrough {W$N's {Gchest and removes $S still beating {rheart{G!{x~
#
Snmbr 100
SName wayaspa~
PName Taka~
TVict {GWith a sharp pain {W$n {Gsinks $s {wteeth {Ginto your flesh and you life slips away!{x~
TChar {GYou bite into $S flesh and savor their life as it drains from their body!{x~
TRoom {W$n {Gsinks $s {wteeth {Ginto {W$N's {Gflesh and watches as $E dies slowly and painfully!{x~
#
Snmbr 999
SName ~
PName ~
TVict {W$n {Gslays you in {Bcold {rblood{G!{x~
TChar {RYou have been killed!{x~
TRoom {W$n {Gslays {W$N {Gin {Bcold {rblood{G!{x~
$


---------------SNIP help entry should be
118 EDITSLAY SLAY~
Slay Version 2.0 by Taka of the GhostMUD project.
(c) 2001 all rights reserved

EDITSLAY <name> <option> <text>

name - the name of the slay command desired.

options
NAME - sets the slay name to the value in the text field
       * if text has the word new you will create a new slay type with the
         name supplied,
GENERAL - If text = 1 then the slay message is user specific
        - If text = 0 then the slay message can be used by all
VICTIM - This is what the victim see when you use this slay type
CHAR   - This is what the slayor see when they slay a victim with this slay 
         type
ROOM   - This is what the room sees when you slay a victim with this slay type

By using VICTIM, CHAR, ROOM you are changing the actual message seen by the
party involved with whatever is in your text field.


This command allows you to edit the slay types changing and creating new slays.
The options above let you customize and create new slay types and allow the
immortals the ability to slay mortals in more than the drab old way.

To create a new slay type you must first use the command to create a new slay
type. EDITSLAY <name> NAME NEW
Where you see <name> would be the name of the new slay type.

-Taka
a_ghost_dancer@excite.com

SPECIAL NOTE: You can use $N,$n,$E,$e and any other social options for
              the messages since it is still edited through act.
~

0 SNIPPETS~
Custom Slay snippet V2.0 by Taka of Ghost dancer mud.
Taka can be reached at a_ghost_dancer@excite.com
~

117 SLAY~
SLAY <name> <type>

This new slay command by Taka allows you to slay persons in a number of
predefined ways. A command to list these slays which are available to you
has been provided in the slay function. Type this SLAY <name> LIST
~