/*___________________________________________________________________________* )()( 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; }