area/
build/testing/
log/
player/
player/backup/
/***************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
 *                                                                         *
 *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
 *  Chastain, Michael Quan, and Mitchell Tse.                              *
 *                                                                         *
 *  In order to use any part of this Merc Diku Mud, you must comply with   *
 *  both the original Diku license in 'license.doc' as well the Merc       *
 *  license in 'license.txt'.  In particular, you may not remove either of *
 *  these copyright notices.                                               *
 *                                                                         *
 *  Much time and thought has gone into this software and you are          *
 *  benefitting.  We hope that you share your changes too.  What goes      *
 *  around, comes around.                                                  *
 ***************************************************************************/
#include <glib.h>

#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 <merc.h>
#include <interp.h>


/*
 * The following special functions are available for mobiles.
 */
DECLARE_SPEC_FUN(	spec_breath_any		);
DECLARE_SPEC_FUN(	spec_breath_acid	);
DECLARE_SPEC_FUN(	spec_breath_fire	);
DECLARE_SPEC_FUN(	spec_breath_frost	);
DECLARE_SPEC_FUN(	spec_breath_gas		);
DECLARE_SPEC_FUN(	spec_breath_lightning	);
DECLARE_SPEC_FUN(	spec_cast_adept		);
DECLARE_SPEC_FUN(	spec_cast_cleric	);
DECLARE_SPEC_FUN(	spec_cast_judge		);
DECLARE_SPEC_FUN(	spec_cast_mage		);
DECLARE_SPEC_FUN(	spec_cast_undead	);
DECLARE_SPEC_FUN(	spec_fido		);
DECLARE_SPEC_FUN(	spec_guard		);
DECLARE_SPEC_FUN(	spec_janitor		);
DECLARE_SPEC_FUN(	spec_mayor		);
DECLARE_SPEC_FUN(	spec_questmaster	);
DECLARE_SPEC_FUN(	spec_poison		);
DECLARE_SPEC_FUN(	spec_thief		);
DECLARE_SPEC_FUN(	spec_eater		);
DECLARE_SPEC_FUN(	spec_gremlin_original	);
DECLARE_SPEC_FUN(	spec_gremlin_born	);
DECLARE_SPEC_FUN(	spec_rogue		);
DECLARE_SPEC_FUN(	spec_clan_guardian	);
DECLARE_SPEC_FUN(	spec_clan_sabbat	);
DECLARE_SPEC_FUN(	spec_clan_camarilla	);
DECLARE_SPEC_FUN(	spec_clan_spiritknights	);
DECLARE_SPEC_FUN(	spec_clan_werewolf	);
DECLARE_SPEC_FUN(	spec_kavir_guardian	);
DECLARE_SPEC_FUN(	spec_zombie_lord	);
DECLARE_SPEC_FUN(	spec_dog		);
DECLARE_SPEC_FUN(	spec_puff		);
DECLARE_SPEC_FUN(	spec_assassin		);
DECLARE_SPEC_FUN(	spec_pagan_member	);
DECLARE_SPEC_FUN(	spec_christian_member	);
DECLARE_SPEC_FUN(	spec_patrol_knight	);
DECLARE_SPEC_FUN(	spec_healer     	);
DECLARE_SPEC_FUN(	spec_plaguebear     	);
DECLARE_SPEC_FUN(	spec_mage_guard     	);

const   struct  spec_type    spec_table[] =
{
	{	"spec_mage_guard",		spec_mage_guard	},
	{	"spec_clan_guardian",		spec_clan_guardian	},
	{	"spec_clan_sabbat",		spec_clan_sabbat	},
	{	"spec_clan_camarilla",		spec_clan_camarilla	},
	{	"spec_clan_werewolf",		spec_clan_werewolf	},
	{	"spec_kavir_guardian",		spec_kavir_guardian	},
	{	"spec_breath_any",		spec_breath_any		},
	{	"spec_breath_acid",		spec_breath_acid	},
	{	"spec_breath_fire",		spec_breath_fire	},
	{	"spec_breath_frost",		spec_breath_frost	},
	{	"spec_breath_gas",		spec_breath_gas		},
	{	"spec_breath_lightning",	spec_breath_lightning	},	
	{	"spec_cast_adept",		spec_cast_adept		},
	{	"spec_cast_cleric",		spec_cast_cleric	},
	{	"spec_cast_judge",		spec_cast_judge		},
	{	"spec_cast_mage",		spec_cast_mage		},
	{	"spec_cast_undead",		spec_cast_undead	},
	{	"spec_questmaster",		spec_questmaster	},
	{	"spec_fido",			spec_fido		},
	{	"spec_guard",			spec_guard		},
	{	"spec_rogue",			spec_rogue		},
	{	"spec_janitor",			spec_janitor		},
	{	"spec_mayor",			spec_mayor		},
	{	"spec_poison",			spec_poison		},
	{	"spec_thief",			spec_thief		},
	{	"spec_assassin",		spec_assassin	        },
	{	"spec_zombie_lord",             spec_zombie_lord        },
	{	"spec_gremlin_original",        spec_gremlin_original   },
	{	"spec_gremlin_born",            spec_gremlin_born       },
	{	"spec_puff",                    spec_puff               },
	{	"spec_pagan_member",            spec_pagan_member       },
	{	"spec_christian_member",        spec_christian_member   },
	{	"spec_patrol_knight",           spec_patrol_knight      },
	{	"spec_healer", 	                spec_healer             },
	{	"spec_plaguebear",              spec_plaguebear         },
	{	NULL,				NULL			}
};

/*
 * Given a name, return the appropriate spec fun.
 */
SPEC_FUN *spec_lookup( const char *name )
{
	int i;
	
	for ( i = 0; spec_table[i].name != NULL; i++)
	{
		if (LOWER(name[0]) == LOWER(spec_table[i].name[0])
			&&  !str_prefix( name,spec_table[i].name))
			return spec_table[i].function;
	}
	
	return 0;
}

char *spec_name( SPEC_FUN *function)
{
	int i;
	
	for (i = 0; spec_table[i].function != NULL; i++)
	{
		if (function == spec_table[i].function)
			return spec_table[i].name;
	}
	
	return NULL;
}


bool spec_questmaster (CHAR_DATA *ch)
{
	if (ch->fighting != NULL) return spec_cast_mage( ch );
	return FALSE;
}

/* A procedure for Puff the Fractal Dragon--> it gives her an attitude.
	Note that though this procedure may make Puff look busy, she in
	fact does nothing quite more often than she did in Merc 1.0;
	due to null victim traps, my own do-nothing options, and various ways
	to return without doing much, Puff is... well, not as BAD of a gadfly
	as she may look, I assure you.  But I think she's fun this way ;)

	(btw--- should you ever want to test out your socials, just tweak
	the percentage table ('silliness') to make her do lots of socials,
	and then go to a quiet room and load up about thirty Puffs... ;) 
			
		written by Seth of Rivers of Mud         */

bool spec_puff( CHAR_DATA *ch )
{
	char buf[MAX_STRING_LENGTH];
	int rnd_social, sn, silliness;
	bool pc_found = TRUE;
	CHAR_DATA *v_next;
	CHAR_DATA *wch;
	CHAR_DATA *wch_next;
	CHAR_DATA *nch;
	CHAR_DATA *ch_next;
	CHAR_DATA *vch;
	CHAR_DATA *vch_next;
	CHAR_DATA *victim;
	extern int social_count;
	
	if ( !IS_AWAKE(ch) )
		return FALSE;
	
	victim = NULL;
	
/* Here's Furey's aggress routine, with some surgery done to it.  
  	All it does is pick a potential victim for a social.  
  	(Thank you, Furey-- I screwed this up many times until I
  	learned of your way of doing it)                      */
	
	for ( wch = char_list; wch != NULL; wch = wch_next )
	{
		wch_next = wch->next;
		if ( IS_NPC(wch)
			||   wch->in_room == NULL )
			continue;
		
		for ( nch = wch->in_room->people; nch != NULL; nch = ch_next )
		{
			int count;
			
			ch_next	= nch->next_in_room;
			
			if ( !IS_NPC(nch) 
				||   number_bits(1) == 0)
				continue;
			
	    /*
	     * Ok we have a 'wch' player character and a 'nch' npc aggressor.
	     * Now make the aggressor fight a RANDOM pc victim in the room,
	     *   giving each 'vch' an equal chance of selection.
	     */
			count	= 0;
			victim	= NULL;
			for ( vch = wch->in_room->people; vch != NULL; vch = vch_next )
			{
				vch_next = vch->next_in_room;
				
				if ( !IS_NPC(vch) )
				{
					if ( number_range( 0, count ) == 0 )
						victim = vch;
					count++;
				}
			}
			
			if (victim == NULL)
				return FALSE;
		}
		
	}
	rnd_social = (number_range (0, ( social_count - 1)) );
	
	/* Choose some manner of silliness to perpetrate.  */
	
	if ( number_percent() > 2 )
		return TRUE;
	
	silliness = number_range (1, 100);
	
	switch (silliness)	
	{
		case 1:
			sprintf( buf, "Puff Version 2.2 (SpiralSoft)");
			do_say ( ch, buf);
			break;
		case 2:
			sprintf( buf, "I could kill you in one hit, ya lamer!");
			do_say ( ch, buf);
			break;
		case 3:
			sprintf( buf, "Bah! Vampires SUCK!");
			do_say ( ch, buf);
			break;
		case 4:
			sprintf( buf, "Bah! Mages SUCK!");
			do_say ( ch, buf);
			break;
		case 5:
			sprintf( buf, "Bah! Werewolves SUCK!");
			do_say ( ch, buf);
			break;
		case 6:
			sprintf( buf, "One of these days.. spiral's going to hook me up to a lexer.. then I'm gonna rule!");
			do_say ( ch, buf);
			break;
        case 7:
			sprintf( buf, "So, know any good jokes?");
			do_say ( ch, buf);
			break;
        case 8:
			sprintf( buf, "Hey what do you expect? I'm just coded in C!");
			do_say ( ch, buf);
			break;
        case 9:
			sprintf( buf, "I love it when I get new things to say.");
			do_say ( ch, buf);
			break;
        case 11:
			sprintf( buf, "I'm so kewl... I'm automated :P");
			do_say ( ch, buf);
			break;
        case 16:
			sprintf( buf, "Arcite's Busy and Spiral went insane.. I'm wondering if your question is that important.");
			do_say ( ch, buf);
			break;
		case 17:
			sprintf( buf, "Be afraid! Dominion is Back! and Spiral's Dedicated to Werewolves! ");
			do_say ( ch, buf);
			break;
		case 19:
			sprintf( buf, "Talon's a dumb ass.. check it out, www.fuktalon.com");
			do_say ( ch, buf);
			break;
		case 20:
			sprintf( buf, "I hear Spiral's single again.");
			do_say ( ch, buf);
			break;
		case 21:
			sprintf( buf, "I hear Dominion's single again.");
			do_say ( ch, buf);
			break;
		case 25:
			sprintf( buf, "I can break you in two!");
			do_say ( ch, buf);
			break;
		case 27:
			sprintf( buf, "Hey stupid.");
			do_say ( ch, buf);
			break;
		case 29:
			sprintf( buf, "I heard the other day that someone is trying to kill me.");
			do_say ( ch, buf);
			break;
		case   30:
			sprintf( buf, "I don't like the drugs, but the drugs like me!"); 
			do_say ( ch, buf);
			break;
		case 35:
			sprintf( buf, "Damn Spiral can't code me right.");
			do_say ( ch, buf);
			break;
		case 36:
			sprintf( buf, "Does Dominion know your cheating?");
			do_say ( ch, buf);
			break;
		case 37:
			sprintf( buf, "Oh I'm sorry did you say something?");
			do_say ( ch, buf);
			break;
		case 40:
			sprintf( buf, "Spiral's the man!");
			do_say ( ch, buf);
			break;
		case 45:
			sprintf( buf, "Did you know I'm the real Imp?");
			do_say ( ch, buf);
			break;
		case 55:
			sprintf( buf, "Did you know that I'm written in Perl?");
			do_say ( ch, buf);
			break;
		case 57:
			sprintf( buf, "Dominion is the man!");
			do_say ( ch, buf);
			break;
		case 60:
			sprintf( buf, "PBackup, Do it often, but don't do it.. if your character has problems.");
			do_ooc ( ch, buf);
			break;
		case 63:
			sprintf( buf, "Hey, I can't belive spiral did that!");
			do_say ( ch, buf);
			break;
		case 65:
			sprintf( buf, "You sure are ugly!");
			do_say ( ch, buf);
			break;
        case 68:
            sprintf( buf, "One of these days.. One of these days.. POW! right in the kisser!");
            do_say(ch,buf);
            break;
        case 100:
			sprintf( buf, "Welcome to Lurking Fear II! Home of the whiners!");
			do_say ( ch, buf);
			break;
		case 75:
			act( social_table[rnd_social].others_no_arg, 
				ch, NULL, NULL, TO_ROOM    );
			act( social_table[rnd_social].char_no_arg,   
				ch, NULL, NULL, TO_CHAR    );
			break;
		default:
			if ( (!pc_found)
				|| 	 (victim != ch->in_room->people) ) 
				return FALSE;
			act( social_table[rnd_social].others_found, 
				ch, NULL, victim, TO_NOTVICT );
			act( social_table[rnd_social].char_found,  
				ch, NULL, victim, TO_CHAR    );
			act( social_table[rnd_social].vict_found, 
				ch, NULL, victim, TO_VICT    );
			break;
		case 97:	
			act( "For a moment, $n flickers and phases.", 
				ch, NULL, NULL, TO_ROOM );
			act( "For a moment, you flicker and phase.", 
				ch, NULL, NULL, TO_CHAR );
			break;
			
/* The Fractal Dragon sometimes teleports herself around, to check out
	new and stranger things.  HOWEVER, to stave off some possible Puff
	repop problems, and to make it possible to play her as a mob without
	teleporting helplessly, Puff does NOT teleport if she's in Limbo,
	OR if she's not fighting or standing.  If you're playing Puff and 
	you want to talk with someone, just rest or sit!
*/
			
		case 78:
			if (ch->position < POS_FIGHTING)
			{
				act( "For a moment, $n seems lucid...", 
					ch, NULL, NULL, TO_ROOM );
				act( "   ...but then $e returns to $s contemplations once again.", 
					ch, NULL, NULL, TO_ROOM );
				act( "For a moment, the world's mathematical beauty is lost to you!",
					ch, NULL, NULL, TO_CHAR );
				act( "   ...but joy! yet another novel phenomenon seizes your attention.", 
					ch, NULL, NULL, TO_CHAR);
				return TRUE;
			}
			if ( ( sn = skill_lookup( "teleport" ) ) < 0 )
				return FALSE;
			(*skill_table[sn].spell_fun) ( sn, ch->level, ch, ch );
	}
	
	
/* Puff has only one spell, and it's the most annoying one, of course.
  	(excepting energy drain, natch)  But to a bemused mathematician,
  	what could possibly be a better resolution to conflict? ;) 
  	Oh-- and notice that Puff casts her one spell VERY well.     */
	
	if ( ch->position != POS_FIGHTING )
		return FALSE;
	
	for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
	{
		v_next = victim->next_in_room;
		if ( victim->fighting == ch && number_bits( 2 ) == 0 )
			break;
	}
	
	if ( victim == NULL )
		return FALSE;
	
	if ( ( sn = skill_lookup( "teleport" ) ) < 0 )
		return FALSE;
	(*skill_table[sn].spell_fun) ( sn, 50, ch, victim );
	return TRUE;
	
}

/*
 * Core procedure for dragons.
 */
bool dragon( CHAR_DATA *ch, char *spell_name )
{
	CHAR_DATA *victim;
	CHAR_DATA *v_next;
	int sn;
	
	if ( ch->position != POS_FIGHTING )
		return FALSE;
	
	for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
	{
		v_next = victim->next_in_room;
		if ( victim->fighting == ch && number_bits( 2 ) == 0 )
			break;
	}
	
	if ( victim == NULL )
		return FALSE;
	
	if ( ( sn = skill_lookup( spell_name ) ) < 0 )
		return FALSE;
	(*skill_table[sn].spell_fun) ( sn, ch->level, ch, victim );
	return TRUE;
}

bool spec_assassin( CHAR_DATA *ch )
{
	char buf[MAX_STRING_LENGTH];
	CHAR_DATA *victim;
    /* CHAR_DATA *v_next; */ 
	int rnd_say;
	
	if ( ch->fighting != NULL )
		return FALSE;
	
	for ( victim = ch->in_room->people; victim != NULL; victim = victim->next_in_room )
	{
               /* this should kill mobs as well as players */
		if (victim->creature != 2)  /* thieves */
			break;
	}
	
	if ( victim == NULL || victim == ch || IS_IMMORTAL(victim) )
		return FALSE;
	if ( victim->level > ch->level + 7 || IS_NPC(victim))
		return FALSE;
	
	rnd_say = number_range (1, 10);
	
	if ( rnd_say <= 5)
		sprintf( buf, "Death is the true end.");
	else if ( rnd_say <= 6)
		sprintf( buf, "Time to die...");
	else if ( rnd_say <= 7)
		sprintf( buf, "Cabrone..."); 
	else if ( rnd_say <= 8)
		sprintf( buf, "Welcome to your fate...");
	else if ( rnd_say <= 9)
		sprintf( buf, "Death to the stupid!");
	else if ( rnd_say <= 10)
		sprintf( buf, "Ever dance with the devil?"); 
	
	do_say( ch, buf );
	multi_hit( ch, victim, gsn_backstab );
	return TRUE;
}


/*
 * Special procedures for mobiles.
 */
bool spec_breath_any( CHAR_DATA *ch )
{
	if ( ch->position != POS_FIGHTING )
		return FALSE;
	
	switch ( number_bits( 3 ) )
	{
		case 0: return spec_breath_fire		( ch );
		case 1:
		case 2: return spec_breath_lightning	( ch );
		case 3: return spec_breath_gas		( ch );
		case 4: return spec_breath_acid		( ch );
		case 5:
		case 6:
		case 7: return spec_breath_frost		( ch );
	}
	
	return FALSE;
}



bool spec_breath_acid( CHAR_DATA *ch )
{
	return dragon( ch, "acid breath" );
}



bool spec_breath_fire( CHAR_DATA *ch )
{
	return dragon( ch, "fire breath" );
}



bool spec_breath_frost( CHAR_DATA *ch )
{
	return dragon( ch, "frost breath" );
}



bool spec_breath_gas( CHAR_DATA *ch )
{
	int sn;
	
	if ( ch->position != POS_FIGHTING )
		return FALSE;
	
	if ( ( sn = skill_lookup( "gas breath" ) ) < 0 )
		return FALSE;
	(*skill_table[sn].spell_fun) ( sn, ch->level, ch, NULL );
	return TRUE;
}



bool spec_breath_lightning( CHAR_DATA *ch )
{
	return dragon( ch, "lightning breath" );
}



bool spec_cast_adept( CHAR_DATA *ch )
{
	CHAR_DATA *victim;
	CHAR_DATA *v_next;
	
	if ( !IS_AWAKE(ch) )
		return FALSE;
	
	for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
	{
		v_next = victim->next_in_room;
		if ( victim != ch && can_see( ch, victim ) && number_bits( 1 ) == 0 )
			break;
	}
	
	if ( victim == NULL )
		return FALSE;
	
	switch ( number_bits( 3 ) )
	{
		case 0:
			act( "$n utters the word 'tehctah'.", ch, NULL, NULL, TO_ROOM );
			spell_armor( skill_lookup( "armor" ), ch->level, ch, victim );
			return TRUE;
			
		case 1:
			act( "$n utters the word 'nhak'.", ch, NULL, NULL, TO_ROOM );
			spell_bless( skill_lookup( "bless" ), ch->level, ch, victim );
			return TRUE;
			
		case 2:
			act( "$n utters the word 'yeruf'.", ch, NULL, NULL, TO_ROOM );
			spell_cure_blindness( skill_lookup( "cure blindness" ),
				ch->level, ch, victim );
			return TRUE;
			
		case 3:
			act( "$n utters the word 'garf'.", ch, NULL, NULL, TO_ROOM );
			spell_cure_light( skill_lookup( "cure light" ),
				ch->level, ch, victim );
			return TRUE;
			
		case 4:
			act( "$n utters the words 'rozar'.", ch, NULL, NULL, TO_ROOM );
			spell_cure_poison( skill_lookup( "cure poison" ),
				ch->level, ch, victim );
			return TRUE;
			
		case 5:
			act( "$n utters the words 'nadroj'.", ch, NULL, NULL, TO_ROOM );
			spell_refresh( skill_lookup( "refresh" ), ch->level, ch, victim );
			return TRUE;
			
	}
	
	return FALSE;
}



bool spec_cast_cleric( CHAR_DATA *ch )
{
	CHAR_DATA *victim;
	CHAR_DATA *v_next;
	char *spell;
	int sn;
	
	if ( ch->position != POS_FIGHTING )
		return FALSE;
	
	for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
	{
		v_next = victim->next_in_room;
		if ( victim->fighting == ch && number_bits( 2 ) == 0 )
			break;
	}
	
	if ( victim == NULL )
		return FALSE;
	
	for ( ;; )
	{
		int min_level;
		
		switch ( number_bits( 4 ) )
		{
			case  0: min_level =  0; spell = "blindness";      break;
			case  1: min_level =  3; spell = "cause serious";  break;
			case  2: min_level =  7; spell = "earthquake";     break;
			case  3: min_level =  9; spell = "cause critical"; break;
			case  4: min_level = 10; spell = "dispel evil";    break;
			case  5: min_level = 12; spell = "curse";          break;
			case  6: min_level = 12; spell = "change sex";     break;
			case  7: min_level = 13; spell = "flamestrike";    break;
			case  8: min_level = 13; spell = "plague";	   break;
			case  9:
			case 10: min_level = 15; spell = "harm";           break;
			default: min_level = 16; spell = "dispel magic";   break;
		}
		
		if ( ch->level >= min_level )
			break;
	}
	
	if ( ( sn = skill_lookup( spell ) ) < 0 )
		return FALSE;
	(*skill_table[sn].spell_fun) ( sn, ch->level, ch, victim );
	return TRUE;
}



bool spec_cast_judge( CHAR_DATA *ch )
{
	CHAR_DATA *victim;
	CHAR_DATA *v_next;
	char *spell;
	int sn;
	
	if ( ch->position != POS_FIGHTING )
		return FALSE;
	
	for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
	{
		v_next = victim->next_in_room;
		if ( victim->fighting == ch && number_bits( 2 ) == 0 )
			break;
	}
	
	if ( victim == NULL )
		return FALSE;
	
	spell = "high explosive";
	if ( ( sn = skill_lookup( spell ) ) < 0 )
		return FALSE;
	(*skill_table[sn].spell_fun) ( sn, ch->level, ch, victim );
	return TRUE;
}



bool spec_cast_mage( CHAR_DATA *ch )
{
	CHAR_DATA *victim;
	CHAR_DATA *v_next;
	char *spell;
	int sn;
	
	if ( ch->position != POS_FIGHTING )
		return FALSE;
	
	for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
	{
		v_next = victim->next_in_room;
		if ( victim->fighting == ch && number_bits( 2 ) == 0 )
			break;
	}
	
	if ( victim == NULL )
		return FALSE;
	
	for ( ;; )
	{
		int min_level;
		
		switch ( number_bits( 4 ) )
		{
			case  0: min_level =  0; spell = "blindness";      break;
			case  1: min_level =  3; spell = "chill touch";    break;
			case  2: min_level =  7; spell = "weaken";         break;
			case  3: min_level =  8; spell = "teleport";       break;
			case  4: min_level = 11; spell = "colour spray";   break;
			case  5: min_level = 12; spell = "change sex";     break;
			case  6: min_level = 13; spell = "energy drain";   break;
			case  7:
			case  8: min_level = 13; spell = "plague";	   break;
			case  9: min_level = 15; spell = "fireball";       break;
			default: min_level = 20; spell = "acid blast";     break;
		}
		
		if ( ch->level >= min_level )
			break;
	}
	
	if ( ( sn = skill_lookup( spell ) ) < 0 )
		return FALSE;
	(*skill_table[sn].spell_fun) ( sn, ch->level, ch, victim );
	return TRUE;
}



bool spec_cast_undead( CHAR_DATA *ch )
{
	CHAR_DATA *victim;
	CHAR_DATA *v_next;
	char *spell;
	int sn;
	
	if ( ch->position != POS_FIGHTING )
		return FALSE;
	
	for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
	{
		v_next = victim->next_in_room;
		if ( victim->fighting == ch && number_bits( 2 ) == 0 )
			break;
	}
	
	if ( victim == NULL )
		return FALSE;
	
	for ( ;; )
	{
		int min_level;
		
		switch ( number_bits( 4 ) )
		{
			case  0: min_level =  0; spell = "curse";          break;
			case  1: min_level =  3; spell = "weaken";         break;
			case  2: min_level =  6; spell = "chill touch";    break;
			case  3: min_level =  9; spell = "blindness";      break;
			case  4: min_level = 12; spell = "poison";         break;
			case  5: min_level = 15; spell = "energy drain";   break;
			case  6: min_level = 18; spell = "harm";           break;
			case  7: min_level = 21; spell = "teleport";       break;
			case  8: min_level = 13; spell = "plague";	   break;
			default: min_level = 24; spell = "gate";           break;
		}
		
		if ( ch->level >= min_level )
			break;
	}
	
	if ( ( sn = skill_lookup( spell ) ) < 0 )
		return FALSE;
	(*skill_table[sn].spell_fun) ( sn, ch->level, ch, victim );
	return TRUE;
}



bool spec_fido( CHAR_DATA *ch )
{
	OBJ_DATA *corpse;
	OBJ_DATA *c_next;
	OBJ_DATA *obj;
	OBJ_DATA *obj_next;
	
	if ( !IS_AWAKE(ch) )
		return FALSE;
	
	for ( corpse = ch->in_room->contents; corpse != NULL; corpse = c_next )
	{
		c_next = corpse->next_content;
		if ( corpse->item_type != ITEM_CORPSE_NPC )
			continue;
		
		act( "$n savagely devours a corpse.", ch, NULL, NULL, TO_ROOM );
		for ( obj = corpse->contains; obj; obj = obj_next )
		{
			obj_next = obj->next_content;
			obj_from_obj( obj );
			obj_to_room( obj, ch->in_room );
		}
		if (corpse != NULL) extract_obj( corpse );
		return TRUE;
	}
	
	return FALSE;
}



bool spec_guard( CHAR_DATA *ch )
{
	char buf[MAX_STRING_LENGTH];
	CHAR_DATA *victim;
	CHAR_DATA *v_next;
	CHAR_DATA *ech;
	int max_evil;
	int rand;
	
	if ( !IS_AWAKE(ch) || ch->fighting != NULL )
		return FALSE;
	
	max_evil = 300;
	ech      = NULL;
	
	for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
	{
		v_next = victim->next_in_room;
		
		if ( !IS_NPC(victim) && IS_EXTRA(victim, EXTRA_AWE) && number_percent() > 95)
	    break;

		if ( victim->fighting != NULL
			&&   victim->fighting != ch
			&&   victim->alignment < max_evil )
		{
			max_evil = victim->alignment;
			ech      = victim;
		}
	}
	
	if ( victim != NULL )
	{
		rand=number_range(1,5);
		if (rand == 1)
		{
			sprintf( buf, "It is an honour to meet you, %s!",
				victim->name->str);
			do_say( ch, buf );
		}
		else if (rand == 2)
		{
			act("You bow deeply before $N.",ch,NULL,victim,TO_CHAR);
			act("$n bows deeply before you.",ch,NULL,victim,TO_VICT);
			act("$n bows deeply before $N.",ch,NULL,victim,TO_NOTVICT);
		}
		else if (rand == 3)
		{
			act("You shake $N's hand.",ch,NULL,victim,TO_CHAR);
			act("$n shakes your hand.",ch,NULL,victim,TO_VICT);
			act("$n shakes $N's hand.",ch,NULL,victim,TO_NOTVICT);
			sprintf( buf, "It's a pleasure to see you again, %s!",
				victim->name->str);
			do_say( ch, buf );
		}
		else if (rand == 4)
		{
			act("You pat $N on the back.",ch,NULL,victim,TO_CHAR);
			act("$n pats you on the back.",ch,NULL,victim,TO_VICT);
			act("$n pats $N on the back.",ch,NULL,victim,TO_NOTVICT);
			sprintf( buf, "Greetings %s!  If you need anything, just say!",
				victim->name->str);
			do_say( ch, buf );
		}
		else
		{
			act("You beam a smile at $N.",ch,NULL,victim,TO_CHAR);
			act("$n beams a smile at you.",ch,NULL,victim,TO_VICT);
			act("$n beams a smile at $N.",ch,NULL,victim,TO_NOTVICT);
		}
		return TRUE;
	}
	
	if ( ech != NULL )
	{
		if (!IS_NPC(ech) && IS_EXTRA(ech, EXTRA_AWE))
		{
	    	sprintf( buf, "How DARE you attack %s? You shall DIE!",
	        ech->name->str);
	    	do_say( ch, buf );
	    	do_rescue( ch, ech->name->str );
	    	return TRUE;
		}
		act( "$n screams 'PROTECT THE INNOCENT!!  BANZAI!!",
			ch, NULL, NULL, TO_ROOM );
		multi_hit( ch, ech, TYPE_UNDEFINED );
		return TRUE;
	}
	
	return FALSE;
}



bool spec_janitor( CHAR_DATA *ch )
{
	OBJ_DATA *trash;
	OBJ_DATA *trash_next;
	
	if ( !IS_AWAKE(ch) )
		return FALSE;
	
	for ( trash = ch->in_room->contents; trash != NULL; trash = trash_next )
	{
		trash_next = trash->next_content;
		if ( !IS_SET( trash->wear_flags, ITEM_TAKE ) )
			continue;
		if ( trash->item_type == ITEM_DRINK_CON
			||   trash->item_type == ITEM_TRASH
			||   trash->cost < 10 )
		{
			act( "$n picks up some trash.", ch, NULL, NULL, TO_ROOM );
			obj_from_room( trash );
			obj_to_char( trash, ch );
			return TRUE;
		}
	}
	
	return FALSE;
}



bool spec_mayor( CHAR_DATA *ch )
{
	static const char open_path[] =
		"W3a3003b33000c111d0d111Oe333333Oe22c222112212111a1S.";
	
	static const char close_path[] =
		"W3a3003b33000c111d0d111CE333333CE22c222112212111a1S.";
	
	static const char *path;
	static int pos;
	static bool move;
	
	if ( !move )
	{
		if ( time_info.hour ==  6 )
		{
			path = open_path;
			move = TRUE;
			pos  = 0;
		}
		
		if ( time_info.hour == 20 )
		{
			path = close_path;
			move = TRUE;
			pos  = 0;
		}
	}
	
	if ( ch->fighting != NULL )
		return spec_cast_cleric( ch );
	if ( !move || ch->position < POS_SLEEPING )
		return FALSE;
	
	switch ( path[pos] )
	{
		case '0':
		case '1':
		case '2':
		case '3':
			move_char( ch, path[pos] - '0' );
			break;
			
		case 'W':
			ch->position = POS_STANDING;
			act( "$n awakens and groans loudly.", ch, NULL, NULL, TO_ROOM );
			break;
			
		case 'S':
			ch->position = POS_SLEEPING;
			act( "$n lies down and falls asleep.", ch, NULL, NULL, TO_ROOM );
			break;
			
		case 'a':
			act( "$n says 'Hello Honey!'", ch, NULL, NULL, TO_ROOM );
			break;
			
		case 'b':
			act( "$n says 'What a view!  I must do something about that dump!'",
				ch, NULL, NULL, TO_ROOM );
			break;
			
		case 'c':
			act( "$n says 'Vandals!  Youngsters have no respect for anything!'",
				ch, NULL, NULL, TO_ROOM );
			break;
			
		case 'd':
			act( "$n says 'Good day, citizens!'", ch, NULL, NULL, TO_ROOM );
			break;
			
		case 'e':
			act( "$n says 'I hereby declare the city of Midgaard open!'",
				ch, NULL, NULL, TO_ROOM );
			break;
			
		case 'E':
			act( "$n says 'I hereby declare the city of Midgaard closed!'",
				ch, NULL, NULL, TO_ROOM );
			break;
			
		case 'O':
			do_unlock( ch, "gate" );
			do_open( ch, "gate" );
			break;
			
		case 'C':
			do_close( ch, "gate" );
			do_lock( ch, "gate" );
			break;
			
		case '.' :
			move = FALSE;
			break;
	}
	
	pos++;
	return FALSE;
}



bool spec_poison( CHAR_DATA *ch )
{
	CHAR_DATA *victim;
	
	if ( ch->position != POS_FIGHTING
		|| ( victim = ch->fighting ) == NULL
		||   number_percent( ) > 2 * ch->level )
		return FALSE;
	
	act( "You bite $N!",  ch, NULL, victim, TO_CHAR    );
	act( "$n bites $N!",  ch, NULL, victim, TO_NOTVICT );
	act( "$n bites you!", ch, NULL, victim, TO_VICT    );
	spell_poison( gsn_poison, ch->level, ch, victim );
	return TRUE;
}



bool spec_thief( CHAR_DATA *ch )
{
	CHAR_DATA *victim;
	CHAR_DATA *v_next;
	int gold;
	
	if ( ch->position != POS_STANDING )
		return FALSE;
	
	for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
	{
		v_next = victim->next_in_room;
		
		if ( IS_NPC(victim)
			||   (!IS_NPC(victim) && IS_IMMMERIT(victim, IMM_MERIT_STEAL))
			||   victim->level >= LEVEL_IMMORTAL
			||   number_bits( 2 ) != 0
			||   !can_see( ch, victim ) )	/* Thx Glop */
			continue;
		
		if ( IS_AWAKE(victim) && number_range( 0, ch->level ) == 0 )
		{
			act( "You discover $n's hands in your wallet!",
				ch, NULL, victim, TO_VICT );
			act( "$N discovers $n's hands in $S wallet!",
				ch, NULL, victim, TO_NOTVICT );
			return TRUE;
		}
		else
		{
			gold = victim->gold * number_range( 1, 20 ) / 100;
			ch->gold     += 7 * gold / 8;
			victim->gold -= gold;
			return TRUE;
		}
	}
	
	return FALSE;
}

bool spec_eater( CHAR_DATA *ch )
{
  /* The spec_eater is a hungry bugger who eats players.  If they get 
   * eaten, they get transported to the room with the same vnum as the 
   * mob Example:  A spec_eater dragon with the vnum 31305 would send 
   * anybody eaten to room 31305.
   * KaVir.
   */
	CHAR_DATA       *victim;
	ROOM_INDEX_DATA *pRoomIndex;
	if ( ch->position != POS_FIGHTING )
	{
		return FALSE;
	}
	if (number_percent() > 50 ) return FALSE;
	victim=ch->fighting;
	act( "$n stares at $N hungrily and licks $s lips!",  ch, NULL, victim, TO_NOTVICT    );
	act( "$n stares at you hungrily and licks $s lips!",  ch, NULL, victim, TO_VICT    );
	if (number_percent() > 25 ) return FALSE;
	pRoomIndex = get_room_index(ch->pIndexData->vnum);
	act( "$n opens $s mouth wide and lunges at you!", ch, NULL, victim, TO_VICT    );
	act( "$n swallows you whole!", ch, NULL, victim, TO_VICT    );
	act( "$n opens $s mouth wide and lunges at $N!",  ch, NULL, victim, TO_NOTVICT );
	act( "$n swallows $N whole!",  ch, NULL, victim, TO_NOTVICT );
	char_from_room(victim);
	char_to_room(victim,pRoomIndex);
	do_emote(ch,"burps loudly.");
	do_look(victim,"auto");
	return TRUE;
}

bool spec_gremlin_original( CHAR_DATA *ch )
{
	OBJ_DATA *object;
	OBJ_DATA *object_next;
	OBJ_DATA *obj;
	char buf  [MAX_STRING_LENGTH];
	
	if ( !IS_AWAKE( ch ) )
		return FALSE;
	
	if (number_percent() > 25)
	{
		CHAR_DATA *victim;
		CHAR_DATA *v_next;
	/* Lets make this mob DO things!  KaVir */
		int speech;
		speech = number_range(1,8);
		for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
		{
			v_next = victim->next_in_room;
			if ( victim != ch && can_see( ch, victim ) && number_bits( 1 ) == 0 )
				break;
		}
		if ( victim != NULL )
		{
			if (speech == 1) 
			{
				str_cpy(buf,"Anyone got any food? I'm famished!");
				do_say(ch,buf);
			}
			if (speech == 2) do_emote(ch,"rubs his tummy hungrily.");
			if (speech == 3) do_emote(ch,"looks around for any scraps of food.");
			if (speech == 4)
			{
				if(!IS_NPC(victim))
					sprintf(buf,"Excuse me %s, have you got any spare food?",victim->name->str);
				else
					sprintf(buf,"I wonder if %s has got any spare food?",victim->short_descr->str);
				do_say(ch,buf);
			}
			
			if (speech == 5)
			{
				str_cpy(buf,"If you're not hungry, drop that pie for me!");
				do_say(ch,buf);
			}
			if (speech == 6)
			{
				if(!IS_NPC(victim))
					sprintf(buf,"Do you have any food, %s?  Pleeeaaase?",victim->name->str);
				else
					sprintf(buf,"I bet %s has lots of spare food!",victim->short_descr->str);
				do_say(ch,buf);
			}
			if (speech == 7)
			{
				if(!IS_NPC(victim))
					sprintf(buf,"Why won't you give me any food, %s?",victim->name->str);
				else
					sprintf(buf,"Why won't you give me any food, %s?",victim->short_descr->str);
				do_say(ch,buf);
			}
			if (speech == 8)
			{
				if(!IS_NPC(victim))
					sprintf(buf,"I think i'll follow you around for a while, ok %s?",victim->name->str);
				else
					sprintf(buf,"I bet %s has lots of food.",victim->short_descr->str);
				do_say(ch,buf);
				do_follow(ch,victim->name->str);
			}
		}
	/*
        return TRUE;
	*/
	}
	
	do_drop(ch,"all");
	for ( object = ch->in_room->contents; object; object = object_next )
	{
		object_next = object->next_content;
		if ( !IS_SET(object->wear_flags, ITEM_TAKE) )
			continue;
		
		if (object == NULL) continue;
		
		if ( object->item_type == ITEM_FOOD
			|| object->item_type == ITEM_TRASH
			|| object->item_type == ITEM_CORPSE_NPC )
		{
			act( "$n picks $p up.", ch, object, NULL, TO_ROOM );
			obj_from_room( object );
			obj_to_char( object, ch );
			str_cpy(buf,"Ah....foooood....goooood!");
			do_say(ch,buf);
			if (object->item_type == ITEM_CORPSE_NPC) do_get(ch,"all corpse");
			act( "$n eats $p.", ch, object, NULL, TO_ROOM );
			if (object != NULL) extract_obj(object);
			if (number_percent() > 25) return TRUE;
			act( "$n sits down and curls up into a ball.", ch,  NULL, NULL, TO_ROOM );
			act( "You watch in amazement as a cocoon forms around $n.", ch,  NULL, NULL, TO_ROOM );
			obj=create_object(get_obj_index(30008),0);
			obj->value[0] = 30002;
			obj->timer = 1;
			obj_to_room(obj,ch->in_room);
			extract_char(ch,TRUE);
			return TRUE;
		}
	}
	return FALSE;
}

bool spec_gremlin_born( CHAR_DATA *ch )
{
	OBJ_DATA        *object;
	OBJ_DATA        *object_next;
	OBJ_DATA        *obj;
	CHAR_DATA	   *victim;
	EXIT_DATA	   *pexit;
	ROOM_INDEX_DATA *to_room;
	int		   door;
	char            buf [MAX_STRING_LENGTH];
	
   /* When they first appear, they try to equip themselves as best they can */
	if ( ch->max_move == 100 )
	{
		do_get(ch,"all");
		do_wear(ch,"all");
		do_drop(ch,"all");
	}
	ch->max_move = ch->max_move -1;
	if ( ch->max_mana > 249 )
	{
		str_cpy(buf,"I cannot go any further...my task is complete.");
		do_say(ch,buf);
		act( "$n falls to the floor and crumbles into dust.", ch, NULL, NULL, TO_ROOM );
		extract_char(ch,TRUE);
		return TRUE;
	}
	if ( ch->max_move < 5 )
	{
		str_cpy(buf,"Alas, there is not enough food to go around...");
		do_say(ch,buf);
		act( "$n falls to the floor and crumbles into dust.", ch, NULL, NULL, TO_ROOM );
		extract_char(ch,TRUE);
		return TRUE;
	}
	else if (( ch->max_move < 35) && number_percent() > 95 )
		act( "$n's stomach growls with hunger.", ch, NULL, NULL, TO_ROOM );
	
	if ( !IS_AWAKE( ch ) )
		return FALSE;
	
	for ( object = ch->in_room->contents; object; object = object_next )
	{
		object_next = object->next_content;
		if ( !IS_SET(object->wear_flags, ITEM_TAKE) )
			continue;
		
		if (object == NULL) continue;
		
		if ( object->item_type == ITEM_FOOD
			|| object->item_type == ITEM_TRASH
			|| object->item_type == ITEM_CORPSE_NPC )
		{
			act( "$n picks $p up.", ch, object, NULL, TO_ROOM );
			obj_from_room( object );
			obj_to_char( object, ch );
			if (object->item_type == ITEM_CORPSE_NPC) do_get(ch,"all corpse");
			act( "$n eats $p.", ch, object, NULL, TO_ROOM );
			if (object != NULL) extract_obj(object);
			if (ch->max_move < 80) ch->max_move = ch->max_move + 20;
			do_wear(ch,"all");
			do_drop(ch,"all");
	 /* Increase the following if gremlins reproduce too fast, and 
	  * reduce it if they reproduce too slowly.  KaVir.
	  */
			if (ch->max_move > 75 && number_percent() > 25)
			{
				if (ch->pIndexData->vnum == 30004)
					obj=create_object(get_obj_index(30009),0);
				else
				{
					obj=create_object(get_obj_index(30008),0);
					obj->value[0] = 30003;
					if (ch->pIndexData->vnum == 30003)
						obj->value[0] = 30004;
					obj->timer = number_range(8,10);
				}
				act( "$n squats down and lays $p!", ch,  obj, NULL, TO_ROOM );
				obj_to_room(obj,ch->in_room);
				if (number_percent() > 25)
					ch->max_mana = ch->max_mana +50;
			}
			return TRUE;
		}
	}
	
	if ( ch->fighting != NULL )
		return spec_poison( ch );
	
   /* We'll give him 3 chances to find an open door */
	door = number_range(0,5);
	if (((pexit = ch->in_room->exit[door]) == NULL) || (to_room = pexit->to_room) == NULL)
		door = number_range(0,5);
	if (((pexit = ch->in_room->exit[door]) == NULL) || (to_room = pexit->to_room) == NULL)
		door = number_range(0,5);
	if (!(((pexit = ch->in_room->exit[door]) == NULL) || (to_room = pexit->to_room) == NULL))
	{
   	/* If the door is closed they'll have to open it */
		if (IS_SET(pexit->exit_info, EX_CLOSED))
		{
			if (door == 0) do_open(ch,"north");
			if (door == 1) do_open(ch,"east");
			if (door == 2) do_open(ch,"south");
			if (door == 3) do_open(ch,"west");
			if (door == 4) do_open(ch,"up");
			if (door == 5) do_open(ch,"down");
		}
   	/* Now they know where they are going, they have to move */
		move_char(ch,door);
/*	return FALSE; */
	}
   /* Now we check the room for someone to kill */
	for (victim = char_list; victim; victim = victim->next)
	{
		if ( victim->in_room != ch->in_room
			|| !victim->in_room
			|| victim == ch
			|| (!IS_NPC(victim) && IS_HERO(victim) && victim->hit < 0)
			|| ((victim->name == ch->name) && (ch->max_move > 30))
			|| ((victim->level > ch->level) && (ch->level < 12 ))
			|| IS_IMMORTAL(victim) )
			continue;
		
		if (victim->in_room == ch->in_room)
		{
			if (victim->name == ch->name)
			{
				str_cpy(buf,"Sorry brother, but I must eat you or I'll starve.");
				do_say(ch,buf);
				do_kill(ch,"gremlin");
				do_kill(ch,"2.gremlin");
				return TRUE;
			}
			else
			{
				do_kill(ch,victim->name->str);
				return TRUE;
			}
			return TRUE;
		}
		continue;
	}
	return FALSE;
}

/* Spec_rogue, coded by Malice. */
bool spec_rogue( CHAR_DATA *ch )
{
/* To add to the life of mobs... they pickup and wear equipment */
	OBJ_DATA *object;
	OBJ_DATA *obj2;
	OBJ_DATA *object_next;
	char buf [MAX_STRING_LENGTH];
	
	if ( !IS_AWAKE( ch ) )
		return FALSE;
	
	for ( object = ch->in_room->contents; object; object = object_next )
	{
		object_next = object->next_content;
		if ( object == NULL )
			continue;
		
		if ( !IS_SET( object->wear_flags, ITEM_TAKE ) )
			continue;
		
		if ( object->item_type == ITEM_CORPSE_NPC )
			continue;
		
		if ( ( object->item_type != ITEM_DRINK_CON
				&& object->item_type != ITEM_TRASH )
			&&
			
			!(( IS_OBJ_STAT( object, ITEM_ANTI_EVIL   ) && IS_EVIL   ( ch ) ) ||
				( IS_OBJ_STAT( object, ITEM_ANTI_GOOD   ) && IS_GOOD   ( ch ) ) ||
				( IS_OBJ_STAT( object, ITEM_ANTI_NEUTRAL) && IS_NEUTRAL( ch ) ) ) )
			
		{
			act( "$n picks up $p and examines it carefully.", ch, object, NULL, TO_ROOM );
			obj_from_room( object );
			obj_to_char( object, ch );
		/*Now compare it to what we already have*/
			for ( obj2 = ch->carrying; obj2; obj2 = obj2->next_content )
			{
				if ( obj2->wear_loc != WEAR_NONE
					&& can_see_obj( ch, obj2 )
					&& object->item_type == obj2->item_type
					&& ( object->wear_flags & obj2->wear_flags & ~ITEM_TAKE) != 0 )
					break;
			}
			if (!obj2)
			{
				switch (object->item_type)
				{
					default:
						str_cpy(buf,"Hey, what a find!");
						do_say(ch,buf);
						break;
					case ITEM_FOOD:
						str_cpy(buf, "This looks like a tasty morsel!");
						do_say(ch,buf);
						do_eat(ch,object->name->str);
						break;
					case ITEM_WAND:
						str_cpy(buf,"Wow, a magic wand!");
						do_say(ch,buf);
						wear_obj(ch,object,FALSE);
						break;
					case ITEM_STAFF:
						str_cpy(buf,"Kewl, a magic staff!");
						do_say(ch,buf);
						wear_obj(ch,object,FALSE);
						break;
					case ITEM_WEAPON:
						str_cpy(buf,"Hey, this looks like a nifty weapon!");
						do_say(ch,buf);
						wear_obj(ch,object,FALSE);
						break;
					case ITEM_ARMOR:
						str_cpy(buf,"Oooh...a nice piece of armor!");
						do_say(ch,buf);
						wear_obj(ch,object,FALSE);
						break;
					case ITEM_POTION:
						str_cpy(buf, "Great!  I was feeling a little thirsty!");
						do_say(ch,buf);
						act( "You quaff $p.", ch, object, NULL ,TO_CHAR );
						act( "$n quaffs $p.", ch, object, NULL, TO_ROOM );
						obj_cast_spell( object->value[1], object->level, ch, ch, NULL );
						obj_cast_spell( object->value[2], object->level, ch, ch, NULL );
						obj_cast_spell( object->value[3], object->level, ch, ch, NULL );
						extract_obj( object );
						break;
					case ITEM_SCROLL:
						str_cpy(buf,"Hmmm I wonder what this says?");
						do_say(ch,buf);
						act( "You recite $p.", ch, object, NULL, TO_CHAR );
						act( "$n recites $p.", ch, object, NULL, TO_ROOM );
						obj_cast_spell( object->value[1], object->level, ch, NULL, object );
						obj_cast_spell( object->value[2], object->level, ch, NULL, object );
						obj_cast_spell( object->value[3], object->level, ch, NULL, object );
						extract_obj( object );
						break;
				}
				return TRUE;
			}
			
			if ((object->level > obj2->level))
			{
				str_cpy(buf,"Now THIS looks like an improvement!");
				do_say(ch,buf);
				remove_obj(ch,obj2->wear_loc,TRUE);
				wear_obj(ch,object,FALSE);
			}
			else
			{
				str_cpy(buf,"I don't want this piece of junk!");
				do_say(ch,buf);
				act("You don't like the look of $p.",ch,object,NULL,TO_CHAR);
				do_drop(ch,object->name->str);
				do_sacrifice(ch,object->name->str);
			}
			return TRUE;
		}
	}
	
	return FALSE;
}

/*
 * Rotains Clan Guardian Spec
 * Original Code by Malice
 */

bool spec_clan_guardian(CHAR_DATA *ch)
{
	DESCRIPTOR_DATA       *d;
	CHAR_DATA             *victim;
	char                  buf[MAX_STRING_LENGTH];
	OBJ_DATA              *obj;
	GSList	*desc_list;
	
	if (ch->fighting) return FALSE;
	
	if (ch->in_room == NULL) return FALSE;
	
   /*if (ch->in_room < 6645 && ch->in_room > 6657) break;*/
	
	for ( desc_list = descriptor_list; desc_list != NULL; desc_list = g_slist_next(desc_list) )
	{
		d = (DESCRIPTOR_DATA*)desc_list->data;
		if (!IS_PLAYING(d)
			|| (victim = d->character) == NULL
			|| IS_NPC(victim)
			|| IS_IMMORTAL(victim)
			|| victim->in_room == NULL
			|| victim->pcdata->chobj != NULL
			|| victim->in_room->area != ch->in_room->area
			|| victim->in_room == ch->in_room
			|| (IS_CLASS(victim, CLASS_VAMPIRE) && IS_SET(victim->special, SPC_INCONNU)))
		{
			continue;
		}
		
		if ((obj = get_obj_carry(victim, "dlwr5"))
			&& obj->pIndexData->vnum==6641)
		{
			return FALSE; 
		}
		else
		{
			if (ch->in_room != victim->in_room)
			{
				act("$n disappears in a haze of red!",victim,NULL,NULL,TO_ROOM);
				act("You disappear into a haze of red!",victim,NULL,NULL,TO_CHAR);
				
				char_from_room( victim );
				char_to_room(victim, ch->in_room);
				
				act("$n appears in a haze of red!",victim,NULL,NULL,TO_ROOM);
				act("You appear into a haze of red!",victim,NULL,NULL,TO_CHAR);
			}
			
			act("$n shouts at you \"You shall DIE!\"",ch,ch->long_descr,victim,TO_VICT);
			act("You let out a battlecry as you defend the clan headquaters!",ch,NULL,victim,TO_CHAR);
/*
        spell_curse( 24 , 100 , ch , victim );
*/
			if (victim->position <= POS_MORTAL && IS_HERO(victim) &&
				ch->position == POS_STANDING)
			{
				char_from_room( victim );
				char_to_room(victim, get_room_index(ROOM_VNUM_ALTAR));
				continue;
			}
			sprintf( buf,"%s Is In DarkLight Headquarters! Attack!\n\r", victim->name->str); 
			do_shout( ch , buf);
			
			multi_hit( ch, victim, gsn_backstab); /* Nice Backstab to start */
			
			return TRUE;
			
		}
	}
	return FALSE;
}

bool spec_clan_sabbat(CHAR_DATA *ch)
{
        DESCRIPTOR_DATA                         *d;
        CHAR_DATA             *victim;
        char                  buf[MAX_STRING_LENGTH];
        GSList  *desc_list;

        if (ch->fighting) return FALSE;

        if (ch->in_room == NULL) return FALSE;

        for ( desc_list = descriptor_list; desc_list != NULL; desc_list = g_slist_next(desc_list) )

        {
        	d = (DESCRIPTOR_DATA*)desc_list->data;
        	victim = d->character;
        	if (victim == NULL
        	        || IS_IMMORTAL(victim)
                        || victim->in_room == NULL
                      //|| victim->pcdata->chobj != NULL
                        || victim->in_room->area != ch->in_room->area
                        || (IS_CLASS(victim, CLASS_VAMPIRE) && IS_SET(victim->special, SPC_INCONNU))
                        || (IS_CLASS(victim, CLASS_VAMPIRE) && IS_SET(victim->sect, SECT_SABBAT)) )
                {
                        continue;
                }

                if (ch->in_room!=victim->in_room)
                {
                        act("$n runs out of the to the room!",ch,NULL,NULL,TO_ROOM);
                        act("You runs out of the to the room!",ch,NULL,NULL,TO_CHAR);

                        char_from_room( ch );
                        char_to_room(ch, victim->in_room);

                        act("$n runs into the room and growls at you!",ch,NULL,NULL,TO_ROOM);
                        act("You run into the room!",ch,NULL,NULL,TO_CHAR);

                 }

                 act("$n begins to growl at you and foam at the mouth!",ch,ch->long_descr,victim,TO_VICT);
                 act("You begin to growl at you and foam at the mouth!",ch,NULL,victim,TO_CHAR);

                 spell_curse( 24 , 100 , ch , victim ); /* No Recall */

                 sprintf( buf,"Masters, %s is in the Sabbat Haven!\r", victim->name->str);
                 do_yell( ch , buf);

                 multi_hit( ch, victim, gsn_punch);

                 return TRUE;

          }
          return FALSE;
}

bool spec_clan_camarilla(CHAR_DATA *ch)
{
	DESCRIPTOR_DATA				*d;
	CHAR_DATA             *victim;
	char                  buf[MAX_STRING_LENGTH];
	GSList	*desc_list;
	
	if (ch->fighting) return FALSE;
	
	if (ch->in_room == NULL) return FALSE;
	
	for ( desc_list = descriptor_list; desc_list != NULL; desc_list = g_slist_next(desc_list) )
	{
		d = (DESCRIPTOR_DATA*)desc_list->data;
		victim = d->character;
		
		if (victim == NULL
			|| IS_IMMORTAL(victim)
			|| victim->in_room == NULL
			//|| victim->pcdata->chobj != NULL
			|| victim->in_room->area != ch->in_room->area
			|| (IS_CLASS(victim, CLASS_VAMPIRE) && IS_SET(victim->special, SPC_INCONNU))
			|| (IS_CLASS(victim, CLASS_VAMPIRE) && IS_SET(victim->sect, SECT_CAMARILLA)) )
		{
			continue;
		}
		
		if (ch->in_room!=victim->in_room)
		{
			act("$n disappears in a swirl of smoke!",ch,NULL,NULL,TO_ROOM);
			act("You disappear in a swirl of smoke!",ch,NULL,NULL,TO_CHAR);
			
			char_from_room( ch );
			char_to_room(ch, victim->in_room);
			
			act("$n appears in a swirl of smoke!",ch,NULL,NULL,TO_ROOM);
			act("You appear in a swirl of smoke!",ch,NULL,NULL,TO_CHAR);
		}
		
		act("$n shouts at you \"You shall DIE!\"",ch,ch->long_descr,victim,TO_VICT);
		act("You let out a battlecry as you defend the clan headquarters!",ch,NULL,victim,TO_CHAR);
		
		spell_curse( 24 , 100 , ch , victim ); /* No Recall */
		
		/*
		if (victim->position <= POS_MORTAL && IS_HERO(victim) &&
			ch->position == POS_STANDING)
		{
			char_from_room( victim );
			char_to_room(victim, get_room_index(ROOM_VNUM_ALTAR));
			continue;
		}
		*/
		sprintf( buf,"%s is in the Camarilla Haven! Attack!\n\r", victim->name->str); 
		do_yell( ch , buf);
		
		multi_hit( ch, victim, gsn_punch);
		
		return TRUE;
		
	}
	return FALSE;
}

bool spec_mage_guard(CHAR_DATA *ch)
{
	DESCRIPTOR_DATA		    *d;
	CHAR_DATA             *victim;
	char                  buf[MAX_STRING_LENGTH];
	GSList	*desc_list;
	
	if (ch->fighting) return FALSE;
	
	if (ch->in_room == NULL) return FALSE;
	
	for ( desc_list = descriptor_list; desc_list != NULL; desc_list = g_slist_next(desc_list) )
	{
		d = (DESCRIPTOR_DATA*)desc_list->data;
		victim = d->character;
		if (victim == NULL
			|| IS_IMMORTAL(victim)
			|| victim->in_room == NULL
			//|| victim->pcdata->chobj != NULL
			|| victim->in_room->area != ch->in_room->area
			|| (IS_CLASS(victim, CLASS_MAGE) && IS_SET(victim->sect, SECT_TRADITIONS)) )
		{
			continue;
		}
		
		if (ch->in_room!=victim->in_room)
		{
			act("$n disappears in a swirl of smoke!",ch,NULL,NULL,TO_ROOM);
			act("You disappear in a swirl of smoke!",ch,NULL,NULL,TO_CHAR);
			
			char_from_room( ch );
			char_to_room(ch, victim->in_room);
			
			act("$n appears in a swirl of smoke!",ch,NULL,NULL,TO_ROOM);
			act("You appear in a swirl of smoke!",ch,NULL,NULL,TO_CHAR);
		}
		
		act("$n shouts at you \"You shall DIE!\"",ch,ch->long_descr,victim,TO_VICT);
		act("You let out a battlecry as you defend the clan headquarters!",ch,NULL,victim,TO_CHAR);
		
		spell_curse( 24 , 100 , ch , victim ); /* No Recall */
		
		/*
		if (victim->position <= POS_MORTAL && IS_HERO(victim) &&
			ch->position == POS_STANDING)
		{
			char_from_room( victim );
			char_to_room(victim, get_room_index(ROOM_VNUM_ALTAR));
			continue;
		}
		*/
		sprintf( buf,"%s is in the Mage Chantry! Attack!\n\r", victim->name->str);
		do_yell( ch , buf);
		
		multi_hit( ch, victim, gsn_punch);
		
		return TRUE;
		
	}
	return FALSE;
}

bool spec_clan_spiritknights(CHAR_DATA *ch)
{
	DESCRIPTOR_DATA       *d;
	CHAR_DATA             *victim;
	char                  buf[MAX_STRING_LENGTH];
	GSList	*desc_list;
	
	if (ch->fighting) return FALSE;
	
	if (ch->in_room == NULL) return FALSE;
	
	for ( desc_list = descriptor_list; desc_list != NULL; desc_list = g_slist_next(desc_list) )
	{
		d = (DESCRIPTOR_DATA*)desc_list->data;
		if (!IS_PLAYING(d)
			|| (victim = d->character) == NULL
			|| IS_NPC(victim)
			|| IS_IMMORTAL(victim)
			|| victim->in_room == NULL
			|| victim->pcdata->chobj != NULL
			|| victim->in_room->area != ch->in_room->area
			|| victim->in_room == ch->in_room
			|| (IS_CLASS(victim, CLASS_VAMPIRE) && IS_SET(victim->special, SPC_INCONNU)) )
		{
			continue;
		}
		
		if (ch->in_room!=victim->in_room)
		{
			act("$n disappears in a swirl of smoke!",ch,NULL,NULL,TO_ROOM);
			act("You disappear in a swirl of smoke!",ch,NULL,NULL,TO_CHAR);
			
			char_from_room( ch );
			char_to_room(ch, victim->in_room);
			
			act("$n appears in a swirl of smoke!",ch,NULL,NULL,TO_ROOM);
			act("You appear in a swirl of smoke!",ch,NULL,NULL,TO_CHAR);
		}
		
		act("$n shouts at you \"You shall DIE!\"",ch,ch->long_descr,victim,TO_VICT);
		act("You let out a battlecry as you defend the clan headquarters!",ch,NULL,victim,TO_CHAR);
		
		spell_curse( 24 , 100 , ch , victim ); /* No Recall */
		
		if (victim->position <= POS_MORTAL && IS_HERO(victim) &&
			ch->position == POS_STANDING)
		{
			char_from_room( victim );
			char_to_room(victim, get_room_index(ROOM_VNUM_ALTAR));
			continue;
		}
		sprintf( buf,"%s Is in the Spirit Knights Headquarters! Attack!\n\r", victim->name->str); 
		do_shout( ch , buf);
		
		multi_hit( ch, victim, gsn_punch);
		
		return TRUE;
		
	}
	return FALSE;
}

bool spec_clan_werewolf(CHAR_DATA *ch)
{
	
	DESCRIPTOR_DATA				*d;
	CHAR_DATA             *victim;
	char                  buf[MAX_STRING_LENGTH];
	GSList	*desc_list;
	
	if ( ch->fighting != NULL )
	{
		if (number_range(1,2) == 1) return spec_breath_frost( ch );
		else return spec_eater( ch );
	}
	
	if (ch->in_room == NULL) return FALSE;
	
	for ( desc_list = descriptor_list; desc_list != NULL; desc_list = g_slist_next(desc_list) )
	{
		d = (DESCRIPTOR_DATA*)desc_list->data;
		victim = d->character;
		if (victim == NULL
			|| IS_IMMORTAL(victim)
			|| victim->in_room == NULL
			//|| victim->pcdata->chobj != NULL
			|| victim->in_room->area != ch->in_room->area
			|| IS_SWWF(victim)
			|| IS_CLASS(victim,CLASS_WEREWOLF))
		{
			continue;
		}
		
        /* Stop Fenris jumping into his own stomach :) */
		if (ch->in_room != victim->in_room
			&& victim->in_room->vnum != 29732 )
		{
			act("$n burrows into the ground!",ch,NULL,NULL,TO_ROOM);
			act("You burrow into the ground!",ch,NULL,NULL,TO_CHAR);
			
			char_from_room( ch );
			char_to_room(ch, victim->in_room);
			
			act("$n bursts from the ground!",ch,NULL,NULL,TO_ROOM);
			act("You burst from the ground!",ch,NULL,NULL,TO_CHAR);
		}
	/*	
		if (victim->position <= POS_MORTAL && IS_HERO(victim) &&
			ch->position == POS_STANDING)
		{
			char_from_room( victim );
			char_to_room(victim, get_room_index(ROOM_VNUM_ALTAR));
			continue;
		}
         */
		sprintf( buf,"%s Is in the caern!! Attack!\n\r", victim->name->str); 
		do_howl( ch , buf);
		one_hit( ch, victim, ( TYPE_HIT + 10 ), 0 );
		return TRUE;
		
	}
	return FALSE;
}

bool spec_kavir_guardian(CHAR_DATA *ch)
{
	DESCRIPTOR_DATA       *d;
	CHAR_DATA             *victim;
	GSList	*desc_list;
/*
   char                  buf[MAX_STRING_LENGTH];
*/
	if (ch->in_room == NULL) return FALSE;
	
	for ( desc_list = descriptor_list; desc_list != NULL; desc_list = g_slist_next(desc_list) )
	{
		d = (DESCRIPTOR_DATA*)desc_list->data;
		if (!IS_PLAYING(d)
			|| (victim = d->character) == NULL
			|| IS_NPC(victim)
			|| IS_IMMORTAL(victim)
			|| victim->in_room == NULL
			|| victim->pcdata->chobj != NULL
			|| victim->in_room->area != ch->in_room->area
			|| victim->in_room == ch->in_room
			|| (IS_CLASS(victim, CLASS_VAMPIRE) && IS_SET(victim->special, SPC_INCONNU))
			|| IS_ITEMAFF(victim, ITEMA_DBPASS))
		{
			continue;
		}
		
		if (ch->in_room!=victim->in_room)
		{
			act("A pair of skeletal hands reach up from the ground.",victim,NULL,NULL,TO_ROOM);
			act("A pair of skeletal hands reach up from the ground.",victim,NULL,NULL,TO_CHAR);
			act("The hands grab $n by the ankles and pull $m into the ground!",victim,NULL,NULL,TO_ROOM);
			act("The hands grab you by the ankles and pull you into the ground!",victim,NULL,NULL,TO_CHAR);
			char_from_room( victim );
			char_to_room(victim, ch->in_room);
		}
		
		if (victim->position <= POS_MORTAL && IS_HERO(victim) &&
			ch->position == POS_STANDING)
		{
/*
         act("$n tears $N's head from $S shoulders!",ch,NULL,victim,TO_NOTVICT);
         act("You tear $N's head from $S shoulders!",ch,NULL,victim,TO_CHAR);
	 send_to_char("Your head is torn from your shoulders!\n\r",victim);
	 sprintf( buf,"%s has been beheaded for his crimes against clan DarkBlade.",victim->name);
	 do_info(ch, buf);
         if (victim->level == 3) victim->level=victim->level-1;
         victim->pdeath=victim->pdeath+1;
*/
			char_from_room( victim );
			char_to_room(victim, get_room_index(ROOM_VNUM_ALTAR));
/*
	 behead( victim );
*/
			continue;
		}
		multi_hit( ch, victim, TYPE_UNDEFINED);
		return TRUE;
	}
	return FALSE;
}

bool spec_zombie_lord( CHAR_DATA *ch )
{
	char buf [MAX_STRING_LENGTH];
	OBJ_DATA		*obj;
	OBJ_DATA		*obj_content;
	OBJ_DATA		*obj_next;
	CHAR_DATA		*victim;
	MOB_INDEX_DATA	*pMobIndex;
	EXIT_DATA		*pexit;
	ROOM_INDEX_DATA	*to_room;
	int door;
	int consider 	= 4;
	bool north_ok 	= TRUE;
	bool east_ok 	= TRUE;
	bool south_ok 	= TRUE;
	bool west_ok 	= TRUE;
	bool up_ok 		= TRUE;
	bool down_ok 	= TRUE;
	int countup 	= 6;
	int option;
	
	if ( ch->position <= POS_SITTING )
	{
		do_stand(ch,"");
		return TRUE;
	}
	if ( (victim = ch->fighting) != NULL )
	{
		if (IS_AFFECTED(ch, AFF_FAERIE_FIRE))
		{
			act("$n's eyes glow bright red for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_dispel_magic( skill_lookup( "dispel magic" ), ch->level, ch, ch );
		}
		else if (IS_AFFECTED(ch, AFF_POISON))
		{
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_cure_poison( skill_lookup( "cure poison" ), ch->level, ch, ch );
		}
		else if (IS_AFFECTED(ch, AFF_BLIND))
		{
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_cure_blindness( skill_lookup( "cure blindness" ), ch->level, ch, ch );
		}
		else if (IS_AFFECTED(ch, AFF_CURSE))
		{
			act("$n's eyes glow bright purple for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_remove_curse( skill_lookup( "remove curse" ), ch->level, ch, ch );
		}
		else if (!IS_AFFECTED(ch, AFF_SANCTUARY))
		{
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_sanctuary( skill_lookup( "sanctuary" ), ch->level, ch, ch );
		}
		else if (!is_affected(ch,skill_lookup("frenzy")) && number_percent() < 50)
		{
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_frenzy( skill_lookup( "frenzy" ), ch->level, ch, ch );
		}
		else if (!is_affected(ch,skill_lookup("darkblessing")) && number_percent() < 50)
		{
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_darkblessing( skill_lookup( "darkblessing" ), ch->level, ch, ch );
		}
		else if (!is_affected(ch,skill_lookup("bless")) && number_percent() < 50)
		{
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_bless( skill_lookup( "bless" ), ch->level, ch, ch );
		}
		else if (!is_affected(ch,skill_lookup("stone skin")) && number_percent() < 50)
		{
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_stone_skin( skill_lookup( "stone skin" ), ch->level, ch, ch );
		}
		else if (!is_affected(ch,skill_lookup("armor")) && number_percent() < 50)
		{
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_armor( skill_lookup( "armor" ), ch->level, ch, ch );
		}
		else if (!is_affected(ch,skill_lookup("shield")) && number_percent() < 50)
		{
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_shield( skill_lookup( "shield" ), ch->level, ch, ch );
		}
		else if (!IS_AFFECTED(victim, AFF_FAERIE_FIRE) && number_percent() < 50)
		{
			act("$n's eyes glow bright red for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_faerie_fire( skill_lookup( "faerie fire" ), ch->level, ch, victim );
		}
		else if (!IS_AFFECTED(victim, AFF_BLIND) && number_percent() < 15)
		{
			act("$n's eyes glow bright red for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_blindness( skill_lookup( "blindness" ), ch->level, ch, victim );
		}
		else if (!IS_AFFECTED(victim, AFF_CURSE) && number_percent() < 15)
		{
			act("$n's eyes glow bright red for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_curse( skill_lookup( "curse" ), ch->level, ch, victim );
		}
		else if (ch->loc_hp[6] > 0)
		{
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_clot( skill_lookup( "clot" ), ch->level, ch, ch );
		}
		else if (ch->hit < (ch->max_hit * 0.5) && number_percent() < 75)
		{
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_heal( skill_lookup( "heal" ), ch->level, ch, ch );
		}
		else if (ch->hit < (ch->max_hit * 0.25) && number_percent() < 50)
		{
			do_flee(ch,"");
			ch->spectype = ZOMBIE_REST;
		}
		else if (ch->hit < (ch->max_hit * 0.1) && number_percent() < 25)
		{
			act("$n's eyes glow bright green for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_teleport( skill_lookup( "teleport" ), ch->level, ch, ch );
			ch->spectype = ZOMBIE_REST;
		}
		else
		{
			switch( number_range(1,10) )
			{
				default:
					do_kick(ch,"");
					break;
				case 1:
					do_disarm(ch,"");
					break;
				case 2:
				case 3:
				case 4:
				case 5:
					act("$n's eyes glow bright red for a moment.",ch,NULL,NULL,TO_ROOM);
					spell_dispel_magic( skill_lookup( "dispel magic" ), ch->level, ch, victim );
					break;
				case 6:
				case 7:
				case 8:
					act("$n's eyes glow bright red for a moment.",ch,NULL,NULL,TO_ROOM);
					spell_harm( skill_lookup( "harm" ), ch->level, ch, victim );
					break;
			}
		}
		if ( (victim = ch->fighting) == NULL ) return TRUE;
		switch( number_percent() )
		{
			default:
				break;
			case 1:
				str_cpy(buf,"Foolish mortal, you think you can kill what is already dead?");
				do_say(ch,buf);
				break;
			case 2:
				if (IS_NPC(victim))
					sprintf(buf,"I shall feast on your soul for this, %s",victim->short_descr->str);
				else
					sprintf(buf,"I shall feast on your soul for this, %s",victim->name->str);
				do_say(ch,buf);
			case 3:
				if (IS_NPC(victim))
					sprintf(buf,"%s shall pay for their arrogance!",victim->short_descr->str);
				else
					sprintf(buf,"%s shall pay for their arrogance!",victim->name->str);
				do_shout(ch,buf);
				break;
			case 4:
				str_cpy(buf,"This fight shall be your last!");
				do_say(ch,buf);
				break;
		}
		return TRUE;
	}
	
	if (ch->spectype != ZOMBIE_TRACKING && ch->spectype != ZOMBIE_REST)
	{
		if ((obj = get_obj_here(ch,"corpse")) != NULL)
		{
			if ( ( pMobIndex = get_mob_index( obj->value[2] ) ) == NULL )
				return spec_rogue(ch);
			victim = create_mobile( pMobIndex );
			char_to_room(victim,ch->in_room);
			sprintf(buf,"zombie %s",victim->name->str);
			sprintf(buf,"The zombie of %s stands here.\n\r",victim->short_descr->str);
			victim->long_descr = g_string_assign(victim->long_descr,buf);
			victim->name = g_string_assign(victim->name,buf);
			sprintf(buf,"the zombie of %s",victim->short_descr->str);
			victim->short_descr = g_string_assign(victim->short_descr,buf);
			act("$n makes a few gestures over $p.",ch,obj,NULL,TO_ROOM);
			act("$n clambers to $s feet.",victim,NULL,NULL,TO_ROOM);
			victim->powertype = g_string_assign(victim->powertype,"zombie");
			for ( obj_content = obj->contains; obj_content != NULL; obj_content = obj_next )
			{
				obj_next = obj_content->next_content;
				obj_from_obj(obj_content);
				obj_to_char(obj_content,victim);
			}
			extract_obj(obj);
/*
	    victim->spec_fun = ch->spec_fun;
*/
			do_wear(victim,"all");
			str_cpy(buf,"I shall spread the corruption!  The time of the Apocalypse is at hand!");
			do_say(victim,buf);
		}
		door = number_range(0,5);
		for ( door = 0; door <= 5; door++ )
		{
			if (((pexit = ch->in_room->exit[door]) == NULL) || 
				(to_room = pexit->to_room) == NULL)
			{
				switch (door)
				{
					case DIR_NORTH: north_ok = FALSE; countup -= 1; break;
					case DIR_SOUTH: south_ok = FALSE; countup -= 1; break;
					case DIR_EAST:  east_ok  = FALSE; countup -= 1; break;
					case DIR_WEST:  west_ok  = FALSE; countup -= 1; break;
					case DIR_UP:    up_ok    = FALSE; countup -= 1; break;
					case DIR_DOWN:  down_ok  = FALSE; countup -= 1; break;
				}
			}
		}
		
		if (countup < 1)
		{
			str_cpy(buf,"Damn, I hate it when this happens!");
			do_say(ch,buf);
			do_recall(ch,"");
			return TRUE;
		}
		
		for ( ; ; )
		{
			option = number_range(0,5);
			if (((pexit = ch->in_room->exit[option]) == NULL) || 
				(to_room = pexit->to_room) == NULL)
				continue;
			if (countup > 1 && option == ch->specpower) continue;
			if (IS_SET(pexit->exit_info, EX_CLOSED))
			{
				if (option == 0) do_open(ch,"north");
				if (option == 1) do_open(ch,"east");
				if (option == 2) do_open(ch,"south");
				if (option == 3) do_open(ch,"west");
				if (option == 4) do_open(ch,"up");
				if (option == 5) do_open(ch,"down");
			}
			switch (option)
			{
				default: break;
				case DIR_NORTH: ch->specpower = DIR_SOUTH; break;
				case DIR_SOUTH: ch->specpower = DIR_NORTH; break;
				case DIR_EAST:  ch->specpower = DIR_WEST;  break;
				case DIR_WEST:  ch->specpower = DIR_EAST;  break;
				case DIR_UP:    ch->specpower = DIR_DOWN;  break;
				case DIR_DOWN:  ch->specpower = DIR_UP;    break;
			}
			move_char(ch,option);
			break;
		}
		
		for (victim = char_list; victim != NULL; victim = victim->next)
		{
			if (victim->in_room == NULL) continue;
			if ( victim->in_room != ch->in_room
				|| victim == ch
				|| (!IS_NPC(victim) && IS_HERO(victim) && victim->hit < 0)
				|| IS_IMMORTAL(victim)
				|| is_safe(ch,victim)
				|| !IS_NPC(victim)
				|| !can_see(ch,victim) )
				continue;
			
			if (IS_NPC(victim) && !str_cmp(victim->powertype->str,"zombie")) continue;
			if (IS_NPC(victim) && victim->pIndexData->vnum == 30011) continue;
			if (victim->in_room == ch->in_room)
			{
				act("$n examines $N closely, looking for $S weaknesses.",ch,NULL,victim,TO_NOTVICT);
				act("$n examines you closely, looking for your weaknesses.",ch,NULL,victim,TO_VICT);
				if      (victim->hit > (ch->hit*1.5)) consider -= 1;
				else if ((victim->hit*1.5) < ch->hit) consider += 1;
				if      (char_ac(victim)-50 > char_ac(ch)) consider -= 1;
				else if (char_ac(victim)+50 < char_ac(ch)) consider += 1;
				if      (char_hitroll(victim)+10 < char_hitroll(ch)) consider += 1;
				else if (char_hitroll(victim)-10 > char_hitroll(ch)) consider -= 1;
				if      (char_damroll(victim)+10 < char_damroll(ch)) consider += 1;
				else if (char_damroll(victim)-10 > char_damroll(ch)) consider -= 1;
				switch (consider)
				{
					default: break;
					case 8:
						str_cpy(buf,"This shouldn't take more than a few seconds!");
						do_say(ch,buf);
						break;
					case 7:
						str_cpy(buf,"Ha! You are no match for me!");
						do_say(ch,buf);
						break;
					case 6:
						str_cpy(buf,"I should be able to win this one...");
						do_say(ch,buf);
						break;
					case 5:
						str_cpy(buf,"Hmmm, close match, but I think I have the edge.");
						do_say(ch,buf);
						break;
					case 4:
						str_cpy(buf,"This one will be tricky...");
						do_say(ch,buf);
						break;
					case 3:
						str_cpy(buf,"Hmmm, I'm not sure if I can win this one.");
						do_say(ch,buf);
						break;
					case 2:
						str_cpy(buf,"Heheh better not risk it...");
						do_say(ch,buf);
						break;
					case 1:
						str_cpy(buf,"I'd need a lot of luck...better not.");
						do_say(ch,buf);
						break;
					case 0:
						str_cpy(buf,"I think I'll give this one a miss!!!");
						do_say(ch,buf);
						break;
				}
				if (IS_IMMORTAL(victim)) continue;
				if (consider < 3) continue;
				do_kill(ch,victim->name->str);
				return TRUE;
			}
		}
	}
	
	switch ( ch->spectype )
	{
		default:
		case ZOMBIE_NOTHING:
			ch->spectype = number_range(1, 3);
			return spec_rogue(ch);
		case ZOMBIE_TRACKING:
/*
	if (strlen(ch->hunting) > 1)
	{
	    ch->spectype = number_range(1, 3);
	    return spec_rogue(ch);
	}
	if      (strlen(ch->in_room->track[0]) > 1)
	    str_cpy(buf,ch->in_room->track[0]);
	else if (strlen(ch->in_room->track[1]) > 1)
	    str_cpy(buf,ch->in_room->track[1]);
	else if (strlen(ch->in_room->track[2]) > 1)
	    str_cpy(buf,ch->in_room->track[2]);
	else if (strlen(ch->in_room->track[3]) > 1)
	    str_cpy(buf,ch->in_room->track[3]);
	else if (strlen(ch->in_room->track[4]) > 1)
	    str_cpy(buf,ch->in_room->track[4]);
	else {ch->spectype = number_range(1, 3);return spec_rogue(ch);}
	do_hunt(ch,buf);
	ch->spectype = number_range(1, 3);
	return spec_rogue(ch);
*/
		case ZOMBIE_ANIMATE:
		case ZOMBIE_CAST:
			if (IS_AFFECTED(ch, AFF_FAERIE_FIRE))
			{
				act("$n's eyes glow bright red for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_dispel_magic( skill_lookup( "dispel magic" ), ch->level, ch, ch );
			}
			else if (IS_AFFECTED(ch, AFF_POISON) && number_percent() < 75)
			{
				act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_cure_poison( skill_lookup( "cure poison" ), ch->level, ch, ch );
			}
			else if (IS_AFFECTED(ch, AFF_BLIND) && number_percent() < 75)
			{
				act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_cure_blindness( skill_lookup( "cure blindness" ), ch->level, ch, ch );
			}
			else if (IS_AFFECTED(ch, AFF_CURSE) && number_percent() < 75)
			{
				act("$n's eyes glow bright purple for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_remove_curse( skill_lookup( "remove curse" ), ch->level, ch, ch );
			}
			else if (!IS_AFFECTED(ch, AFF_SANCTUARY) && number_percent() < 75)
			{
				act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_sanctuary( skill_lookup( "sanctuary" ), ch->level, ch, ch );
			}
			else if (!is_affected(ch,skill_lookup("frenzy")) && number_percent() < 50)
			{
				act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_frenzy( skill_lookup( "frenzy" ), ch->level, ch, ch );
			}
			else if (!is_affected(ch,skill_lookup("darkblessing")) && number_percent() < 50)
			{
				act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_darkblessing( skill_lookup( "darkblessing" ), ch->level, ch, ch );
			}
			else if (!is_affected(ch,skill_lookup("bless")) && number_percent() < 50)
			{
				act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_bless( skill_lookup( "bless" ), ch->level, ch, ch );
			}
			else if (!is_affected(ch,skill_lookup("stone skin")) && number_percent() < 50)
			{
				act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_stone_skin( skill_lookup( "stone skin" ), ch->level, ch, ch );
			}
			else if (!is_affected(ch,skill_lookup("armor")) && number_percent() < 50)
			{
				act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_armor( skill_lookup( "armor" ), ch->level, ch, ch );
			}
			else if (!is_affected(ch,skill_lookup("shield")) && number_percent() < 50)
			{
				act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_shield( skill_lookup( "shield" ), ch->level, ch, ch );
			}
			else if (ch->loc_hp[6] > 0)
			{
				act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_clot( skill_lookup( "clot" ), ch->level, ch, ch );
			}
			else if (ch->hit < ch->max_hit)
			{
				act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_heal( skill_lookup( "heal" ), ch->level, ch, ch );
			}
			else if (!is_affected(ch,skill_lookup("frenzy")))
			{
				act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_frenzy( skill_lookup( "frenzy" ), ch->level, ch, ch );
			}
			else if (!is_affected(ch,skill_lookup("darkblessing")))
			{
				act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_darkblessing( skill_lookup( "darkblessing" ), ch->level, ch, ch );
			}
			else if (!is_affected(ch,skill_lookup("bless")))
			{
				act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_bless( skill_lookup( "bless" ), ch->level, ch, ch );
			}
			else if (!is_affected(ch,skill_lookup("stone skin")))
			{
				act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_stone_skin( skill_lookup( "stone skin" ), ch->level, ch, ch );
			}
			else if (!is_affected(ch,skill_lookup("armor")))
			{
				act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_armor( skill_lookup( "armor" ), ch->level, ch, ch );
			}
			else if (!is_affected(ch,skill_lookup("shield")))
			{
				act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_shield( skill_lookup( "shield" ), ch->level, ch, ch );
			}
			else ch->spectype = 0;
			if (ch->hit < (ch->max_hit*0.25)) ch->spectype = ZOMBIE_REST;
			return TRUE;
		case ZOMBIE_REST:
			if (ch->hit >= ch->max_hit)
			{do_stand(ch,"");ch->spectype = 0;return TRUE;}
			if (IS_AFFECTED(ch, AFF_CURSE))
			{
				act("$n's eyes glow bright purple for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_remove_curse( skill_lookup( "remove curse" ), ch->level, ch, ch );
				return TRUE;
			}
			if (ch->in_room->vnum != ROOM_VNUM_ALTAR) do_recall(ch,"");
			if (ch->in_room->vnum == ROOM_VNUM_TEMPLE) do_north(ch,"");
			if (ch->position == POS_STANDING) do_rest(ch,"");
			if (ch->hit < ch->max_hit)
			{
				act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
				spell_heal( skill_lookup( "heal" ), ch->level, ch, ch );
			}
			return TRUE;
	}
	return FALSE;
}

bool spec_dog( CHAR_DATA *ch )
{
	OBJ_DATA *obj;
	OBJ_DATA *o_next;
	CHAR_DATA *vch;
	CHAR_DATA *vch_next;
	EXIT_DATA		*pexit;
	ROOM_INDEX_DATA	*to_room;
	int door;
	bool north_ok 	= TRUE;
	bool east_ok 	= TRUE;
	bool south_ok 	= TRUE;
	bool west_ok 	= TRUE;
	bool up_ok 		= TRUE;
	bool down_ok 	= TRUE;
	int countup 	= 6;
	int option;
	int random = number_range(1,5);
	
	if ( !IS_AWAKE(ch) )
	{
		if (random <= 2)
			do_wake(ch,"");
		return TRUE;
	}
	else if (ch->position < POS_STANDING)
	{
		if (random <= 2)
			do_stand(ch,"");
		else
		{
			if (ch->in_room->vnum == 29107 && number_range(1,4) <= 2)
				act("$n eats some dog food from $s food bowl",ch,NULL,NULL,TO_ROOM);
			else if (ch->in_room->vnum == 29107)
				act("$n drinks some water from $s water bowl",ch,NULL,NULL,TO_ROOM);
		}
		return TRUE;
	}
	
	if (ch->in_room == NULL) return TRUE;
	
	if (ch->in_room->vnum == 29104 && random <= 2)
	{
		if ( (random = number_range(1,5)) == 1)
		{
			act("$n curls up in front of the fire.",ch,NULL,NULL,TO_ROOM);
			do_sleep(ch,"");
		}
		else if (random == 2)
			act("$n starts scratching up the carpet.",ch,NULL,NULL,TO_ROOM);
		else if (random == 3)
			act("$n barks loudly.",ch,NULL,NULL,TO_ROOM);
		else if (random == 4)
		{
			act("$n jumps onto the couch.",ch,NULL,NULL,TO_ROOM);
			do_sit(ch,"");
		}
		else if (random == 5)
			act("$n tries to crawl under a chair.",ch,NULL,NULL,TO_ROOM);
		return TRUE;
	}
	else if (ch->in_room->vnum == 29104 && random <= 2)
	{
		if ( (random = number_range(1,5)) == 1)
		{
			act("$n curls up under the dining table.",ch,NULL,NULL,TO_ROOM);
			do_sleep(ch,"");
		}
		else if (random == 2)
			act("$n starts scratching up the carpet.",ch,NULL,NULL,TO_ROOM);
		else if (random == 3)
			act("$n barks loudly.",ch,NULL,NULL,TO_ROOM);
		else if (random == 4)
		{
			act("$n jumps onto a chair.",ch,NULL,NULL,TO_ROOM);
			do_sit(ch,"");
		}
		else if (random == 5)
			act("$n tries to crawl under a chair.",ch,NULL,NULL,TO_ROOM);
		return TRUE;
	}
	else if (ch->in_room->vnum == 29113 && random <= 2)
	{
		if ( (random = number_range(1,5)) == 1)
			act("$n starts scratching up the carpet.",ch,NULL,NULL,TO_ROOM);
		else if (random == 2)
			act("$n tries to climb into the bath.",ch,NULL,NULL,TO_ROOM);
		else if (random == 3)
			act("$n barks loudly.",ch,NULL,NULL,TO_ROOM);
		else if (random == 4)
		{
			act("$n sits behind the bathroom door.",ch,NULL,NULL,TO_ROOM);
			do_sit(ch,"");
		}
		else if (random == 5)
			act("$n tries to squeeze behind the sink.",ch,NULL,NULL,TO_ROOM);
		return TRUE;
	}
	else if (ch->in_room->vnum == 29107 && random <= 2)
	{
		if ( (random = number_range(1,5)) == 1)
			act("$n sniffs around for food on the kitchen floor.",ch,NULL,NULL,TO_ROOM);
		else if (random == 2)
			act("$n looks up hungrilly at the cupboard.",ch,NULL,NULL,TO_ROOM);
		else if (random == 3)
			act("$n barks loudly.",ch,NULL,NULL,TO_ROOM);
		else if (random == 4)
		{
			act("$n walks over to $s food bowl.",ch,NULL,NULL,TO_ROOM);
			do_sit(ch,"");
		}
		else if (random == 5)
			act("$n looks out the back door for cats to chase.",ch,NULL,NULL,TO_ROOM);
		return TRUE;
	}
	else if ((ch->in_room->vnum == 29100 || ch->in_room->vnum == 29101 || 
			ch->in_room->vnum == 29117) && random <= 2)
	{
		if ( (random = number_range(1,5)) == 1)
			act("$n sniffs a flower.",ch,NULL,NULL,TO_ROOM);
		else if (random == 2)
			act("$n rolls around on the grass.",ch,NULL,NULL,TO_ROOM);
		else if (random == 3)
			act("$n tries to eat a blade of grass.",ch,NULL,NULL,TO_ROOM);
		else if (random == 4)
			act("$n pounces on a grasshopper.",ch,NULL,NULL,TO_ROOM);
		else if (random == 5)
			act("$n sniffs the air and growls playfully.",ch,NULL,NULL,TO_ROOM);
		return TRUE;
	}
	if (random <= 2)
	{
		if ( (random = number_range(1,5)) == 1)
			act("$n sniffs the carpet.",ch,NULL,NULL,TO_ROOM);
		else if (random == 2)
			act("$n barks loudly.",ch,NULL,NULL,TO_ROOM);
		else if (random == 3)
			do_sit(ch,"");
		return TRUE;
	}
	
	if ( number_range(1,5) <= 3 )
	{
		door = number_range(0,5);
		for ( door = 0; door <= 5; door++ )
		{
			if (((pexit = ch->in_room->exit[door]) == NULL) || 
				(to_room = pexit->to_room) == NULL)
			{
				switch (door)
				{
					case DIR_NORTH: north_ok = FALSE; countup -= 1; break;
					case DIR_SOUTH: south_ok = FALSE; countup -= 1; break;
					case DIR_EAST:  east_ok  = FALSE; countup -= 1; break;
					case DIR_WEST:  west_ok  = FALSE; countup -= 1; break;
					case DIR_UP:    up_ok    = FALSE; countup -= 1; break;
					case DIR_DOWN:  down_ok  = FALSE; countup -= 1; break;
				}
			}
		}
		
		if (countup < 1)
		{
			if (number_percent() < 80)
				act("$n barks loudly",ch,NULL,NULL,TO_ROOM);
			else
				do_sleep(ch,"");
			return TRUE;
		}
		
		for ( ; ; )
		{
			option = number_range(0,5);
			if (((pexit = ch->in_room->exit[option]) == NULL) || 
				(to_room = pexit->to_room) == NULL)
				continue;
			if (countup > 1 && option == ch->specpower) continue;
			if (IS_SET(pexit->exit_info, EX_CLOSED))
			{
				if (option == 0)
					act("$n scratches at the north door.",ch,NULL,NULL,TO_ROOM);
				if (option == 1)
					act("$n scratches at the east door.",ch,NULL,NULL,TO_ROOM);
				if (option == 2)
					act("$n scratches at the south door.",ch,NULL,NULL,TO_ROOM);
				if (option == 3)
					act("$n scratches at the west door.",ch,NULL,NULL,TO_ROOM);
				if (option == 4)
					act("$n scratches at the upward door.",ch,NULL,NULL,TO_ROOM);
				if (option == 5)
					act("$n scratches at the downward door.",ch,NULL,NULL,TO_ROOM);
				act("$n barks loudly at the door.",ch,NULL,NULL,TO_ROOM);
				for ( vch = char_list; vch != NULL; vch = vch_next )
				{
					vch_next	= vch->next;
					if ( vch->in_room == NULL || IS_NPC(vch) )
						continue;
					if ( vch->in_room == ch->in_room )
						continue;
					if ( vch->in_room->area == ch->in_room->area )
						send_to_char("You hear the sound of a dog barking nearby.\n\r",vch);
				}
				return TRUE;
			}
			switch (option)
			{
				default: break;
				case DIR_NORTH: ch->specpower = DIR_SOUTH; break;
				case DIR_SOUTH: ch->specpower = DIR_NORTH; break;
				case DIR_EAST:  ch->specpower = DIR_WEST;  break;
				case DIR_WEST:  ch->specpower = DIR_EAST;  break;
				case DIR_UP:    ch->specpower = DIR_DOWN;  break;
				case DIR_DOWN:  ch->specpower = DIR_UP;    break;
			}
			move_char(ch,option);
			break;
		}
	}
	
	for ( obj = ch->in_room->contents; obj != NULL; obj = o_next )
	{
		o_next = obj->next_content;
		if (number_range(1,2) == 1) continue;
		act( "$n sniffs $p.", ch, obj, NULL, TO_ROOM );
		if ( obj->item_type == ITEM_FOOD )
		{
			act( "$n eats $p.", ch, obj, NULL, TO_ROOM );
			extract_obj(obj);
		}
		return TRUE;
	}
	return TRUE;
}

bool spec_pagan_member( CHAR_DATA *ch)    //troll
{
	CHAR_DATA *vch, *victim = NULL;
	int count = 0;
	char *message;
	
	if (!IS_AWAKE(ch) || ch->in_room == NULL 
		||  ch->fighting != NULL)
		return FALSE;
	
	for (vch = ch->in_room->people;  vch != NULL;  vch = vch->next_in_room)
	{
		if (!IS_NPC(vch) || ch == vch)
			continue;
		
		if (vch->pIndexData->vnum == 2106)   //MOB_VNUM_PATROLMAN)
			return FALSE;
		
		if (ch->level > vch->level - 2 && !is_safe(ch,vch))
		{
			if (number_range(0,count) == 0)
				victim = vch;
			
			count++;
		}
	}
	
	if (victim == NULL)
		return FALSE;
	
	switch (number_range(0,6))
	{
		default:  message = NULL; 	break;
		case 0:	message = "$n yells 'I've been looking for you, punk!'";
			break;
		case 1: message = "With a scream of rage, $n attacks $N.";
			break;
		case 2: message = 
				"$n says 'What's Christian trash like you doing around here?'";
			break;
		case 3: message = "$n cracks his knuckles and says 'Do ya feel lucky?'";
			break;
		case 4: message = "$n says 'There's no Knights to save you this time!'";
			break;	
		case 5: message = "$n says 'Time to join your brothers, in heaven!'";
			break;
		case 6: message = "$n says 'Let's rock.'";
			break;
	}
	
	if (message != NULL)
		act(message,ch,NULL,victim,TO_ALL);
	multi_hit( ch, victim, TYPE_UNDEFINED );
	return TRUE;
}

bool spec_christian_member( CHAR_DATA *ch)     //ogre
{
	CHAR_DATA *vch, *victim = NULL;
	int count = 0;
	char *message;
	
	if (!IS_AWAKE(ch) || ch->in_room == NULL
		||  IS_AFFECTED(ch,AFF_CHARM) || ch->fighting != NULL)
		return FALSE;
	
	for (vch = ch->in_room->people;  vch != NULL;  vch = vch->next_in_room)
	{
		if (!IS_NPC(vch) || ch == vch)
			continue;
		
		if (vch->pIndexData->vnum == 2106)      //MOB_VNUM_PATROLMAN)
			return FALSE;
		
		if (ch->level > vch->level - 2 && !is_safe(ch,vch))
		{
			if (number_range(0,count) == 0)
				victim = vch;
			
			count++;
		}
	}
	
	if (victim == NULL)
		return FALSE;
	
	switch (number_range(0,6))
	{
		default: message = NULL;	break;
		case 0: message = "$n yells 'I've been looking for you, punk!'";
			break;
		case 1: message = "With a scream of rage, $n attacks $N.'";
			break;
		case 2: message =
				"$n says 'What's Pagan filth like you doing around here?'";
			break;
		case 3: message = "$n cracks his knuckles and says 'Do ya feel lucky?'";
			break;
		case 4: message = "$n says 'There's no Knights to save you this time!'";
			break;
		case 5: message = "$n says 'Time to join your brothers, in hell!'";
			break;
		case 6: message = "$n says 'Let's rock.'";
			break;
	}
	
	if (message != NULL)
		act(message,ch,NULL,victim,TO_ALL);
	multi_hit( ch, victim, TYPE_UNDEFINED );
	return TRUE;
}

bool spec_patrol_knight(CHAR_DATA *ch)
{
	CHAR_DATA *vch,*victim = NULL;
	OBJ_DATA *obj;
	char *message;
	int count = 0;
	
	if (!IS_AWAKE(ch) || ch->in_room == NULL
		||  IS_AFFECTED(ch,AFF_CHARM) || ch->fighting != NULL)
		return FALSE;
	
	for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
	{
		if (vch == ch)
			continue;
		
		if (vch->fighting != NULL)
		{
			if (number_range(0,count) == 0)
				victim = (vch->level > vch->fighting->level) 
					? vch : vch->fighting;
			count++;
		}
	}
	
	if (victim == NULL || (IS_NPC(victim) && victim->spec_fun == ch->spec_fun))
		return FALSE;
	
	if (((obj = get_eq_char(ch,WEAR_NECK_1)) != NULL 
			&&   obj->pIndexData->vnum == 2116)               //OBJ_VNUM_WHISTLE)
		||  ((obj = get_eq_char(ch,WEAR_NECK_2)) != NULL
			&&   obj->pIndexData->vnum == 2116))              //OBJ_VNUM_WHISTLE))
	{
		act("You shake $p hard.",ch,obj,NULL,TO_CHAR);
		act("$n shakes $p, ***DIINNGG DOONNGG***",ch,obj,NULL,TO_ROOM);
		
		for ( vch = char_list; vch != NULL; vch = vch->next )
		{
			if ( vch->in_room == NULL )
				continue;
			
			if (vch->in_room != ch->in_room 
				&&  vch->in_room->area == ch->in_room->area)
				send_to_char( "You hear a loud bell ringing.\n\r", vch );
		}
	}
	
	switch (number_range(0,6))
	{
		default:	message = NULL;		break;
		case 0:	message = "$n yells 'All roit! All roit! break it up!'";
			break;
		case 1: message = 
				"$n says 'Society's to blame, but what's a bloke to do?'";
			break;
		case 2: message = 
				"$n mumbles 'bloody kids will be the death of us all.'";
			break;
		case 3: message = "$n shouts 'Stop that! Stop that!' and attacks.";
			break;
		case 4: message = "$n pulls out his mace and goes to work.";
			break;
		case 5: message = 
				"$n sighs in resignation and proceeds to break up the fight.";
			break;
		case 6: message = "$n says 'Settle down, you hooligans!'";
			break;
	}
	
	if (message != NULL)
		act(message,ch,NULL,NULL,TO_ALL);
	
	multi_hit(ch,victim,TYPE_UNDEFINED);
	
	return TRUE;
}

bool spec_healer( CHAR_DATA *ch )
{
	int silliness;
	//bool pc_found = TRUE;
	CHAR_DATA *nch;
	CHAR_DATA *ch_next;
	CHAR_DATA *vch;
	CHAR_DATA *vch_next;
	CHAR_DATA *victim;
	
	if ( !IS_AWAKE(ch) )
		return FALSE;
	
	victim = NULL;
	
		for ( nch = ch->in_room->people; nch != NULL; nch = ch_next )
		{
			int count;
			
			ch_next	= nch->next_in_room;
			
			if ( !IS_NPC(nch) 
				||   number_bits(1) == 0)
				continue;
			
			count	= 0;
			victim	= NULL;
			for ( vch = ch->in_room->people; vch != NULL; vch = vch_next )
			{
				vch_next = vch->next_in_room;
				
				if (!IS_HERO(vch) && !IS_NPC(vch) )
				{
					if ( number_range( 0, count ) == 0 )
						victim = vch;
					count++;
				}
			}
			
			if (victim == NULL)
				return FALSE;
		}
		
	if ( number_percent() > 25 )
		return FALSE;

	if (victim == NULL)
		return FALSE;
	
	/* Cast spells for poor souls */
	silliness = number_range (1, 25);
	
	switch (silliness)	
	{
		case 1:
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_bless( skill_lookup( "bless" ), ch->level, ch, victim );
			break;
		case 2:
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_armor( skill_lookup( "armor" ), ch->level, ch, victim );
			break;
		case 3:
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_cure_blindness( skill_lookup( "cure blindness" ), ch->level, ch, victim );
			break;
		case 4:
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_cure_critical( skill_lookup( "cure critical" ), ch->level, ch, victim );
			break;
		case 5:
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_cure_light( skill_lookup( "cure light" ), ch->level, ch, victim );
			break;
		case 6:
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_cure_poison( skill_lookup( "cure poison" ), ch->level, ch, victim );
			break;
		case 7:
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_cure_serious( skill_lookup( "cure serious" ), ch->level, ch, victim );
			break;
		case 8:
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_fly( skill_lookup( "fly" ), ch->level, ch, victim );
			break;
		case 9:
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_frenzy( skill_lookup( "frenzy" ), ch->level, ch, victim );
			break;
		case 10:
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_mass_invis( skill_lookup( "mass invis" ), ch->level, ch, victim );
			break;
		case 11:
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_stone_skin( skill_lookup( "stone skin" ), ch->level, ch, victim );
			break;
		case 12:
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_sanctuary( skill_lookup( "sanctuary" ), ch->level, ch, victim );
			break;
		case 13:
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_protection( skill_lookup( "protection" ), ch->level, ch, victim );
			break;
		case 14:
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_cure_disease( skill_lookup( "cure disease" ), ch->level, ch, victim );
			break;
		case 15:
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_refresh( skill_lookup( "refresh" ), ch->level, ch, victim );
			break;
		case 16:
			act("$n's eyes glow bright blue for a moment.",ch,NULL,NULL,TO_ROOM);
			spell_darkblessing( skill_lookup( "darkblessing" ), ch->level, ch, victim );
			break;
		default:
			break;
	}
	return TRUE;
	
}

bool spec_plaguebear( CHAR_DATA *ch )
{
	int silliness;
	char buf[MAX_STRING_LENGTH];
	//bool pc_found = TRUE;
	CHAR_DATA *nch;
	CHAR_DATA *ch_next;
	CHAR_DATA *vch;
	CHAR_DATA *vch_next;
	CHAR_DATA *victim;
	
	if ( !IS_AWAKE(ch) )
		return FALSE;
	
	victim = NULL;
	
/* Here's Furey's aggress routine, with some surgery done to it.  
  	All it does is pick a potential victim for a social.  
  	(Thank you, Furey-- I screwed this up many times until I
  	learned of your way of doing it)                      */
	
	for ( nch = ch->in_room->people; nch != NULL; nch = ch_next )
	{
		int count;
		
		ch_next	= nch->next_in_room;
		
		if ( !IS_NPC(nch) 
			||   number_bits(1) == 0)
			continue;
			
	    /*
	     * Ok we have a 'wch' player character and a 'nch' npc aggressor.
	     * Now make the aggressor fight a RANDOM pc victim in the room,
	     *   giving each 'vch' an equal chance of selection.
	     */
			count	= 0;
			victim	= NULL;
			for ( vch = ch->in_room->people; vch != NULL; vch = vch_next )
			{
				vch_next = vch->next_in_room;
				
				if ( !IS_NPC(vch) )
				{
					if ( number_range( 0, count ) == 0 )
						victim = vch;
					count++;
				}
			}
			
			if (victim == NULL)
				return FALSE;
		}
		
	if ( number_percent() > 25 )
		return FALSE;

	if (victim == NULL)
		return FALSE;
	
	/* Cast spells for poor souls */
	silliness = number_range (1, 25);
	
	switch (silliness)	
	{
		case 1:
			sprintf( buf, "Here ya go a gift from our godess to you!");
			do_say ( ch, buf);
			act("{R$n's eyes glow bright red as they touch $N.{x",ch,NULL,victim,TO_ROOM);
			spell_plague( skill_lookup( "plague" ), ch->level, ch, victim );
			break;
		case 2:
			sprintf( buf, "We shall spread out gift to you!");
			do_say ( ch, buf);
			act("{R$n's eyes glow bright red as they touch $N.{x",ch,NULL,victim,TO_ROOM);
			spell_plague( skill_lookup( "plague" ), ch->level, ch, victim );
			break;
		case 3:
			sprintf( buf, "By newra you shall be plagued!");
			do_say ( ch, buf);
			act("{R$n's eyes glow bright red as they touch $N.{x",ch,NULL,victim,TO_ROOM);
			spell_plague( skill_lookup( "plague" ), ch->level, ch, victim );
			break;
		case 4:
			sprintf( buf, "excuse me, did you just see a eye roll here?");
			do_say ( ch, buf);
			break;
		case 5:
			sprintf( buf, "Feel the burn!");
			do_say ( ch, buf);
			act("{R$n's eyes glow bright red for a moment.{x",ch,NULL,NULL,TO_ROOM);
			spell_plague( skill_lookup( "plague" ), ch->level, ch, victim );
			break;
		case 6:
			sprintf( buf, "I told {WSpiral{c to kiss my ass and now look what happend!{x");
			do_say ( ch, buf);
			break;
		default:
			break;
	}
	return TRUE;
	
}

// Guards proc
void call_guards(CHAR_DATA *ch){
    CHAR_DATA *wch,*victim = NULL;
    bool found = FALSE;
    int count = 0,x;

    for (wch = ch->in_room->people; wch != NULL; wch = wch->next_in_room) {
        if (!IS_NPC(wch) && wch->creature != 0 && !IS_IMMORTAL(wch)) {
            if (IS_VAMPIRE(wch)) {
                //fangs or claws showed
                if (IS_VAMPAFF(wch,VAM_FANGS) && IS_VAMPAFF(wch,VAM_CLAWS)) {
                    found = TRUE;
                }
            }
            if (IS_MAGE(wch)) {
                //paradox is past a certain level
                if (wch->paradox[0] > 350) {
                    found = TRUE;
                }
            }
            if (IS_SWWF(wch)) {
                //they are ANY form other then human
                if (wch->pcdata->wwf_shape != SHAPE_HOMID) {
                    found = TRUE;
                }
            }
        }
    }
    
    if (!found) {
        return;
    }
    
    if (dice(5,20) < 95) {
        return;
    }
    
    //BRING IN THE GUARDS
    do_yell(ch, "Guards! Guards! I just saw a freak! Guards!");
    
    count = dice(1,4);
    
    for (x = 0;x < count; x++ ) {
        if (dice(1,10) > 5) 
            victim=create_mobile( get_mob_index( MOB_VNUM_LEO ) );
        else
            victim=create_mobile( get_mob_index( MOB_VNUM_E_LEO ) );
		if (victim == NULL)
			return;
        char_to_room( victim, ch->in_room );
    }
    
    do_yell(victim,"Do not worry fair citizens! For we are here!");
    
    return;
}