daleken/
daleken/data/notes/
daleken/data/player/
daleken/data/system/poses/
daleken/doc/Homepage/images/
daleken/log/
/*___________________________________________________________________________*
   )()(			  DalekenMUD 1.12 (C) 2000			)()(
   `]['		       by Martin Thomson, Lee Brooks,			`]['
    ||		       Ken Herbert and David Jacques			 ||
    || ----------------------------------------------------------------- ||
    || Envy Diku Mud improvements copyright (C) 1994 by Michael Quan,	 ||
    || David Love, Guilherme 'Willie' Arnold, and Mitchell Tse.		 ||
    || Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael	 ||
    || Chastain, Michael Quan, and Mitchell Tse.			 ||
    || Original Diku Mud copyright (C) 1990, 1991			 ||
    || by Sebastian Hammer, Michael Seifert, Hans Henrik St{rfeldt,	 ||
    || Tom Madsen, and Katja Nyboe.					 ||
    || ----------------------------------------------------------------- ||
    || Any use of this software must follow the licenses of the		 ||
    || creators.  Much time and thought has gone into this software and	 ||
    || you are benefitting. We hope that you share your changes too.	 ||
    || What goes around, comes around.					 ||
    || ----------------------------------------------------------------- ||
    ||                             magic_def.c                           ||
    || Defensive spells code.                                            ||
 *_/<>\_________________________________________________________________/<>\_*/


#include <math.h>
#include "mud.h"
#include "event.h"


/*
 * The kludgy global is for spells who want more stuff from command line.
 */
extern const char *target_name;

/*
 * Code for Psionicist spells/skills by Thelonius
 */
void spell_adrenaline_control( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = level - 5;
    af.location = APPLY_DEX;
    af.modifier = 2;
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    af.location = APPLY_CON;
    affect_to_char( victim, &af, ch );

    send_to_char( "You have just had a huge adrenaline rush!\n\r", victim );
    act( "$n has just had an adrenaline rush!", victim, NULL, NULL,
	TO_ROOM );

    return;
}


void spell_aid( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.location = APPLY_HIT;
    af.modifier = number_range( level * 3, level * 4 );
    af.duration = 24 * ( level / 50 );
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    if( victim != ch )
	send_to_char( "Ok.\n\r", ch );
    send_to_char( "You feel the assistance of your god.\n\r", victim );
    act( "$n is now aided by the physical presence of $s god.", victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_armour( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.location = APPLY_AC;
    af.modifier = -20;
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    if( ch != victim )
	send_to_char( "Ok.\n\r", ch );
    send_to_char( "You feel someone protecting you.\n\r", victim );
    return;
}


void spell_aura_sight( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.location = APPLY_NONE;
    af.modifier = 0;
    vset( af.bitvector, AFF_AURA_SIGHT );
    af.duration = 24 * (level / 50) + 24;
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "You can now see a glowing nimbus surrounding everyone.\n\r",
		  victim );
    act( "&g$n's eyes spin wildly then glow &Bblue&g.",
	 victim, NULL, NULL, TO_ROOM );

    return;
}


void spell_awen( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;
    int sntemp;

    if( ( IS_GOOD( ch ) && !IS_GOOD( victim ) )
	|| ( IS_NEUTRAL( ch ) && !IS_NEUTRAL( victim ) )
	|| ( IS_EVIL( ch ) && !IS_EVIL( victim ) ) )
    {
	send_to_char( "Your God doesn't like that person.\n\r", ch );
	return;
    }

    sntemp = skill_lookup( "bless" );
    ( *skill_table[sntemp].spell_fun ) ( sntemp, level, ch, vo );

    sntemp = skill_lookup( "armour" );
    ( *skill_table[sntemp].spell_fun ) ( sntemp, level, ch, vo );

    sntemp = skill_lookup( "holy armour" );
    ( *skill_table[sntemp].spell_fun ) ( sntemp, level, ch, vo );

    sntemp = skill_lookup( "holy aura" );
    ( *skill_table[sntemp].spell_fun ) ( sntemp, level, ch, vo );

    sntemp = skill_lookup( "protection" );
    ( *skill_table[sntemp].spell_fun ) ( sntemp, level, ch, vo );

    sntemp = skill_lookup( "sanctuary" );
    ( *skill_table[sntemp].spell_fun ) ( sntemp, level, ch, vo );

    af.type = gsn_awen;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.modifier = af.location = 0;
    vzero( af.bitvector );
    affect_to_char( victim, &af, ch );

    return;
}


void spell_bark_skin( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = level;
    af.location = APPLY_AC;
    af.modifier = -30;
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "Your skin forms a hard layer.\n\r", victim );
    act( "$n's skin turns to bark.", victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_bind_flesh( int sn, int level, CHAR_DATA *ch, void *vo )
{
    OBJ_DATA *limb;
    CHAR_DATA *vch = (CHAR_DATA *)vo;
    int add;

    if( !( limb = get_held( ch, ITEM_LIMB, TRUE ) ) )
    {
	send_to_char( "You aren't holding a limb to bind.\n\r", ch );
	return;
    }

    add = limb->value[0];
    if( ( add & vch->body_parts ) == add )
    {
	send_to_char( "That was pointless, they have the parts.\n\r", ch );
	extract_obj( limb );
	return;
    }
    vch->body_parts |= add;
    act( "$n binds $p onto your body.", ch, limb, vch, TO_VICT );
    act( "$n binds $p onto $N's body.", ch, limb, vch, TO_NOTVICT );
    if( limb->value[3] != 0
	&& !IS_SET( race_table[ch->race].race_abilities, RACE_NO_POISON ) )
    {
	/* The shit was poisoned! */
	AFFECT_DATA af;

	act( "$n turns a pale &ggreen&n.", ch, NULL, NULL, TO_ROOM );
	send_to_char( "You suddenly feel sick.\n\r", ch );

	af.type = gsn_poison;
	af.duration = 10;
	af.location = APPLY_STR;
	af.modifier = -2;
	vset( af.bitvector, AFF_POISON );
	affect_join( ch, &af );
    }
    send_to_char( "Ok.\n\r", ch );
    extract_obj( limb );
    return;
}


void spell_biofeedback( int sn, int level, CHAR_DATA *ch, void *vo )
{
    sn = skill_lookup( "Sanctuary" );

    if( ch->hit < 30 )
	send_to_char( "Your body couldn't handle that strain.\n\r", ch );
    else
    {
	ch->hit -= 25;
	( *skill_table[sn].spell_fun ) ( sn, level, ch, vo );
    }

    return;
}


void spell_bless( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.location = APPLY_HITROLL;
    af.modifier = level / 8;
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    af.location = APPLY_MAGIC_RESIST;
    af.modifier = level / 8;
    affect_to_char( victim, &af, ch );
    if( ch != victim )
	send_to_char( "Ok.\n\r", ch );
    send_to_char( "You feel righteous.\n\r", victim );
    return;
}


void spell_boost( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = level;
    af.duration = 24;
    af.location = APPLY_CON;
    af.modifier = 10;
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, NULL ) )
	return;
    af.location = APPLY_DEX;
    affect_to_char( victim, &af, NULL );
    af.location = APPLY_WIS;
    affect_to_char( victim, &af, NULL );
    af.location = APPLY_INT;
    affect_to_char( victim, &af, NULL );
    af.location = APPLY_STR;
    affect_to_char( victim, &af, NULL );

    act( "You have invested $N with divine prescence!",
	 ch, NULL, victim, TO_CHAR );
    send_to_char( "You feel totally boosted!\n\r", victim );
    act( "$N has been invested with divine prescence by $n!",
	 ch, NULL, victim, TO_NOTVICT );
    if( IS_NPC( victim ) || !IS_SET( victim->pcdata->pc_bits, PC_BIT_RACIAL )
	|| ch != victim )
    {
	log_string( "%s casting BOOST on %s.", ch->name, victim->name );
	wiznetf( ch, WIZ_MISC, get_trust( ch ), "%s casting BOOST on %s.",
		 ch->name, victim->name );
    }
}


void spell_breathing( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24;
    af.location = 0;
    af.modifier = 0;
    vset( af.bitvector, AFF_BREATHING );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "You no longer feel the need to breathe.\n\r", victim );
    act( "$n can now live without breathing.", victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_burning_hands( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    if( is_affected( victim, gsn_chill_touch ) )
    {
	act( "$N's hands are too cold for you to set them on fire.",
	     ch, NULL, victim, TO_CHAR );
	return;
    }

    af.type = sn;
    af.level = level;
    af.location = APPLY_BODY_TEMP;
    af.modifier = 5;
    vset( af.bitvector, AFF_MAGICHANDS );
    af.duration = number_fuzzy( level / 4 );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "Your hands suddenly flare with extreme heat.\n\r", victim );
    act( "&g$n's hands begin to sizzle with &rfire&g.",
	 victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_cell_adjustment( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;

    if( is_affected( victim, gsn_poison ) )
    {
	affect_strip( victim, gsn_poison );
	send_to_char( "A warm feeling runs through your body.\n\r", victim );
	act( "$N looks better.", ch, NULL, victim, TO_NOTVICT );
    }
    if( is_affected( victim, gsn_plague ) )
    {
	affect_strip( victim, gsn_plague );
	send_to_char( "A warm feeling runs through your body.\n\r", victim );
	act( "$N looks better.", ch, NULL, victim, TO_NOTVICT );
    }
    if( is_affected( victim, gsn_hex ) )
    {
	affect_strip( victim, gsn_hex );
	send_to_char( "You feel better.\n\r", victim );
    }
    if( is_affected( victim, skill_lookup( "warp flesh" ) ) )
    {
	affect_strip( victim, skill_lookup( "warp flesh" ) );
	send_to_char( "Your flesh regains colour and looks healthier.\n\r",
		      victim );
    }
    xREMOVE_BIT( victim->affected_by, AFF_POISON );
    xREMOVE_BIT( victim->affected_by, AFF_PLAGUE );
    xREMOVE_BIT( victim->affected_by, AFF_WARP_FLESH );
    send_to_char( "Ok.\n\r", ch );
    return;
}


void spell_chaos_shield( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    if( victim->alignment >= 0 )
    {
	act( "$N is too &Bgood&x for that!", ch, NULL, victim, TO_CHAR);
	return;
    }

    af.type = sn;
    af.level = level;
    af.duration = level;
    af.location = APPLY_AC;
    af.modifier = -25;
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    if( ch == victim )
    {
	act( "You perform a ritual sacrifice, and are cloaked in darkness.",
	     ch, NULL, victim, TO_CHAR );
	act( "$n performs a ritual sacrifice, and $e is cloaked in darkness.",
	     ch, NULL, NULL, TO_ROOM );
    }
    else
    {
	act( "$n perform$% a ritual sacrifice, and $N is cloaked in darkness.",
	     ch, NULL, victim, TO_ALL );
    }
    return;
}


void spell_chill_touch( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    if( is_affected( victim, gsn_burning_hands ) )
    {
	act( "$N's hands are too hot to freeze like that.",
	     ch, NULL, victim, TO_CHAR );
	return;
    }

    af.type = sn;
    af.level = level;
    af.location = APPLY_BODY_TEMP;
    af.modifier = -5;
    vset( af.bitvector, AFF_MAGICHANDS );
    af.duration = number_fuzzy( level / 4 );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "Heat slowly drains from your hands.\n\r", victim );
    act( "&g$n's hands become extremely &ccold&g.",
	 victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_combat_mind( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.location = APPLY_HITROLL;
    af.modifier = level / 6;
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    af.location = APPLY_AC;
    af.modifier = -level / 2 - 5;
    affect_to_char( victim, &af, ch );

    if( victim != ch )
	send_to_char( "OK.\n\r", ch );
    send_to_char( "You gain a keen understanding of battle tactics.\n\r",
		  victim );
    return;
}


void spell_complete_healing( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;

    victim->hit = victim->max_hit;
    update_pos( victim );
    if( ch != victim )
	send_to_char( "Ok.\n\r", ch );
    send_to_char( "Ahhhhhh...You are completely healed!\n\r", victim );
    return;
}


void spell_concentration( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * ( ( level + 50 ) / 100 );
    af.location = APPLY_HITROLL;
    af.modifier = -10 - level / 50;
    vset( af.bitvector, AFF_FAST_TALK );
    if( !affect_to_char( victim, &af, ch ) )
	return;
    send_to_char( "You concentrate your energies into keeping you safe.\n\r",
		  ch );

    return;
}


void spell_cure( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    int heal;
    int extra;

    heal = level + get_curr_wis( ch ) / 3 + number_range( 1, 6 );

    extra = total_mana( ch->mana );
    extra = UMIN( extra, UMIN( 50, level / 2 ) );
    heal += extra + extra * UMIN( 50, level / 2 ) / 10;
    take_generic_mana( ch, extra );

    if( victim->hit < victim->max_hit )
	victim->hit = UMIN( victim->hit + heal, victim->max_hit );
    else
	victim->hit = UMAX( victim->hit - heal, victim->max_hit );
    update_pos( victim );

    act( "$n looks better.", victim, NULL, NULL, TO_ROOM);
    send_to_char( "You feel better!\n\r", victim );
    return;
}


void spell_cure_blindness( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;

    if( !is_affected( victim, gsn_blindness )
	&& !is_affected( victim, skill_lookup( "colour_spray" ) ) )
	return;

    affect_strip( victim, gsn_blindness );
    affect_strip( victim, skill_lookup( "colour spray" ) );
    xREMOVE_BIT( victim->affected_by, AFF_BLIND );

    if( ch != victim )
	send_to_char( "Ok.\n\r", ch );
    send_to_char( "Your vision returns!\n\r", victim );
    return;
}


void spell_cure_poison( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;

    if( !is_affected( victim, gsn_poison ) )
	return;

    affect_strip( victim, gsn_poison );

    send_to_char( "Ok.\n\r", ch );
    send_to_char( "A warm feeling runs through your body.\n\r", victim );
    act( "$N looks better.", ch, NULL, victim, TO_NOTVICT );

    return;
}


void spell_dark_claws( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.location = APPLY_NONE;
    af.modifier = 0;
    vset( af.bitvector, AFF_MAGICHANDS );
    af.duration = number_fuzzy( level / 4 );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "&gLong claws, dripping with venom, extend from your fingers.\n\r", victim );
    act( "&g$n grows claws, which drip caustic poison.",
	 victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_darkness( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = level;
    af.location = APPLY_NONE;
    af.modifier = 0;
    vset( af.bitvector, AFF_DARKNESS );
    if( !affect_to_char( victim, &af, NULL ) )
	return;

    if( victim == ch )
    {
	act( "&g$n weaves an inpenetrable web of &Kdarkness&g around $mself.",
	     ch, NULL, victim, TO_ROOM );
	act( "&gYou weave an inpenetrable web of &Kdarkness&g around yourself.",
	     ch, NULL, victim, TO_ALL );
    }
    else
	act( "&g$n weave$% an inpenetrable web of &Kdarkness&g around $N.",
	     ch, NULL, victim, TO_ALL );

    return;
}


void spell_detect_evil( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = level;
    af.location = APPLY_NONE;
    af.modifier = 0;
    vset( af.bitvector, AFF_DETECT_EVIL );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    if( ch != victim )
	send_to_char( "Ok.\n\r", ch );
    send_to_char( "Your eyes tingle.\n\r", victim );
    return;
}


void spell_detect_hidden( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = level;
    af.location = APPLY_NONE;
    af.modifier = 0;
    vset( af.bitvector, AFF_DETECT_HIDDEN );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    if( ch != victim )
	send_to_char( "Ok.\n\r", ch );
    send_to_char( "Your awareness improves.\n\r", victim );
    return;
}


void spell_detect_invis( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = level;
    af.location = APPLY_NONE;
    af.modifier = 0;
    vset( af.bitvector, AFF_DETECT_INVIS );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    if( ch != victim )
	send_to_char( "Ok.\n\r", ch );
    send_to_char( "Your eyes tingle.\n\r", victim );
    return;
}


void spell_magic_awareness( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = level;
    af.location = APPLY_NONE;
    af.modifier = 0;
    vset( af.bitvector, AFF_DETECT_MAGIC );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    if( ch != victim )
	send_to_char( "Ok.\n\r", ch );
    send_to_char( "Your eyes tingle.\n\r", victim );
    return;
}


void spell_detect_poison( int sn, int level, CHAR_DATA *ch, void *vo )
{
    OBJ_DATA *obj = (OBJ_DATA *)vo;

    if( obj->item_type == ITEM_DRINK_CON || obj->item_type == ITEM_FOOD )
    {
	if( obj->value[3] != 0 )
	    send_to_char( "You smell poisonous fumes.\n\r", ch );
	else
	    send_to_char( "It looks very delicious.\n\r", ch );
    }
    else
    {
	send_to_char( "It doesn't look poisoned.\n\r", ch );
    }

    return;
}


void spell_displacement( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.location = APPLY_AC;
    af.modifier = 4 - level;
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "Your form shimmers, and you appear displaced.\n\r",
		 victim );
    act( "$n shimmers and appears in a different location.",
	victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_divine_protection( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    if( ( IS_GOOD( ch ) && !IS_GOOD( victim ) )
	|| ( IS_NEUTRAL( ch ) && !IS_NEUTRAL( victim ) )
	|| ( IS_EVIL( ch ) && !IS_EVIL( victim ) ) )
    {
	send_to_char( "Your God doesn't like that person.\n\r", ch );
	return;
    }

    af.type = sn;
    af.level = level;
    af.location = APPLY_AC;
    af.modifier = -50;
    vzero( af.bitvector );
    af.duration = 24 * ( 1 + level / 50 );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    af.location = APPLY_RESILIENCE;
    affect_to_char( victim, &af, ch );

    act( "$N's god makes $n invulnerable.", victim, NULL, ch, TO_ROOM );
    if( victim == ch )
	send_to_char( "You ask your god to make you invulnerable.\n\r", ch );
    else
	act( "$N asks $S god to make you invulnerable.", victim, NULL, ch, TO_CHAR );
    return;
}


void spell_divinity( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    int heal;

    heal = level * 5 + get_curr_wis( ch ) * 3 + dice( 5, 20 );
    if( victim->hit < victim->max_hit )
	victim->hit = UMIN( victim->hit + heal, victim->max_hit );
    else
	victim->hit = UMAX( victim->hit - heal, victim->max_hit );
    update_pos( victim );

    send_to_char( "You have been touched by the gods!\n\r", victim );
    act( "$n looks like he has been touched by the gods.", victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_empowerment( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    if( victim == ch )
    {
	send_to_char( "You allready share a deep spiritual link with them.\n\r", ch );
	return;
    }
    if( get_curr_wis( ch ) <= 5 )
    {
	send_to_char( "You feel nothing, the link fades.\n\r", ch );
	return;
    }

    af.type = sn;
    af.level = level;
    af.duration = level;
    af.location = APPLY_WIS;
    af.modifier = UMIN( 5, level / 25 );
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    af.modifier *= -1;
    affect_to_char( ch, &af, ch );

    act( "You empower $N with your wisdom.", ch, NULL, victim, TO_CHAR );
    act( "$n shares a piece of $s wisdom with you.",
	 ch, NULL, victim, TO_VICT );
}


void spell_energy_containment( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.modifier = level / 5;
    af.location = APPLY_MAGIC_RESIST;
    vzero( af.bitvector );
    affect_to_char( victim, &af, ch );

    send_to_char( "You can now absorb some forms of energy.\n\r", ch );
    return;
}


void spell_enhanced_strength( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = level;
    af.location = APPLY_STR;
    af.modifier = 2 + ( level / 50 );
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "You are HUGE!\n\r", victim );
    return;
}


void spell_enlarge( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * (level / 50 + 1);
    af.location = APPLY_SIZE;
    af.modifier = race_table[victim->race].size * level / 50 + 1;
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "You feel yourself suddenly grow larger than before.\n\r",
		  victim );
    act( "&g$n suddenly bulges outwards, growing rapidly.",
	 victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_exorcise( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;

    if( !is_affected( victim, gsn_vampiric_bite ) )
	return;

    /*
     * We actually give the vampiric curse a chance to save
     * at the victim's level
     */
    if( !saves_spell( level, victim, ch, sn ) )
	return;

    affect_strip( victim, gsn_vampiric_bite );

    send_to_char( "Ok.\n\r", ch );
    send_to_char( "A warm feeling runs through your body.\n\r", victim );
    act( "$N looks better.", ch, NULL, victim, TO_NOTVICT );

    return;
}


void spell_faith_shield( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *gch;
    AFFECT_DATA af;
    int count = 0;

    act( "You surround your group in the protection of $g.",
	 ch, NULL, NULL, TO_CHAR );
    for( gch = ch->in_room->people; gch; gch = gch->next_in_room )
    {
	if( !is_same_group( gch, ch ) || !can_see( ch, gch ) )
	    continue;
	if( ( IS_GOOD( ch ) && !IS_GOOD( gch ) )
	    || ( IS_NEUTRAL( ch ) && !IS_NEUTRAL( gch ) )
	    || ( IS_EVIL( ch ) && !IS_EVIL( gch ) ) )
	    continue;
	count++;
    }

    af.type	= sn;
    af.level	= level;
    af.location	= APPLY_AC;
    af.duration	= 24 * ( level / 50 );
    af.modifier = URANGE( -100, -5 * count, -10 );
    vzero( af.bitvector );

    for( gch = ch->in_room->people; gch; gch = gch->next_in_room )
    {
	if( !is_same_group( gch, ch ) || !can_see( ch, gch ) )
	    continue;
	if( ( IS_GOOD( ch ) && !IS_GOOD( gch ) )
	    || ( IS_NEUTRAL( ch ) && !IS_NEUTRAL( gch ) )
	    || ( IS_EVIL( ch ) && !IS_EVIL( gch ) ) )
	    continue;
	if( affect_to_char( gch, &af, ch ) )
	    act( "$o faith in $g shelters you from harm.",
		 ch, NULL, gch, TO_VICT );
    }
    return;
}


void spell_familiar( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;

    if( ch->pcdata->familiar > 0 )
    {
	send_to_char( "You summon forces to replenish your fading familiar.\n\r", victim );
	act( "$n summons forces to heal $s familiar.", victim, NULL, NULL, TO_ROOM );
    }
    else
    {
	send_to_char( "You gesture dramatically and a small demon appears.\n\r", victim );
	act( "$n waves $s arms about and conjures up a familiar.", victim, NULL, NULL, TO_ROOM );
    }
    victim->pcdata->familiar = power( level * 14 + number_percent( ), 5, get_curr_int( ch ) - 20 );
    return;
}


void spell_fast_talk( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 12 * ( ( level + 50 ) / 100 );
    af.location = APPLY_HITROLL;
    af.modifier = -40;
    vset( af.bitvector, AFF_FAST_TALK );
    if( !affect_to_char( victim, &af, ch ) )
	return;
    send_to_char( "You prepare yourself to talk your way out of trouble.\n\r", victim );

    return;
}


void spell_feast( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *gch;

    act( "$n call$% on $g to provide a filling feast.",
	 ch, NULL, NULL, TO_ALL );
    for( gch = ch->in_room->people; gch; gch = gch->next_in_room )
    {
	if( !can_see( ch, gch ) || IS_NPC( gch ) )
	    continue;

	gch->pcdata->condition[COND_FULL]
	    = race_table[gch->race].hunger_mod * 10;
	gch->pcdata->condition[COND_THIRST]
	    = race_table[gch->race].thirst_mod * 10;
	send_to_char( "You are completely nourished!\n\r", gch );
    }
    return;
}


/* Flame shield spell from Malice of EnvyMud */
void spell_flaming( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = number_fuzzy( level / 8 );
    af.location = APPLY_NONE;
    af.modifier = 0;
    vset( af.bitvector, AFF_ATTACKSHIELD );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "You are surrounded by a flaming shield.\n\r", victim );
    act( "$n is surrounded by a flaming shield.",
	victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_flesh_armour( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.location = APPLY_RESILIENCE;
    af.modifier = -40 - level / 50;
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "Your flesh turns to steel.\n\r", victim );
    act( "$n's flesh turns to steel.", victim, NULL, NULL, TO_NOTVICT );
    return;
}


void spell_fly( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.location = APPLY_NONE;
    af.modifier = 0;
    vset( af.bitvector, AFF_FLYING );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "Your feet rise off the ground.\n\r", victim );
    act( "$n's feet rise off the ground.", victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_foci( int sn, int level, CHAR_DATA *ch, void *vo )
{
    AFFECT_DATA af;
    int sntemp;

    sntemp = skill_lookup( "giant strength" );
    ( *skill_table[sntemp].spell_fun ) ( sntemp, level, ch, vo );

    sntemp = skill_lookup( "phase shift" );
    ( *skill_table[sntemp].spell_fun ) ( sntemp, level, ch, vo );

    sntemp = skill_lookup( "shield" );
    ( *skill_table[sntemp].spell_fun ) ( sntemp, level, ch, vo );

    sntemp = skill_lookup( "fly" );
    ( *skill_table[sntemp].spell_fun ) ( sntemp, level, ch, vo );

    sntemp = skill_lookup( "stone skin" );
    ( *skill_table[sntemp].spell_fun ) ( sntemp, level, ch, vo );

    sntemp = skill_lookup( "haste" );
    ( *skill_table[sntemp].spell_fun ) ( sntemp, level, ch, vo );

    af.type = gsn_foci;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.modifier = af.location = 0;
    vzero( af.bitvector );
    affect_to_char( (CHAR_DATA *)vo, &af, ch );

    return;
}


void spell_fortitudes( int sn, int level, CHAR_DATA *ch, void *vo )
{
    AFFECT_DATA af;
    int sntemp;

    sntemp = skill_lookup( "thought shield" );
    ( *skill_table[sntemp].spell_fun ) ( sntemp, level, ch, vo );

    sntemp = skill_lookup( "mental barrier" );
    ( *skill_table[sntemp].spell_fun ) ( sntemp, level, ch, vo );

    sntemp = skill_lookup( "combat mind" );
    ( *skill_table[sntemp].spell_fun ) ( sntemp, level, ch, vo );

    sntemp = skill_lookup( "displacement" );
    ( *skill_table[sntemp].spell_fun ) ( sntemp, level, ch, vo );

    sntemp = skill_lookup( "flesh armour" );
    ( *skill_table[sntemp].spell_fun ) ( sntemp, level, ch, vo );

    sntemp = skill_lookup( "energy containment" );
    ( *skill_table[sntemp].spell_fun ) ( sntemp, level, ch, vo );

    af.type = gsn_fortitudes;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.modifier = af.location = 0;
    vzero( af.bitvector );
    affect_to_char( (CHAR_DATA *)vo, &af, ch );

    return;
}


void spell_ghoul_form( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;


    af.type = sn;
    af.level = level;
    af.duration = level / 3;
    af.location = APPLY_NONE;
    af.modifier = 0;
    vset( af.bitvector, AFF_GHOUL );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    if( ch != victim )
	send_to_char( "Ok.\n\r", ch );
    send_to_char( "You turn insubstantial.\n\r", victim );
    return;
}


void spell_giant_strength( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.location = APPLY_STR;
    af.modifier = 2 + ( level / 50 );
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    if( ch != victim )
	send_to_char( "Ok.\n\r", ch );
    send_to_char( "You feel stronger.\n\r", victim );
    return;
}


void spell_golden_touch( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    int heal;

    if( ch == victim )
    {
	send_to_char( "You find it impossible to heal yourself this way.\n\r",
		      ch );
	return;
    }
    heal = level / 2 + get_curr_dex( ch ) + get_curr_wis( ch ) + dice( 2, 6 );

    if( number_bits( 3 ) == 0 )
	heal *= 3;
    if( number_bits( 3 ) == 0 )
	heal *= 3;
    if( victim->hit < victim->max_hit )
	victim->hit = UMIN( victim->hit + heal, victim->max_hit );
    else
	victim->hit = UMAX( victim->hit - heal, victim->max_hit );
    update_pos( victim );

    send_to_char( "Your golden touch alleviates their wounds.\n\r", ch );
    act( "$n's golden touch heals you.", ch, NULL, victim, TO_VICT );
    act( "$N is healed by $n's touch.", ch, NULL, victim, TO_NOTVICT );
    return;
}


void spell_haste( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.location = APPLY_DEX;
    af.modifier = 2 + level / 100;
    vset( af.bitvector, AFF_HASTE );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    act( "$n's motions speed up and start to blur.", victim, NULL, NULL, TO_ROOM );
    act( "You feel fast, VERY fast!", victim, NULL, NULL, TO_CHAR );
    return;
}


void spell_heal( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    int mod;
    int extra;

    mod = level * 2 + get_curr_wis( ch ) + dice( 3, 8 );

    extra = total_mana( ch->mana );
    extra = UMIN( extra, level );
    mod += extra + extra * UMIN( 200, level ) / 50;
    take_generic_mana( ch, extra );

    if( victim->hit < victim->max_hit )
	victim->hit = UMIN( victim->hit + mod, victim->max_hit );
    else
	victim->hit = UMAX( victim->hit - mod, victim->max_hit );
    update_pos( victim );

    mod = number_range( 0, 30 );
    mod = 1 << mod;
    if( !IS_NPC( ch )
	&& IS_SET( race_table[victim->race].body_parts, mod )
	&& !IS_SET( victim->body_parts, mod )
	&& number_range( 0, 250 - ch->pcdata->learned[sn] ) == 0 )
    {
	act( "$n regrows $t.", victim,
	    flag_string( body_part_flags, &mod ), NULL, TO_ROOM );
	act( "You regrow $t.", victim,
	    flag_string( body_part_flags, &mod ), NULL, TO_ROOM );
	SET_BIT( victim->body_parts, mod );
    }

    act( "$n looks much better.", victim, NULL, NULL, TO_ROOM );
    send_to_char( "A warm feeling fills your body.\n\r", victim );
    return;
}


void spell_heavenly_guidance( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24;
    af.location = APPLY_SPEED;
    af.modifier = 10;
    vset( af.bitvector, AFF_NEVERMISS );
    if( !affect_to_char( victim, &af, NULL ) )
	return;

    act( "$n now moves with supreme assurance.", victim, NULL, NULL, TO_ROOM );
    act( "You feel the hands of $g are guiding you.",
	 victim, NULL, NULL, TO_CHAR );
    return;
}


void spell_hog( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24;
    af.location = APPLY_HITROLL;
    af.modifier = 2000;
    vzero( af.bitvector );
    affect_to_char( victim, &af, NULL );

    af.location = APPLY_DAMROLL;
    affect_to_char( victim, &af, NULL );

    if( ch != victim )
	act( "You have given $N Hand Of God.", ch, NULL, victim, TO_CHAR );
    send_to_char( "Your hands FLARE with power!\n\r", victim );
    if( IS_NPC( victim ) || !IS_SET( victim->pcdata->pc_bits, PC_BIT_RACIAL )
	|| ch != victim )
    {
	log_string( "%s casting HOG on %s.", ch->name, victim->name );
	wiznetf( ch, WIZ_MISC, get_trust( ch ), "%s casting HOG on %s.",
		 ch->name, victim->name );
    }
    return;
}


void spell_holy_armour( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.location = APPLY_AC;
    af.modifier = -30;
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    act( "$n is now armoured by a heavenly force.",
	 victim, NULL, ch, TO_NOTVICT );
    send_to_char( "You feel greatly protected.\n\r", victim );
    send_to_char( "Ok.\n\r", ch );
    return;
}


void spell_holy_aura( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.location = APPLY_AC;
    af.modifier = -40;
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    act( "$N's god surrounds $n with a protective aura.",
	 victim, NULL, ch, TO_NOTVICT );
    send_to_char( "You feel a holy aura surround you.\n\r", victim );
    send_to_char( "Ok.\n\r", ch );
    return;
}


void spell_inertial_barrier( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *gch;
    AFFECT_DATA af;

    for( gch = ch->in_room->people; gch; gch = gch->next_in_room )
    {
	if( !is_same_group( gch, ch ) )
	    continue;

	af.type = sn;
	af.level = level;
	af.duration = 24 * ( 1 + level / 50 );
	af.modifier = 0;
	af.location = APPLY_NONE;
	vset( af.bitvector, AFF_PROTECT );
	if( affect_to_char( gch, &af, ch ) )
	{
	    act( "An inertial barrier forms around $n.", gch, NULL, NULL,
		 TO_ROOM );
	    send_to_char( "An inertial barrier forms around you.\n\r", gch );
	}
    }
    return;
}


void spell_infravision( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 2 * level;
    af.location = APPLY_NONE;
    af.modifier = 0;
    vset( af.bitvector, AFF_INFRARED );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "Your eyes glow red.\n\r", victim );
    act( "$n's eyes glow red.\n\r", ch, NULL, NULL, TO_ROOM );
    return;
}


void spell_invis( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.location = APPLY_NONE;
    af.modifier = 0;
    vset( af.bitvector, AFF_INVISIBLE );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "You fade out of existence.\n\r", victim );
    act( "$n fades out of existence.", victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_intellect_fortress( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *gch;
    AFFECT_DATA af;

    for( gch = ch->in_room->people; gch; gch = gch->next_in_room )
    {
	if( !is_same_group( gch, ch ) )
	    continue;

	af.type = sn;
	af.level = level;
	af.duration = 24;
	af.location = APPLY_AC;
	af.modifier = -40;
	vzero( af.bitvector );
	if( affect_to_char( gch, &af, ch ) )
	{
	    send_to_char( "A virtual fortress forms around you.\n\r", gch );
	    act( "A virtual fortress forms around $N.", gch, NULL, gch, TO_ROOM );
	}
    }
    return;
}


void spell_lay_hands( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;

    if( is_affected( victim, gsn_plague ) )
	affect_strip( victim, gsn_plague );
    if( is_affected( victim, gsn_poison ) )
	affect_strip( victim, gsn_poison );
    if( is_affected( victim, gsn_blindness ) )
	affect_strip( victim, gsn_blindness );
    if( is_affected( victim, gsn_hex ) )
	affect_strip( victim, gsn_hex );
    xREMOVE_BIT( victim->affected_by, AFF_BLEEDING );
    xREMOVE_BIT( victim->affected_by, AFF_PLAGUE );
    xREMOVE_BIT( victim->affected_by, AFF_POISON );
    xREMOVE_BIT( victim->affected_by, AFF_BLIND );
    victim->hit += number_fuzzy( level / 7 );
    if( victim->hit > victim->max_hit )
	victim->hit = UMAX( victim->max_hit, victim->hit - level / 14 );
    act( "You lay your hands on $N and $E is cured of all ills.",
	ch, NULL, victim, TO_CHAR );
    act( "$n lays $s hands on $N and $E is cured of all ills.",
	ch, NULL, victim, TO_NOTVICT );
    act( "$n lays $s hands on you, you feel much better.",
	ch, NULL, victim, TO_VICT );
    return;
}


void spell_lend_health( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    int hpch;

    if( ch == victim )
    {
	send_to_char( "Lend health to yourself?	 What a weirdo.\n\r", ch );
	return;
    }
    hpch = UMIN( 50, victim->max_hit - victim->hit );
    if( hpch == 0 )
    {
	act( "Nice thought, but $N doesn't need healing.", ch, NULL,
	    victim, TO_CHAR );
	return;
    }
    if( ch->hit - hpch < 50 )
    {
	send_to_char( "You aren't healthy enough yourself!\n\r", ch );
	return;
    }
    victim->hit += hpch;
    ch->hit -= hpch;
    update_pos( victim );
    update_pos( ch );

    act( "You lend some of your health to $N.", ch, NULL, victim, TO_CHAR );
    act( "$n lends you some of $s health.", ch, NULL, victim, TO_VICT );

    return;
}


void spell_levitation( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = level + 3;
    af.location = APPLY_BODY_PART;
    af.modifier = 0;
    vset( af.bitvector, AFF_FLYING );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "Your feet rise off the ground.\n\r", victim );
    act( "$n's feet rise off the ground.", victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_mana_balm( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    int heal = ( level - 50 ) * 3 / 20 + get_curr_int( ch ) + 30;
    int mana[MAGIC_MAX], i;

    heal = UMIN( 99, heal );
    for( i = 0; i < MAGIC_MAX; ++i )
	mana[i] = heal;
    heal = 0;
    for( i = 0; i < MAGIC_MAX; ++i )
    {
	int shuffle = number_range( mana[i] / -3, mana[i] / 3 );
	mana[i] -= shuffle;
	heal += shuffle;
    }
    for( i = 0; i < MAGIC_MAX; ++i )
	mana[i] += heal / MAGIC_MAX;

    for( i = 0; i < MAGIC_MAX; ++i )
	victim->mana[i] = UMIN( victim->max_mana[i], victim->mana[i] + mana[i] );
    act( "$n bursts with renewed energy!", victim, NULL, NULL, TO_ROOM );
    send_to_char( "You feel a strong burst of energy!\n\r", victim );
    return;
}


void spell_mass_bless( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *gch;
    int sntemp = skill_lookup( "bless" );

    for( gch = ch->in_room->people; gch; gch = gch->next_in_room )
    {
	if( !is_same_group( gch, ch ) || !can_see( ch, gch ) )
	    continue;
	( *skill_table[sntemp].spell_fun )
	    ( sntemp, level, ch, ( void * )gch );
    }
    send_to_char( "You have bestowed your blessing on your group.\n\r", ch );

    return;
}


void spell_mass_heal( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *gch;
    int heal;

    for( gch = ch->in_room->people; gch; gch = gch->next_in_room )
    {
	if( !is_same_group( gch, ch ) || !can_see( ch, gch ) )
	    continue;

	heal = 3 * level / 2 + get_curr_wis( ch ) + dice( 2, 8 );
	if( gch->hit < gch->max_hit )
	{
	    heal = UMIN( heal, gch->max_hit - gch->hit );
	    gch->hit = gch->hit + heal;
	}
	else
	    gch->hit = UMAX( gch->hit - heal, gch->max_hit );

	update_pos( gch );

	send_to_char( "You feel better!\n\r", gch );
    }
    send_to_char( "OK.\n\r", ch );

    return;
}


void spell_mass_invis( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *gch;
    AFFECT_DATA af;

    for( gch = ch->in_room->people; gch; gch = gch->next_in_room )
    {
	if( !is_same_group( gch, ch ) || !can_see( ch, gch ) )
	    continue;


	af.type = sn;
	af.level = level;
	af.duration = 24;
	af.location = APPLY_NONE;
	af.modifier = 0;
	vset( af.bitvector, AFF_INVISIBLE );
	if( affect_to_char( gch, &af, ch ) )
	{
	    send_to_char( "You slowly fade out of existence.\n\r", gch );
	    act( "$n slowly fades out of existence.", gch, NULL, NULL, TO_ROOM );
	}
    }
    send_to_char( "Ok.\n\r", ch );

    return;
}


void spell_medicine( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    int heal;

    heal = dice( 2, 4 ) + level / 10 - 2;
    heal = heal * get_curr_wis( ch ) / 18;
    if( victim->hit < victim->max_hit )
	victim->hit = UMIN( victim->hit + heal, victim->max_hit );
    else
	victim->hit = UMAX( victim->hit - heal, victim->max_hit );
    update_pos( victim );

    if( xIS_SET( victim->affected_by, AFF_BLEEDING ) )
	do_tend( ch, victim->name );
    act( "$N looks better.", ch, NULL, victim, TO_NOTVICT );
    if( ch != victim )
	send_to_char( "Ok.\n\r", ch );
    send_to_char( "You feel better!\n\r", victim );
    return;
}


void spell_mental_barrier( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.location = APPLY_AC;
    af.modifier = -20;
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "You erect a mental barrier around yourself.\n\r",
		 victim );
    act( "$n erects a mental barrier around $mself.", victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_phase_shift( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;


    af.type = sn;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.location = APPLY_NONE;
    af.modifier = 0;
    vset( af.bitvector, AFF_PASS_DOOR );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "You turn translucent.\n\r", victim );
    act( "$n turns translucent.", victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_prayer( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    OBJ_DATA *obj;
    AFFECT_DATA af;
    int result;

    if( is_affected( victim, sn ) )
    {
	act( "&g$g doesn't answer $o prayer.", ch, NULL, NULL, TO_ROOM );
	return;
    }
    af.type = sn;
    af.level = level;
    af.duration = 12 * ( 1 + level / 50 );
    af.location = APPLY_NONE;
    af.modifier = 0;
    vzero( af.bitvector );

    result = dice( 2, 25 ) - 26;
    if( !IS_NPC( victim ) && victim->pcdata->religion
	&& victim->in_room->area->order
	&& victim->pcdata->religion == victim->in_room->area->order->religion )
	result++;

    switch( result )
    {
    case 0:
    default:
	result = 0;
	break;
    case -1:
	af.location = APPLY_AC;
	af.modifier = 5 + level / 3;
	break;
    case 1:
	af.location = APPLY_AC;
	af.modifier = -5 - level / 5;
	break;
    case -2:
	af.location = APPLY_SPEED;
	af.modifier = -1 - level / 10;
	break;
    case 2:
	af.location = APPLY_DAMROLL;
	af.modifier = 2 + level / 10;
	break;
    case -3: case 3:
	af.location = APPLY_STR;
	af.modifier = result * dice( 2, 4 ) / abs( result );
	break;
    case -4: case 4:
	af.location = APPLY_DEX;
	af.modifier = result * dice( 2, 3 ) / abs( result );
	break;
    case -5: case 5:
	af.location = APPLY_CON;
	af.modifier = result * number_range( 1, 3 ) / abs( result );
	break;
    case -6: case 6:
	af.location = APPLY_WIS;
	af.modifier = result * number_range( 1, 3 ) / abs( result );
	break;
    case -7: case 7:
	af.location = APPLY_INT;
	af.modifier = result * number_range( 1, 3 ) / abs( result );
	break;
    case -8: case 8:
	af.location = APPLY_MOVE;
	af.modifier = result * number_range( level * 3, level * 4 )
	    / abs( result );
	break;
    case -9: case 9:
	af.location = APPLY_HIT;
	af.modifier = result * number_range( level * 3, level * 4 )
	    / abs( result );
	break;
    case -10: case 10:
	af.location = APPLY_MANA_AIR + number_range( 0, 4 );
	af.modifier = result * number_range( level * 3, level * 4 )
	    / abs( result );
	break;
    case -11:
	af.location = APPLY_HITROLL;
	af.modifier = -1 - level / 5;
	break;
    case 11:
	af.location = APPLY_RESILIENCE;
	af.modifier = -5 - level / 20;
	break;
    case -12: case 12:
	af.location = APPLY_AIR + number_range( 0, 4 );
	af.modifier = result * number_range( 1, 3 ) / abs( result );
	break;
    case -13:
	bamf( victim );
	break;
    case 13:
	spell_endurance( skill_lookup( "endurance" ), level, ch, victim );
	break;
    case -14:
	af.location = APPLY_RACE;
	af.modifier = race_lookup( "vampire" ) - victim->race;
	xSET_BIT( af.bitvector, AFF_POLYMORPH );
	break;
    case 14:
	spell_heal( skill_lookup( "heal" ), level, ch, victim );
	break;
    case -15:
	af.location = APPLY_RACE;
	af.modifier = race_lookup( "ooze" ) - victim->race;
	xSET_BIT( af.bitvector, AFF_POLYMORPH );
	break;
    case 15:
	spell_mana_balm( skill_lookup( "mana balm" ), level, ch, victim );
	break;
    case -16:
	af.location = APPLY_MAGIC_RESIST;
	af.modifier = -2 - level / 20;
	break;
    case 16:
	spell_feast( skill_lookup( "feast" ), level, ch, victim );
	break;
    case 20:
    {
	OBJ_DATA *obj_next;
	for( obj = victim->carrying; obj; obj = obj_next )
	{
	    obj_next = obj->next_content;
	    if( obj->deleted || obj->condition >= 1000
		|| IS_OBJ_STAT( obj, ITEM_FRAGILE ) )
		obj->condition = 1000;
	    if( xIS_SET( obj->pIndexData->progtypes, REPAIR_PROG ) )
		oprog_percent_check( victim, obj, ch, REPAIR_PROG );
	    if( victim->deleted || ch->deleted
		|| victim->in_room != ch->in_room
		|| number_bits( 3 ) == 0 )
		break;
	}
    }
    break;
    }
    if( !affect_to_char( victim, &af, ch ) )
	result = 0;

    if( result == 0 )
	send_to_char( "Your prayer goes unanswered.\n\r", victim );
    else if( result < 0 )
	act( "&gYou feel the disapproval of $g.", ch, NULL, NULL, TO_CHAR );
    else
	act( "&gYou feel that $g is pleased.", ch, NULL, NULL, TO_CHAR );

    return;
}


void spell_protection( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.location = APPLY_NONE;
    af.modifier = 0;
    vset( af.bitvector, AFF_PROTECT );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    if( ch != victim )
	send_to_char( "Ok.\n\r", ch );
    send_to_char( "You feel protected.\n\r", victim );
    return;
}


void spell_psychic_healing( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    int heal;

    heal = dice( 3, 6 ) + 2 * level / 3;
    victim->hit = UMIN( victim->hit + heal, victim->max_hit );
    update_pos( victim );

    send_to_char( "You feel better!\n\r", victim );
    return;
}


void spell_endurance( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;

    victim->move = UMIN( victim->move + level, victim->max_move );

    if( ch != victim )
	send_to_char( "Ok.\n\r", ch );
    send_to_char( "You feel less tired.\n\r", victim );
    return;
}


/* timed event healing */
void spell_regeneration( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    EVENT *e;

    e = create_char_event( victim, evn_regeneration,
			   PULSE_PER_SECOND );
    e->data[0] = 4 * level + 2 * get_curr_wis( ch ) + dice( 4, 12 );
    e->data[1] = e->data[0];

    act( "$n takes a deep sigh as $s wounds begin to disappear.",
	 victim, NULL, NULL, TO_ROOM );
    send_to_char( "You can feel the accelerated healing begin.\n\r", victim );
    return;
}


/* Expulsion of ITEM_NOREMOVE addition by Katrina */
void spell_remove_hex( int sn, int level, CHAR_DATA *ch, void *vo )
{
    OBJ_DATA *obj;
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    int iWear, chance;
    int yesno = 0;

    for( iWear = WEAR_NONE + 1; iWear < MAX_WEAR; iWear++ )
    {
	if( !( obj = get_eq_char( victim, iWear ) )
	    || !IS_SET( obj->extra_flags, ITEM_NOREMOVE ) )
	    continue;

	chance = ch->level - obj->level + get_curr_wis( ch ) + 40;
	if( chance > number_bits( 7 ) && number_bits( 2 ) == 0 )
	{
	    REMOVE_BIT( obj->extra_flags, ITEM_NOREMOVE );
	    act( "&gA &Kblack mist&g escapes from $p.",
		 victim, obj, ch, TO_CHAR );
	    act( "&gA &Kblack mist&g escapes from $p.",
		 victim, obj, ch, TO_ROOM );
	    yesno = 1;
	    break;
	}
    }
    if( is_affected( victim, gsn_hex ) )
    {
	affect_strip( victim, gsn_hex );
	send_to_char( "You feel better.\n\r", victim );
	yesno = 1;
    }

    if( ch != victim && yesno )
	send_to_char( "Ok.\n\r", ch );
    return;
}


void spell_remove_silence( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;

    /*
     *	Note: because this spell is declared as TAR_CHAR_DEFENSIVE,
     *	do_cast will set vo = ch with no argument.  Since it is
     *	impossible for a silenced character to cast anyway, if
     *	victim == ch, that means there was no argument supplied
     *	( or the spellcaster tried to specify themself ), i.e., trying
     *	to remove a "Cone of Silence" from ch->in_room.
     *	This might seem pointless, but it will work within obj_cast_spell.
     *	Thelonius ( Monk ) 5/94
     */
    if( victim == ch )
    {
	ROOM_INDEX_DATA *pRoomIndex;
	bool DidSomething;

	pRoomIndex = ch->in_room;
	DidSomething = FALSE;

	if( IS_SET( pRoomIndex->room_flags, ROOM_TEMP_CONE_OF_SILENCE ) )
	{
	    REMOVE_BIT( pRoomIndex->room_flags, ROOM_TEMP_CONE_OF_SILENCE );
	    send_to_char( "You have lifted the cone of silence!\n\r", ch );
	    act( "$n has lifted the cone of silence!",
		ch, NULL, NULL, TO_ROOM );
	    DidSomething = TRUE;
	}

	if( IS_AFFECTED( victim, AFF_MUTE ) )
	{
	    affect_strip( victim, gsn_mute );
	    send_to_char( "You lift the veil of silence from yourself.\n\r",
			 ch );
	    act( "$n lifts the veil of silence from $mself.",
		ch, NULL, victim, TO_VICT );
	    DidSomething = TRUE;
	}

	if( !DidSomething )
	    send_to_char( "Fzzzzzzzzz...\n\r", ch );

	return;
    }

    if( IS_AFFECTED( victim, AFF_MUTE ) )
    {
	affect_strip( victim, gsn_mute );
	act( "You lift the veil of silence from $N.",
	    ch, NULL, victim, TO_CHAR );
	act( "$n lifts the veil of silence from you.",
	    ch, NULL, victim, TO_VICT );
	act( "$n lifts the veil of silence from $N.",
	    ch, NULL, victim, TO_NOTVICT );
    }
    else
	act( "$N is not silenced.", ch, NULL, victim, TO_CHAR );

    return;
}


void spell_repair_flesh( int sn, int level, CHAR_DATA *ch, void *vo )
{
    OBJ_DATA *limb;
    CHAR_DATA *vch = (CHAR_DATA *)vo;
    int add;

    if( !( limb = get_held( ch, ITEM_LIMB, TRUE ) ) )
    {
	send_to_char( "You aren't holding a limb to bind.\n\r", ch );
	return;
    }

    add = limb->value[0] & race_table[vch->race].body_parts;
    if( ( add & vch->body_parts ) == add )
    {
	send_to_char( "That was pointless, they have the parts.\n\r", ch );
	extract_obj( limb );
	return;
    }
    vch->body_parts |= add;
    act( "$n uses $p to repair your limbs.", ch, limb, vch, TO_VICT );
    act( "$n uses $p to repair $N.", ch, limb, vch, TO_NOTVICT );
    if( limb->value[3] != 0
	&& !IS_SET( race_table[ch->race].race_abilities, RACE_NO_POISON ) )
    {
	/* The shit was poisoned! */
	AFFECT_DATA af;

	act( "$n turns a pale &ggreen&n.", ch, 0, 0, TO_ROOM );
	send_to_char( "You suddenly feel sick.\n\r", ch );

	af.type = gsn_poison;
	af.duration = 10;
	af.location = APPLY_STR;
	af.modifier = -2;
	vset( af.bitvector, AFF_POISON );
	affect_join( ch, &af );
    }
    send_to_char( "Ok.\n\r", ch );
    extract_obj( limb );
    return;
}


void spell_reparation( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    char align[MAX_INPUT_LENGTH];

    target_name = one_argument( target_name, align );

    if( !str_cmp( target_name, "good" ) )
    {
	victim->alignment = UMIN( 1000, victim->alignment + 50 );
	send_to_char( "You feel touched by god.\n\r", victim );
	act( "$n looks a little more angelic.", victim, NULL, NULL, TO_ROOM );
    }
    else if( !str_cmp( target_name, "neutral " ) )
    {
	if( victim->alignment < 0 )
	    victim->alignment = UMIN( 0, victim->alignment + 50 );
	else
	    victim->alignment = UMAX( 0, victim->alignment - 50 );
	send_to_char( "You no longer feel any need for alignment.\n\r", victim );
	act( "$n is like switzerland, $e isn't taking sides.", victim, NULL, NULL, TO_ROOM );
    }
    else if( !str_cmp( target_name, "evil" ) )
    {
	victim->alignment = UMAX( -1000, victim->alignment - 50 );
	send_to_char( "You lose all sense of remorse.\n\r", victim );
	act( "$n looks a lot more evil.", victim, NULL, NULL, TO_ROOM );
    }
    else
    {
	send_to_char( "You must choose 'good', 'neutral' or 'evil'.\n\r", ch );
	return;
    }
    return;
}


/*
 * four spells rely on this function it saves on lines of code
 * --Symposium
 */
void spell_resist_temp( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.location = APPLY_BODY_TEMP;
    af.modifier = 25 + level / 5;
    if( IS_SET( skill_table[sn].skill_type, SKILL_TYPE_ICE ) )
	af.modifier = 0 - af.modifier;
    vzero( af.bitvector );
    af.duration = 5 + level / 2;
    if( !affect_to_char( victim, &af, ch ) )
	return;

    if( IS_SET( skill_table[sn].skill_type, SKILL_TYPE_ICE ) )
    {
	if( ch != victim )
	{
	    act( "$n is now sweating profusely in the extreme heat.",
		victim, NULL, ch, TO_ROOM );
	    send_to_char( "You now find that the room is way too hot.\n\r",
			 victim );
	}
	else
	{
	    act( "$n creates a barrier of ice around $mself.",
		ch, NULL, NULL, TO_ROOM );
	    send_to_char( "You create a barrier of ice around yourself.\n\r",
			 ch );
	}
    }
    else
    {
	if( ch != victim )
	{
	    act( "$n is now shivering uncontrollably in the cold.",
		victim, NULL, ch, TO_ROOM );
	    send_to_char( "You now find that the room is way too cold.\n\r",
			 victim );
	}
	else
	{
	    act( "$n erects a screen of flames around $mself.",
		victim, NULL, ch, TO_ROOM );
	    send_to_char( "You erect a screen of flames around yourself.\n\r",
			 victim );
	}
    }
    return;
}


void spell_resist_poison( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.location = APPLY_NONE;
    af.modifier = 0;
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    act( "You suddenly feel your metabolism increase in strength.",
	 victim, NULL, NULL, TO_CHAR );
    act( "$n shudders as $e feels $s metabolism rate increase.",
	 victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_sanctuary( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = number_fuzzy( level / 4 );
    af.location = APPLY_NONE;
    af.modifier = 0;
    vset( af.bitvector, AFF_SANCTUARY );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "You are surrounded by a white aura.\n\r", victim );
    act( "$n is surrounded by a white aura.", victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_sense_life( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    if( IS_SET( race_table[victim->race].race_abilities, RACE_UNDEAD ) )
    {
	act( "$N lacks the life force required for this spell.",
	     ch, NULL, victim, TO_CHAR );
	return;
    }

    af.type = sn;
    af.level = level;
    af.duration = number_fuzzy( level / 4 );
    af.location = APPLY_NONE;
    af.modifier = 0;
    vset( af.bitvector, AFF_SENSE_LIFE );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "You become acutely aware of the life force nearby.\n\r",
		  victim );
    act( "$n looks around and calmly smiles.", victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_share_strength( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    if( victim == ch )
    {
	send_to_char( "You can't share strength with yourself.\n\r", ch );
	return;
    }
    if( get_curr_str( ch ) <= 5 )
    {
	send_to_char( "You are too weak to share your strength.\n\r", ch );
	return;
    }

    af.type = sn;
    af.level = level;
    af.duration = level;
    af.location = APPLY_STR;
    af.modifier = 1 + ( level >= 20 ) + ( level >= 30 );
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    af.modifier = -1 - ( level >= 20 ) - ( level >= 30 );
    affect_to_char( ch, &af, ch );

    act( "You share your strength with $N.", ch, NULL, victim, TO_CHAR );
    act( "$n shares $s strength with you.", ch, NULL, victim, TO_VICT );
    return;
}


void spell_shield( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.location = APPLY_AC;
    af.modifier = -20;
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "You are surrounded by a force shield.\n\r", victim );
    act( "$n is surrounded by a force shield.", victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_shocking_grasp( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.location = APPLY_NONE;
    af.modifier = 0;
    vset( af.bitvector, AFF_MAGICHANDS );
    af.duration = number_fuzzy( level / 4 );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "Your hands begin to crackle with electricity.\n\r", victim );
    act( "&g$n's hands begin to crackle with small sparks of &Welectricity&g.",
	 victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_shrink( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * (level / 50 + 1);
    af.location = APPLY_SIZE;
    af.modifier = race_table[victim->race].size * 50 / ( level + 50 )
	- race_table[victim->race].size;
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "You feel yourself suddenly shrink down to nothing.\n\r",
		  victim );
    act( "&g$n suddenly shrinks down to a small fraction of their original size.",
	 victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_stone_skin( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.location = APPLY_AC;
    af.modifier = -40;
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "Your skin turns to stone.\n\r", victim );
    act( "$n's skin turns to stone.", victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_thought_shield( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *victim = (CHAR_DATA *)vo;
    AFFECT_DATA af;

    af.type = sn;
    af.level = level;
    af.duration = 24 * ( 1 + level / 50 );
    af.location = APPLY_AC;
    af.modifier = -20;
    vzero( af.bitvector );
    if( !affect_to_char( victim, &af, ch ) )
	return;

    send_to_char( "A shield forms around you.\n\r", victim );
    act( "A shield forms around $n.", victim, NULL, NULL, TO_ROOM );
    return;
}


void spell_warcry( int sn, int level, CHAR_DATA *ch, void *vo )
{
    CHAR_DATA *gch;
    AFFECT_DATA af;

    act( "&g$n roar$% a defiant cry!", ch, NULL, NULL, TO_ALL );
    af.type = sn;
    af.level = level;
    af.duration = 3 + level / 50;
    af.modifier = 5 + level / 50;
    vzero( af.bitvector );
    for( gch = ch->in_room->people; gch; gch = gch->next_in_room )
    {
	if( !is_same_group( gch, ch ) )
	    continue;

	if( ( IS_GOOD( ch ) && !IS_GOOD( gch ) )
	    || ( IS_NEUTRAL( ch ) && !IS_NEUTRAL( gch ) )
	    || ( IS_EVIL( ch ) && !IS_EVIL( gch ) ) )
	{
	    send_to_char( "Your God doesn't like that person.\n\r", ch );
	    continue;
	}

	af.location = APPLY_HITROLL;
	if( !affect_to_char( gch, &af, NULL ) )
	    continue;

	af.location = APPLY_DAMROLL;
	if( !affect_to_char( gch, &af, NULL ) )
	    continue;

	send_to_char( "You feel more confident of your success in battle.\n\r", gch );
	act( "$N looks more confident of $s success in battle.", gch, NULL, gch, TO_ROOM );
    }
    return;
}