empiremud/cnf/
empiremud/doc/
empiremud/lib/boards/
empiremud/lib/etc/
empiremud/lib/misc/
empiremud/lib/plralias/F-J/
empiremud/lib/plralias/K-O/
empiremud/lib/plralias/P-T/
empiremud/lib/plralias/U-Z/
empiremud/lib/plrobjs/
empiremud/lib/plrobjs/F-J/
empiremud/lib/plrobjs/K-O/
empiremud/lib/plrobjs/P-T/
empiremud/lib/plrobjs/U-Z/
empiremud/lib/world/
empiremud/lib/world/mob/
empiremud/lib/world/obj/
empiremud/log/
/* ************************************************************************
*   File: vampire.c                                      EmpireMUD AD 1.0 *
*  Usage: Vampire code, based up White Wolf's Vampire: The Dark Ages      *
*                                                                         *
*  All rights reserved.  See license.doc for complete information.        *
*                                                                         *
*  Code base by Paul Clarke.  EmpireMUD Project, a tbgMUD Production.     *
*  Based upon CircleMUD 3.0, beta patch level 17, by Jeremy Elson.        *
*                                                                         *
*  Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University *
*  CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991.               *
************************************************************************ */

#include "conf.h"
#include "sysdep.h"

#include "structs.h"
#include "utils.h"
#include "comm.h"
#include "interpreter.h"
#include "handler.h"
#include "db.h"
#include "skills.h"
#include "vnums.h"
#include "empire.h"


/* External Definitions */
extern bool can_fight(Creature ch, Creature victim);
void death_log(Creature ch, Creature killer, int type);
void die(Creature ch);
void remove_lore(Creature ch, int type, long value);
extern int rev_dir[];
extern int last_action_rotation;


struct clan_data clan[] = {
	{ "Assamite",		TRUE,	TRUE,	{ DISC_CELERITY,	DISC_OBFUSCATE,		DISC_QUIETUS	}},
	{ "Brujah",			FALSE,	TRUE,	{ DISC_CELERITY,	DISC_POTENCE,		DISC_PRESENCE	}},
	{ "Cappadocian",	TRUE,	TRUE,	{ DISC_AUSPEX,		DISC_FORTITUDE,		DISC_MORTIS		}},
	{ "Follower of Set",TRUE,	TRUE,	{ DISC_OBFUSCATE,	DISC_PRESENCE,		DISC_SERPENTIS	}},
	{ "Gangrel",		TRUE,	TRUE,	{ DISC_ANIMALISM,	DISC_FORTITUDE,		DISC_PROTEAN	}},
	{ "Lasombra",		TRUE,	TRUE,	{ DISC_DOMINATE,	DISC_OBTENEBRATION,	DISC_POTENCE	}},
	{ "Malkavian",		FALSE,	TRUE,	{ DISC_AUSPEX,		DISC_DEMENTATION,	DISC_OBFUSCATE	}},
	{ "Nosferatu",		FALSE,	TRUE,	{ DISC_ANIMALISM,	DISC_OBFUSCATE,		DISC_POTENCE	}},
	{ "Ravnos",			FALSE,	TRUE,	{ DISC_ANIMALISM,	DISC_CHIMERSTRY,	DISC_FORTITUDE	}},
	{ "Toreador",		FALSE,	TRUE,	{ DISC_AUSPEX,		DISC_CELERITY,		DISC_PRESENCE	}},
	{ "Tremere",		TRUE,	TRUE,	{ DISC_AUSPEX,		DISC_DOMINATE,		DISC_THAUMATURGY}},
	{ "Tzimisce",		TRUE,	TRUE,	{ DISC_ANIMALISM,	DISC_AUSPEX,		DISC_VICISSITUDE}},
	{ "Ventrue",		FALSE,	TRUE,	{ DISC_DOMINATE,	DISC_FORTITUDE,		DISC_PRESENCE	}},
	{ "Caitiff",		FALSE,	FALSE,	{ -1,				-1,					-1				}},

	{ "\n", 0, 0, { -1, -1, -1 }}
	};


struct discipline_data disc[] = {
	{ "Animalism",		FALSE	},
	{ "Auspex",			FALSE	},
	{ "Celerity",		FALSE	},
	{ "Chimerstry",		FALSE	},
	{ "Dementation",	FALSE	},
	{ "Dominate",		FALSE	},
	{ "Fortitude",		FALSE	},
	{ "Mortis",			TRUE	},
	{ "Obfuscate",		FALSE	},
	{ "Obtenebration",	TRUE	},
	{ "Potence",		FALSE	},
	{ "Presence",		FALSE	},
	{ "Protean",		TRUE	},
	{ "Quietus",		TRUE	},
	{ "Serpentis",		TRUE	},
	{ "Thaumaturgy",	TRUE	},
	{ "Vicissitude",	TRUE	},

	{ "\n", 0 }
	};


struct discipline_data path[] = {
	{ "Rego Vitae",			TRUE	},
	{ "Creo Ignem",			TRUE	},
	{ "Rego Motus",			TRUE	},
	{ "Rego Tempestas",		TRUE	},
	{ "Rego Aquam",			TRUE	},
	{ "Rego Elementum",		TRUE	},
	{ "Way of Levinbolt",	TRUE	},
	{ "Path of Warding",	TRUE	},

	{ "\n", 0 }
	};


byte GET_MAX_BLOOD(Creature ch) {
	if (IS_NPC(ch))
		switch (MOB_TYPE(ch)) {
			case MTYPE_ANIMAL:			return 5;
			case MTYPE_HUMAN:			return 10;
			default:					return 5;
			}

	if (IS_VAMPIRE(ch))
		switch (GET_GENERATION(ch)) {
			case 1:		return 100;
			case 2:		return 100;
			case 3:		return 100;
			case 4:		return 50;
			case 5:		return 40;
			case 6:		return 30;
			case 7:		return 20;
			default:	return MAX(10, 10+13-GET_GENERATION(ch));
			}

	if (IS_GHOUL(ch))
		return (10 + GET_VAMP_BLOOD(ch));

	if (IS_WEREWOLF(ch))
		return 25;

	return 10;
	}


ACMD(do_bite) {
	Creature victim;
	byte to_hit, to_dodge = 0, dam = 0;

	one_argument(argument, arg);

	if (GET_FEEDING_FROM(ch)) {
		msg_to_char(ch, "You stop feeding.\r\n");
		act("$n stops feeding from $N.", FALSE, ch, 0, GET_FEEDING_FROM(ch), TO_ROOM);
		GET_FED_ON_BY(GET_FEEDING_FROM(ch)) = NULL;
		GET_FEEDING_FROM(ch) = NULL;
		}
	else if (GET_ACTION(ch) != ACT_EMBRACE && GET_ACTION(ch) != ACT_NONE)
		msg_to_char(ch, "You're a bit busy right now.\r\n");
	else if (!*arg)
		msg_to_char(ch, "Bite whom?\r\n");
	else if (subcmd ? (!(victim = get_player_vis(ch, arg, FIND_CHAR_ROOM))) : (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM))))
		msg_to_char(ch, NOPERSON);
	else if (ch == victim)
		msg_to_char(ch, "That seems a bit redundant..\r\n");
	else if (GET_FED_ON_BY(victim))
		msg_to_char(ch, "Sorry, somebody beat you to it.\r\n");
	else if (IS_GOD(victim) || IS_IMMORTAL(victim))
		msg_to_char(ch, "You can't bite an immortal!\r\n");
	else if ((IS_NPC(victim) || !PRF_FLAGGED(victim, PRF_BITEABLE)) && !can_fight(ch, victim))
		act("You can't attack $N!", FALSE, ch, 0, victim, TO_CHAR);
	else {
		if (SHOULD_APPEAR(ch))
			appear(ch);

		/* if the person isn't biteable, gotta roll! */
		if ((IS_NPC(victim) || !PRF_FLAGGED(victim, PRF_BITEABLE)) && AWAKE(victim)) {
			to_hit = ww_dice(GET_DEXTERITY(ch) + GET_BRAWL(ch), 6 + GET_BLOCK(victim));

			if (AWAKE(victim) && CAN_SEE(victim, ch))
				to_dodge = ww_dice(GET_DEXTERITY(victim) + GET_DODGE(victim), 8);

			if (to_hit > to_dodge) {
				dam = ww_dice(GET_STRENGTH(ch) + 2 + to_hit - to_dodge, 6) + GET_POTENCE(ch);
				dam -= ww_dice(GET_FORTITUDE(ch), 6);
				}
			if (dam <= 0) {
				act("You lunge at $N, but $E dodges you!", FALSE, ch, 0, victim, TO_CHAR);
				act("$n lunges at $N, but $E dodges it!", FALSE, ch, 0, victim, TO_NOTVICT);
				act("$n lunges at you, but you dodge $m!", FALSE, ch, 0, victim, TO_VICT);
				WAIT_STATE(ch, PULSE_VIOLENCE * 2);
				if (!FIGHTING(victim))
					hit(victim, ch);
				return;
				}
			}

		/* All-clear */
		GET_FEEDING_FROM(ch) = victim;
		GET_FED_ON_BY(victim) = ch;

		if (!IS_NPC(victim) && PRF_FLAGGED(victim, PRF_BITEABLE)) {
			act("You grasp $N's wrist and bite into it.", FALSE, ch, 0, victim, TO_CHAR);
			act("$n grasps $N's wrist and bites into it.", FALSE, ch, 0, victim, TO_NOTVICT);
			act("$n grasps your wrist and bites into it.", FALSE, ch, 0, victim, TO_VICT);
			}
		else {
			act("You lunge at $N, grasping onto $S neck and biting into it vigorously!", FALSE, ch, 0, victim, TO_CHAR);
			act("$n lunges at $N, grasping onto $S neck and biting into it vigorously!", FALSE, ch, 0, victim, TO_NOTVICT);
			act("$n lunges at you...  $e grasps onto your neck and bites into it!", FALSE, ch, 0, victim, TO_VICT | TO_SLEEP);
			}
		}
	}


/* Vampire mechanic for stealing power through blood-sucking */
void diablerize_char(Creature ch, Creature victim) {
	struct affected_type *af;
	int i, j = 0;
	bool found = FALSE;

	if (GET_GENERATION(ch) > GET_GENERATION(victim)) {
		GET_GENERATION(ch) -= 1;
		GET_GENERATION(victim) += 1;

		gain_experience(ch, 5 * (13 - GET_GENERATION(ch)));

		/* 1 Humanity guaranteed lost */
		GET_HUMANITY(ch) -= 1;

		CREATE(af, struct affected_type, 1);
		af->type = ATYPE_DIABLERIE;
		af->duration = 17280;
		af->modifier = 0;
		af->location = APPLY_NONE;
		af->bitvector = 0;
		af->disc_bit = 0;

		if (affected_by_spell(ch, ATYPE_DIABLERIE))
			affect_from_char(ch, ATYPE_DIABLERIE);
		affect_to_char(ch, af);

		/* If the gen is STILL higher, give a point of a discipline */
		if (GET_GENERATION(ch) + 1 > GET_GENERATION(victim)) {
			while (j++ < 20 && !found) {
				i = number(0, NUM_DISCS - 1);
				if (GET_DISC(victim, i) > GET_DISC(ch, i) + 1) {
					GET_REAL_DISC(ch, i) += 1;
					found = TRUE;
					}
				}
			}
		}

	/* Humanity */
	if (ww_dice(GET_CONSCIENCE(ch), 6) < 1 && GET_HUMANITY(ch) > 0)
		GET_HUMANITY(ch) -= 1;

	SAVE_CHAR(ch);
	SAVE_CHAR(victim);
	}


void update_biting(void) {
	Creature ch, next_ch, victim;
	int amt;

	for (ch = character_list; ch; ch = next_ch) {
		next_ch = ch->next;

		if (!(victim = GET_FEEDING_FROM(ch)))
			continue;

		if (GET_POS(ch) < POS_STANDING) {
			GET_FEEDING_FROM(ch) = NULL;
			GET_FED_ON_BY(victim) = NULL;
			continue;
			}

		if (victim->in_room != ch->in_room) {
			GET_FEEDING_FROM(ch) = NULL;
			GET_FED_ON_BY(victim) = NULL;
			continue;
			}

		/* Transfer blood */
		GET_BLOOD(victim) -= 2;

		/* Quickened blood */
		amt = 2;
		if (GET_QUIETUS(ch) >= 7 && !IS_VAMPIRE(victim) && !IS_GHOUL(victim))
			if (ww_dice(GET_STAMINA(ch) + GET_OCCULT(ch), 6) > 1)
				amt *= 2;

		GET_BLOOD(ch) = MIN(GET_MAX_BLOOD(ch), GET_BLOOD(ch) + amt);

		if (GET_BLOOD(victim) <= 0 && GET_ACTION(ch) != ACT_EMBRACE) {
			GET_BLOOD(victim) = 0;

			if (!IS_NPC(victim) && !PRF_FLAGGED(ch, PRF_AUTOKILL)) {
				do_bite(ch, "", 0, 0);
				return;
				}

			act("You pull the last of $N's blood from $S veins, and $E falls limply to the ground!", FALSE, ch, 0, victim, TO_CHAR);
			act("$N falls limply from $n's arms!", FALSE, ch, 0, victim, TO_NOTVICT);
			act("You feel faint as the last of your blood is pulled from your body!", FALSE, ch, 0, victim, TO_VICT);

			if (IS_VAMPIRE(victim))
				diablerize_char(ch, victim);

			if (!IS_NPC(victim))
				gain_experience(victim, -5);

			act("$n is dead!  R.I.P.", FALSE, victim, 0, 0, TO_ROOM);
			msg_to_char(victim, "You are dead!  Sorry...\r\n");
			if (!IS_NPC(victim)) {
				death_log(victim, ch, ATTACK_EXECUTE);
				add_lore(ch, LORE_PLAYER_KILL, GET_IDNUM(victim));
				add_lore(victim, LORE_PLAYER_DEATH, GET_IDNUM(ch));
				}

			GET_FED_ON_BY(victim) = NULL;
			GET_FEEDING_FROM(ch) = NULL;

			die(victim);
			}
		else {
			act("You shudder with ecstasy as you feed from $N!", FALSE, ch, 0, victim, TO_CHAR);
			act("$n shudders with ecstasy as $e feeds from $N!", FALSE, ch, 0, victim, TO_NOTVICT);
			act("A surge of ecstasy fills your body as $n feeds from your veins!", FALSE, ch, 0, victim, TO_VICT);
			}
		}
	}


void embrace_char(Creature ch, Creature victim) {
	GET_FEEDING_FROM(ch) = NULL;
	GET_FED_ON_BY(victim) = NULL;

	/* set BEFORE set as a vampire! */
	GET_APPARENT_AGE(victim) = GET_AGE(victim);

	if (IS_GHOUL(victim))
		REMOVE_BIT(PLR_FLAGS(victim), PLR_GHOUL);
	SET_BIT(PLR_FLAGS(victim), PLR_VAMPIRE);

	GET_GENERATION(victim) = GET_GENERATION(ch) + 1;

	if (clan[(int) GET_CLAN(ch)].hardcore && !IS_HARDCORE(victim))
		GET_REAL_CLAN(victim) = CLAN_CAITIFF;
	else
		GET_REAL_CLAN(victim) = GET_CLAN(ch);

	GET_PRIMARY_PATH(victim) = GET_PRIMARY_PATH(ch);

	GET_CONSCIENCE(victim) = GET_CONSCIENCE(ch);
	GET_SELF_CONTROL(victim) = GET_SELF_CONTROL(ch);
	GET_COURAGE(victim) = GET_COURAGE(ch);

	GET_HUMANITY(victim) -= number(0, 4);

	/* Reduce mortal skills by 1/2 */

	GET_BLOOD(victim) = 3;
	GET_BLOOD(ch) -= 1;

	act("$N drops limply from your fangs...", FALSE, ch, 0, victim, TO_CHAR);
	act("$N drops limply from $n's fangs...", FALSE, ch, 0, victim, TO_NOTVICT);
	act("You fall limply the ground.  In the distance, you think you see a light...", FALSE, ch, 0, victim, TO_VICT);

	act("You tear open your wrist with your fangs and drip blood into $N's mouth!", FALSE, ch, 0, victim, TO_CHAR);
	act("$n tears open $s wrist with $s teeth and drips blood into $N's mouth!", FALSE, ch, 0, victim, TO_NOTVICT);
	msg_to_char(victim, "Suddenly, a warm sensation touches your lips and a stream of blood flows down your throat..\r\n");
	msg_to_char(victim, "As the blood fills you, a strange sensation covers your body...  The light in the distance turns blood-red and a hunger builds within you!\r\n");
	msg_to_char(victim, "You come to the sudden realization that you are no longer the child of any God, but the progeny of Caine, cursed forever to drink blood!\r\n");

	msg_to_char(victim, "You sit up quickly, nearly knocking over your sire!\r\n");
	act("$n sits up quickly!", FALSE, victim, 0, 0, TO_ROOM);

	gain_experience(ch, 15);
	gain_experience(victim, 25);

	add_lore(victim, LORE_EMBRACE_VAMPIRE, GET_IDNUM(ch));
	add_lore(ch, LORE_MAKE_VAMPIRE, GET_IDNUM(victim));

	/* Turn off that Embrace action */
	GET_ACTION(ch) = ACT_NONE;

	SAVE_CHAR(ch);
	SAVE_CHAR(victim);
	}


ACMD(do_embrace) {
	extern struct time_info_data *real_time_passed(time_t t2, time_t t1);

	extern int last_action_rotation;
	Creature victim;
	struct time_info_data playing_time;

	one_argument(argument, arg);

	if (!*arg)
		msg_to_char(ch, "Embrace whom?\r\n");
	else if (GET_ACTION(ch) != ACT_NONE)
		msg_to_char(ch, "You're too busy to do that.\r\n");
	else if (GET_GENERATION(ch) >= 13)
		msg_to_char(ch, "Your blood is too thin to Embrace.\r\n");
	else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)))
		msg_to_char(ch, NOPERSON);
	else if (IS_NPC(victim))
		msg_to_char(ch, "You can't Embrace an NPC.\r\n");
	else if (IS_VAMPIRE(victim))
		msg_to_char(ch, "You can't Embrace a vampire!\r\n");
	else if (IS_GOD(victim) || IS_IMMORTAL(victim))
		msg_to_char(ch, "You can't Embrace a deity!\r\n");
	else {
		playing_time = *real_time_passed((time(0) - victim->player.time.logon) + victim->player.time.played, 0);

		if (playing_time.day < 0)
			msg_to_char(ch, "You may not Embrace someone with less than a full day of play time.\r\n");
		else {
			/* Werewolves can't be Embraced, they'll die */
			if (!IS_WEREWOLF(victim)) {
				GET_ACTION(ch) = ACT_EMBRACE;
				GET_ACTION_ROTATION(ch) = last_action_rotation;
				GET_ACTION_ROOM(ch) = NOWHERE;
				}
			sprintf(buf, "%s", GET_NAME(victim));
			do_bite(ch, buf, 0, 1);
			}
		}
	}


ACMD(do_vampire_heal) {
	int amt = 1;

	one_argument(argument, arg);

	if (!*arg)
		amt = MIN(GET_BLOOD(ch) - 1, GET_DAMAGE(ch) - GET_AGG_DAMAGE(ch));

	if (GET_DAMAGE(ch) == 0)
		msg_to_char(ch, "You don't need to be healed!\r\n");
	else if (*arg && (amt = (MIN(GET_DAMAGE(ch), atoi(arg)))) < 1)
		msg_to_char(ch, "Heal yourself how much?\r\n");
	else if (amt > GET_DAMAGE(ch) - GET_AGG_DAMAGE(ch))
		msg_to_char(ch, "You can't heal that much!\r\n");
	else if (amt < 0)
		msg_to_char(ch, "You can't heal that much!\r\n");
	else if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
	else if (amt > GET_BLOOD(ch) - 1)
		msg_to_char(ch, "You don't have enough blood to do that!\r\n");
	else {
		GET_BLOOD(ch) -= amt;
		GET_DAMAGE(ch) -= amt;

		if (GET_POS(ch) < POS_SLEEPING && GET_DAMAGE(ch) < 7)
			GET_POS(ch) = POS_STANDING;

		msg_to_char(ch, "You focus your blood into your wounds, supernaturally healing them!\r\n");
		act("$n's wounds seal themself!", FALSE, ch, 0, 0, TO_ROOM);
		}
	}


ACMD(do_slit) {
	if (GET_SLIT_WRIST(ch))
		msg_to_char(ch, "Your wrist has already been slit!\r\n");
	else {
		GET_SLIT_WRIST(ch) = TRUE;
		WAIT_STATE(ch, PULSE_VIOLENCE);
		msg_to_char(ch, "You slit your wrist with your thumbnail!\r\n");
		act("$n places $s thumbnail to $s wrist and slices it open!", TRUE, ch, 0, 0, TO_ROOM);
		}
	}


ACMD(do_seal) {
	if (!GET_SLIT_WRIST(ch))
		msg_to_char(ch, "Your wrist isn't even slit!\r\n");
	else {
		GET_SLIT_WRIST(ch) = FALSE;
		WAIT_STATE(ch, PULSE_VIOLENCE);
		msg_to_char(ch, "You lick shut the wound on your wrist.\r\n");
		act("$n slides $s tongue across $s wrist, sealing the open wound!", TRUE, ch, 0, 0, TO_ROOM);
		}
	}


ACMD(do_feed) {
	Creature victim;
	int amt = 0;

	two_arguments(argument, arg, buf);

	if (!GET_SLIT_WRIST(ch))
		msg_to_char(ch, "You must slit your wrist first.\r\n");
	else if (!*arg || !*buf)
		msg_to_char(ch, "Feed whom how much blood?\r\n");
	else if ((amt = atoi(buf)) <= 0)
		msg_to_char(ch, "Feed how much blood?\r\n");
	else if (amt > GET_BLOOD(ch) - 1)
		msg_to_char(ch, "You can't give THAT much blood.\r\n");
	else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)))
		msg_to_char(ch, NOPERSON);
	else if (IS_NPC(victim) || (!PRF_FLAGGED(victim, PRF_FEEDABLE) && !IS_INJURED(victim, INJ_TORPOR)))
		act("$E refuses your vitae.", FALSE, ch, 0, victim, TO_CHAR);
	else {
		act("You feed $N some blood from your wrist!", FALSE, ch, 0, victim, TO_CHAR);
		act("$n feeds $N some blood from a cut in $s wrist!", TRUE, ch, 0, victim, TO_NOTVICT);
		act("$n feeds you some blood from the cut in $s wrist!", FALSE, ch, 0, victim, TO_VICT);

		/* Make the target a Ghoul */
		if (!IS_NPC(victim) && !IS_VAMPIRE(victim) && CAN_SPEND_BLOOD(ch)) {
			/* This is done BEFORE making victim a Ghoul so if he's already one, it doesn't do it */
			GET_GENERATION(victim) = (IS_GHOUL(victim) ? MIN(GET_GENERATION(victim), GET_GENERATION(ch)) : GET_GENERATION(ch));

			if (!IS_GHOUL(victim)) {
				remove_lore(ch, LORE_MAKE_GHOUL, -1);
				add_lore(victim, LORE_MAKE_GHOUL, GET_IDNUM(ch));
				}

			GET_REAL_CLAN(victim) = NUM_CLANS;	/* 1 > max */

			SET_BIT(PLR_FLAGS(victim), PLR_GHOUL);
			/* Update his vampire-blood counter */
			GET_VAMP_BLOOD(victim) = MIN(10, GET_VAMP_BLOOD(victim) + amt);
			/* Ghouls have at least 1 point of Potence */
			GET_REAL_DISC(victim, DISC_POTENCE) = MAX(1, GET_REAL_DISC(victim, DISC_POTENCE));
			}

		/* Remove torpor */
		if (IS_VAMPIRE(victim) && IS_INJURED(victim, INJ_TORPOR)) {
			REMOVE_BIT(INJURY_FLAGS(victim), INJ_TORPOR);
			msg_to_char(victim, "You awaken from torpor!\r\n");
			GET_POS(victim) = POS_RESTING;
			}

		/* Actual blood is set here so as not to conflict with ghoul code */
		GET_BLOOD(ch) -= amt;
		GET_BLOOD(victim) = MIN(GET_MAX_BLOOD(victim), GET_BLOOD(victim) + amt);

		/*
		 * Blood Oath
		 *  This will address the thrall of the Blood Oath in the future.
		 *  Until then, there is no downside to sharing blood.
		 */
		}
	}


ACMD(do_teach) {
	extern struct time_info_data *real_time_passed(time_t t2, time_t t1);

	Creature target;
	int discipline = -1;
	struct time_info_data playing_time;

	/* calculate play time */
	playing_time = *real_time_passed((time(0) - ch->player.time.logon) + ch->player.time.played, 0);

	two_arguments(argument, arg, buf);

	if (*buf)
		for (discipline = 0; !is_abbrev(buf, disc[discipline].name) && str_cmp(disc[discipline].name, "\n"); discipline++);

	if (playing_time.day < 2)
		msg_to_char(ch, "You require two days of play time to teach disciplines.\r\n");
	else if (!*arg || !*buf)
		msg_to_char(ch, "Teach whom, and what discipline?\r\n");
	else if (!(target = get_char_vis(ch, arg, FIND_CHAR_ROOM)))
		msg_to_char(ch, NOPERSON);
	else if (ch == target)
		msg_to_char(ch, "You can't teach yourself!  What do you think this is, Disciplines For Dummies?\r\n");
	else if (IS_NPC(target))
		act("You can't teach $M that!", FALSE, ch, 0, target, TO_CHAR);
	else if (!IS_VAMPIRE(target) && !IS_GHOUL(target))
		msg_to_char(ch, "You may only teach disciplines to vampires and ghouls.\r\n");
	else if (discipline == -1 || !str_cmp(disc[discipline].name, "\n"))
		msg_to_char(ch, "That's not a discipline!\r\n");
	else if (!PRF_FLAGGED(target, PRF_TEACHABLE))
		act("$E does not wish to be taught.", FALSE, ch, 0, target, TO_CHAR);
	else if (GET_REAL_DISC(ch, discipline) <= GET_REAL_DISC(target, discipline))
		act("There's nothing you could teach $M about that discipline.", FALSE, ch, 0, target, TO_CHAR);
	else if (GET_REAL_DISC(target, discipline) >= disc_max(target))
		act("$N already knows as much about that discipline as $E can learn.", FALSE, ch, 0, target, TO_CHAR);
	else if (discipline == DISC_THAUMATURGY && GET_REAL_DISC(target, discipline) >= 5)
		act("$N already knows as much about that discipline as $E can learn.", FALSE, ch, 0, target, TO_CHAR);
	else if ((!GET_REAL_DISC(target, discipline) && GET_EXPERIENCE(target) < 10) || (GET_REAL_DISC(target, discipline) && GET_EXPERIENCE(target) < 7 * GET_REAL_DISC(target, discipline)))
		act("$E does not have enough experience points to learn that!", FALSE, ch, 0, target, TO_CHAR);
	else {
		if (GET_REAL_DISC(target, discipline))
			gain_experience(target, -7 * GET_REAL_DISC(target, discipline));
		else
			gain_experience(target, -10);

		GET_REAL_DISC(target, discipline) += 1;

		if (discipline == DISC_THAUMATURGY)
			GET_REAL_PATH(target, (int) GET_REAL_PRIMARY_PATH(target)) = GET_THAUMATURGY(target);

		sprintf(buf, "You teach a new level of %s to $N!", disc[discipline].name);
		sprintf(buf1, "$n teaches you a new level of %s!", disc[discipline].name);

		act(buf, FALSE, ch, 0, target, TO_CHAR);
		act(buf1, FALSE, ch, 0, target, TO_VICT);

		SAVE_CHAR(target);
		}
	}


/* Returns the room number of the BEDROOM for a vampire to start in */
room_rnum create_haven(Creature ch) {
	void create_exit(room_rnum from, room_rnum to, int dir, bool back);
	extern room_rnum create_room(room_vnum vnum);
	extern room_vnum find_free_vnum();
	extern int create_empire(Creature ch);
	extern bool is_entrance(int rnum);

	room_rnum hall = create_room(find_free_vnum());
	room_rnum bedroom = create_room(find_free_vnum());
	room_rnum study = create_room(find_free_vnum());
	int e = -1, to_dir[3], dir = NORTH, count = 0;
	room_rnum main_room = 0;
	Creature m;

	/* if the owner has no empire, build one now */
	if ((e = real_empire(GET_LOYALTY(ch))) == -1 && GET_IDNUM(ch) != 0)
		e = create_empire(ch);

	if (e != -1)
		empire[e].territory += 1;

	/* Find a place to be */
	while (count < 10000000) {
		count++;
		main_room = number(0, MAP_SIZE - 1);

		/* Make sure it isn't owned.. */
		if (world[main_room].owner != 0)
			continue;

		/* Make sure it's a type we can use */
		if (SECT(main_room) != SECT_DESERT && SECT(main_room) != SECT_FIELD && SECT(main_room) != SECT_FOREST_4 && SECT(main_room) != SECT_MOUNTAIN)
			continue;

		/* Check for a valid direction of same sect */
		for (dir = 0; dir < NUM_2D_DIRS; dir++)
			if (!number(0, 1) && SECT(real_shift(main_room, shift_dir[dir][0], shift_dir[dir][1])) == SECT(main_room))
				break;
		if (dir == NUM_2D_DIRS)
			continue;

		/* Check that this isn't an entrance */
		if (is_entrance(main_room))
			continue;

		/* Check to make sure no pc's are in the room */
		for (m = world[main_room].people; m; m = m->next_in_room)
			if (!IS_NPC(m))
				break;
		if (m)
			continue;

		/* Room is clear */
		break;
		}
	if (count == 10000000)
		return 0;

	/* Clean out the room.. this isn't a farm */
	while (world[main_room].people)
		extract_char(world[main_room].people);

	switch (SECT(main_room)) {
		case SECT_MOUNTAIN:
			world[main_room].type = BUILDING_HAVEN_CAVE;
			world[hall].type = RTYPE_TUNNEL;
			break;
		case SECT_DESERT:
			world[main_room].type = BUILDING_HAVEN_PUEBLO;
			world[hall].type = RTYPE_HALL;
			break;
		case SECT_FOREST_4:
			world[main_room].type = BUILDING_HAVEN_BURROW;
			world[hall].type = RTYPE_TUNNEL;
			break;
		case SECT_FIELD:
		default:
			world[main_room].type = BUILDING_HAVEN_HOUSE;
			world[hall].type = RTYPE_HALL;
			break;
		}

	/* the main room */
	SECT(main_room) = SECT_BUILDING;
	world[main_room].owner = GET_IDNUM(ch);
	world[main_room].home_room = NOWHERE;
	world[main_room].type2 = 0;
	world[main_room].building_entrance = rev_dir[dir];
	world[main_room].res.logs = 0;
	world[main_room].res.sticks = 0;
	world[main_room].res.iron = 0;
	world[main_room].res.rocks = 0;
	world[main_room].build_value = 0;
	world[main_room].spare = 0;
	world[main_room].inside_rooms = 3;
	if (e != -1)
		empire[e].haven = world[main_room].number;

	/* the hallway */
	SECT(hall) = SECT_INSIDE;
	world[hall].owner = GET_IDNUM(ch);
	world[hall].home_room = world[main_room].number;
	world[hall].type2 = 0;

	/* the bedroom */
	SECT(bedroom) = SECT_INSIDE;
	world[bedroom].owner = GET_IDNUM(ch);
	world[bedroom].home_room = world[main_room].number;
	world[bedroom].type = RTYPE_BEDROOM;
	world[bedroom].type2 = 0;

	/* the study */
	SECT(study) = SECT_INSIDE;
	world[study].owner = GET_IDNUM(ch);
	world[study].home_room = world[main_room].number;
	world[study].type = RTYPE_STUDY;
	world[study].type2 = 0;

	/* load a board in the study */
	obj_to_room(read_object(BOARD_MORT, VIRTUAL), study);

	/* set up the directions */
	switch (dir) {
		case NORTH:
			to_dir[0] = EAST;
			to_dir[1] = SOUTH;
			to_dir[2] = WEST;
			break;
		case EAST:
			to_dir[0] = NORTH;
			to_dir[1] = WEST;
			to_dir[2] = SOUTH;
			break;
		case SOUTH:
			to_dir[0] = EAST;
			to_dir[1] = NORTH;
			to_dir[2] = WEST;
			break;
		case WEST:
		default:
			to_dir[0] = EAST;
			to_dir[1] = SOUTH;
			to_dir[2] = NORTH;
			break;
		}

	/* link the rooms */
	create_exit(main_room, real_shift(main_room, shift_dir[dir][0], shift_dir[dir][1]), dir, FALSE);
	create_exit(main_room, hall, rev_dir[dir], TRUE);

	/* these are linked randomly */
	switch (number(0, 5)) {
		case 0:
			create_exit(hall, bedroom, to_dir[0], TRUE);
			create_exit(hall, study, to_dir[1], TRUE);
			break;
		case 1:
			create_exit(hall, bedroom, to_dir[1], TRUE);
			create_exit(hall, study, to_dir[0], TRUE);
			break;
		case 2:
			create_exit(hall, bedroom, to_dir[0], TRUE);
			create_exit(hall, study, to_dir[2], TRUE);
			break;
		case 3:
			create_exit(hall, bedroom, to_dir[2], TRUE);
			create_exit(hall, study, to_dir[0], TRUE);
			break;
		case 4:
			create_exit(hall, bedroom, to_dir[1], TRUE);
			create_exit(hall, study, to_dir[2], TRUE);
			break;
		case 5:
		default:
			create_exit(hall, bedroom, to_dir[2], TRUE);
			create_exit(hall, study, to_dir[1], TRUE);
			break;
		}

	/* and we're done.. return the bedroom rnum */
	return (bedroom);
	}


/* Finds a haven loadroom if the character's empire has one */
room_rnum find_haven(Creature ch) {
	int e, i;
	room_rnum h;

	if ((e = real_empire(GET_LOYALTY(ch))) == -1)
		return NOWHERE;

	if ((h = real_room(empire[e].haven)) == NOWHERE)
		return NOWHERE;

	for (i = 0; i < NUM_OF_DIRS; i++)
		if (world[h].dir_option[i] && world[h].dir_option[i]->to_room != NOWHERE)
			if (SECT(world[h].dir_option[i]->to_room) == SECT_INSIDE)
				return (world[h].dir_option[i]->to_room);

	return NOWHERE;
	}


/* ************************** Discipline Code *************************** */

#define ADISC(name)		void name(Creature ch, char *argument, int subcmd)
extern struct discipline_power_data discs[];
extern struct discipline_power_data paths[];


/* A dummy function for discs that aren't ready yet ********************* */
ADISC(disc_uncoded) {
	msg_to_char(ch, "This discipline is currently uncoded.\r\n");
	}


/* Animalism Powers */
ADISC(disc_animalism) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Animalism is the art of communicating with and controlling animals.  More\r\nimportantly, though, is its understanding of the Beast within.\r\nPowers:\r\n");

	for (i = 0; str_cmp(discs[i].name, "\n"); i++)
		if (discs[i].disc == DISC_ANIMALISM && discs[i].level <= GET_ANIMALISM(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", discs[i].name);
			else
				found = TRUE;
			}
	}


ADISC(disc_feral_speech) {
	msg_to_char(ch, "Feral speech is a power which allows you to understand the communication of\r\nanimals, or those who have shapeshifted into the form of an animal.  It is\r\nalso the first step to being able to command the animals.\r\n");
	}


ADISC(disc_noahs_call) {
	Creature mob;
	int i;

	int num_animals = 10;	/* 1 < than the number of vnums */
	int vnums[] = { SMALL_WOLF, SHEEP, DEER, BUCK, SQUIRREL, COW, DOG, HORSE, MULE, CAMEL, CAT };

	switch (SECT(ch->in_room)) {
		case SECT_OCEAN:
		case SECT_RIVER:
			msg_to_char(ch, "You can't summon animals while in the water!\r\n");
			return;
		case SECT_MOUNTAIN:
			msg_to_char(ch, "You can't summon animals onto a mountain!\r\n");
			return;
		case SECT_BUILDING:
		case SECT_MULTI:
		case SECT_INSIDE:
			msg_to_char(ch, "You can't summon animals indoors!  Go outside first.\r\n");
			return;
		case SECT_ROAD:
		case SECT_WELL:
		case SECT_FOUNTAIN:
		case SECT_BARRIER:
		case SECT_MONUMENT_OPEN:
		case SECT_MONUMENT_CLOSED:
		case SECT_TOWER_OF_SOULS:
		case SECT_WASTELAND:
			msg_to_char(ch, "You can't summon animals here.\r\n");
			return;
		}

	i = ww_dice(GET_CHARISMA(ch) + GET_SURVIVAL(ch), 6);

	msg_to_char(ch, "You rock your head backward and howl into the wind...\r\n");
	act("$n rocks $s head backward and howls into the wind!", FALSE, ch, 0, 0, TO_ROOM);

	if (i <= 0)
		msg_to_char(ch, "...but no animals respond.\r\n");
	else
		for (; i > 0; i--) {
			char_to_room((mob = read_mobile(vnums[number(0, num_animals)], VIRTUAL)), ch->in_room);
			act("$n runs up!", FALSE, mob, 0, 0, TO_ROOM);
			}
	}


ADISC(disc_cowing_the_beast) {
	Creature victim;
	int result;
	struct affected_type *af;

	one_argument(argument, arg);

	if (!*arg && !FIGHTING(ch))
		msg_to_char(ch, "Whose beast would you like to cow?\r\n");
	else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)) && !(victim = FIGHTING(ch)))
		msg_to_char(ch, NOPERSON);
	else if ((IS_GOD(victim) && !IS_GOD(ch)) || IS_IMMORTAL(victim))
		act("You can't cow $S beast!", FALSE, ch, 0, victim, TO_CHAR);
	else if (IS_VAMPIRE(victim) && IS_VAMPIRE(ch) && GET_GENERATION(victim) <= GET_GENERATION(ch))
		act("$E is too powerful for you to cow $S beast.", FALSE, ch, 0, victim, TO_CHAR);
	else if (DSC_FLAGGED(victim, DSC_CANT_SPEND_WILLPOWER))
		act("$S beast is already cowed.", FALSE, ch, 0, victim, TO_CHAR);
	else if (!can_fight(ch, victim))
		act("You can't cow $N!", FALSE, ch, 0, victim, TO_CHAR);
	else if ((result = ww_dice(GET_MANIPULATION(ch) + GET_INTIMIDATION(ch), 7)) BOTCHED) {
		if (SHOULD_APPEAR(ch))
			appear(ch);

		act("In trying to cow $N's beast, your is accidently tranquilized!", FALSE, ch, 0, victim, TO_CHAR);

		CREATE(af, struct affected_type, 1);
		af->type = ATYPE_COWING_THE_BEAST;
		af->duration = 12;
		af->modifier = 0;
		af->location = APPLY_NONE;
		af->bitvector = 0;
		af->disc_bit = DSC_CANT_SPEND_WILLPOWER;

		affect_join(ch, af, 1, 0, 0, 0);
		}
	else if (result FAILED) {
		if (SHOULD_APPEAR(ch))
			appear(ch);

		act("$n screams at you!", FALSE, ch, 0, victim, TO_VICT);
		act("$n screams at $N!", FALSE, ch, 0, victim, TO_NOTVICT);
		act("Try as you might, you fail to cow $S beast!", FALSE, ch, 0, victim, TO_CHAR);
		}
	else {
		if (SHOULD_APPEAR(ch))
			appear(ch);

		act("You focus your beast and ROAR at $N!", FALSE, ch, 0, victim, TO_CHAR);
		act("$n leaps at $N and ROARS at $M!", FALSE, ch, 0, victim, TO_NOTVICT);
		act("$n leaps at you, roaring loudly!", FALSE, ch, 0, victim, TO_VICT);
		msg_to_char(victim, "You shiver uncomfortably and back down!\r\n");
		act("$n shivers uncomfortably and takes an uneasy step backwards!", FALSE, victim, 0, 0, TO_ROOM);

		CREATE(af, struct affected_type, 1);
		af->type = ATYPE_COWING_THE_BEAST;
		af->duration = result;
		af->modifier = 0;
		af->location = APPLY_NONE;
		af->bitvector = 0;
		af->disc_bit = DSC_CANT_SPEND_WILLPOWER;

		affect_to_char(victim, af);
		}
	}


/* Auspex Powers */
ADISC(disc_auspex) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Auspex is a sense-enhancing power with deep roots in mental prowess.  It\r\nallows superior mental ability and serves as a countermeasure to Obfuscate.\r\nPowers:\r\n");

	for (i = 0; str_cmp(discs[i].name, "\n"); i++)
		if (discs[i].disc == DISC_AUSPEX && discs[i].level <= GET_AUSPEX(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", discs[i].name);
			else
				found = TRUE;
			}
	}


ADISC(disc_heightened_senses) {
	if (DSC_FLAGGED(ch, DSC_HEIGHTENED_SENSES)) {
		msg_to_char(ch, "You lower your senses.\r\n");
		REMOVE_BIT(DSC_FLAGS(ch), DSC_HEIGHTENED_SENSES);
		}
	else {
		msg_to_char(ch, "You heighten your senses.\r\n");
		SET_BIT(DSC_FLAGS(ch), DSC_HEIGHTENED_SENSES);
		}
	}


ADISC(disc_soulsight) {
	Creature victim;
	byte detail;

	one_argument(argument, arg);

	if (!*arg)
		msg_to_char(ch, "Use soulsight upon whom?\r\n");
	else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)))
		msg_to_char(ch, NOPERSON);
	else if (victim == ch)
		msg_to_char(ch, "You can't use this upon yourself!\r\n");
	else {
		detail = ww_dice(GET_PERCEPTION(ch) + GET_EMPATHY(ch), 8 - SENSES_BONUS(ch));

		act("Your analysis of $N reveals:", FALSE, ch, 0, victim, TO_CHAR);
		if (DSC_FLAGGED(victim, DSC_SOUL_MASK))
			act(" $E is a human.", FALSE, ch, 0, victim, TO_CHAR);
		else if (detail >= 3) {
			sprintf(buf, " $E is a %s.", IS_VAMPIRE(victim) ? "Cainite" : (IS_GHOUL(victim) ? "ghoul" : (IS_WEREWOLF(victim) ? "Lupine" : (IS_HUMAN(victim) ? "human" : "unknown"))));
			act(buf, FALSE, ch, 0, victim, TO_CHAR);

			/* Clan weakness: Assamite */
			if (IS_VAMPIRE(victim) && (affected_by_spell(victim, ATYPE_DIABLERIE) || GET_CLAN(victim) == CLAN_ASSAMITE))
				act(" $E has recently committed Diablerie.", FALSE, ch, 0, victim, TO_CHAR);
			}
		else
			msg_to_char(ch, "Nothing of interest.\r\n");

		WAIT_STATE(ch, PULSE_VIOLENCE * 2);
		}
	}


ADISC(disc_spirits_touch) {
	extern const char *extra_bits[];
	extern const int dam_type[];
	extern struct attack_hit_type attack_hit_text[];
	extern const char *drinks[];
	extern const char *crops[];
	extern const char *affected_bits[];

	Object obj;
	byte detail;

	one_argument(argument, arg);

	if (!*arg)
		msg_to_char(ch, "Use spirit's touch on what object?\r\n");
	else if (!(obj = get_obj_in_list_vis(ch, arg, ch->carrying)) && !(obj = get_obj_in_list_vis(ch, arg, world[ch->in_room].contents)))
		msg_to_char(ch, "You see nothing like that here.\r\n");
	else {
		detail = ww_dice(GET_PERCEPTION(ch) + GET_EMPATHY(ch), 6 - SENSES_BONUS(ch));

		act("Your analysis of $p reveals:", FALSE, ch, obj, 0, TO_CHAR);

		sprintbit(GET_OBJ_EXTRA(obj), extra_bits, buf, TRUE);
		msg_to_char(ch, "It is: &2%s&0\r\n", buf);

		sprintbit(obj->obj_flags.bitvector, affected_bits, buf, TRUE);
		msg_to_char(ch, "Grants: %s\r\n", buf);

		switch (GET_OBJ_TYPE(obj)) {
			case ITEM_WEAPON:
				if (GET_OBJ_VAL(obj, 0) > 0)
					msg_to_char(ch, "Has %d attacks' worth of aggravated damage.", GET_OBJ_VAL(obj, 0));
				else if (GET_OBJ_VAL(obj, 0) == -1)
					msg_to_char(ch, "Does aggravated damage.\r\n");

				msg_to_char(ch, "Damage equal to Strength");
				if (GET_OBJ_VAL(obj, 1) != 0)
					msg_to_char(ch, " %+d.\r\n", GET_OBJ_VAL(obj, 1));
				else
					msg_to_char(ch, ".\r\n");

				switch (dam_type[GET_OBJ_VAL(obj, 2)]) {
					case DAM_BASHING:			sprintf(buf, "bashing");	break;
					case DAM_LETHAL:			sprintf(buf, "lethal");		break;
					case DAM_AGGRAVATED:		sprintf(buf, "aggravated");	break;
					}
				msg_to_char(ch, "Damage type is %s (%s).\r\n", attack_hit_text[GET_OBJ_VAL(obj, 2)].singular, buf);
				break;
			case ITEM_WORN:
				if (CAN_WEAR(obj, ITEM_WEAR_SHEATH) && GET_OBJ_VAL(obj, 0) > -1)
					msg_to_char(ch, "Holds weapon type %s.\r\n", attack_hit_text[GET_OBJ_VAL(obj, 0)].singular);
				if (CAN_WEAR(obj, ITEM_WEAR_SHEATH) && GET_OBJ_VAL(obj, 1) > -1)
					msg_to_char(ch, "Holds weapon type %s.\r\n", attack_hit_text[GET_OBJ_VAL(obj, 1)].singular);
				if (CAN_WEAR(obj, ITEM_WEAR_SHEATH) && GET_OBJ_VAL(obj, 2) > -1)
					msg_to_char(ch, "Holds weapon type %s.\r\n", attack_hit_text[GET_OBJ_VAL(obj, 2)].singular);
				break;
			case ITEM_CONTAINER:
				msg_to_char(ch, "Holds %d pounds.\r\n", GET_OBJ_VAL(obj, 0));
				break;
			case ITEM_DRINKCON:
				msg_to_char(ch, "Contains %d ounces of %s.\r\n", GET_OBJ_VAL(obj, 1), drinks[GET_OBJ_VAL(obj, 2)]);
				break;
			case ITEM_FOOD:
				msg_to_char(ch, "Fills for %d hours.\r\n", GET_OBJ_VAL(obj, 0));
				if (OBJ_FLAGGED(obj, ITEM_PLANTABLE))
					msg_to_char(ch, "Plants %s.\r\n", crops[GET_OBJ_VAL(obj, 1)]);
				break;
			case ITEM_CORPSE:
				msg_to_char(ch, "Corpse of ");

				if (real_mobile(GET_OBJ_VAL(obj, 0)) != NOTHING)
					msg_to_char(ch, "%s\r\n", GET_MOB_NAME_BY_PROTO(real_mobile(GET_OBJ_VAL(obj, 0))));
				else if (GET_OBJ_VAL(obj, 0) >= 0)
					msg_to_char(ch, "nothing.\r\n");
				else
					msg_to_char(ch, "%s.\r\n", get_name_by_id(-1 * GET_OBJ_VAL(obj, 0)) ? CAP(get_name_by_id(-1 * GET_OBJ_VAL(obj, 0))) : "a player");

				msg_to_char(ch, "Size: %d cu.\r\n", GET_OBJ_VAL(obj, 1));

				break;
			case ITEM_SKIN:
				msg_to_char(ch, "Size: %d cu.\r\n", GET_OBJ_VAL(obj, 0));
				break;
			case ITEM_CART:
				msg_to_char(ch, "Holds %d pounds.\r\n", GET_OBJ_VAL(obj, 0));
				if (GET_OBJ_VAL(obj, 2))
					msg_to_char(ch, "Capable of firing shots.\r\n");
				break;
			case ITEM_MISSILE_WEAPON:
				msg_to_char(ch, "Fires %d shot%s per round ", GET_OBJ_VAL(obj, 0), GET_OBJ_VAL(obj, 0) != 1 ? "s" : "");
				msg_to_char(ch, "for %d damage.\r\n", GET_OBJ_VAL(obj, 1));
				break;
			case ITEM_ARROW:
				if (GET_OBJ_VAL(obj, 0) || GET_OBJ_VAL(obj, 1))
					msg_to_char(ch, "Adds %+d damage %s.\r\n", GET_OBJ_VAL(obj, 1), GET_OBJ_VAL(obj, 0) ? "(aggravated)" : "");
				break;
 			}
		}
	}


ADISC(disc_farsight) {
	extern room_rnum find_target_room(Creature ch, char *rawroomstr);

	room_rnum loc;

	skip_spaces(&argument);

	if (AFF_FLAGGED(ch, AFF_BLIND))
		msg_to_char(ch, "How can you see anybody if you're blind?\r\n");
	else if ((loc = find_target_room(ch, argument)) == NOWHERE)
		return;
	else if (ww_dice(GET_PERCEPTION(ch) + GET_EMPATHY(ch), 6 - SENSES_BONUS(ch)) < 1)
		msg_to_char(ch, "You fail.\r\n");
	else {
		msg_to_char(ch, "You use farsight to scry:\r\n");
		look_at_room_by_rnum(ch, loc);
		}
	}


/* Celerity Powers */
ADISC(disc_celerity) {
	struct affected_type *af;
	int i = 0;

	one_argument(argument, arg);

	if (*arg)
		i = atoi(arg);

	if (affected_by_spell(ch, ATYPE_CELERITY))
		msg_to_char(ch, "You have already activated Celerity!\r\n");
	else if (i < 1 || i > GET_CELERITY(ch))
		msg_to_char(ch, "You may only use Celerity for a number of attacks between 1 and %d.\r\n", GET_CELERITY(ch));
	else if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
	else if (GET_BLOOD(ch) < i + 1)
		msg_to_char(ch, "You don't have enough blood for that!\r\n");
	else {
		CREATE(af, struct affected_type, 1);
		af->type = ATYPE_CELERITY;
		af->duration = 1;
		af->modifier = i;
		af->location = APPLY_ATTACKS;
		af->bitvector = 0;
		af->disc_bit = 0;

		affect_join(ch, af, 0, 0, 0, 0);

		GET_BLOOD(ch) -= i;

		msg_to_char(ch, "You activate Celerity, moving with preternatural speed!\r\n");
		}
	}


/* Chimerstry Powers */
ADISC(disc_chimerstry) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Chimerstry is an illusion power with its roots in the magic of the fae.  At\r\nits lower levels, its primary function is fooling individual senses.  As the\r\npower progresses, though, it becomes strong enough to overcome all senses, and\r\nphysically interact with targets.\r\nPowers:\r\n");

	for (i = 0; str_cmp(discs[i].name, "\n"); i++)
		if (discs[i].disc == DISC_CHIMERSTRY && discs[i].level <= GET_CHIMERSTRY(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", discs[i].name);
			else
				found = TRUE;
			}
	}


/* Dementation Powers */
ADISC(disc_dementation) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Dementation is the refined art of freeing the minds of others.  It can\r\ndemolish one's sanity and deteriorate willpower quickly.  Though it is, in\r\ntruth, a mutation of Dominate, this power is far more deadly.\r\nPowers:\r\n");

	for (i = 0; str_cmp(discs[i].name, "\n"); i++)
		if (discs[i].disc == DISC_DEMENTATION && discs[i].level <= GET_DEMENTATION(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", discs[i].name);
			else
				found = TRUE;
			}
	}


/* Dominate Powers */
ADISC(disc_dominate) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Dominate, often seen as one of the strongest disciplines, is the ability to\r\nforce one's own will into the mind of another.  Those who have refined this\r\nart are nearly irresistable.\r\nPowers:\r\n");

	for (i = 0; str_cmp(discs[i].name, "\n"); i++)
		if (discs[i].disc == DISC_DOMINATE && discs[i].level <= GET_DOMINATE(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", discs[i].name);
			else
				found = TRUE;
			}
	}


ADISC(disc_observance) {
	ACMD(do_say);
	Creature victim;
	char *to_do;

	argument = two_arguments(argument, arg, buf);

	if (!*arg || !*buf)
		msg_to_char(ch, "Force whom to observe what command?\r\n");
	else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)))
		msg_to_char(ch, NOPERSON);
	else if (ch == victim)
		msg_to_char(ch, "That seems rather pointless, doesn't it?\r\n");
	else if (IS_NPC(victim) && MOB_TYPE(victim) != MTYPE_HUMAN)
		msg_to_char(ch, "You can only give commands to humans.\r\n");
	else if (IS_VAMPIRE(victim) && GET_GENERATION(ch) >= GET_GENERATION(victim))
		msg_to_char(ch, "You cannot force your will upon those of more powerful blood.\r\n");
	else if (!AWAKE(victim))
		msg_to_char(ch, "Your victim will need to be awake to understand you.\r\n");
	else if (*argument && !str_str(argument, buf))
		msg_to_char(ch, "If you wish to include your orders in a sentence, you must include the word in that sentence.\r\nFormat: discipline \"observance of the spoken word\" <target> <command> <sentance including command>\r\n");
	else if (!CAN_SEE(victim, ch))
		act("How do you intend to dominate $M if $E can't even see you?", FALSE, ch, 0, victim, TO_CHAR);
	else {
		/* do_say corrodes buf */
		to_do = str_dup(buf);

		/* The command is spoken.. */
		if (!*argument)
			strcpy(argument, buf);
		do_say(ch, argument, 0, 0);

		/* The victim MUST be able to understand.. */
		if (IS_NPC(victim) || IS_SET(GET_LANGUAGES(victim), LANGUAGE_BIT(GET_SPEAKING(ch))))
			if (ww_dice(GET_MANIPULATION(ch) + GET_INTIMIDATION(ch), GET_WILLPOWER(victim)) > 0)
				command_interpreter(victim, to_do);
		}
	}


ADISC(disc_murmur) {
	ACMD(do_say);
	Creature victim;

	argument = one_argument(argument, arg);
	skip_spaces(&argument);

	if (!*arg || !*argument)
		msg_to_char(ch, "Force whom to do what?\r\n");
	else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)))
		msg_to_char(ch, NOPERSON);
	else if (ch == victim)
		msg_to_char(ch, "That seems rather pointless, doesn't it?\r\n");
	else if (IS_NPC(victim) && MOB_TYPE(victim) != MTYPE_HUMAN)
		msg_to_char(ch, "You can only give commands to humans.\r\n");
	else if (IS_VAMPIRE(victim) && GET_GENERATION(ch) >= GET_GENERATION(victim))
		msg_to_char(ch, "You cannot force your will upon those of more powerful blood.\r\n");
	else if (!AWAKE(victim))
		msg_to_char(ch, "Your victim will need to be awake to understand you.\r\n");
	else if (!CAN_SEE(victim, ch))
		act("How do you intend to dominate $M if $E can't even see you?", FALSE, ch, 0, victim, TO_CHAR);
	else {
		/* The command is spoken.. */
		do_say(ch, argument, 0, 0);

		/* The victim MUST be able to understand.. */
		if (IS_NPC(victim) || IS_SET(GET_LANGUAGES(victim), LANGUAGE_BIT(GET_SPEAKING(ch))))
			if (ww_dice(GET_MANIPULATION(ch) + GET_LEADERSHIP(ch), GET_WILLPOWER(victim)) > 0)
				command_interpreter(victim, argument);
		}
	}


/* Fortitude Powers */
ADISC(disc_fortitude) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Fortitude, at its simplest level, is a form of superhuman stamina so strong\r\nthat it can even resist the most extreme forms of damage.  At its higher\r\nlevels, it is so strong that its user can shatter diamonds against his skin,\r\nand can walk in the day.\r\nPowers:\r\n");

	for (i = 0; str_cmp(discs[i].name, "\n"); i++)
		if (discs[i].disc == DISC_FORTITUDE && discs[i].level <= GET_FORTITUDE(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", discs[i].name);
			else
				found = TRUE;
			}
	}


ADISC(disc_armor_of_vitality) {
	struct affected_type *af;

	if (affected_by_spell(ch, ATYPE_ARMOR_OF_VITALITY)) {
		msg_to_char(ch, "You return your flesh to its normal, soft state.\r\n");
		affect_from_char(ch, ATYPE_ARMOR_OF_VITALITY);
		return;
		}

	CREATE(af, struct affected_type, 1);
	af->type = ATYPE_ARMOR_OF_VITALITY;
	af->duration = 1;
	af->modifier = 0;
	af->location = APPLY_NONE;
	af->bitvector = 0;
	af->disc_bit = DSC_ARMOR_OF_VITALITY;

	affect_join(ch, af, 0, 0, 0, 0);

	msg_to_char(ch, "Your flesh hardens until it is as solid as marble!\r\n");

	WAIT_STATE(ch, PULSE_VIOLENCE);
	}


ADISC(disc_bestow_vigor) {
	struct affected_type *af;
	Creature victim;
	int amt = 0;

	two_arguments(argument, arg, buf);

	if (!GET_SLIT_WRIST(ch))
		msg_to_char(ch, "You must slit your wrist first.\r\n");
	else if (!*arg || !*buf)
		msg_to_char(ch, "Feed whom how much blood to bestow vigor?\r\n");
	else if ((amt = atoi(buf)) <= 0)
		msg_to_char(ch, "Feed how much blood?\r\n");
	else if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
	else if (amt > GET_BLOOD(ch) - 1)
		msg_to_char(ch, "You can't give THAT much blood.\r\n");
	else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)))
		msg_to_char(ch, NOPERSON);
	else if (affected_by_spell(victim, ATYPE_BESTOW_VIGOR))
		act("Someone has already bestown vigor upon $M.", FALSE, ch, 0, victim, TO_CHAR);
	else if (!IS_VAMPIRE(victim) || !IS_VAMPIRE(ch))
		msg_to_char(ch, "Bestow vigor can only be used from one Cainite to another.\r\n");
	else if (IS_NPC(victim) || (!PRF_FLAGGED(victim, PRF_FEEDABLE) && !IS_INJURED(victim, INJ_TORPOR)))
		act("$E refuses your vitae.", FALSE, ch, 0, victim, TO_CHAR);
	else if (GET_FORTITUDE(victim) >= GET_FORTITUDE(ch))
		msg_to_char(ch, "What would be the point of bestowing Fortitude to someone who already knows as much (or more) about it than you?\r\n");
	else if (GET_FORTITUDE(ch) - GET_FORTITUDE(victim) < amt)
		msg_to_char(ch, "You can only bestow %d Fortitude!\r\n", GET_FORTITUDE(ch) - GET_FORTITUDE(victim));
	else {
		act("You feed $N some blood from your wrist!", FALSE, ch, 0, victim, TO_CHAR);
		act("$n feeds $N some blood from a cut in $s wrist!", TRUE, ch, 0, victim, TO_NOTVICT);
		act("$n feeds you some blood from the cut in $s wrist!", FALSE, ch, 0, victim, TO_VICT);

		msg_to_char(victim, "You feel your supernatural fortitude enhance!\r\n");

		/* Remove torpor */
		if (IS_VAMPIRE(victim) && IS_INJURED(victim, INJ_TORPOR)) {
			REMOVE_BIT(INJURY_FLAGS(victim), INJ_TORPOR);
			msg_to_char(victim, "You awaken from torpor!\r\n");
			GET_POS(victim) = POS_RESTING;
			}

		GET_BLOOD(ch) -= amt;
		GET_BLOOD(victim) = MIN(GET_MAX_BLOOD(victim), GET_BLOOD(victim) + amt);


		CREATE(af, struct affected_type, 1);
		af->type = ATYPE_BESTOW_VIGOR;
		af->duration = MAX(1, ww_dice(GET_STAMINA(ch) + GET_SURVIVAL(ch), 8));
		af->modifier = amt;
		af->location = APPLY_FORTITUDE;
		af->bitvector = 0;
		af->disc_bit = 0;

		affect_join(victim, af, 0, 0, 0, 0);

		/*
		 * Blood Oath
		 *  This will address the thrall of the Blood Oath in the future.
		 *  Until then, there is no downside to sharing blood.
		 */
		}
	}


ADISC(disc_eternal_vigilance) {
	msg_to_char(ch, "Eternal vigilance allows you to stay awake all day, with your actions unrestricted.  While you are still damaged by the sun, you no longer need to sleep.  You must, however, spend an additional point of blood per day.\r\n");
	}


/* Mortis Powers */
ADISC(disc_mortis) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Mortis is the Cappadocian art of commanding death itself.  At its most\r\nfundamental level, Mortis can bend time around an individual, inciting death\r\nor aging.  At its higher levels, it can literally raise corpses as servants.\r\nPowers:\r\n");

	for (i = 0; str_cmp(discs[i].name, "\n"); i++)
		if (discs[i].disc == DISC_MORTIS && discs[i].level <= GET_MORTIS(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", discs[i].name);
			else
				found = TRUE;
			}
	}



ADISC(disc_masque_of_death) {
	struct affected_type *af;
	Creature victim;

	one_argument(argument, arg);

	if (*arg)
		victim = get_char_vis(ch, arg, FIND_CHAR_ROOM);
	else
		victim = ch;

	if (!victim)
		msg_to_char(ch, "Inflict the masque of death upon whom?\r\n");
	else if (victim != ch && (IS_GOD(victim) || IS_IMMORTAL(victim)))
		msg_to_char(ch, "You cannot use this power on so godly a target!\r\n");
	else if (victim != ch && affected_by_spell(victim, ATYPE_MASQUE_OF_DEATH))
		act("$E is already affected by the masque of death!", FALSE, ch, 0, victim, TO_CHAR);
	else if (affected_by_spell(victim, ATYPE_MASQUE_OF_DEATH)) {
		if (GET_BLOOD(ch) < 3)
			msg_to_char(ch, "You lack the blood to return to normal prematurely.\r\n");
		else {
			GET_BLOOD(ch) -= 2;
			affect_from_char(ch, ATYPE_MASQUE_OF_DEATH);
			msg_to_char(ch, "Your skin returns to normal!\r\n");
			act("$n's skin fills out and $e returns to normal!", TRUE, ch, 0, 0, TO_ROOM);
			}
		}
	else if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
	else if (GET_BLOOD(ch) < 2)
		msg_to_char(ch, "You lack the blood to activate the masque of death!\r\n");
	else {
		GET_BLOOD(ch) -= 1;

		if (ch != victim) {
			act("You touch $N with your cold hand..", FALSE, ch, 0, victim, TO_CHAR);
			act("$n touches you with a cold, clammy hand..", FALSE, ch, 0, victim, TO_VICT);
			act("$n touches $N with a cold, clammy hand..", TRUE, ch, 0, victim, TO_NOTVICT);

			if (ww_dice(GET_STAMINA(ch) + GET_MEDICINE(ch), GET_STAMINA(victim) + 3) < 1) {
				msg_to_char(ch, "But nothing happens.\r\n");
				return;
				}
			}

		CREATE(af, struct affected_type, 2);
		af[0].type = ATYPE_MASQUE_OF_DEATH;
		af[1].type = ATYPE_MASQUE_OF_DEATH;
		af[0].duration = 6;
		af[1].duration = 6;
		af[0].modifier = MIN(0, MAX(-1 * (GET_DEXTERITY(victim) - 1), -2));
		af[1].modifier = MIN(0, MAX(-1 * (GET_APPEARANCE(victim) - 1), -2));
		af[0].location = APPLY_DEXTERITY;
		af[1].location = APPLY_APPEARANCE;
		af[0].bitvector = 0;
		af[1].bitvector = 0;
		af[0].disc_bit = DSC_MASQUE_OF_DEATH;
		af[1].disc_bit = DSC_MASQUE_OF_DEATH;

		affect_join(victim, af, 0, 0, 0, 0);
		affect_join(victim, af+1, 0, 0, 0, 0);

		msg_to_char(victim, "Your skin shrivels and your joints stiffen!\r\n");
		act("$n's skin shrivels and pales!", TRUE, victim, 0, 0, TO_ROOM);

		WAIT_STATE(ch, PULSE_VIOLENCE);
		}
	}


ADISC(disc_blight) {
	struct affected_type *af;
	Creature victim;

	one_argument(argument, arg);

	if (!*arg)
		msg_to_char(ch, "Blight whom?\r\n");
	else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)))
		msg_to_char(ch, NOPERSON);
	else if (ch == victim)
		msg_to_char(ch, "You wouldn't want to do that to yourself...\r\n");
	else if (IS_GOD(victim) || IS_IMMORTAL(victim))
		msg_to_char(ch, "You cannot use this power on so godly a target!\r\n");
	else if (affected_by_spell(victim, ATYPE_BLIGHT))
		act("$E is already affected by the Blight!", FALSE, ch, 0, victim, TO_CHAR);
	else if (!can_fight(ch, victim))
		act("You can't attack $M!", FALSE, ch, 0, victim, TO_CHAR);
	else if (!CAN_SPEND_WILLPOWER(ch))
		msg_to_char(ch, "Your willpower is shattered, you can't do that!\r\n");
	else if (GET_WILLPOWER(ch) < 1)
		msg_to_char(ch, "You have no Willpower points to spend!\r\n");
	else {
		if (SHOULD_APPEAR(ch))
			appear(ch);

		GET_WILLPOWER(ch) -= 1;

		act("You touch $N with your cold hand..", FALSE, ch, 0, victim, TO_CHAR);
		act("$n touches you with a cold, clammy hand..", FALSE, ch, 0, victim, TO_VICT);
		act("$n touches $N with a cold, clammy hand..", TRUE, ch, 0, victim, TO_NOTVICT);

		if (ww_dice(GET_MANIPULATION(ch) + GET_MEDICINE(ch), GET_WILLPOWER(victim)) < 1) {
			msg_to_char(ch, "But nothing happens.\r\n");
			return;
			}

		CREATE(af, struct affected_type, 3);
		af[0].type = ATYPE_BLIGHT;
		af[1].type = ATYPE_BLIGHT;
		af[2].type = ATYPE_BLIGHT;
		af[0].duration = 6;
		af[1].duration = 6;
		af[2].duration = 6;
		af[0].modifier = MIN(0, MAX(-1 * (GET_DEXTERITY(victim) - 1), -3));
		af[1].modifier = MIN(0, MAX(-1 * (GET_STRENGTH(victim) - 1), -3));
		af[2].modifier = MIN(0, MAX(-1 * (GET_STAMINA(victim) - 1), -3));
		af[0].location = APPLY_DEXTERITY;
		af[1].location = APPLY_STRENGTH;
		af[2].location = APPLY_STAMINA;
		af[0].bitvector = 0;
		af[1].bitvector = 0;
		af[2].bitvector = 0;
		af[0].disc_bit = DSC_BLIGHT;
		af[1].disc_bit = DSC_BLIGHT;
		af[2].disc_bit = DSC_BLIGHT;

		affect_join(victim, af, 0, 0, 0, 0);
		affect_join(victim, af+1, 0, 0, 0, 0);
		affect_join(victim, af+2, 0, 0, 0, 0);

		msg_to_char(victim, "Your skin wrinkles and your joints stiffen!\r\n");
		act("$n's skin wrinkes and $e hunches over!", TRUE, victim, 0, 0, TO_ROOM);

		WAIT_STATE(ch, PULSE_VIOLENCE);
		}
	}


ADISC(disc_awaken) {
	Creature victim;

	one_argument(argument, arg);

	if (!CAN_SPEND_WILLPOWER(ch))
		msg_to_char(ch, "Your willpower is shattered, you can't do that!\r\n");
	else if (GET_WILLPOWER(ch) < 2)
		msg_to_char(ch, "You don't have the Willpower to Awaken.\r\n");
	else if (*arg && GET_POS(ch) == POS_STANDING) {
		if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)))
			msg_to_char(ch, NOPERSON);
		else if (!IS_INJURED(victim, INJ_TORPOR))
			act("$N is not in torpor!", FALSE, ch, 0, victim, TO_CHAR);
		else {
			GET_WILLPOWER(ch) -= 2;

			REMOVE_BIT(INJURY_FLAGS(victim), INJ_TORPOR);
			GET_BLOOD(victim) = 1;
			act("You touch $N on the lips..", FALSE, ch, 0, victim, TO_CHAR);
			act("$n touches you on the lips..", FALSE, ch, 0, victim, TO_CHAR | TO_SLEEP);
			GET_DAMAGE(victim) = MIN(6, GET_DAMAGE(victim));
			GET_AGG_DAMAGE(victim) = MIN(GET_DAMAGE(victim), GET_AGG_DAMAGE(victim));
			GET_POS(victim) = POS_SITTING;
			msg_to_char(victim, "You sit up suddenly!\r\n");
			act("$n sits up suddenly!", TRUE, victim, 0, 0, TO_ROOM);
			}
		}
	else if (!IS_INJURED(ch, INJ_TORPOR))
		msg_to_char(ch, "You aren't in torpor!\r\n");
	else {
		GET_WILLPOWER(ch) -= 2;

		REMOVE_BIT(INJURY_FLAGS(ch), INJ_TORPOR);
		GET_BLOOD(ch) = 1;
		GET_DAMAGE(ch) = MIN(6, GET_DAMAGE(ch));
		GET_AGG_DAMAGE(ch) = MIN(GET_DAMAGE(ch), GET_AGG_DAMAGE(ch));
		GET_POS(ch) = POS_SITTING;
		msg_to_char(ch, "You sit up suddenly!\r\n");
		act("$n sits up suddenly!", TRUE, ch, 0, 0, TO_ROOM);
		}
	}


ADISC(disc_deaths_whisper) {
	if (DSC_FLAGGED(ch, DSC_DEATHS_WHISPER)) {
		if (GET_BLOOD(ch) < 2)
			msg_to_char(ch, "You don't have enough blood to revert to normal!\r\n");
		else {
			msg_to_char(ch, "Your flesh returns to normal!\r\n");
			act("$n appears normal again!", TRUE, ch, 0, 0, TO_ROOM);
			REMOVE_BIT(DSC_FLAGS(ch), DSC_DEATHS_WHISPER);
			GET_POS(ch) = POS_STANDING;
			GET_BLOOD(ch) -= 2;
			}
		}
	else if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
	else if (GET_BLOOD(ch) < 3)
		msg_to_char(ch, "You could do that, but you don't have enough blood to awaken!\r\n");
	else if (GET_POS(ch) == POS_FIGHTING)
		msg_to_char(ch, "You can't use death's whisper while fighting!\r\n");
	else {
		msg_to_char(ch, "You fall to the ground, dead!\r\n");
		act("$n falls to the ground, dead!", TRUE, ch, 0, 0, TO_ROOM);
		SET_BIT(DSC_FLAGS(ch), DSC_DEATHS_WHISPER);
		GET_POS(ch) = POS_SLEEPING;
		}
	}


ADISC(disc_black_death) {
	void enter_torpor(Creature ch, byte type);
	Creature victim;

	one_argument(argument, arg);

	if (!*arg)
		msg_to_char(ch, "Inflict the black death upon whom?\r\n");
	else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)))
		msg_to_char(ch, NOPERSON);
	else if (ch == victim)
		msg_to_char(ch, "You wouldn't want to do that to yourself...\r\n");
	else if (IS_GOD(victim) || IS_IMMORTAL(victim))
		msg_to_char(ch, "You cannot use this power on so godly a target!\r\n");
	else if (IS_INJURED(victim, INJ_TORPOR))
		act("$E is already in torpor!", FALSE, ch, 0, victim, TO_CHAR);
	else if (!can_fight(ch, victim))
		act("You can't attack $M!", FALSE, ch, 0, victim, TO_CHAR);
	else if (!CAN_SPEND_WILLPOWER(ch))
		msg_to_char(ch, "Your willpower is shattered, you can't do that!\r\n");
	else if (GET_WILLPOWER(ch) < 2)
		msg_to_char(ch, "You have insufficient Willpower points to spend!\r\n");
	else {
		if (SHOULD_APPEAR(ch))
			appear(ch);

		GET_WILLPOWER(ch) -= 2;

		act("You touch $N with your cold hand..", FALSE, ch, 0, victim, TO_CHAR);
		act("$n touches you with a cold, clammy hand..", FALSE, ch, 0, victim, TO_VICT);
		act("$n touches $N with a cold, clammy hand..", TRUE, ch, 0, victim, TO_NOTVICT);

		if (ww_dice(GET_STAMINA(ch) + GET_OCCULT(ch), GET_WILLPOWER(victim)) < 1) {
			msg_to_char(ch, "But nothing happens.\r\n");
			return;
			}

		msg_to_char(victim, "You fall to the ground, dead!\r\n");
		act("$n falls to the ground, dead!", TRUE, victim, 0, 0, TO_ROOM);

		if (IS_VAMPIRE(victim))
			enter_torpor(victim, 2);
		else {
			if (!IS_NPC(victim)) {
				death_log(victim, ch, ATTACK_EXECUTE);
				add_lore(ch, LORE_PLAYER_KILL, GET_IDNUM(victim));
				add_lore(victim, LORE_PLAYER_DEATH, GET_IDNUM(ch));
				}
			die(victim);
			}

		WAIT_STATE(ch, PULSE_VIOLENCE);
		}
	}


/* Obfuscate Powers */
ADISC(disc_obfuscate) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Obfuscate is a mental power which clouds the minds of others, changing what\r\nthey see.  It can be used to hide in plain sight, or to masquerade as another\r\nperson.  At its most powerful levels, Obfuscate can even mask its user's soul,\r\npreventing even the most powerful means of detection.\r\nPowers:\r\n");

	for (i = 0; str_cmp(discs[i].name, "\n"); i++)
		if (discs[i].disc == DISC_OBFUSCATE && discs[i].level <= GET_OBFUSCATE(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", discs[i].name);
			else
				found = TRUE;
			}
	}


ADISC(disc_cloak_of_shadows) {
	Creature c;

	if (AFF_FLAGGED(ch, AFF_HIDE)) {
		msg_to_char(ch, "You make yourself apparent.\r\n");
		act("$n appears from the shadows.", TRUE, ch, 0, 0, TO_ROOM);
		REMOVE_BIT(AFF_FLAGS(ch), AFF_HIDE);
		return;
		}

	for (c = world[ch->in_room].people; c; c = c->next_in_room)
		if (c != ch && CAN_SEE(c, ch) && AWAKE(c) && (!IS_NPC(c) || MOB_TYPE(c) == MTYPE_HUMAN) && ww_dice(GET_PERCEPTION(c) + GET_ALERTNESS(c), GET_WITS(ch) + GET_STEALTH(ch) - SENSES_BONUS(c)) > 0) {
			msg_to_char(ch, "You can't hide in the shadows with somebody watching!\r\n");
			WAIT_STATE(ch, PULSE_VIOLENCE);
			return;
			}

	SET_BIT(AFF_FLAGS(ch), AFF_HIDE);
	msg_to_char(ch, "You hide in the shadows.\r\n");
	}


/* if subcmd, ignores people */
ADISC(disc_unseen_presence) {
	Creature c;

	if (DSC_FLAGGED(ch, DSC_UNSEEN_PRESENCE)) {
		msg_to_char(ch, "You make yourself apparent.\r\n");
		act("$n appears from the shadows.", TRUE, ch, 0, 0, TO_ROOM);
		REMOVE_BIT(DSC_FLAGS(ch), DSC_UNSEEN_PRESENCE);
		return;
		}

	if (!subcmd)
		for (c = world[ch->in_room].people; c; c = c->next_in_room)
			if (c != ch && CAN_SEE(c, ch) && AWAKE(c) && (!IS_NPC(c) || MOB_TYPE(c) == MTYPE_HUMAN) && ww_dice(GET_PERCEPTION(c) + GET_ALERTNESS(c), GET_WITS(ch) + GET_STEALTH(ch) - SENSES_BONUS(c)) > 0) {
				msg_to_char(ch, "You can't vanish into the shadows with somebody watching!\r\n");
				WAIT_STATE(ch, PULSE_VIOLENCE);
				return;
				}

	if (subcmd && ww_dice(GET_CHARISMA(ch) + GET_STEALTH(ch), 7) < 1) {
		msg_to_char(ch, "You fail.\r\n");
		WAIT_STATE(ch, PULSE_VIOLENCE);
		}

	SET_BIT(DSC_FLAGS(ch), DSC_UNSEEN_PRESENCE);
	msg_to_char(ch, "You vanish into the shadows.\r\n");
	}


ADISC(disc_mask_of_a_thousand_faces) {
	Creature c;

	if (DSC_FLAGGED(ch, DSC_MASK)) {
		msg_to_char(ch, "You lower your mask.\r\n");
		act("$n seems to dissolve, and returns to normal.", TRUE, ch, 0, 0, TO_ROOM);
		REMOVE_BIT(DSC_FLAGS(ch), DSC_MASK);
		return;
		}

	for (c = world[ch->in_room].people; c; c = c->next_in_room)
		if (c != ch && CAN_SEE(c, ch) && AWAKE(c) && (!IS_NPC(c) || MOB_TYPE(c) == MTYPE_HUMAN) && ww_dice(GET_PERCEPTION(c) + GET_ALERTNESS(c), GET_WITS(ch) + GET_STEALTH(ch) - SENSES_BONUS(c)) > 0) {
			msg_to_char(ch, "You can't mask yourself with someone watching!\r\n");
			WAIT_STATE(ch, PULSE_VIOLENCE);
			return;
			}

	if (ww_dice(GET_MANIPULATION(ch) + GET_ACTING(ch), 7) > 0)
		SET_BIT(DSC_FLAGS(ch), DSC_MASK);
	msg_to_char(ch, "You conceal your true appearance!\r\n");
	}


ADISC(disc_cloak_the_gathering) {
	struct follow_type *fol;
	int count = GET_STEALTH(ch);

	if (ww_dice(GET_CHARISMA(ch) + GET_STEALTH(ch), 7) < 1) {
		msg_to_char(ch, "You fail.\r\n");
		WAIT_STATE(ch, PULSE_VIOLENCE * 2);
		}

	for (fol = ch->followers; fol && count > 0; fol = fol->next)
		if (fol->follower->in_room == ch->in_room) {
			count--;

			act("$N vanishes!", TRUE, ch, 0, fol->follower, TO_CHAR);
			msg_to_char(fol->follower, "You vanish into the shadows!\r\n");
			SET_BIT(DSC_FLAGS(fol->follower), DSC_UNSEEN_PRESENCE);
			}

	SET_BIT(DSC_FLAGS(ch), DSC_UNSEEN_PRESENCE);
	msg_to_char(ch, "You vanish into the shadows.\r\n");
	}


ADISC(disc_soul_mask) {
	if (DSC_FLAGGED(ch, DSC_SOUL_MASK)) {
		msg_to_char(ch, "You dissolve your soul mask.\r\n");
		REMOVE_BIT(DSC_FLAGS(ch), DSC_SOUL_MASK);
		return;
		}

	if (ww_dice(GET_MANIPULATION(ch) + GET_ACTING(ch), 7) > 0)
		SET_BIT(DSC_FLAGS(ch), DSC_SOUL_MASK);
	msg_to_char(ch, "You conceal your halo!\r\n");
	}


ADISC(disc_veil_the_legions) {
	Creature c;

	for (c = world[ch->in_room].people; c; c = c->next_in_room)
		if (c != ch && AWAKE(c) && (!IS_NPC(c) || MOB_TYPE(c) == MTYPE_HUMAN)) {
			act("$N vanishes!", TRUE, ch, 0, c, TO_CHAR);
			msg_to_char(c, "You vanish into the shadows!\r\n");
			SET_BIT(DSC_FLAGS(c), DSC_UNSEEN_PRESENCE);
			}

	SET_BIT(DSC_FLAGS(ch), DSC_UNSEEN_PRESENCE);
	msg_to_char(ch, "You vanish into the shadows!\r\n");
	}


/* Obtenebration Powers */
ADISC(disc_obtenebration) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Developed by the Lasombra, Obtenebration is fundamentally control over the\r\nshadows.  Any true Lasombra, though, will tell you that it is mastery over\r\ndarkness itself.\r\nPowers:\r\n");

	for (i = 0; str_cmp(discs[i].name, "\n"); i++)
		if (discs[i].disc == DISC_OBTENEBRATION && discs[i].level <= GET_OBTENEBRATION(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", discs[i].name);
			else
				found = TRUE;
			}
	}


ADISC(disc_shadowplay) {
	ACMD(do_flee);

	Creature c, next_c;

	act("You weave the shadows between your fingers and spin them around your form!", FALSE, ch, 0, 0, TO_CHAR);
	act("$n weaves the shadows between $s fingers and spins them around $s body!", FALSE, ch, 0, 0, TO_ROOM);

	for (c = world[ch->in_room].people; c; c = next_c) {
		next_c = c->next_in_room;

		if (!IS_GOD(c) && !IS_IMMORTAL(c) && (!IS_VAMPIRE(c) || GET_GENERATION(c) > GET_GENERATION(ch)) && ww_dice(GET_COURAGE(c), 6) < 1)
			do_flee(c, "", 0, 0);
		}

	WAIT_STATE(ch, PULSE_VIOLENCE * 2);
	}


ADISC(disc_nocturne) {
	struct affected_type *af;

	if (room_affected_by_spell(ch->in_room, ATYPE_NOCTURNE)) {
		affect_from_room(ch->in_room, ATYPE_NOCTURNE);

		msg_to_char(ch, "You wave your hand and the darkness dissipates.\r\n");
		act("$n waves $s hand and the darkness dissipates.", FALSE, ch, 0, 0, TO_ROOM);
		}
	else {
		msg_to_char(ch, "You wave your hand, coalescing the shadows into one inky darkness!\r\n");
		act("$n waves $s hand, coalescing the shadows into one inky darkness!", FALSE, ch, 0, 0, TO_ROOM);

		CREATE(af, struct affected_type, 1);
		af->type = ATYPE_NOCTURNE;
		af->duration = 12;
		af->modifier = 0;
		af->location = APPLY_NONE;
		af->bitvector = ROOM_AFF_DARK;
		af->disc_bit = 0;

		affect_to_room(ch->in_room, af);
		}

	WAIT_STATE(ch, PULSE_VIOLENCE * 2);
	}


ADISC(disc_arms_of_ahriman) {
	void add_follower(Creature ch, Creature leader);
	struct affected_type *af;
	Creature arm;
	int i;

	if (DSC_FLAGGED(ch, DSC_ARMS_OF_AHRIMAN))
		msg_to_char(ch, "You can't form more arms yet.\r\n");
	else if ((i = ww_dice(GET_MANIPULATION(ch) + GET_OCCULT(ch), 7)) < 1)
		msg_to_char(ch, "You fail to form the arms of Ahriman.\r\n");
	else {
		while (i--) {
			char_to_room((arm = read_mobile(ARM_OF_AHRIMAN, VIRTUAL)), ch->in_room);
			SET_BIT(AFF_FLAGS(arm), AFF_CHARM);
			GET_STRENGTH(arm) = arm->real_abils.strength = GET_OBTENEBRATION(ch);
			MOB_DAMAGE(arm) = GET_STRENGTH(arm);
			GET_DEXTERITY(arm) = arm->real_abils.dexterity = GET_OBTENEBRATION(ch);
			act("$N extends from your body!", FALSE, ch, 0, arm, TO_CHAR);
			act("$N extends from $n's body!", TRUE, ch, 0, arm, TO_ROOM);
			add_follower(arm, ch);
			}
		CREATE(af, struct affected_type, 1);
		af->type = ATYPE_ARMS_OF_AHRIMAN;
		af->duration = 6;
		af->modifier = 0;
		af->location = APPLY_NONE;
		af->bitvector = 0;
		af->disc_bit = DSC_ARMS_OF_AHRIMAN;

		affect_to_char(ch, af);
		}
	}


ADISC(disc_nightshades) {
	Creature victim;
	struct affected_type *af;

	msg_to_char(ch, "You summon forth a chaotic saraband of whirling shadows!\r\n");

	for (victim = world[ch->in_room].people; victim; victim = victim->next_in_room) {
		if (ch == victim)
			continue;
		if (AFF_FLAGGED(victim, AFF_BLIND))
			continue;

		act("$n summons forth a chaotic saraband of whirling shadows!", FALSE, ch, 0, victim, TO_VICT);

		if (GET_OBTENEBRATION(victim) >= GET_OBTENEBRATION(ch))
			continue;
		if (!can_fight(ch, victim))
			continue;
		if (affected_by_spell(victim, ATYPE_NIGHTSHADES))
			continue;

		CREATE(af, struct affected_type, 1);
		af->type = ATYPE_NIGHTSHADES;
		af->duration = 1;
		af->modifier = -2;
		af->location = APPLY_DEXTERITY;
		af->bitvector = 0;
		af->disc_bit = 0;

		affect_to_char(victim, af);

		msg_to_char(victim, "The nightshades swirl around you violently!\r\n");
		}
	}


/* Presence Powers */
ADISC(disc_presence) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Presence, developed primarily by the Toreador to incite loyalty in followers,\r\nis in many ways a power which draws attention to the wielder.  This attention,\r\nhowever, is usually positive.  It enhances the personality of the Cainite\r\nwielding it, making her desires unbearable to resist.\r\nPowers:\r\n");

	for (i = 0; str_cmp(discs[i].name, "\n"); i++)
		if (discs[i].disc == DISC_PRESENCE && discs[i].level <= GET_PRESENCE(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", discs[i].name);
			else
				found = TRUE;
			}
	}


ADISC(disc_awe) {
	int result;

	if (DSC_FLAGGED(ch, DSC_AWE)) {
		msg_to_char(ch, "You lower your supernatural awe.\r\n");
		act("$n seems less important now.", TRUE, ch, 0, 0, TO_ROOM);
		REMOVE_BIT(DSC_FLAGS(ch), DSC_AWE);
		}
	else if (GET_DAYS_SINCE_BATHING(ch) > GET_PRESENCE(ch))
		msg_to_char(ch, "You're too disgusting to inspire awe!\r\n");
	else if ((result = ww_dice(GET_CHARISMA(ch) + GET_ACTING(ch), 7)) FAILED)
		msg_to_char(ch, "You fail.\r\n");
	else {
		/* The character thinks he succeeded unless he botched */
		msg_to_char(ch, "You create a field of supernatural awe around yourself.\r\n");
		if (result > 0) {
			act("The light glints off of $n's eyes, and $e suddenly seems more important.", TRUE, ch, 0, 0, TO_ROOM);
			SET_BIT(DSC_FLAGS(ch), DSC_AWE);
			}
		}
	WAIT_STATE(ch, PULSE_VIOLENCE * 2);
	}


ADISC(disc_dread_gaze) {
	ACMD(do_flee);

	Creature victim;

	one_argument(argument, arg);

	if (!*arg && !FIGHTING(ch))
		msg_to_char(ch, "Use the Dread Gaze upon whom?\r\n");
	else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)) && !(victim = FIGHTING(ch)))
		msg_to_char(ch, NOPERSON);
	else if (!can_fight(ch, victim))
		act("You can't use the Dread Gaze upon $N!", FALSE, ch, 0, victim, TO_CHAR);
	else {
		if (SHOULD_APPEAR(ch))
			appear(ch);

		act("You bare your fangs and hiss menacingly at $N!", FALSE, ch, 0, victim, TO_CHAR);
		act("$n bares $s fangs and hisses menacingly at $N!", FALSE, ch, 0, victim, TO_NOTVICT);
		act("$n bares $s fangs and hisses at you!", FALSE, ch, 0, victim, TO_VICT);

		if (ww_dice(GET_CHARISMA(ch) + GET_INTIMIDATION(ch), GET_WITS(victim) + 3) > 0)
			do_flee(victim, "", 0, 0);
		}
	}


ADISC(disc_entrancement) {
	bool circle_follow(Creature ch, Creature victim);
	void add_follower(Creature ch, Creature leader);

	Creature victim;
	struct affected_type *af;
	int result;

	one_argument(argument, arg);

	if (!*arg)
		msg_to_char(ch, "Entrance who?\r\n");
	else if (GET_DAYS_SINCE_BATHING(ch) > GET_PRESENCE(ch))
		msg_to_char(ch, "You're too disgusting to entrance!\r\n");
	else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)))
		msg_to_char(ch, NOPERSON);
	else if (IS_NPC(victim) && MOB_TYPE(victim) != MTYPE_HUMAN)
		msg_to_char(ch, "You can only entrance humans.\r\n");
	else if (IS_VAMPIRE(victim) && GET_GENERATION(victim) <= GET_GENERATION(ch))
		act("$N is too powerful to entrance.", FALSE, ch, 0, victim, TO_CHAR);
	else if (IS_GOD(victim) || IS_IMMORTAL(victim))
		msg_to_char(ch, "You can't use this power on deities.\r\n");
	else if (DSC_FLAGGED(victim, DSC_ENTRANCEMENT))
		act("$E is already entranced.", FALSE, ch, 0, victim, TO_CHAR);
	else if (!can_fight(ch, victim))
		act("You can't entrance $N!", FALSE, ch, 0, victim, TO_CHAR);
	else if (!CAN_SEE(victim, ch))
		act("How do you intend to entrance $M if $E can't even see you?", FALSE, ch, 0, victim, TO_CHAR);
	else if ((result = ww_dice(GET_APPEARANCE(ch) + GET_EMPATHY(ch), GET_WILLPOWER(victim))) <= 0)
		act("You can't seem to entrance $N.", FALSE, ch, 0, victim, TO_CHAR);
	else if (circle_follow(victim, ch))
		msg_to_char(ch, "You can't entrance $N, that would create a follow-loop.\r\n");
	else {
		if (SHOULD_APPEAR(ch))
			appear(ch);

		CREATE(af, struct affected_type, 1);
		af->type = ATYPE_ENTRANCEMENT;
		af->duration = result;
		af->modifier = 0;
		af->location = APPLY_NONE;
		af->bitvector = 0;
		af->disc_bit = DSC_ENTRANCEMENT;

		affect_to_char(victim, af);

		act("You entrance $N.", FALSE, ch, 0, victim, TO_CHAR);
		act("$n catches your eye and you feel entranced by $m!", FALSE, ch, 0, victim, TO_VICT);

		if (victim->master)
			stop_follower(victim);
		REMOVE_BIT(AFF_FLAGS(victim), AFF_PARTY);
		add_follower(victim, ch);
		}
	}


ADISC(disc_summon) {
	Creature mob;
	int i;

	int num_summons = 3;	/* 1 < than the number of vnums */
	int vnums[] = { HUMAN_MALE_1, HUMAN_MALE_2, HUMAN_FEMALE_1, HUMAN_FEMALE_2 };

	switch (SECT(ch->in_room)) {
		case SECT_OCEAN:
		case SECT_RIVER:
			msg_to_char(ch, "You can't summon anyone while in the water!\r\n");
			return;
		case SECT_MOUNTAIN:
			msg_to_char(ch, "You can't summon anybody onto a mountain!\r\n");
			return;
		case SECT_WELL:
		case SECT_BARRIER:
		case SECT_TOWER_OF_SOULS:
		case SECT_WASTELAND:
			msg_to_char(ch, "You can't summon anyone here.\r\n");
			return;
		}


	if (GET_DAYS_SINCE_BATHING(ch) > GET_PRESENCE(ch)) {
		msg_to_char(ch, "You're too disgusting to elicit followers!\r\n");
		return;
		}

	i = MIN(3, ww_dice(GET_CHARISMA(ch) + GET_SUBTERFUGE(ch), 5));

	msg_to_char(ch, "You whistle loudly...\r\n");
	act("$n whistles loudly!", FALSE, ch, 0, 0, TO_ROOM);

	if (i <= 0)
		msg_to_char(ch, "...but nobody responds.\r\n");
	else
		for (; i > 0; i--) {
			char_to_room((mob = read_mobile(vnums[number(0, num_summons)], VIRTUAL)), ch->in_room);
			act("$n loyally approaches!", FALSE, mob, 0, 0, TO_ROOM);
			}
	}


ADISC(disc_majesty) {
	if (DSC_FLAGGED(ch, DSC_MAJESTY)) {
		msg_to_char(ch, "You reduce your supernatural majesty.\r\n");
		act("$n seems less majestic now.", TRUE, ch, 0, 0, TO_ROOM);
		REMOVE_BIT(DSC_FLAGS(ch), DSC_MAJESTY);
		}
	else if (GET_DAYS_SINCE_BATHING(ch) > GET_PRESENCE(ch))
		msg_to_char(ch, "You're too disgusting to use this power!\r\n");
	else {
		msg_to_char(ch, "You create a sense of supernatural majesty about yourself.\r\n");
		act("$n glows majestically.", TRUE, ch, 0, 0, TO_ROOM);
		SET_BIT(DSC_FLAGS(ch), DSC_MAJESTY);
		}
	WAIT_STATE(ch, PULSE_VIOLENCE * 2);
	}


/* Protean Powers */
ADISC(disc_protean) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Protean is the heart of all shape-changing powers.  It is the art of modifying\r\none's body through exercise of one's blood.  At its most powerful levels, it\r\nis said to be able to overcome even the crippling state of torpor.\r\nPowers:\r\n");

	for (i = 0; str_cmp(discs[i].name, "\n"); i++)
		if (discs[i].disc == DISC_PROTEAN && discs[i].level <= GET_PROTEAN(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", discs[i].name);
			else
				found = TRUE;
			}
	}


ADISC(disc_witness_of_darkness) {
	if (DSC_FLAGGED(ch, DSC_WITNESS_OF_DARKNESS)) {
		msg_to_char(ch, "You allow the glow in your eyes to fade, as does the room.\r\n");
		act("The glow in $n's eyes fades.", TRUE, ch, 0, 0, TO_ROOM);
		REMOVE_BIT(DSC_FLAGS(ch), DSC_WITNESS_OF_DARKNESS);
		}
	else {
		msg_to_char(ch, "You focus your energy into igniting your eyes...\r\n");
		msg_to_char(ch, "Your vision improves.\r\n");
		act("$n's eyes begin to glow an eerie red.", TRUE, ch, 0, 0, TO_ROOM);
		SET_BIT(DSC_FLAGS(ch), DSC_WITNESS_OF_DARKNESS);
		}
	WAIT_STATE(ch, PULSE_VIOLENCE * 2);
	}


ADISC(disc_talons_of_the_beast) {
	if (DSC_FLAGGED(ch, DSC_TALONS_OF_THE_BEAST)) {
		msg_to_char(ch, "Your claws meld back into your fingers!\r\n");
		act("$n's claws meld back into $s fingers!", TRUE, ch, 0, 0, TO_ROOM);
		REMOVE_BIT(DSC_FLAGS(ch), DSC_TALONS_OF_THE_BEAST);
		WAIT_STATE(ch, PULSE_VIOLENCE * 2);
		}
	else if (MORPH_FLAGGED(ch, MORPH_FLAG_NO_TALONS))
		msg_to_char(ch, "You can't grow talons in the form!\r\n");
	else if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
	else if (GET_BLOOD(ch) < 2)
		msg_to_char(ch, "You don't have enough blood to safely extend your claws!\r\n");
	else {
		msg_to_char(ch, "Focus your energy into your hands...\r\n");
		msg_to_char(ch, "Your fingers grow into grotesque claws!\r\n");
		act("$n's fingers grow into giant claws!", TRUE, ch, 0, 0, TO_ROOM);

		/* Unfortunately, this shreds anything that's worn.. */
		if (GET_EQ(ch, WEAR_HANDS)) {
			act("Your claws tear apart $p!", FALSE, ch, GET_EQ(ch, WEAR_HANDS), 0, TO_CHAR);
			act("$s claws tear apart $p!", TRUE, ch, GET_EQ(ch, WEAR_HANDS), 0, TO_ROOM);
			extract_obj(GET_EQ(ch, WEAR_HANDS));
			}
		if (GET_EQ(ch, WEAR_FINGER_R)) {
			act("Your claws destroy $p!", FALSE, ch, GET_EQ(ch, WEAR_FINGER_R), 0, TO_CHAR);
			act("$s claws destroy $p!", TRUE, ch, GET_EQ(ch, WEAR_FINGER_R), 0, TO_ROOM);
			extract_obj(GET_EQ(ch, WEAR_FINGER_R));
			}
		if (GET_EQ(ch, WEAR_FINGER_L)) {
			act("Your claws shreds $p!", FALSE, ch, GET_EQ(ch, WEAR_FINGER_L), 0, TO_CHAR);
			act("$s claws shreds $p!", TRUE, ch, GET_EQ(ch, WEAR_FINGER_L), 0, TO_ROOM);
			extract_obj(GET_EQ(ch, WEAR_FINGER_L));
			}

		SET_BIT(DSC_FLAGS(ch), DSC_TALONS_OF_THE_BEAST);
		GET_BLOOD(ch) -= 1;
		WAIT_STATE(ch, PULSE_VIOLENCE * 2);
		}
	}


ADISC(disc_earthmeld) {
	extern room_vnum find_free_vnum();
	extern room_rnum create_room(room_vnum vnum);

	struct affected_type *af;

	switch (SECT(ch->in_room)) {
		case SECT_ROAD:
		case SECT_TOWER_OF_SOULS:
			if (GET_DISC(ch, DISC_PROTEAN) >= 8)
				break;
		case SECT_RIVER:
		case SECT_OCEAN:
		case SECT_BUILDING:
		case SECT_INSIDE:
		case SECT_WELL:
		case SECT_FOUNTAIN:
		case SECT_MULTI:
		case SECT_MONUMENT_CLOSED:
			msg_to_char(ch, "You can't earthmeld without natural ground below you!\r\n");
			return;
		}

	if (!CAN_SPEND_BLOOD(ch)) {
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
		return;
		}

	if (GET_BLOOD(ch) < 2) {
		msg_to_char(ch, "You don't have enough blood to inter yourself.\r\n");
		return;
		}

	if (GET_RIDING(ch)) {
		msg_to_char(ch, "You can't do that while mounted.\r\n");
		return;
		}

	if (DSC_FLAGGED(ch, DSC_EARTHMELD)) {
		msg_to_char(ch, "You're already earthmelded.\r\n");
		return;
		}

	GET_BLOOD(ch) -= 1;
	msg_to_char(ch, "You sink into the ground!\r\n");
	act("$n sinks right into the ground!", TRUE, ch, 0, 0, TO_ROOM);
	GET_POS(ch) = POS_SLEEPING;

	CREATE(af, struct affected_type, 1);
	af->type = ATYPE_EARTHMELD;
	af->duration = -1;
	af->modifier = 0;
	af->location = APPLY_NONE;
	af->bitvector = AFF_NO_TARGET_IN_ROOM | AFF_NO_SEE_IN_ROOM;
	af->disc_bit = DSC_EARTHMELD;

	affect_to_char(ch, af);
	};


ADISC(disc_form_of_the_beast) {
	int morph_to = MORPH_NONE;

	one_argument(argument, arg);

	if (GET_ACTION(ch) != ACT_NONE)
		msg_to_char(ch, "You're too busy to transform now!\r\n");
	else if (!*arg)
		msg_to_char(ch, "Do you wish to become a bat or a wolf, or normal again?\r\n");
	else if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
	else if (GET_BLOOD(ch) < 2)
		msg_to_char(ch, "You don't have enough blood to transform!\r\n");
	else {
		if (is_abbrev(arg, "bat"))
			morph_to = MORPH_PROTEAN_BAT;
		else if (is_abbrev(arg, "wolf"))
			morph_to = MORPH_PROTEAN_WOLF;
		else if (is_abbrev(arg, "normal"))
			morph_to = MORPH_NONE;
		else {
			msg_to_char(ch, "You may become a bat or a wolf, or normal again?\r\n");
			return;
			}

		if (GET_MORPH(ch) == morph_to) {
			msg_to_char(ch, "You're already in that form!\r\n");
			return;
			}

		GET_BLOOD(ch) -= 1;
		GET_ACTION(ch) = ACT_MORPHING;
		GET_ACTION_ROOM(ch) = NOWHERE;
		GET_ACTION_VNUM(ch, 0) = morph_to;
		GET_ACTION_TIMER(ch) = 4;
		GET_ACTION_ROTATION(ch) = last_action_rotation;

		msg_to_char(ch, "You begin to transform!\r\n");
		}
	}


ADISC(disc_body_of_spirit) {
	int morph_to = MORPH_PROTEAN_MIST;

	if (GET_ACTION(ch) != ACT_NONE)
		msg_to_char(ch, "You're too busy to transform now!\r\n");
	else if (GET_MORPH(ch) == morph_to && (morph_to = MORPH_NONE) && 0)
		msg_to_char(ch, "You should never see this message!\r\n");
	else if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
	else if (morph_to != MORPH_NONE && GET_BLOOD(ch) < 2)
		msg_to_char(ch, "You don't have enough blood to transform!\r\n");
	else {
		if (morph_to != MORPH_NONE)
			GET_BLOOD(ch) -= 1;
		GET_ACTION(ch) = ACT_MORPHING;
		GET_ACTION_ROOM(ch) = NOWHERE;
		GET_ACTION_VNUM(ch, 0) = morph_to;
		GET_ACTION_TIMER(ch) = 2;
		GET_ACTION_ROTATION(ch) = last_action_rotation;

		msg_to_char(ch, "You begin to transform!\r\n");
		}
	}


ADISC(disc_blissful_slumber) {
	msg_to_char(ch, "Blissful slumber allows you to sleep while in mist form.\r\n");
	}


ADISC(disc_mastery_of_the_earth) {
	extern int do_simple_move(Creature ch, int dir, room_rnum to_room, int need_specials_check, byte mode);

	int dir;
	room_rnum to_room;

	one_argument(argument, arg);

	if (!DSC_FLAGGED(ch, DSC_EARTHMELD))
		msg_to_char(ch, "You aren't even interred within the earth!\r\n");
	else if (SECT(ch->in_room) == SECT_INSIDE)
		msg_to_char(ch, "You can't do that here.\r\n");
	else if (!*arg)
		msg_to_char(ch, "Which way would you like to move?\r\n");
	else if (is_abbrev(arg, "look"))
		look_at_room(ch);
	else if ((dir = parse_direction(arg)) < 0)
		msg_to_char(ch, "That's not a direction!\r\n");
	else if (dir == UP || dir == DOWN)
		msg_to_char(ch, "You can't go up or down from here!\r\n");
	else if ((to_room = real_shift(ch->in_room, shift_dir[dir][0], shift_dir[dir][1])) == NOWHERE)
		msg_to_char(ch, "You can't go that way!\r\n");
	else if (SECT(to_room) == SECT_RIVER || SECT(to_room) == SECT_OCEAN)
		msg_to_char(ch, "You can't pass through the water!\r\n");
	else if (GET_MOVE(ch) < 1)
		msg_to_char(ch, "You don't have enough energy left to do that.\r\n");
	else
		do_simple_move(ch, dir, to_room, TRUE, 4);
	}


ADISC(disc_purify_the_body) {
	msg_to_char(ch, "Purify the body allows you to expel stakes from your body in some occurances.\r\n");
	}


/* Potence Powers */
ADISC(disc_potence) {
	msg_to_char(ch, "Potence is a supernatural strength, inherent to ghouls and many vampires.  Its\r\npower transcends mere muscles, allowing powerful users to tear apart solid\r\nmetal and lift huge carriages with their bare hands!\r\n");
	}


/* Quietus Powers */
ADISC(disc_quietus) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Assamites from the east have spent much time developing the infamous Quietus.\r\nIt is one of the most prized combat arts among the Cainites, and its powers\r\nare so deadly that few survive its attacks.\r\nPowers:\r\n");

	for (i = 0; str_cmp(discs[i].name, "\n"); i++)
		if (discs[i].disc == DISC_QUIETUS && discs[i].level <= GET_QUIETUS(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", discs[i].name);
			else
				found = TRUE;
			}
	}


ADISC(disc_silence_of_death) {
	struct affected_type *af;

	if (room_affected_by_spell(ch->in_room, ATYPE_SILENCE_OF_DEATH)) {
		affect_from_room(ch->in_room, ATYPE_SILENCE_OF_DEATH);

		msg_to_char(ch, "You dispell the silence.\r\n");
		act("Noise returns to the area.", FALSE, ch, 0, 0, TO_ROOM);
		}
	else {
		msg_to_char(ch, "You focus all of the noise in the room into one point-source, and destroy it!\r\n");
		act("The room becomes eerily silent!", FALSE, ch, 0, 0, TO_ROOM);

		CREATE(af, struct affected_type, 1);
		af->type = ATYPE_SILENCE_OF_DEATH;
		af->duration = 4;
		af->modifier = 0;
		af->location = APPLY_NONE;
		af->bitvector = ROOM_AFF_SILENT;
		af->disc_bit = 0;

		affect_to_room(ch->in_room, af);
		}

	WAIT_STATE(ch, PULSE_VIOLENCE * 2);
	}


ADISC(disc_weakness) {
	struct affected_type *af;
	Creature victim;
	int to_hit = 0, duration = 0;

	one_argument(argument, arg);

	if (!*arg)
		msg_to_char(ch, "Inflict weakness upon whom?\r\n");
	else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)))
		msg_to_char(ch, NOPERSON);
	else if (ch == victim)
		msg_to_char(ch, "You wouldn't want to do that to yourself...\r\n");
	else if (IS_GOD(victim) || IS_IMMORTAL(victim))
		msg_to_char(ch, "You cannot use this power on so godly a target!\r\n");
	else if (affected_by_spell(victim, ATYPE_WEAKNESS) || GET_STAMINA(victim) <= 1)
		act("$E is already affected by the weakness!", FALSE, ch, 0, victim, TO_CHAR);
	else if (!can_fight(ch, victim))
		act("You can't attack $M!", FALSE, ch, 0, victim, TO_CHAR);
	else if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
	else if (GET_BLOOD(ch) < 2)
		msg_to_char(ch, "You lack enough blood to inflict weakness!\r\n");
	else {
		if (SHOULD_APPEAR(ch))
			appear(ch);

		GET_BLOOD(ch) -= 1;

		act("You touch $N with your cold hand..", FALSE, ch, 0, victim, TO_CHAR);
		act("$n touches you with a cold, clammy hand..", FALSE, ch, 0, victim, TO_VICT);
		act("$n touches $N with a cold, clammy hand..", TRUE, ch, 0, victim, TO_NOTVICT);

		if ((to_hit = ww_dice(GET_WILLPOWER(ch), GET_STAMINA(victim) + GET_FORTITUDE(victim))) < 1) {
			msg_to_char(ch, "But nothing happens.\r\n");
			return;
			}

		switch(to_hit) {
			case 0:
			case 1:	duration = 1;		break;
			case 2:	duration = 12;		break;
			case 3:	duration = 48;		break;
			case 4:	duration = 128;		break;
			case 5:
				if (victim->real_abils.stamina > 1)
					victim->real_abils.stamina -= 1;
				affect_total(victim);
				break;
			}

		if (duration > 0) {
			CREATE(af, struct affected_type, 1);
			af->type = ATYPE_WEAKNESS;
			af->duration = duration;
			af->modifier = -1;
			af->location = APPLY_STAMINA;
			af->bitvector = 0;
			af->disc_bit = 0;

			affect_join(victim, af, 0, 0, 0, 0);
			}

		msg_to_char(victim, "You feel weak!\r\n");
		act("$n hunches over with disease!", TRUE, victim, 0, 0, TO_ROOM);

		WAIT_STATE(ch, PULSE_VIOLENCE);
		}
	}


ADISC(disc_disease) {
	struct affected_type *af;
	Creature victim;
	int to_hit = 0, duration = 0;

	one_argument(argument, arg);

	if (!*arg)
		msg_to_char(ch, "Inflict disease upon whom?\r\n");
	else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)))
		msg_to_char(ch, NOPERSON);
	else if (ch == victim)
		msg_to_char(ch, "You wouldn't want to do that to yourself...\r\n");
	else if (IS_GOD(victim) || IS_IMMORTAL(victim))
		msg_to_char(ch, "You cannot use this power on so godly a target!\r\n");
	else if (affected_by_spell(victim, ATYPE_DISEASE) || (GET_STAMINA(victim) <= 1 && GET_DEXTERITY(victim) <= 1 && GET_STRENGTH(victim) <= 1))
		act("$E is already affected by the disease!", FALSE, ch, 0, victim, TO_CHAR);
	else if (!can_fight(ch, victim))
		act("You can't attack $M!", FALSE, ch, 0, victim, TO_CHAR);
	else if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
	else if (GET_BLOOD(ch) < 4)
		msg_to_char(ch, "You lack enough blood to inflict disease!\r\n");
	else {
		if (SHOULD_APPEAR(ch))
			appear(ch);

		GET_BLOOD(ch) -= 3;

		act("You touch $N with your cold hand..", FALSE, ch, 0, victim, TO_CHAR);
		act("$n touches you with a cold, clammy hand..", FALSE, ch, 0, victim, TO_VICT);
		act("$n touches $N with a cold, clammy hand..", TRUE, ch, 0, victim, TO_NOTVICT);

		if ((to_hit = ww_dice(GET_WILLPOWER(ch), GET_WILLPOWER(victim))) < 1) {
			msg_to_char(ch, "But nothing happens.\r\n");
			return;
			}

		switch(to_hit) {
			case 0:
			case 1:	duration = 1;		break;
			case 2:	duration = 12;		break;
			case 3:	duration = 48;		break;
			case 4:	duration = 128;		break;
			case 5:
				if (victim->real_abils.strength > 1)
					victim->real_abils.strength -= 1;
				if (victim->real_abils.dexterity > 1)
					victim->real_abils.dexterity -= 1;
				if (victim->real_abils.stamina > 1)
					victim->real_abils.stamina -= 1;
				affect_total(victim);
				break;
			}

		if (duration > 0) {
			CREATE(af, struct affected_type, 3);
			af[0].type = ATYPE_DISEASE;
			af[1].type = ATYPE_DISEASE;
			af[2].type = ATYPE_DISEASE;
			af[0].duration = duration;
			af[1].duration = duration;
			af[2].duration = duration;
			af[0].modifier = -1;
			af[1].modifier = -1;
			af[2].modifier = -1;
			af[0].location = APPLY_STRENGTH;
			af[1].location = APPLY_DEXTERITY;
			af[2].location = APPLY_STAMINA;
			af[0].bitvector = 0;
			af[1].bitvector = 0;
			af[2].bitvector = 0;
			af[0].disc_bit = 0;
			af[1].disc_bit = 0;
			af[2].disc_bit = 0;

			if (GET_STRENGTH(victim) > 1)
				affect_join(victim, af, 0, 0, 0, 0);
			if (GET_DEXTERITY(victim) > 1)
				affect_join(victim, af+1, 0, 0, 0, 0);
			if (GET_STAMINA(victim) > 1)
				affect_join(victim, af+2, 0, 0, 0, 0);
			}

		msg_to_char(victim, "You feel weak!\r\n");
		act("$n hunches over with disease!", TRUE, victim, 0, 0, TO_ROOM);

		WAIT_STATE(ch, PULSE_VIOLENCE);
		}
	}


ADISC(disc_blood_agony) {
	extern const int blood_cap[];
	extern const int dam_type[];

	Object weapon;
	int amt = 0;

	two_arguments(argument, arg, buf);

	if (!GET_SLIT_WRIST(ch))
		msg_to_char(ch, "You must slit your wrist first.\r\n");
	else if (!*arg || !*buf)
		msg_to_char(ch, "Coat what weapon with how much blood?\r\n");
	else if ((amt = atoi(buf)) <= 0)
		msg_to_char(ch, "Coat it with how much blood?\r\n");
	else if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
	else if (amt > GET_BLOOD(ch) - 1)
		msg_to_char(ch, "You can't use THAT much blood.\r\n");
	else if (!(weapon = get_obj_in_list_vis(ch, arg, ch->carrying)))
		msg_to_char(ch, "You don't seem to have anything like that.\r\n");
	else if (GET_OBJ_TYPE(weapon) != ITEM_WEAPON)
		msg_to_char(ch, "You can only coat weapons with blood!\r\n");
	else if (dam_type[GET_OBJ_VAL(weapon, 2)] != DAM_LETHAL || GET_OBJ_VAL(weapon, 0) < 0)
		msg_to_char(ch, "You can't coat this weapon with blood!\r\n");
	else if (blood_cap[GET_OBJ_VAL(weapon, 2)] <= GET_OBJ_VAL(weapon, 0) + amt)
		msg_to_char(ch, "You can't coat it with any more blood!\r\n");
	else {
		act("You smear some blood from your wrist onto $p!", FALSE, ch, weapon, 0, TO_CHAR);
		act("$n smears some blood from $s open wrist onto $p!", TRUE, ch, weapon, 0, TO_ROOM);

		GET_OBJ_VAL(weapon, 0) += amt;
		GET_BLOOD(ch) -= amt;
		}
	}


ADISC(disc_blood_essence) {
	Creature victim;
	Object container;
	int amt = 0;

	argument = two_arguments(argument, arg, buf);
	one_argument(argument, buf1);

	/*
	 * arg = target
	 * buf = amount
	 * buf1 = countainer
	 */

	if (!*arg || !*buf || !*buf1)
		msg_to_char(ch, "Drain whose blood (and what amount) into what?\r\n");
	else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)))
		msg_to_char(ch, NOPERSON);
	else if (!IS_VAMPIRE(victim))
		msg_to_char(ch, "Only vampire blood may be stored with blood essence.\r\n");
	else if (IS_GOD(victim) || IS_IMMORTAL(victim))
		msg_to_char(ch, "You can't drain blood from an immortal!\r\n");
	else if (victim != ch && AWAKE(victim) && !PRF_FLAGGED(victim, PRF_BITEABLE))
		act("$E refuses to let you drain $S blood!", FALSE, ch, 0, victim, TO_CHAR);
	else if (victim != ch && !AWAKE(victim) && !can_fight(ch, victim))
		act("You can't drain $S blood!", FALSE, ch, 0, victim, TO_CHAR);
	else if ((amt = atoi(buf)) <= 0)
		msg_to_char(ch, "Drain how much blood?\r\n");
	else if (GET_BLOOD(victim) < amt + 1)
		msg_to_char(ch, "You can't drain THAT much!\r\n");
	else if (!(container = get_obj_in_list_vis(ch, buf1, ch->carrying)))
		msg_to_char(ch, "You don't seem to have a %s.\r\n", buf1);
	else if (GET_OBJ_TYPE(container) != ITEM_DRINKCON)
		msg_to_char(ch, "You can't drain blood into that!\r\n");
	else if (GET_OBJ_VAL(container, 1) > 0 && GET_OBJ_VAL(container, 2) != LIQ_BLOOD)
		act("$p already contains something else!", FALSE, ch, container, 0, TO_CHAR);
	else if (GET_OBJ_VAL(container, 1) >= GET_OBJ_VAL(container, 0))
		act("$p is already full.", FALSE, ch, container, 0, TO_CHAR);
	else {
		if (ch == victim) {
			act("You drain some of your blood into $p!", FALSE, ch, container, 0, TO_CHAR);
			act("$n drains some of $s blood into $p!", TRUE, ch, container, 0, TO_ROOM);
			}
		else {
			if (SHOULD_APPEAR(ch))
				appear(ch);

			act("You drain some of $N's blood into $p!", FALSE, ch, container, victim, TO_CHAR);
			act("$n drains some of your blood into $p!", FALSE, ch, container, victim, TO_VICT);
			act("$n drains some of $N's blood into $p!", FALSE, ch, container, victim, TO_NOTVICT);
			}

		amt = MIN(amt, GET_OBJ_VAL(container, 0) - GET_OBJ_VAL(container, 1));

		GET_BLOOD(victim) -= amt;
		GET_OBJ_VAL(container, 1) += amt;
		GET_OBJ_VAL(container, 2) = LIQ_BLOOD;
		}
	}


ADISC(disc_blood_sweat) {
	Creature victim;
	int loss;

	one_argument(argument, arg);

	if (!*arg)
		msg_to_char(ch, "Cause whom to sweat blood?\r\n");
	else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)))
		msg_to_char(ch, NOPERSON);
	else if (ch == victim)
		msg_to_char(ch, "You wouldn't want to do that to yourself...\r\n");
	else if (IS_GOD(victim) || IS_IMMORTAL(victim))
		msg_to_char(ch, "You cannot use this power on so godly a target!\r\n");
	else if (!can_fight(ch, victim))
		act("You can't attack $M!", FALSE, ch, 0, victim, TO_CHAR);
	else {
		if (SHOULD_APPEAR(ch))
			appear(ch);

		act("You touch $N with your cold hand..", FALSE, ch, 0, victim, TO_CHAR);
		act("$n touches you with a cold, clammy hand..", FALSE, ch, 0, victim, TO_VICT);
		act("$n touches $N with a cold, clammy hand..", TRUE, ch, 0, victim, TO_NOTVICT);

		if ((loss = ww_dice(GET_WILLPOWER(ch), GET_STAMINA(victim) + 3)) < 1) {
			msg_to_char(ch, "But nothing happens.\r\n");
			return;
			}

		GET_BLOOD(victim) = MAX(0, GET_BLOOD(victim) - loss);

		/* should cause frenzy: read book */

		msg_to_char(victim, "You begin to sweat blood!\r\n");
		act("$n begins to sweat blood!", TRUE, victim, 0, 0, TO_ROOM);

		WAIT_STATE(ch, PULSE_VIOLENCE);
		}
	}


ADISC(disc_quicken_the_mortal_blood) {
	msg_to_char(ch, "Quicken the mortal blood allows you to increase the effectiveness of the blood you take from mortals.  It is automatic.\r\n");
	}


ADISC(disc_hinder_the_cainite_vitae) {
	struct affected_type *af;
	Creature victim;
	int duration = 0;

	one_argument(argument, arg);

	if (!*arg)
		msg_to_char(ch, "Hinder whose vitae?\r\n");
	else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)))
		msg_to_char(ch, NOPERSON);
	else if (ch == victim)
		msg_to_char(ch, "You wouldn't want to do that to yourself...\r\n");
	else if (IS_GOD(victim) || IS_IMMORTAL(victim))
		msg_to_char(ch, "You cannot use this power on so godly a target!\r\n");
	else if (!can_fight(ch, victim))
		act("You can't attack $M!", FALSE, ch, 0, victim, TO_CHAR);
	else if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
	else if (GET_BLOOD(ch) < 4)
		msg_to_char(ch, "You lack enough blood to do that!\r\n");
	else {
		if (SHOULD_APPEAR(ch))
			appear(ch);

		GET_BLOOD(ch) -= 3;

		act("You touch $N with your cold hand..", FALSE, ch, 0, victim, TO_CHAR);
		act("$n touches you with a cold, clammy hand..", FALSE, ch, 0, victim, TO_VICT);
		act("$n touches $N with a cold, clammy hand..", TRUE, ch, 0, victim, TO_NOTVICT);

		if ((duration = ww_dice(GET_WILLPOWER(ch), GET_STAMINA(victim) + GET_FORTITUDE(victim))) < 1) {
			msg_to_char(ch, "But nothing happens.\r\n");
			return;
			}

		CREATE(af, struct affected_type, 1);
		af->type = ATYPE_HINDER_VITAE;
		af->duration = duration;
		af->modifier = 0;
		af->location = APPLY_NONE;
		af->bitvector = 0;
		af->disc_bit = DSC_CANT_SPEND_BLOOD;

		affect_join(victim, af, 1, 0, 0, 0);

		msg_to_char(victim, "Your blood becomes inert!\r\n");

		WAIT_STATE(ch, PULSE_VIOLENCE);
		}
	}


/* Serpentis Powers */
ADISC(disc_serpentis) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Serpentis is a rather strange mutation of Protean.  Hailing from the sands of\r\nthe desert where it was developed by the Setites, its grotesque shape-shifting\r\nabilities make its users as deadly as the formidable cobra.\r\nPowers:\r\n");

	for (i = 0; str_cmp(discs[i].name, "\n"); i++)
		if (discs[i].disc == DISC_SERPENTIS && discs[i].level <= GET_SERPENTIS(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", discs[i].name);
			else
				found = TRUE;
			}
	}


ADISC(disc_tongue_of_the_asp) {
	if (DSC_FLAGGED(ch, DSC_TONGUE_OF_THE_ASP)) {
		msg_to_char(ch, "Your tongue reverts to normal.\r\n");
		REMOVE_BIT(DSC_FLAGS(ch), DSC_TONGUE_OF_THE_ASP);
		}
	else {
		msg_to_char(ch, "You tongue extends and forks!\r\n");
		SET_BIT(DSC_FLAGS(ch), DSC_TONGUE_OF_THE_ASP);
		}
	}


ADISC(disc_bitumenous_flesh) {
	struct affected_type *af;

	if (DSC_FLAGGED(ch, DSC_BITUMENOUS_FLESH)) {
		if (GET_BLOOD(ch) < 2)
			msg_to_char(ch, "You don't have enough blood to revert to normal!\r\n");
		else {
			msg_to_char(ch, "Your flesh softens and the mummified layers flake off!\r\n");
			act("$n sheds a layer of skin and appears normal again!", TRUE, ch, 0, 0, TO_ROOM);

			if (affected_by_spell(ch, ATYPE_BITUMENOUS_FLESH))
				affect_from_char(ch, ATYPE_BITUMENOUS_FLESH);
			REMOVE_BIT(DSC_FLAGS(ch), DSC_BITUMENOUS_FLESH);
			GET_POS(ch) = POS_STANDING;
			GET_BLOOD(ch) -= 2;
			}
		}
	else if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
	else if (GET_BLOOD(ch) < 3)
		msg_to_char(ch, "You could do that, but you don't have enough blood to awaken!\r\n");
	else if (GET_POS(ch) == POS_FIGHTING)
		msg_to_char(ch, "You can't mummify yourself while fighting!\r\n");
	else {
		msg_to_char(ch, "Your flesh hardens as you mummify yourself!\r\n");
		act("$n's flesh hardens and $e falls to the ground!", TRUE, ch, 0, 0, TO_ROOM);
		GET_POS(ch) = POS_SLEEPING;

		CREATE(af, struct affected_type, 1);
		af->type = ATYPE_BITUMENOUS_FLESH;
		af->duration = -1;
		af->modifier = 0;
		af->location = APPLY_NONE;
		af->bitvector = AFF_IMMUNE_PHYSICAL;
		af->disc_bit = DSC_BITUMENOUS_FLESH;

		affect_to_char(ch, af);
		}
	}


ADISC(disc_breath_of_the_basilisk) {
	Creature victim, next_victim;
	int dam;

	if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
	else if (GET_BLOOD(ch) < 2)
		msg_to_char(ch, "You don't have enough blood to do that!\r\n");
	else {
		if (SHOULD_APPEAR(ch))
			appear(ch);

		GET_BLOOD(ch) -= 1;

		msg_to_char(ch, "You summon all of your inner corruption, and spew it forth in a cloud of taint!\r\n");
		act("$n retches forward and spews a cloud of hideous gas!", FALSE, ch, 0, 0, TO_ROOM);

		for (victim = world[ch->in_room].people; victim; victim = next_victim) {
			next_victim = victim->next_in_room;

			if (ch == victim || !can_fight(ch, victim))
				continue;

			if ((dam = ww_dice(GET_DEXTERITY(ch) + GET_BRAWL(ch), 6)) < 1)
				continue;

			damage(ch, victim, dam, ATTACK_BASILISK, DAM_AGGRAVATED);
			}
		}
	}


/* Vicissitude Powers */
ADISC(disc_vicissitude) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Vicissitude is a very corrupt derivative of Protean.  Its powers are so\r\nextensive that it can be used to mold flesh and bone into virtually any shape\r\nthat its user can devise.  Even more fearsome is that it can be used to mold\r\nothers.  It is truly a power to be feared.\r\nPowers:\r\n");

	for (i = 0; str_cmp(discs[i].name, "\n"); i++)
		if (discs[i].disc == DISC_VICISSITUDE && discs[i].level <= GET_VICISSITUDE(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", discs[i].name);
			else
				found = TRUE;
			}
	}


ADISC(disc_malleable_visage) {
	extern const char *hair_colors[];
	extern const char *skin_colors[];
	extern const char *eye_colors[];

	/* I highly doubt this could be done easily with a structure.. */
	/* with a subcmd, this is mortal clay (2), not malleable vis */

	Creature victim;
	int to_val = 0;

	argument = two_arguments(argument, arg, buf);

	if (!subcmd) {
		strcpy(argument, buf);
		strcpy(buf, arg);
		}
	else
		skip_spaces(&argument);

	/*
	 * arg = victim
	 * buf = command
	 * argument = modifier
	 */

	if (subcmd && !*arg)
		msg_to_char(ch, "Modify whose body, and in what way?\r\n");
	else if (!*buf)
		msg_to_char(ch, "Modify what?  You know how to do: skin, hair, eyes, weight\r\n");
	else if (!(subcmd ? (victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)) : (victim = ch)))
		msg_to_char(ch, NOPERSON);
	else if (victim != ch && IS_NPC(victim))
		msg_to_char(ch, "You fail!\r\n");
	else if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
	else if (GET_BLOOD(ch) < 2)
		msg_to_char(ch, "You don't have enough blood for that.\r\n");
	else if (victim != ch && ww_dice(GET_DEXTERITY(ch) + GET_CRAFTS(ch), 7) < 1)
		msg_to_char(ch, "You try, but fail!\r\n");

	/* skin */
	else if (is_abbrev(buf, "skin")) {
		if (!*argument)
			msg_to_char(ch, "Change %s skin what color?\r\n", ch == victim ? "your" : HSHR(victim));
		else if ((to_val = search_block(argument, skin_colors, FALSE)) < 0)
			msg_to_char(ch, "You don't know of any skin color called '%s'!\r\n", argument);
		else if (GET_SKIN(victim) == to_val)
			msg_to_char(ch, "But the skin is already %s!\r\n", skin_colors[to_val]);
		else {
			GET_BLOOD(ch) -= 1;
			GET_SKIN(victim) = to_val;

			if (ch == victim) {
				sprintf(buf, "$n rubs $s skin, changing it %s!", skin_colors[to_val]);
				act(buf, TRUE, ch, 0, 0, TO_ROOM);
				msg_to_char(ch, "You rub yous skin, changing it %s!\r\n", skin_colors[to_val]);
				}
			else {
				sprintf(buf, "You rub $N's skin, changing it %s!", skin_colors[to_val]);
				sprintf(buf1, "$n rubs $N's skin, changing it %s!", skin_colors[to_val]);
				sprintf(buf2, "$n rubs $N's skin, changing it %s!", skin_colors[to_val]);

				act(buf, TRUE, ch, 0, victim, TO_CHAR);
				act(buf1, FALSE, ch, 0, victim, TO_VICT);
				act(buf2, FALSE, ch, 0, victim, TO_NOTVICT);
				}
			}
		}

	/* hair */
	else if (is_abbrev(buf, "hair")) {
		if (!*argument)
			msg_to_char(ch, "Change %s hair what color?\r\n", ch == victim ? "your" : HSHR(victim));
		else if ((to_val = search_block(argument, hair_colors, FALSE)) < 0)
			msg_to_char(ch, "You don't know of any hair color called '%s'!\r\n", argument);
		else if (GET_HAIR(victim) == to_val)
			msg_to_char(ch, "But the hair is already %s!\r\n", hair_colors[to_val]);
		else {
			GET_BLOOD(ch) -= 1;
			GET_HAIR(victim) = to_val;

			if (ch == victim) {
				sprintf(buf, "$n runs $s hands through $s hair, changing it %s!", hair_colors[to_val]);
				act(buf, TRUE, ch, 0, 0, TO_ROOM);
				msg_to_char(ch, "You run your hands through your hair, changing it %s!\r\n", hair_colors[to_val]);
				}
			else {
				sprintf(buf, "You run your hands through $N's hair, changing it %s!", hair_colors[to_val]);
				sprintf(buf1, "$n runs $s hands through your hair, changing it %s!", hair_colors[to_val]);
				sprintf(buf2, "$n runs $s hands through $N's hair, changing it %s!", hair_colors[to_val]);

				act(buf, TRUE, ch, 0, victim, TO_CHAR);
				act(buf1, FALSE, ch, 0, victim, TO_VICT);
				act(buf2, FALSE, ch, 0, victim, TO_NOTVICT);
				}
			}
		}

	/* eyes */
	else if (is_abbrev(buf, "eyes")) {
		if (!*argument)
			msg_to_char(ch, "Change %s eyes what color?\r\n", ch == victim ? "your" : HSHR(victim));
		else if ((to_val = search_block(argument, eye_colors, FALSE)) < 0)
			msg_to_char(ch, "You don't know of any eye color called '%s'!\r\n", argument);
		else if (GET_EYES(victim) == to_val)
			msg_to_char(ch, "But the eyes are already %s!\r\n", eye_colors[to_val]);
		else {
			GET_BLOOD(ch) -= 1;
			GET_EYES(victim) = to_val;

			if (ch == victim) {
				sprintf(buf, "$n rubs $s eyes, changing them %s!", eye_colors[to_val]);
				act(buf, TRUE, ch, 0, 0, TO_ROOM);
				msg_to_char(ch, "You rub your eyes, changing them %s!\r\n", eye_colors[to_val]);
				}
			else {
				sprintf(buf, "You rub $N's eyes, changing them %s!", eye_colors[to_val]);
				sprintf(buf1, "$n rubs your eyes, changing them %s!", eye_colors[to_val]);
				sprintf(buf2, "$n rubs $N's eyes, changing them %s!", eye_colors[to_val]);

				act(buf, TRUE, ch, 0, victim, TO_CHAR);
				act(buf1, FALSE, ch, 0, victim, TO_VICT);
				act(buf2, FALSE, ch, 0, victim, TO_NOTVICT);
				}
			}
		}

	/* weight */
	else if (subcmd && is_abbrev(buf, "weight")) {
		if (!*argument)
			msg_to_char(ch, "Make %s larger or smaller?\r\n", ch == victim ? "yourself" : HMHR(victim));
		else if ((to_val = (is_abbrev(argument, "larger") ? 1 : 0)) && 0)
			msg_to_char(ch, "You should never see this message.\r\n");
		else if (!to_val && (to_val = (is_abbrev(argument, "smaller") ? 2 : 0)) && 0)
			msg_to_char(ch, "You should never see this message.\r\n");
		else if (!to_val)
			msg_to_char(ch, "Make %s larger or smaller?\r\n", ch == victim ? "yourself" : HMHR(victim));
		else if (GET_WEIGHT(ch) > 200 && to_val == 1)
			msg_to_char(ch, "You can't make %s any larger!\r\n", ch == victim ? "yourself" : HMHR(victim));
		else if (GET_WEIGHT(ch) < 80 && to_val == 2)
			msg_to_char(ch, "You can't make %s any smaller!\r\n", ch == victim ? "yourself" : HMHR(victim));
		else {
			GET_BLOOD(ch) -= 1;
			if (to_val == 1)
				GET_WEIGHT(ch) += 8;
			else
				GET_WEIGHT(ch) -= 8;

			if (ch == victim) {
				sprintf(buf, "$n twists and pulls at $s flesh, maing $m significantly %s!", to_val == 1 ? "larger" : "smaller");
				act(buf, TRUE, ch, 0, 0, TO_ROOM);
				msg_to_char(ch, "You pull at your flesh, %screasing your weight!\r\n", to_val == 1 ? "in" : "de");
				}
			else {
				sprintf(buf, "You grasp and pull at $N's flesh, making $m much %s!", to_val == 1 ? "larger" : "smaller");
				sprintf(buf1, "$n twists and pulls on your flesh, making you much %s!", to_val == 1 ? "larger" : "smaller");
				sprintf(buf2, "$n horribly distorts $N, making $m drastically %s!", to_val == 1 ? "larger" : "smaller");

				act(buf, TRUE, ch, 0, victim, TO_CHAR);
				act(buf1, FALSE, ch, 0, victim, TO_VICT);
				act(buf2, FALSE, ch, 0, victim, TO_NOTVICT);
				}
			}
		}

	else
		msg_to_char(ch, "You can't change that physical attribute!\r\n");
	}


ADISC(disc_rend_the_osseous_frame) {
	/* I highly doubt this could be done easily with a structure.. */

	Creature victim;
	int to_val = 0;

	argument = two_arguments(argument, arg, buf);

	skip_spaces(&argument);

	/*
	 * arg = victim
	 * buf = command
	 * argument = modifier
	 */

	if (subcmd && !*arg)
		msg_to_char(ch, "Modify whose body, and in what way?\r\n");
	else if (!*buf)
		msg_to_char(ch, "Modify what?  You know how to do: height\r\n");
	else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)))
		msg_to_char(ch, NOPERSON);
	else if (victim != ch && IS_NPC(victim))
		msg_to_char(ch, "You fail!\r\n");
	else if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
	else if (GET_BLOOD(ch) < 2)
		msg_to_char(ch, "You don't have enough blood for that.\r\n");
	else if (victim != ch && ww_dice(GET_STRENGTH(ch) + GET_CRAFTS(ch), 7) < 1)
		msg_to_char(ch, "You try, but fail!\r\n");

	/* height */
	else if (is_abbrev(buf, "height")) {
		if (!*argument)
			msg_to_char(ch, "Make %s taller or shorter?\r\n", ch == victim ? "yourself" : HMHR(victim));
		else if ((to_val = (is_abbrev(argument, "taller") ? 1 : 0)) && 0)
			msg_to_char(ch, "You should never see this message.\r\n");
		else if (!to_val && (to_val = (is_abbrev(argument, "shorter") ? 2 : 0)) && 0)
			msg_to_char(ch, "You should never see this message.\r\n");
		else if (!to_val)
			msg_to_char(ch, "Make %s taller or shorter?\r\n", ch == victim ? "yourself" : HMHR(victim));
		else if (GET_HEIGHT(ch) > 80 && to_val == 1)
			msg_to_char(ch, "You can't make %s any taller!\r\n", ch == victim ? "yourself" : HMHR(victim));
		else if (GET_HEIGHT(ch) < 50 && to_val == 2)
			msg_to_char(ch, "You can't make %s any shorter!\r\n", ch == victim ? "yourself" : HMHR(victim));
		else {
			GET_BLOOD(ch) -= 1;
			if (to_val == 1)
				GET_HEIGHT(ch) += 5;
			else
				GET_HEIGHT(ch) -= 5;

			if (ch == victim) {
				sprintf(buf, "$n twists and pulls at $s form, maing $m drastically %s!", to_val == 1 ? "taller" : "shorter");
				act(buf, TRUE, ch, 0, 0, TO_ROOM);
				msg_to_char(ch, "You pull at your frame, %screasing your height!\r\n", to_val == 1 ? "in" : "de");
				}
			else {
				sprintf(buf, "You twist and pull at $N's form, making $m much %s!", to_val == 1 ? "taller" : "shorter");
				sprintf(buf1, "$n twists and pulls on your skeleton, making you much %s!", to_val == 1 ? "taller" : "shorter");
				sprintf(buf2, "$n horribly distorts $N, making $m drastically %s!", to_val == 1 ? "taller" : "shorter");

				act(buf, TRUE, ch, 0, victim, TO_CHAR);
				act(buf1, FALSE, ch, 0, victim, TO_VICT);
				act(buf2, FALSE, ch, 0, victim, TO_NOTVICT);
				}
			}
		}

	else
		msg_to_char(ch, "You can't change that physical attribute!\r\n");
	}


ADISC(disc_generic_morph) {
	int morph_to = MORPH_NONE;
	int cost = 1;

	switch (subcmd) {
		case 0:
			morph_to = MORPH_ZULO_SHAPE;
			cost = 3;
			break;
		case 1:
			morph_to = MORPH_CHIROPTERAN_MARAUDER;
			cost = 4;
			break;
		case 2:
			morph_to = MORPH_PLASMA_FORM;
			cost = 1;
			break;
		case 3:
			morph_to = MORPH_FORM_OF_THE_COBRA;
			cost = 1;
			break;
		}

	if (GET_ACTION(ch) != ACT_NONE)
		msg_to_char(ch, "You're too busy to transform now!\r\n");
	else if (GET_MORPH(ch) == morph_to && (morph_to = MORPH_NONE) && 0)
		msg_to_char(ch, "You should never see this message!\r\n");
	else if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
	else if (morph_to != MORPH_NONE && GET_BLOOD(ch) < cost + 1)
		msg_to_char(ch, "You don't have enough blood to transform!\r\n");
	else {
		if (morph_to != MORPH_NONE)
			GET_BLOOD(ch) -= cost;
		GET_ACTION(ch) = ACT_MORPHING;
		GET_ACTION_ROOM(ch) = NOWHERE;
		GET_ACTION_VNUM(ch, 0) = morph_to;
		GET_ACTION_TIMER(ch) = 2;
		GET_ACTION_ROTATION(ch) = last_action_rotation;

		msg_to_char(ch, "You begin to transform!\r\n");
		}
	}


ADISC(disc_liquefy_the_mortal_coil) {
	Creature victim;
	int to_hit = 0, resist = 0;

	one_argument(argument, arg);

	if (!*arg)
		msg_to_char(ch, "Liquify whom?\r\n");
	else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)))
		msg_to_char(ch, NOPERSON);
	else if (ch == victim)
		msg_to_char(ch, "You wouldn't want to do that to yourself...\r\n");
	else if (IS_GOD(victim) || IS_IMMORTAL(victim))
		msg_to_char(ch, "You cannot use this power on so godly a target!\r\n");
	else if (GET_MORPH(victim) == MORPH_PLASMA_FORM)
		act("$E is already liquified!", FALSE, ch, 0, victim, TO_CHAR);
	else if (!can_fight(ch, victim))
		act("You can't attack $M!", FALSE, ch, 0, victim, TO_CHAR);
	else if (!CAN_SPEND_WILLPOWER(ch))
		msg_to_char(ch, "Your willpower is shattered, you can't do that!\r\n");
	else if (GET_WILLPOWER(ch) < 1)
		msg_to_char(ch, "You lack the willpower to do that!\r\n");
	else {
		if (SHOULD_APPEAR(ch))
			appear(ch);

		GET_WILLPOWER(ch) -= 1;

		act("You touch $N with your cold hand..", FALSE, ch, 0, victim, TO_CHAR);
		act("$n touches you with a cold, clammy hand..", FALSE, ch, 0, victim, TO_VICT);
		act("$n touches $N with a cold, clammy hand..", TRUE, ch, 0, victim, TO_NOTVICT);

		to_hit = ww_dice(GET_STAMINA(ch) + GET_CRAFTS(ch), 8);
		resist = ww_dice(GET_STAMINA(victim), 6);

		if (to_hit <= resist || to_hit < 1) {
			msg_to_char(ch, "But nothing happens.\r\n");
			return;
			}

		msg_to_char(victim, "You liquefy and splash to the ground!\r\n");
		act("$n splashes to the ground in a red, blood-like blob!", TRUE, victim, 0, 0, TO_ROOM);

		perform_morph(victim, MORPH_PLASMA_FORM);

		WAIT_STATE(ch, PULSE_VIOLENCE);
		}
	}


/* ** THAUMATURGIC PATHS ** */
ADISC(disc_thaumaturgy) {
	int i;

	msg_to_char(ch, "When the mage Tremere made himself and his followers into vampires years ago,\r\nthey found their magic to have been destroyed by the change.  In the wake of\r\ntheir self-Embrace, they were left powerless.  Never ones to be halted in a\r\nquest, the Tremere developed Thaumaturgy, an unliving mockery of true magic.\r\n(Use the \"path\" command to utilize its powers)\r\nPaths:\r\n");

	for (i = 0; str_cmp(path[i].name, "\n"); i++)
		if (GET_PATH(ch, i))
			msg_to_char(ch, " %s\r\n", path[i].name);
	}


/* Rego Vitae */
ADISC(disc_rego_vitae) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Rego Vitae powers:\r\n");

	for (i = 0; str_cmp(paths[i].name, "\n"); i++)
		if (paths[i].disc == PATH_REGO_VITAE && paths[i].level <= GET_REGO_VITAE(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", paths[i].name);
			else
				found = TRUE;
			}
	}


ADISC(path_taste_for_blood) {
	extern const char *breed[];
	extern const char *auspice[];
	extern struct tribe_data tribe[];

	Creature victim;
	int i, j, c;
	byte roll = ww_dice(GET_WILLPOWER(ch), 4);

	one_argument(argument, arg);

	if (GET_FEEDING_FROM(ch))
		msg_to_char(ch, "You fail: You've already got your fangs in someone else.\r\n");
	else if (GET_ACTION(ch) != ACT_NONE)
		msg_to_char(ch, "You fail: You're a bit busy right now.\r\n");
	else if (!*arg)
		msg_to_char(ch, "You fail: Taste whose blood?\r\n");
	else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)))
		msg_to_char(ch, "You fail: There's nobody by that name here.\r\n");
	else if (ch == victim)
		msg_to_char(ch, "You fail: It seems redundant to taste your own blood..\r\n");
	else if (!IS_NPC(victim) && AWAKE(victim) && !PRF_FLAGGED(victim, PRF_BITEABLE))
		act("You fail: You don't have permission to taste $N's blood!", FALSE, ch, 0, victim, TO_CHAR);
	else if (roll < 1)
		msg_to_char(ch, "You fail.\r\n");
	else {
		act("You taste a sample of $N's blood!", FALSE, ch, 0, victim, TO_CHAR);
		act("$n tastes a sample of your blood!", FALSE, ch, 0, victim, TO_VICT);
		act("$n tastes a sample of $N's blood!", FALSE, ch, 0, victim, TO_NOTVICT);

		/* Blood Oath? */

		WAIT_STATE(ch, PULSE_VIOLENCE);

		/* 1 success */
		sprintf(buf, "This is $O, a %s.", IS_VAMPIRE(victim) ? "Cainite" : (IS_GHOUL(victim) ? "ghoul" : (IS_WEREWOLF(victim) ? "Lupine" : "mortal")));
		act(buf, FALSE, ch, 0, victim, TO_CHAR);

		if (GET_BLOOD(victim) != GET_MAX_BLOOD(victim)) {
			sprintf(buf, "$E is missing about %d%% of $S blood.", (GET_MAX_BLOOD(victim) - GET_BLOOD(victim)) * 100 / GET_MAX_BLOOD(victim));
			act(buf, FALSE, ch, 0, victim, TO_CHAR);
			}

		sprintf(buf, "$E is about %d years old.", GET_AGE(victim) + number(-1, 1));
		act(buf, FALSE, ch, 0, victim, TO_CHAR);

		/* 2 successes */
		if (roll < 2)
			return;

		if (IS_WEREWOLF(victim))
			sprintf(buf, "$S breed is %s, born %s %s, of the tribe %s.", breed[(int) GET_BREED(victim)], AN(auspice[(int) GET_AUSPICE(victim)]), auspice[(int) GET_AUSPICE(victim)], tribe[(int) GET_TRIBE(victim)].name);
		else if (IS_VAMPIRE(victim))
			sprintf(buf, "$E is of Clan %s.", clan[(int) GET_CLAN(victim)].name);
		else
			*buf = '\0';

		if (*buf)
			act(buf, FALSE, ch, 0, victim, TO_CHAR);

		/* 3 successes */
		if (roll < 3)
			return;

		if (IS_VAMPIRE(victim)) {
			sprintf(buf, "You think $E is Generation %d.", GET_GENERATION(victim));
			act(buf, FALSE, ch, 0, victim, TO_CHAR);
			}

		/* 4 successes */
		if (roll < 4)
			return;

		if (IS_VAMPIRE(victim) || IS_GHOUL(victim)) {
			*buf = '\0';
			for (i = 0, c = 0; i < NUM_DISCS; i++)
				if (GET_DISC(victim, i) > 0) {
					sprintf(buf + strlen(buf), " %-14.14s", disc[i].name);
					for (j = 1; j <= 10; j++) {
						if (GET_DISC(victim, i) >= j)
							strcat(buf, "*");
						else
							strcat(buf, " ");
						}
					if (!(++c % 3))
						strcat(buf, "\r\n ");
					}
			if (c % 3)
				strcat(buf, "\r\n ");
			if (*buf) {
				msg_to_char(ch, " +------------------------------- Disciplines --------------------------------+\r\n ");
				msg_to_char(ch, buf);
				}

			if (GET_THAUMATURGY(victim)) {
				*buf = '\0';
				for (i = 0, c = 0; i < NUM_PATHS; i++)
					if (GET_PATH(victim, i) > 0) {
						sprintf(buf + strlen(buf), " %-19.19s", path[i].name);
						for (j = 1; j <= 5; j++) {
							if (GET_PATH(victim, i) >= j)
								strcat(buf, "*");
							else
								strcat(buf, " ");
							}
						if (!(++c % 3))
							strcat(buf, "\r\n ");
						}
				if (c % 3)
					strcat(buf, "\r\n ");
				if (*buf) {
					msg_to_char(ch, "+---------------------------------- Paths ----------------------------------+\r\n ");
					msg_to_char(ch, buf);
					}
				}
			}
		}
	}


/* Creo Ignem */
ADISC(disc_creo_ignem) {
	extern const char *dirs[];
	extern Object light_obj(Object obj, int list_entry);
	extern int can_light(Object obj);

	Creature victim = NULL;
	Object obj = NULL;
	int i = 0;
	room_rnum room;
	bool dir = FALSE;

	one_argument(argument, arg);

	if (!*arg)
	 	msg_to_char(ch, "Set what aflame?\r\n");
	else if (!(obj = get_obj_in_list_vis(ch, arg, ch->carrying)) && !(obj = get_obj_in_list_vis(ch, arg, world[ch->in_room].contents)) && !(victim = get_char_vis(ch, arg, FIND_CHAR_ROOM)) && ((i = parse_direction(arg)) == NOWHERE || !(dir = TRUE)))
		msg_to_char(ch, "You see nothing called %s here.", arg);
	else if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
	else if (GET_BLOOD(ch) < 2)
		msg_to_char(ch, "You don't have enough blood to do that!\r\n");

	/* obj handling */
	else if (obj && (i = can_light(obj)) == -1)
		act("$p refuses to light.", FALSE, ch, obj, 0, TO_CHAR);
	else if (obj) {
		act("You wave your hand and light $p.", FALSE, ch, obj, 0, TO_CHAR);
		act("$n waves $s hand and lights $p.", FALSE, ch, obj, 0, TO_ROOM);

		light_obj(obj, i);

		GET_BLOOD(ch) -= 1;
		}

	/* dir handling */
	else if (dir && GET_CREO_IGNEM(ch) < 3)
		msg_to_char(ch, "You require at least level 3 to burn buildings!\r\n");
	else if (dir && !IS_OUTDOORS(ch))
		msg_to_char(ch, "You can only light buildings on fire from outside!\r\n");
	else if (dir && ((room = real_shift(ch->in_room, shift_dir[i][0], shift_dir[i][1])) == NOWHERE || !BUILDING_CAN_BURN(room)))
		msg_to_char(ch, "You can only light wooden buildings on fire!\r\n");
	else if (dir) {
		msg_to_char(ch, "You extend your hand and shoot a bolt of fire %s!\r\n", dirs[i]);
		sprintf(buf, "$n extends $s hand and shoots a bolt of fire %s!", dirs[i]);
		act(buf, FALSE, ch, 0, 0, TO_ROOM);

		if (!world[room].burning)
			world[room].burning = number((6 - GET_CREO_IGNEM(ch)), 10);
		else if (world[room].burning > 1)
			world[room].burning -= 1;

		if (world[room].people)
			act("The building ignites in a ball of fire!", FALSE, world[room].people, 0, 0, TO_CHAR | TO_ROOM);

		GET_BLOOD(ch) -= 1;
		}

	/* damage handling */
	else if (victim && GET_CREO_IGNEM(ch) < 4)
		msg_to_char(ch, "You require at least level 4 to attack with fire!\r\n");
	else if (victim && !can_fight(ch, victim))
		act("You can't attack $M!", FALSE, ch, 0, victim, TO_CHAR);
	else if (victim && ww_dice(GET_DEXTERITY(ch) + GET_ATHLETICS(ch), 7) < 1) {
		GET_BLOOD(ch) -= 1;

		damage(ch, victim, 0, ATTACK_CREO_IGNEM, DAM_AGGRAVATED);
		}
	else if (victim) {
		GET_BLOOD(ch) -= 1;

		damage(ch, victim, GET_CREO_IGNEM(ch) + number(-1, 2), ATTACK_CREO_IGNEM, DAM_AGGRAVATED);
		}

	else
		msg_to_char(ch, "You fail.\r\n");

	WAIT_STATE(ch, PULSE_VIOLENCE * 2);
	}


/* Rego Motus */
ADISC(disc_rego_motus) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Rego Motus powers:\r\n");

	for (i = 0; str_cmp(paths[i].name, "\n"); i++)
		if (paths[i].disc == PATH_REGO_MOTUS && paths[i].level <= GET_REGO_MOTUS(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", paths[i].name);
			else
				found = TRUE;
			}
	}


/* Rego Tempestas */
ADISC(disc_rego_tempestas) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Rego Tempestas powers:\r\n");

	for (i = 0; str_cmp(paths[i].name, "\n"); i++)
		if (paths[i].disc == PATH_REGO_TEMPESTAS && paths[i].level <= GET_REGO_TEMPESTAS(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", paths[i].name);
			else
				found = TRUE;
			}
	}


/* Rego Aquam */
ADISC(disc_rego_aquam) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Rego Aquam powers:\r\n");

	for (i = 0; str_cmp(paths[i].name, "\n"); i++)
		if (paths[i].disc == PATH_REGO_AQUAM && paths[i].level <= GET_REGO_AQUAM(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", paths[i].name);
			else
				found = TRUE;
			}
	}


/* Rego Elementum */
ADISC(disc_rego_elementum) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Rego Elementum powers:\r\n");

	for (i = 0; str_cmp(paths[i].name, "\n"); i++)
		if (paths[i].disc == PATH_REGO_ELEMENTUM && paths[i].level <= GET_REGO_ELEMENTUM(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", paths[i].name);
			else
				found = TRUE;
			}
	}


/* Way of Levinbolt */
ADISC(disc_way_of_levinbolt) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Way of Levinbolt powers:\r\n");

	for (i = 0; str_cmp(paths[i].name, "\n"); i++)
		if (paths[i].disc == PATH_WAY_OF_LEVINBOLT && paths[i].level <= GET_WAY_OF_LEVINBOLT(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", paths[i].name);
			else
				found = TRUE;
			}
	}


/* Path of Warding */
ADISC(disc_path_of_warding) {
	int i;
	bool found = FALSE;

	msg_to_char(ch, "Path of Warding powers:\r\n");

	for (i = 0; str_cmp(paths[i].name, "\n"); i++)
		if (paths[i].disc == PATH_PATH_OF_WARDING && paths[i].level <= GET_PATH_OF_WARDING(ch)) {
			if (found)
				msg_to_char(ch, " %s\r\n", paths[i].name);
			else
				found = TRUE;
			}
	}


/* Other */

/* Rise from an earthmeld - not vampire-specific, for safety */
ACMD(do_rise) {
	bool override = FALSE;

	skip_spaces(&argument);

	if (*argument == '+')
		override = TRUE;

	if (!DSC_FLAGGED(ch, DSC_EARTHMELD))
		msg_to_char(ch, "You aren't even interred in the earth!\r\n");
	else if (IS_VAMPIRE(ch) && weather_info.sunlight != SUN_DARK && !ROOM_AFF_FLAGGED(ch->in_room, ROOM_AFF_DARK) && !override)
		msg_to_char(ch, "You can't rise from the ground in broad sunlight!\r\nType 'rise +' to rise anyway, though you may be burnt by the sun.\r\n");
	else if (GET_DISC(ch, DISC_PROTEAN) >= 8 && (SECT(ch->in_room) == SECT_BUILDING || SECT(ch->in_room) == SECT_MULTI || SECT(ch->in_room) == SECT_MONUMENT_CLOSED))
		msg_to_char(ch, "You can't rise here!\r\n");
	else {
		msg_to_char(ch, "You rise from the ground!\r\n");
		if (affected_by_spell(ch, ATYPE_EARTHMELD))
			affect_from_char(ch, ATYPE_EARTHMELD);
		REMOVE_BIT(DSC_FLAGS(ch), DSC_EARTHMELD);
		act("$n rises from the ground!", TRUE, ch, 0, 0, TO_ROOM);
		GET_POS(ch) = POS_STANDING;
		look_at_room(ch);
		}
	}


ACMD(do_boost) {
	struct affected_type *af;
	int amount = 0, amount1 = 0, amount2 = 0;

	two_arguments(argument, arg, buf);

	if (!*arg || !*buf)
		msg_to_char(ch, "Which Physical Attribute do you wish to boost, and by how much?\r\n");
	else if ((amount = atoi(buf)) <= 0)
		msg_to_char(ch, "Boost it by how much?\r\n");
	else if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");

	/* Strength */
	else if (is_abbrev(arg, "strength")) {
		if ((amount = MIN(amount, att_max(ch) - GET_STRENGTH(ch))) <= 0)
			msg_to_char(ch, "Your strength is already at maximum!\r\n");
		else if (amount > GET_BLOOD(ch) - 1)
			msg_to_char(ch, "You don't have enough blood to boost your strength that much!\r\n");
		else {
			CREATE(af, struct affected_type, 1);
			af->type = ATYPE_BOOST;
			af->duration = 12;
			af->location = APPLY_STRENGTH;
			af->modifier = amount;
			af->bitvector = 0;
			af->disc_bit = 0;

			affect_join(ch, af, 0, 1, 1, 0);

			GET_BLOOD(ch) -= amount;

			msg_to_char(ch, "You force blood into your muscles, boosting your strength!\r\n");
			}
		}

	/* Dexterity */
	else if (is_abbrev(arg, "dexterity")) {
		if ((amount = MIN(amount, att_max(ch) - GET_DEXTERITY(ch))) <= 0)
			msg_to_char(ch, "Your dexterity is already at maximum!\r\n");
		else if (amount > GET_BLOOD(ch) - 1)
			msg_to_char(ch, "You don't have enough blood to boost your dexterity that much!\r\n");
		else {
			CREATE(af, struct affected_type, 1);
			af->type = ATYPE_BOOST;
			af->duration = 12;
			af->location = APPLY_DEXTERITY;
			af->modifier = amount;
			af->bitvector = 0;
			af->disc_bit = 0;

			affect_join(ch, af, 0, 1, 1, 0);

			GET_BLOOD(ch) -= amount;

			msg_to_char(ch, "You focus your blood, increasing your dexterity!\r\n");
			}
		}

	/* Stamina */
	else if (is_abbrev(arg, "stamina")) {
		if ((amount = MIN(amount, att_max(ch) - GET_STAMINA(ch))) <= 0)
			msg_to_char(ch, "Your stamina is already at maximum!\r\n");
		else if (amount > GET_BLOOD(ch) - 1)
			msg_to_char(ch, "You don't have enough blood to boost your stamina that much!\r\n");
		else {
			CREATE(af, struct affected_type, 1);
			af->type = ATYPE_BOOST;
			af->duration = 12;
			af->location = APPLY_STAMINA;
			af->modifier = amount;
			af->bitvector = 0;
			af->disc_bit = 0;

			affect_join(ch, af, 0, 1, 1, 0);

			GET_BLOOD(ch) -= amount;

			msg_to_char(ch, "You focus your blood, increasing your endurance!\r\n");
			}
		}

	/* All */
	else if (is_abbrev(arg, "all")) {
		amount = MIN(amount, att_max(ch) - GET_STRENGTH(ch));
		amount1 = MIN(amount, att_max(ch) - GET_DEXTERITY(ch));
		amount2 = MIN(amount, att_max(ch) - GET_STAMINA(ch));

		if (amount <= 0 && amount1 <= 0 && amount <= 0)
			msg_to_char(ch, "Your Physical Attributes are already at maximum!\r\n");
		else if (amount + amount1 + amount2 > GET_BLOOD(ch) - 1)
			msg_to_char(ch, "You don't have enough blood to boost your Attributes that much!\r\n");
		else {
			CREATE(af, struct affected_type, 3);
			af[0].type = ATYPE_BOOST;
			af[0].duration = 12;
			af[0].location = APPLY_STRENGTH;
			af[0].modifier = amount;
			af[0].bitvector = 0;
			af[0].disc_bit = 0;

			af[1].type = ATYPE_BOOST;
			af[1].duration = 12;
			af[1].location = APPLY_DEXTERITY;
			af[1].modifier = amount1;
			af[1].bitvector = 0;
			af[1].disc_bit = 0;

			af[2].type = ATYPE_BOOST;
			af[2].duration = 12;
			af[2].location = APPLY_STAMINA;
			af[2].modifier = amount2;
			af[2].bitvector = 0;
			af[2].disc_bit = 0;

			affect_join(ch, af, 0, 1, 1, 0);
			affect_join(ch, af + 1, 0, 1, 1, 0);
			affect_join(ch, af + 2, 0, 1, 1, 0);

			GET_BLOOD(ch) -= amount + amount1 + amount2;

			msg_to_char(ch, "You force blood through your body, increasing your Physical Attributes!\r\n");
			}
		}

	else
		msg_to_char(ch, "Would you like to increase your strength, dexterity, or stamina?\r\n");
	}


/* Data structure ******************************************************* */
struct discipline_power_data discs[] = {
		/* Animalism */
		{ "Animalism",				DISC_ANIMALISM,		1,	POS_DEAD,		0,	disc_animalism	},
		{ "feral speech",			DISC_ANIMALISM,		1,	POS_DEAD,		0,	disc_feral_speech	},
		{ "Noah's call",			DISC_ANIMALISM,		2,	POS_FIGHTING,	0,	disc_noahs_call	},
		{ "cowing the beast",		DISC_ANIMALISM,		3,	POS_FIGHTING,	0,	disc_cowing_the_beast	},
		{ "ride the wild mind",		DISC_ANIMALISM,		4,	POS_STANDING,	0,	disc_uncoded	},
		{ "drawing out the beast",	DISC_ANIMALISM,		5,	POS_FIGHTING,	0,	disc_uncoded	},
		{ "quickened unity",		DISC_ANIMALISM,		6,	POS_STANDING,	0,	disc_uncoded	},
		{ "twist the feral will",	DISC_ANIMALISM,		7,	POS_FIGHTING,	0,	disc_uncoded	},
		{ "taunt the caged beast",	DISC_ANIMALISM,		8,	POS_FIGHTING,	0,	disc_uncoded	},

		/* Auspex */
		{ "Auspex",					DISC_AUSPEX,		1,	POS_DEAD,		0,	disc_auspex	},
		{ "heightened senses",		DISC_AUSPEX,		1,	POS_RESTING,	0,	disc_heightened_senses	},
		{ "soulsight",				DISC_AUSPEX,		2,	POS_RESTING,	0,	disc_soulsight	},
		{ "spirit's touch",			DISC_AUSPEX,		3,	POS_RESTING,	0,	disc_spirits_touch	},
		{ "steal secrets",			DISC_AUSPEX,		4,	POS_STANDING,	0,	disc_uncoded	},
		{ "anima walk",				DISC_AUSPEX,		5,	POS_STANDING,	0,	disc_uncoded	},
		{ "farsight",				DISC_AUSPEX,		6,	POS_STANDING,	0,	disc_farsight	},
		{ "oracle's sight",			DISC_AUSPEX,		7,	POS_STANDING,	0,	disc_uncoded	},

		/* Celerity */
		{ "Celerity",				DISC_CELERITY,		1,	POS_RESTING,	0,	disc_celerity	},

		/* Chimerstry */
		{ "Chimerstry",				DISC_CHIMERSTRY,	1,	POS_DEAD,		0,	disc_chimerstry	},
		{ "ignus fatuus",			DISC_CHIMERSTRY,	1,	POS_STANDING,	0,	disc_uncoded	},
		{ "dweomer",				DISC_CHIMERSTRY,	2,	POS_STANDING,	0,	disc_uncoded	},
		{ "apparition",				DISC_CHIMERSTRY,	3,	POS_STANDING,	0,	disc_uncoded	},
		{ "permanency",				DISC_CHIMERSTRY,	4,	POS_STANDING,	0,	disc_uncoded	},
		{ "horrid reality",			DISC_CHIMERSTRY,	5,	POS_STANDING,	0,	disc_uncoded	},
		{ "mass horror",			DISC_CHIMERSTRY,	6,	POS_STANDING,	0,	disc_uncoded	},
		{ "mirror's visage",		DISC_CHIMERSTRY,	7,	POS_STANDING,	0,	disc_uncoded	},

		/* Dementation */
		{ "Dementation",			DISC_DEMENTATION,	1,	POS_DEAD,		0,	disc_dementation	},
		{ "incubus passion",		DISC_DEMENTATION,	1,	POS_FIGHTING,	0,	disc_uncoded	},
		{ "haunt the soul",			DISC_DEMENTATION,	2,	POS_FIGHTING,	0,	disc_uncoded	},
		{ "eyes of chaos",			DISC_DEMENTATION,	3,	POS_STANDING,	0,	disc_uncoded	},
		{ "confusion",				DISC_DEMENTATION,	4,	POS_FIGHTING,	0,	disc_uncoded	},
		{ "howling lunacy",			DISC_DEMENTATION,	5,	POS_FIGHTING,	0,	disc_uncoded	},
		{ "kiss of the moon",		DISC_DEMENTATION,	6,	POS_FIGHTING,	0,	disc_uncoded	},
		{ "prison of the mind",		DISC_DEMENTATION,	7,	POS_FIGHTING,	0,	disc_uncoded	},

		/* Dominate */
		{ "Dominate",				DISC_DOMINATE,		1,	POS_DEAD,		0,	disc_dominate	},
		{ "observance of the spoken word",DISC_DOMINATE,1,	POS_FIGHTING,	0,	disc_observance	},
		{ "murmur of the false will",DISC_DOMINATE,		2,	POS_FIGHTING,	0,	disc_murmur	},
		{ "reveler's memory",		DISC_DOMINATE,		3,	POS_FIGHTING,	0,	disc_uncoded	},
		{ "lure of subtle whispers",DISC_DOMINATE,		4,	POS_FIGHTING,	0,	disc_uncoded	},
		{ "vessel",					DISC_DOMINATE,		5,	POS_STANDING,	0,	disc_uncoded	},
		{ "fealty",					DISC_DOMINATE,		6,	POS_STANDING,	0,	disc_uncoded	},
		{ "command the legion",		DISC_DOMINATE,		7,	POS_FIGHTING,	0,	disc_uncoded	},

		/* Fortitude */
		{ "Fortitude",				DISC_FORTITUDE,		1,	POS_DEAD,		0,	disc_fortitude	},
		{ "armor of vitality",		DISC_FORTITUDE,		6,	POS_STANDING,	0,	disc_armor_of_vitality	},
		{ "bestow vigor",			DISC_FORTITUDE,		7,	POS_STANDING,	0,	disc_bestow_vigor	},
		{ "eternal vigilance",		DISC_FORTITUDE,		8,	POS_STANDING,	0,	disc_eternal_vigilance	},

		/* Mortis */
		{ "Mortis",					DISC_MORTIS,		1,	POS_DEAD,		0,	disc_mortis		},
		{ "masque of death",		DISC_MORTIS,		1,	POS_STANDING,	0,	disc_masque_of_death	},
		{ "blight",					DISC_MORTIS,		2,	POS_FIGHTING,	0,	disc_blight	},
		{ "awaken",					DISC_MORTIS,		3,	POS_DEAD,		0,	disc_awaken	},
		{ "death's whisper",		DISC_MORTIS,		4,	POS_STUNNED,	0,	disc_deaths_whisper	},
		{ "black death",			DISC_MORTIS,		5,	POS_FIGHTING,	0,	disc_black_death	},
		{ "vigor mortis",			DISC_MORTIS,		6,	POS_STANDING,	0,	disc_uncoded	},
		{ "plague wind",			DISC_MORTIS,		7,	POS_FIGHTING,	0,	disc_uncoded	},

		/* Obfuscate */
		{ "Obfuscate",				DISC_OBFUSCATE,		1,	POS_DEAD,		0,	disc_obfuscate	},
		{ "cloak of shadows",		DISC_OBFUSCATE,		1,	POS_STANDING,	0,	disc_cloak_of_shadows	},
		{ "unseen presence",		DISC_OBFUSCATE,		2,	POS_STANDING,	0,	disc_unseen_presence	},
		{ "mask of a thousand faces",DISC_OBFUSCATE,	3,	POS_STANDING,	0,	disc_mask_of_a_thousand_faces	},
		{ "vanish from the mind's eye",DISC_OBFUSCATE,	4,	POS_STANDING,	1,	disc_unseen_presence	},
		{ "cloak the gathering",	DISC_OBFUSCATE,		5,	POS_STANDING,	0,	disc_cloak_the_gathering	},
		{ "soul mask",				DISC_OBFUSCATE,		6,	POS_STANDING,	0,	disc_soul_mask	},
		{ "veil the legions",		DISC_OBFUSCATE,		7,	POS_STANDING,	0,	disc_veil_the_legions	},

		/* Obtenebration */
		{ "Obtenebration",			DISC_OBTENEBRATION,	1,	POS_DEAD,		0,	disc_obtenebration},
		{ "shadow play",			DISC_OBTENEBRATION,	1,	POS_STANDING,	0,	disc_shadowplay	},
		{ "nocturne",				DISC_OBTENEBRATION,	2,	POS_STANDING,	0,	disc_nocturne	},
		{ "arms of Ahriman",		DISC_OBTENEBRATION,	3,	POS_FIGHTING,	0,	disc_arms_of_ahriman	},
		{ "nightshades",			DISC_OBTENEBRATION,	4,	POS_FIGHTING,	0,	disc_nightshades	},
		{ "tenebrous form",			DISC_OBTENEBRATION,	5,	POS_STANDING,	0,	disc_uncoded	},
		{ "walk the abyss",			DISC_OBTENEBRATION,	6,	POS_STANDING,	0,	disc_uncoded	},
		{ "death shroud",			DISC_OBTENEBRATION,	7,	POS_STANDING,	0,	disc_uncoded	},

		/* Potence */
		{ "Potence",				DISC_POTENCE,		1,	POS_DEAD,		0,	disc_potence	},

		/* Presence */
		{ "Presence",				DISC_PRESENCE,		1,	POS_DEAD,		0,	disc_presence	},
		{ "awe",					DISC_PRESENCE,		1,	POS_STANDING,	0,	disc_awe	},
		{ "dread gaze",				DISC_PRESENCE,		2,	POS_FIGHTING,	0,	disc_dread_gaze	},
		{ "entrancement",			DISC_PRESENCE,		3,	POS_STANDING,	0,	disc_entrancement	},
		{ "summon",					DISC_PRESENCE,		4,	POS_STANDING,	0,	disc_summon	},
		{ "majesty",				DISC_PRESENCE,		5,	POS_STANDING,	0,	disc_majesty	},
		{ "passion",				DISC_PRESENCE,		6,	POS_FIGHTING,	0,	disc_uncoded	},
		{ "unholy penance",			DISC_PRESENCE,		7,	POS_STANDING,	0,	disc_uncoded	},

		/* Protean */
		{ "Protean",				DISC_PROTEAN,		1,	POS_DEAD,		0,	disc_protean	},
		{ "witness of darkness",	DISC_PROTEAN,		1,	POS_RESTING,	0,	disc_witness_of_darkness	},
		{ "talons of the beast",	DISC_PROTEAN,		2,	POS_FIGHTING,	0,	disc_talons_of_the_beast	},
		{ "interred in the earth",	DISC_PROTEAN,		3,	POS_STANDING,	0,	disc_earthmeld	},
		{ "form of the beast",		DISC_PROTEAN,		4,	POS_STANDING,	0,	disc_form_of_the_beast	},
		{ "body of spirit",			DISC_PROTEAN,		5,	POS_STANDING,	0,	disc_body_of_spirit	},
		{ "blissful slumber",		DISC_PROTEAN,		6,	POS_STANDING,	0,	disc_blissful_slumber	},
		{ "mastery of the earth",	DISC_PROTEAN,		7,	POS_SLEEPING,	0,	disc_mastery_of_the_earth	},
		{ "purify the body",		DISC_PROTEAN,		8,	POS_STANDING,	0,	disc_purify_the_body	},

		/* Quietus */
		{ "Quietus",				DISC_QUIETUS,		1,	POS_DEAD,		0,	disc_quietus	},
		{ "silence of death",		DISC_QUIETUS,		1,	POS_STANDING,	0,	disc_silence_of_death	},
		{ "weakness",				DISC_QUIETUS,		2,	POS_FIGHTING,	0,	disc_weakness	},
		{ "disease",				DISC_QUIETUS,		3,	POS_FIGHTING,	0,	disc_disease	},
		{ "blood agony",			DISC_QUIETUS,		4,	POS_STANDING,	0,	disc_blood_agony	},
		{ "blood essence",			DISC_QUIETUS,		5,	POS_STANDING,	0,	disc_blood_essence	},
		{ "blood sweat",			DISC_QUIETUS,		6,	POS_FIGHTING,	0,	disc_blood_sweat	},
		{ "quicken the mortal blood",DISC_QUIETUS,		7,	POS_STANDING,	0,	disc_quicken_the_mortal_blood	},
		{ "hinder the Cainite vitae",DISC_QUIETUS,		8,	POS_FIGHTING,	0,	disc_hinder_the_cainite_vitae	},

		/* Serpentis */
		{ "Serpentis",				DISC_SERPENTIS,		1,	POS_DEAD,		0,	disc_serpentis	},
		{ "eyes of the serpent",	DISC_SERPENTIS,		1,	POS_FIGHTING,	0,	disc_uncoded	},
		{ "tongue of the asp",		DISC_SERPENTIS,		2,	POS_FIGHTING,	0,	disc_tongue_of_the_asp	},
		{ "bitumenous flesh",		DISC_SERPENTIS,		3,	POS_STUNNED,	0,	disc_bitumenous_flesh	},
		{ "form of the cobra",		DISC_SERPENTIS,		4,	POS_STANDING,	3,	disc_generic_morph	},
		{ "cheat Thoth's scale",	DISC_SERPENTIS,		5,	POS_STANDING,	0,	disc_uncoded	},
		{ "breath of the basilisk",	DISC_SERPENTIS,		6,	POS_FIGHTING,	0,	disc_breath_of_the_basilisk	},
		{ "Set's curse",			DISC_SERPENTIS,		7,	POS_FIGHTING,	0,	disc_uncoded	},
		{ "Apep's semblance",		DISC_SERPENTIS,		8,	POS_STANDING,	0,	disc_uncoded	},

		/* Thaumaturgy */
		{ "Thaumaturgy",			DISC_THAUMATURGY,	1,	POS_DEAD,		0,	disc_thaumaturgy},

		/* Vicissitude */
		{ "Vicissitude",			DISC_VICISSITUDE,	1,	POS_DEAD,		0,	disc_vicissitude},
		{ "malleable visage",		DISC_VICISSITUDE,	1,	POS_STANDING,	0,	disc_malleable_visage	},
		{ "transmogrify the mortal clay",	DISC_VICISSITUDE,	2,	POS_STANDING,	1,	disc_malleable_visage	},
		{ "rend the osseous frame",	DISC_VICISSITUDE,	3,	POS_STANDING,	0,	disc_rend_the_osseous_frame	},
		{ "awaken the zulo shape",	DISC_VICISSITUDE,	4,	POS_STANDING,	0,	disc_generic_morph	},
		{ "ascendancy of the sanguine humor",	DISC_VICISSITUDE,	5,	POS_STANDING,	2,	disc_generic_morph	},
		{ "chiropteran marauder",	DISC_VICISSITUDE,	6,	POS_STANDING,	1,	disc_generic_morph	},
		{ "liquefy the mortal coil",DISC_VICISSITUDE,	7,	POS_FIGHTING,	0,	disc_liquefy_the_mortal_coil	},

		{ "\n", -1, -1, -1, 0, NULL }
		};


/* paths */
struct discipline_power_data paths[] = {
		/* Rego Vitae */
		{ "Rego Vitae",			PATH_REGO_VITAE,		1,	POS_STANDING,		0,	disc_rego_vitae	},
		{ "taste for blood",	PATH_REGO_VITAE,		1,	POS_RESTING,		0,	path_taste_for_blood	},
		{ "blood rage",			PATH_REGO_VITAE,		2,	POS_STANDING,		0,	disc_uncoded	},
		{ "blood of potency",	PATH_REGO_VITAE,		3,	POS_STANDING,		0,	disc_uncoded	},
		{ "theft of vitae",		PATH_REGO_VITAE,		4,	POS_STANDING,		0,	disc_uncoded	},
		{ "cauldron of blood",	PATH_REGO_VITAE,		5,	POS_STANDING,		0,	disc_uncoded	},

		/* Creo Ignem */
		{ "Creo Ignem",			PATH_CREO_IGNEM,		1,	POS_FIGHTING,		0,	disc_creo_ignem	},

		/* Rego Motus */
		{ "Rego Motus",			PATH_REGO_MOTUS,		1,	POS_STANDING,		0,	disc_rego_motus	},
		{ "levitate",			PATH_REGO_MOTUS,		1,	POS_STANDING,		0,	disc_uncoded	},
		{ "fly",				PATH_REGO_MOTUS,		3,	POS_STANDING,		0,	disc_uncoded	},

		/* Rego Tempestas */
		{ "Rego Tempestas",		PATH_REGO_TEMPESTAS,	1,	POS_STANDING,		0,	disc_rego_tempestas	},
		{ "fog",				PATH_REGO_TEMPESTAS,	1,	POS_STANDING,		0,	disc_uncoded	},
		{ "rain",				PATH_REGO_TEMPESTAS,	2,	POS_STANDING,		0,	disc_uncoded	},
		{ "wind",				PATH_REGO_TEMPESTAS,	3,	POS_STANDING,		0,	disc_uncoded	},
		{ "storm",				PATH_REGO_TEMPESTAS,	4,	POS_STANDING,		0,	disc_uncoded	},
		{ "lightning",			PATH_REGO_TEMPESTAS,	5,	POS_STANDING,		0,	disc_uncoded	},

		/* Rego Aquam */
		{ "Rego Aquam",			PATH_REGO_AQUAM,		1,	POS_STANDING,		0,	disc_rego_aquam	},
		{ "eyes of the sea",	PATH_REGO_AQUAM,		1,	POS_STANDING,		0,	disc_uncoded	},
		{ "prison of water",	PATH_REGO_AQUAM,		2,	POS_STANDING,		0,	disc_uncoded	},
		{ "dehydrate",			PATH_REGO_AQUAM,		3,	POS_STANDING,		0,	disc_uncoded	},
		{ "flowing wall",		PATH_REGO_AQUAM,		4,	POS_STANDING,		0,	disc_uncoded	},
		{ "blood to water",		PATH_REGO_AQUAM,		5,	POS_STANDING,		0,	disc_uncoded	},

		/* Rego Elementum */
		{ "Rego Elementum",		PATH_REGO_ELEMENTUM,	1,	POS_STANDING,		0,	disc_rego_elementum	},
		{ "elemental strength",	PATH_REGO_ELEMENTUM,	1,	POS_STANDING,		0,	disc_uncoded	},
		{ "wooden tongues",		PATH_REGO_ELEMENTUM,	2,	POS_STANDING,		0,	disc_uncoded	},
		{ "animate unmoving",	PATH_REGO_ELEMENTUM,	3,	POS_STANDING,		0,	disc_uncoded	},
		{ "elemental form",		PATH_REGO_ELEMENTUM,	4,	POS_STANDING,		0,	disc_uncoded	},
		{ "summon elemental",	PATH_REGO_ELEMENTUM,	5,	POS_STANDING,		0,	disc_uncoded	},

		/* Way of Levinbolt */
		{ "Way of Levinbolt",	PATH_WAY_OF_LEVINBOLT,	1,	POS_STANDING,		0,	disc_way_of_levinbolt	},
		{ "spark",				PATH_WAY_OF_LEVINBOLT,	1,	POS_STANDING,		0,	disc_uncoded	},
		{ "illuminate",			PATH_WAY_OF_LEVINBOLT,	2,	POS_STANDING,		0,	disc_uncoded	},
		{ "body of light",		PATH_WAY_OF_LEVINBOLT,	3,	POS_STANDING,		0,	disc_uncoded	},
		{ "Jupiter's aegis",	PATH_WAY_OF_LEVINBOLT,	4,	POS_STANDING,		0,	disc_uncoded	},
		{ "lightning dance",	PATH_WAY_OF_LEVINBOLT,	5,	POS_STANDING,		0,	disc_uncoded	},

		/* Path of Warding */
		{ "Path of Warding",	PATH_PATH_OF_WARDING,	1,	POS_STANDING,		0,	disc_path_of_warding	},
		{ "bar the common passage",	PATH_PATH_OF_WARDING,	1,	POS_STANDING,		0,	disc_uncoded	},
		{ "glyph of scrying",	PATH_PATH_OF_WARDING,	2,	POS_STANDING,		0,	disc_uncoded	},
		{ "runes of power",		PATH_PATH_OF_WARDING,	3,	POS_STANDING,		0,	disc_uncoded	},
		{ "glyph of enlightenment",	PATH_PATH_OF_WARDING,	4,	POS_STANDING,		0,	disc_uncoded	},
		{ "secure sacred domain",	PATH_PATH_OF_WARDING,	5,	POS_STANDING,		0,	disc_uncoded	},

		{ "\n", -1, -1, -1, 0, NULL }
		};


int find_disc_by_name(char *name) {
	int i;
	bool ok;
	char *b1, *b2;
	char w1[256], w2[256];

	for (i = 0; strcmp(discs[i].name, "\n"); i++) {
		if (is_abbrev(name, discs[i].name))
			return (i);

		ok = TRUE;

		b1 = any_one_arg(discs[i].name, w1);
		b2 = any_one_arg(name, w2);
		while (*w1 && *w2 && ok) {
			if (!is_abbrev(w2, w1))
				ok = FALSE;
			b1 = any_one_arg(b1, w1);
			b2 = any_one_arg(b2, w2);
			}

		if (ok && !*w2)
			return (i);
		}

	return (-1);
	}


int find_path_by_name(char *name) {
	int i;
	bool ok;
	char *b1, *b2;
	char w1[256], w2[256];

	for (i = 0; strcmp(paths[i].name, "\n"); i++) {
		if (is_abbrev(name, paths[i].name))
			return (i);

		ok = TRUE;

		b1 = any_one_arg(paths[i].name, w1);
		b2 = any_one_arg(name, w2);
		while (*w1 && *w2 && ok) {
			if (!is_abbrev(w2, w1))
				ok = FALSE;
			b1 = any_one_arg(b1, w1);
			b2 = any_one_arg(b2, w2);
			}

		if (ok && !*w2)
			return (i);
		}

	return (-1);
	}


ACMD(do_discipline) {
	char *a, *targ;
	int d;

	if (IS_NPC(ch))
		return;

	a = strtok(argument, "\"");

	if (!a) {
		msg_to_char(ch, "Use what discipline?\r\n");
		return;
		}

	a = strtok(NULL, "\"");
	if (!a) {
		msg_to_char(ch, "You must enclose the discipline name in \"quotes.\"\r\n");
		return;
		}

	/* targ is the rest of what they typed, the arguments */
	targ = strtok(NULL, "\0");
	if (targ)
		skip_spaces(&targ);
	else
		targ = str_dup("");

	d = find_disc_by_name(a);

	if (d < 0) {
		msg_to_char(ch, "You don't know of any power like that!\r\n");
		return;
		}

	if (discs[d].level > GET_DISC(ch, (int) discs[d].disc)) {
		msg_to_char(ch, "You don't know how to use that power!\r\n");
		return;
		}

	if (GET_POS(ch) < discs[d].min_pos) {
		switch (GET_POS(ch)) {
			case POS_DEAD:
				send_to_char("Lie still; you are DEAD!!! :-(\r\n", ch);
				break;
			case POS_INCAP:
			case POS_MORTALLYW:
				send_to_char("You are in a pretty bad shape, unable to do anything!\r\n", ch);
				break;
			case POS_STUNNED:
				send_to_char("All you can do right now is think about the stars!\r\n", ch);
				break;
			case POS_SLEEPING:
				send_to_char("In your dreams, or what?\r\n", ch);
				break;
			case POS_RESTING:
				send_to_char("Nah... You feel too relaxed to do that..\r\n", ch);
				break;
			case POS_SITTING:
				send_to_char("Maybe you should get on your feet first?\r\n", ch);
				break;
			case POS_FIGHTING:
				send_to_char("No way!  You're fighting for your life!\r\n", ch);
				break;
			}
		}
	else
		((*discs[d].command_pointer) (ch, targ, discs[d].subcmd));
	}


ACMD(do_path) {
	char *a, *targ;
	int d;
	byte roll;

	if (IS_NPC(ch))
		return;

	a = strtok(argument, "\"");

	if (!a) {
		msg_to_char(ch, "Use what path?\r\n");
		return;
		}

	a = strtok(NULL, "\"");
	if (!a) {
		msg_to_char(ch, "You must enclose the path name in \"quotes.\"\r\n");
		return;
		}

	/* targ is the rest of what they typed, the arguments */
	targ = strtok(NULL, "\0");
	if (targ)
		skip_spaces(&targ);
	else
		targ = str_dup("");

	d = find_path_by_name(a);

	if (d < 0) {
		msg_to_char(ch, "You don't know of any power like that!\r\n");
		return;
		}

	if (paths[d].level > GET_PATH(ch, (int) paths[d].disc)) {
		msg_to_char(ch, "You don't know how to use that power!\r\n");
		return;
		}

	if (GET_POS(ch) < paths[d].min_pos) {
		switch (GET_POS(ch)) {
			case POS_DEAD:
				send_to_char("Lie still; you are DEAD!!! :-(\r\n", ch);
				break;
			case POS_INCAP:
			case POS_MORTALLYW:
				send_to_char("You are in a pretty bad shape, unable to do anything!\r\n", ch);
				break;
			case POS_STUNNED:
				send_to_char("All you can do right now is think about the stars!\r\n", ch);
				break;
			case POS_SLEEPING:
				send_to_char("In your dreams, or what?\r\n", ch);
				break;
			case POS_RESTING:
				send_to_char("Nah... You feel too relaxed to do that..\r\n", ch);
				break;
			case POS_SITTING:
				send_to_char("Maybe you should get on your feet first?\r\n", ch);
				break;
			case POS_FIGHTING:
				send_to_char("No way!  You're fighting for your life!\r\n", ch);
				break;
			}
		}
	else if (!CAN_SPEND_BLOOD(ch))
		msg_to_char(ch, "Your blood is inert, you can't do that!\r\n");
	else if (GET_BLOOD(ch) < 2)
		msg_to_char(ch, "You don't have enough blood to use paths.\r\n");
	else if (!CAN_SPEND_WILLPOWER(ch))
		msg_to_char(ch, "Your willpower is shattered, you can't do that!\r\n");
	else {
		if (paths[d].level > 1) {
			GET_BLOOD(ch) -= 1;
			roll = ww_dice(GET_WILLPOWER(ch), paths[d].level + 3);
			}
		else
			roll = 1;

		if (roll FAILED)
			msg_to_char(ch, "You fail!\r\n");
		else if (roll BOTCHED) {
			msg_to_char(ch, "You fail!\r\n");
			if (GET_MAX_WILLPOWER(ch) > 0)
				GET_MAX_WILLPOWER(ch) -= 1;
			if (GET_WILLPOWER(ch) > GET_MAX_WILLPOWER(ch))
				GET_WILLPOWER(ch) = GET_MAX_WILLPOWER(ch);
			}
		else
			((*paths[d].command_pointer) (ch, targ, paths[d].subcmd));
		}
	}