/*************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * Envy Diku Mud improvements copyright (C) 1994 by Michael Quan, David * * Love, Guilherme 'Willie' Arnold, and Mitchell Tse. * * * * In order to use any part of this Envy Diku Mud, you must comply with * * the original Diku license in 'license.doc', the Merc license in * * 'license.txt', as well as the Envy license in 'license.nvy'. * * In particular, you may not remove either of these copyright notices. * * * * Much time and thought has gone into this software and you are * * benefitting. We hope that you share your changes too. What goes * * around, comes around. * ***************************************************************************/ #define unix 1 #if defined( macintosh ) #include <types.h> #else #include <sys/types.h> #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "merc.h" /* * External functions. */ bool is_safe args( ( CHAR_DATA *ch, CHAR_DATA *victim ) ); void set_fighting args( ( CHAR_DATA *ch, CHAR_DATA *victim ) ); /* * Local functions. */ void say_spell args( ( CHAR_DATA *ch, int sn ) ); int blood_count args( ( OBJ_DATA *list, int amount ) ); void magic_mob args( ( CHAR_DATA *ch, OBJ_DATA *obj, int vnum ) ); int slot_lookup args( ( int slot ) ); int sc_dam args( ( CHAR_DATA *ch, int dam ) ); /* * "Permament sn's": slot loading for objects -- Altrag */ int slot_lookup( int slot ) { int sn; for ( sn = 0; skill_table[sn].name[0] != '\0'; sn++ ) if ( skill_table[sn].slot == slot ) return sn; bug( "Slot_lookup: no such slot #%d", slot ); return 0; } /* * Replacement for MAX_SKILL -- Altrag */ bool is_sn( int sn ) { int cnt; for ( cnt = 0; skill_table[cnt].name[0] != '\0'; cnt++ ) if ( cnt == sn ) return TRUE; return FALSE; } void magic_mob ( CHAR_DATA *ch, OBJ_DATA *obj, int vnum ) { CHAR_DATA *victim; CHAR_DATA *zombie; MOB_INDEX_DATA *ZombIndex; MOB_INDEX_DATA *pMobIndex; char *name; char buf [MAX_STRING_LENGTH]; if ( !( pMobIndex = get_mob_index( vnum ) ) ) { send_to_char(AT_BLUE, "Nothing happens.\n\r", ch); return; } ZombIndex = get_mob_index( 3 ); victim = create_mobile( pMobIndex ); zombie = create_mobile( ZombIndex ); name = victim->short_descr; sprintf( buf, zombie->short_descr, name ); free_string( zombie->short_descr ); zombie->short_descr = str_dup(buf); sprintf( buf, zombie->long_descr, name ); free_string( zombie->long_descr ); zombie->long_descr = str_dup(buf); victim->perm_hit /= 2; victim->hit = MAX_HIT(victim); zombie->mod_hit = victim->mod_hit; zombie->perm_hit = victim->perm_hit; zombie->hit = victim->hit; zombie->level = victim->level; SET_BIT( zombie->act, ACT_UNDEAD ); SET_BIT( zombie->act, ACT_PET ); SET_BIT( zombie->affected_by, AFF_CHARM ); char_to_room( zombie, ch->in_room ); add_follower( zombie, ch ); update_pos( zombie ); act( AT_BLUE, "$n passes $s hands over $p, $E slowly rises to serve $S new master.", ch, obj, zombie, TO_ROOM ); act( AT_BLUE, "You animate $p, it rises to serve you.", ch, obj, NULL, TO_CHAR ); char_to_room( victim, ch->in_room ); extract_char ( victim, TRUE ); return; } int blood_count( OBJ_DATA *list, int amount ) { OBJ_DATA *obj; int count; OBJ_DATA *obj_next; count = 0; for ( obj = list; obj; obj = obj_next ) { obj_next = obj->next_content; if ( obj->deleted ) continue; if ( ( obj->item_type == ITEM_BLOOD ) && ( count != amount ) ) { count++; extract_obj( obj ); } } return count; } void update_skpell( CHAR_DATA *ch, int sn ) { int xp = 0; char buf[MAX_STRING_LENGTH]; int adept; if ( IS_NPC( ch ) ) return; adept = IS_NPC( ch ) ? 100 : class_table[prime_class( ch )].skill_adept; if ( ch->pcdata->learned[sn] <= 0 || ch->pcdata->learned[sn] >= adept ) return; ch->pcdata->learned[sn] += ( get_curr_wis( ch ) / 5 ); if ( ch->pcdata->learned[sn] > adept ) ch->pcdata->learned[sn] = adept; xp = ch->level / 5; if ( xp < 2 ) xp = 2; xp = number_range( xp * 2, ( xp * xp ) / 3 ); if (!(ch->fighting)) { sprintf( buf, "You gain %d experience for your success with %s.\n\r", xp, skill_table[sn].name ); send_to_char( C_DEFAULT, buf, ch ); } gain_exp( ch, xp ); return; } int skill_lookup( const char *name ) { int sn; for ( sn = 0; skill_table[sn].name[0] != '\0'; sn++ ) { if ( !skill_table[sn].name ) break; if ( LOWER( name[0] ) == LOWER( skill_table[sn].name[0] ) && !str_prefix( name, skill_table[sn].name ) ) return sn; } return -1; } /* * Utter mystical words for an sn. */ void say_spell( CHAR_DATA *ch, int sn ) { CHAR_DATA *rch; char *pName; char buf [ MAX_STRING_LENGTH ]; char buf2 [ MAX_STRING_LENGTH ]; int iSyl; int length; struct syl_type { char * old; char * new; }; static const struct syl_type syl_table [ ] = { { " ", " " }, { "ar", "abra" }, { "au", "kada" }, { "bless", "fido" }, { "blind", "nose" }, { "bur", "mosa" }, { "cu", "judi" }, { "de", "oculo" }, { "en", "unso" }, { "light", "dies" }, { "lo", "hi" }, { "mor", "zak" }, { "move", "sido" }, { "ness", "lacri" }, { "ning", "illa" }, { "per", "duda" }, { "ra", "gru" }, { "re", "candus" }, { "son", "sabru" }, { "tect", "infra" }, { "tri", "cula" }, { "ven", "nofo" }, { "a", "a" }, { "b", "b" }, { "c", "q" }, { "d", "e" }, { "e", "z" }, { "f", "y" }, { "g", "o" }, { "h", "p" }, { "i", "u" }, { "j", "y" }, { "k", "t" }, { "l", "r" }, { "m", "w" }, { "n", "i" }, { "o", "a" }, { "p", "s" }, { "q", "d" }, { "r", "f" }, { "s", "g" }, { "t", "h" }, { "u", "j" }, { "v", "z" }, { "w", "x" }, { "x", "n" }, { "y", "l" }, { "z", "k" }, { "", "" } }; buf[0] = '\0'; for ( pName = skill_table[sn].name; *pName != '\0'; pName += length ) { for ( iSyl = 0; ( length = strlen( syl_table[iSyl].old ) ) != 0; iSyl++ ) { if ( !str_prefix( syl_table[iSyl].old, pName ) ) { strcat( buf, syl_table[iSyl].new ); break; } } if ( length == 0 ) length = 1; } sprintf( buf2, "$n %s the words, '%s'.", prime_class(ch) != CLASS_BARD ? "utters" : "sings", buf ); sprintf( buf, "$n %s the words, '%s'.", prime_class(ch) != CLASS_BARD ? "utters" : "sings", skill_table[sn].name ); for ( rch = ch->in_room->people; rch; rch = rch->next_in_room ) { if ( rch != ch ) act(AT_BLUE, is_class( rch, prime_class(ch) ) ? buf : buf2, ch, NULL, rch, TO_VICT ); } return; } /* * Compute a saving throw. * Negative apply's make saving throw better. */ bool saves_spell( int level, CHAR_DATA *victim ) { int save; int base = 20; int savebase; if ( IS_NPC( victim ) ) base += 30; savebase = 0 - victim->saving_throw / 2; if ( victim->race == RACE_DWARF ) savebase += 25 * savebase / 100; if ( !IS_NPC( victim ) ) savebase /= 6; else savebase /= 2; save = base + ( victim->level - level ) + savebase; save = URANGE( 5, save, ( victim->race == RACE_DWARF ) ? 95 : 90 ); return number_percent( ) < save; } /* * The kludgy global is for spells who want more stuff from command line. */ char *target_name; void do_acspell ( CHAR_DATA *ch, OBJ_DATA *pObj, char *argument ) { void *vo; OBJ_DATA *obj = NULL; CHAR_DATA *victim; char arg1 [ MAX_INPUT_LENGTH ]; char arg2 [ MAX_INPUT_LENGTH ]; int sn; int spec; spec = skill_lookup( "astral walk" ); target_name = one_argument( argument, arg1 ); one_argument( target_name, arg2 ); if ( IS_NPC( ch ) ) if ( IS_SET( ch->affected_by, AFF_CHARM ) ) return; if ( ( sn = skill_lookup( arg1 ) ) < 0) { send_to_char(AT_BLUE, "You can't do that.\n\r", ch ); return; } if ( ( sn == spec ) && ( is_name( ch, arg2, ch->name ) ) ) { send_to_char( AT_BLUE, "You are already in the same room as yourself.\n\r", ch ); return; } /* * Locate targets. */ victim = NULL; obj = NULL; vo = NULL; switch ( skill_table[sn].target ) { default: bug( "Do_cast: bad target for sn %d.", sn ); return; case TAR_GROUP_OFFENSIVE: case TAR_GROUP_DEFENSIVE: case TAR_GROUP_ALL: case TAR_GROUP_OBJ: case TAR_GROUP_IGNORE: group_cast( sn, URANGE( 1, ch->level, LEVEL_HERO ), ch, arg2 ); return; case TAR_IGNORE: break; case TAR_CHAR_OFFENSIVE: if ( IS_SET( ch->in_room->room_flags, ROOM_NO_OFFENSIVE ) ) { send_to_char( AT_BLUE, "You failed.\n\r", ch ); return; } if ( arg2[0] == '\0' ) { if ( !( victim = ch->fighting ) ) { send_to_char(AT_BLUE, "Cast the spell on whom?\n\r", ch ); return; } } else { if ( !( victim = get_char_room( ch, arg2 ) ) ) { send_to_char(AT_BLUE, "They aren't here.\n\r", ch ); return; } } if ( IS_AFFECTED(victim, AFF_PEACE) ) { send_to_char(AT_WHITE, "A wave of peace overcomes you.\n\r", ch); return; } if ( IS_AFFECTED( ch, AFF_PEACE) ) { affect_strip( ch, skill_lookup("aura of peace") ); REMOVE_BIT( ch->affected_by, AFF_PEACE ); } if ( is_safe(ch, victim) ) { send_to_char(AT_BLUE,"You failed.\n\r",ch); return; } vo = (void *) victim; break; case TAR_CHAR_DEFENSIVE: if ( arg2[0] == '\0' ) { victim = ch; } else { if ( !( victim = get_char_room( ch, arg2 ) ) ) { send_to_char(AT_BLUE, "They aren't here.\n\r", ch ); return; } } vo = (void *) victim; break; case TAR_CHAR_SELF: if ( arg2[0] != '\0' && !is_name( ch, arg2, ch->name ) ) { send_to_char(AT_BLUE, "You cannot cast this spell on another.\n\r", ch ); return; } vo = (void *) ch; break; case TAR_OBJ_INV: if ( arg2[0] == '\0' ) { send_to_char(AT_BLUE, "What should the spell be cast upon?\n\r", ch ); return; } if ( !( obj = get_obj_carry( ch, arg2 ) ) ) { send_to_char(AT_BLUE, "You are not carrying that.\n\r", ch ); return; } vo = (void *) obj; break; } WAIT_STATE( ch, skill_table[sn].beats ); if ( IS_SET( ch->in_room->room_flags, ROOM_NO_MAGIC ) ) { send_to_char( AT_BLUE, "You failed.\n\r", ch ); return; } if ( !IS_NPC( ch ) ) update_skpell( ch, sn ); (*skill_table[sn].spell_fun) ( sn, URANGE( 1, ch->level, LEVEL_HERO ), ch, vo ); if ( vo ) { oprog_invoke_trigger( pObj, ch, vo ); if ( skill_table[sn].target == TAR_OBJ_INV ) oprog_cast_sn_trigger( obj, ch, sn, vo ); rprog_cast_sn_trigger( ch->in_room, ch, sn, vo ); } if ( skill_table[sn].target == TAR_CHAR_OFFENSIVE && victim->master != ch && victim != ch && IS_AWAKE( victim ) ) { CHAR_DATA *vch; for ( vch = ch->in_room->people; vch; vch = vch->next_in_room ) { if ( vch->deleted ) continue; if ( victim == vch && !victim->fighting ) { multi_hit( victim, ch, TYPE_UNDEFINED ); break; } } } return; } void do_cast( CHAR_DATA *ch, char *argument ) { void *vo; OBJ_DATA *obj; CHAR_DATA *victim; char arg1 [ MAX_INPUT_LENGTH ]; char arg2 [ MAX_INPUT_LENGTH ]; int mana; int sn; bool IS_DIVINE; /* int spec; */ /* char buf [ MAX_STRING_LENGTH ];*/ /* spec = skill_lookup( "astral walk" ); */ IS_DIVINE = FALSE; target_name = one_argument( argument, arg1 ); if ( arg1[0] != '\0' ) if ( !str_prefix( arg1, "divine" ) && ch->level >= LEVEL_IMMORTAL ) { IS_DIVINE = TRUE; target_name = one_argument( target_name, arg1 ); } one_argument( target_name, arg2 ); if ( arg1[0] == '\0' ) { if ( prime_class(ch) != CLASS_BARD ) send_to_char(AT_BLUE, "Cast which what where?\n\r", ch ); else send_to_char(AT_BLUE, "Sing what song?\n\r", ch ); return; } if ( IS_NPC( ch ) ) if ( IS_SET( ch->affected_by, AFF_CHARM ) ) return; if ( !IS_NPC( ch ) ) if ( ( sn = skill_lookup( arg1 ) ) < 0 || !can_use_skpell( ch, sn ) ) { send_to_char(AT_BLUE, "You can't do that.\n\r", ch ); return; } if ( IS_NPC( ch ) ) if ( ( sn = skill_lookup( arg1 ) ) < 0 ) return; if ( ch->position < skill_table[sn].minimum_position ) { send_to_char(AT_BLUE, "You can't concentrate enough.\n\r", ch ); return; } /* if ( ch->level < LEVEL_IMMORTAL && ch->class == CLASS_VAMPIRE ) if ( !IS_SET( ch->in_room->room_flags, ROOM_INDOORS ) ) { if ( time_info.hour > 6 && time_info.hour < 18 ) { int chance; chance = 15; if (number_percent ( )< chance) { send_to_char(AT_RED, "The sun blocks your magic!\n\r", ch ); return; } } } */ if ( IS_STUNNED( ch, STUN_MAGIC ) ) { if ( prime_class(ch) != CLASS_BARD ) send_to_char(AT_LBLUE, "You're too stunned to cast spells.\n\r", ch ); else send_to_char(AT_LBLUE, "You're too stunned to sing songs.\n\r", ch ); return; } if ( !IS_NPC( ch ) && ( !( ch->level > LEVEL_MORTAL ) ) ) { mana = SPELL_COST( ch, sn ); if ( ch->race == RACE_ELF || ch->race == RACE_ELDER ) mana -= mana / 4; } else mana = 0; /* * Locate targets. */ victim = NULL; obj = NULL; vo = NULL; switch ( skill_table[sn].target ) { default: bug( "Do_cast: bad target for sn %d.", sn ); return; case TAR_GROUP_OFFENSIVE: case TAR_GROUP_DEFENSIVE: case TAR_GROUP_ALL: case TAR_GROUP_OBJ: case TAR_GROUP_IGNORE: group_cast( sn, URANGE( 1, ch->level, LEVEL_HERO ), ch, arg2 ); return; case TAR_IGNORE: break; case TAR_CHAR_OFFENSIVE: if ( IS_SET( ch->in_room->room_flags, ROOM_NO_OFFENSIVE ) ) { send_to_char( AT_BLUE, "You failed.\n\r", ch ); return; } if ( arg2[0] == '\0' ) { if ( !( victim = ch->fighting ) ) { if ( prime_class(ch) != CLASS_BARD ) send_to_char(AT_BLUE, "Cast the spell on whom?\n\r", ch ); else send_to_char(AT_BLUE, "Sing the song to whom?\n\r", ch ); return; } } else { if ( !( victim = get_char_room( ch, arg2 ) ) ) { send_to_char(AT_BLUE, "They aren't here.\n\r", ch ); return; } } if ( IS_AFFECTED(victim, AFF_PEACE) ) { send_to_char(AT_WHITE, "A wave of peace overcomes you.\n\r", ch); return; } if ( IS_AFFECTED( ch, AFF_PEACE) ) { affect_strip( ch, skill_lookup("aura of peace") ); REMOVE_BIT( ch->affected_by, AFF_PEACE ); } if (is_safe(ch, victim ) ) { send_to_char( AT_BLUE, "You failed.\n\r",ch); return; } vo = (void *) victim; break; case TAR_CHAR_DEFENSIVE: if ( arg2[0] == '\0' ) { victim = ch; } else { if ( !( victim = get_char_room( ch, arg2 ) ) ) { send_to_char(AT_BLUE, "They aren't here.\n\r", ch ); return; } } vo = (void *) victim; break; case TAR_CHAR_SELF: if ( arg2[0] != '\0' && !is_name( ch, arg2, ch->name ) ) { if ( prime_class(ch) != CLASS_BARD ) send_to_char(AT_BLUE, "You cannot cast this spell on another.\n\r", ch ); else send_to_char(AT_BLUE, "You cannot sing this song for others.\n\r", ch ); return; } vo = (void *) ch; break; case TAR_OBJ_INV: if ( arg2[0] == '\0' ) { send_to_char(AT_BLUE, "What should the spell be cast upon?\n\r", ch ); return; } if ( !(obj = get_obj_here( ch, arg2 ) ) ) { send_to_char( AT_BLUE, "You can't find that.\n\r", ch ); return; } vo = (void *) obj; break; } if ( !IS_NPC( ch ) ) if ( !is_class( ch, CLASS_VAMPIRE ) && ch->mana < mana ) { send_to_char(AT_BLUE, "You don't have enough mana.\n\r", ch ); return; } else if ( ( ch->bp < mana ) && ( is_class( ch, CLASS_VAMPIRE ) ) ) { send_to_char(AT_RED, "You are to starved to cast, you must feed.\n\r", ch ); return; } if ( str_cmp( skill_table[sn].name, "ventriloquate" ) ) say_spell( ch, sn ); if ( IS_SET( ch->in_room->room_flags, ROOM_NO_MAGIC ) ) { send_to_char( AT_BLUE, "You failed.\n\r", ch ); return; } if ( ( IS_SET( ch->in_room->room_flags, ROOM_NO_OFFENSIVE ) ) && ( skill_table[sn].target == TAR_CHAR_OFFENSIVE ) ) { send_to_char( AT_BLUE, "You failed.\n\r", ch ); return; } WAIT_STATE( ch, skill_table[sn].beats ); if ( !IS_NPC( ch ) ) if ( number_percent( ) > ch->pcdata->learned[sn] ) { send_to_char(AT_BLUE, "You lost your concentration.\n\r", ch ); MT( ch ) -= mana / 2; } else { MT( ch ) -= mana; if ( ( IS_AFFECTED2( ch, AFF_CONFUSED ) ) && number_percent( ) < 10 ) { act(AT_YELLOW, "$n looks around confused at what's going on.", ch, NULL, NULL, TO_ROOM ); send_to_char( AT_YELLOW, "You become confused and botch the spell.\n\r", ch ); return; } update_skpell( ch, sn ); (*skill_table[sn].spell_fun) ( sn, IS_DIVINE ? URANGE( 1, ch->level, LEVEL_HERO )*3 : URANGE( 1, ch->level, LEVEL_HERO ) , ch, vo ); } if ( IS_NPC( ch ) ) (*skill_table[sn].spell_fun) ( sn, IS_DIVINE ? URANGE( 1, ch->level, LEVEL_HERO )*3 : URANGE( 1, ch->level, LEVEL_HERO ) , ch, vo ); if ( vo ) { if ( skill_table[sn].target == TAR_OBJ_INV ) oprog_cast_sn_trigger( obj, ch, sn, vo ); rprog_cast_sn_trigger( ch->in_room, ch, sn, vo ); } if ( skill_table[sn].target == TAR_CHAR_OFFENSIVE && victim->master != ch && victim != ch && IS_AWAKE( victim ) ) { CHAR_DATA *vch; for ( vch = ch->in_room->people; vch; vch = vch->next_in_room ) { if ( vch->deleted ) continue; if ( victim == vch && !victim->fighting ) { multi_hit( victim, ch, TYPE_UNDEFINED ); break; } } } return; } /* * Cast spells at targets using a magical object. */ void obj_cast_spell( int sn, int level, CHAR_DATA *ch, CHAR_DATA *victim, OBJ_DATA *obj ) { void *vo; if ( sn <= 0 ) return; if ( !is_sn(sn) || skill_table[sn].spell_fun == 0 ) { bug( "Obj_cast_spell: bad sn %d.", sn ); return; } if ( IS_SET( ch->in_room->room_flags, ROOM_NO_MAGIC ) ) { send_to_char( AT_BLUE, "The magic of the item fizzles.\n\r", ch ); return; } switch ( skill_table[sn].target ) { default: bug( "Obj_cast_spell: bad target for sn %d.", sn ); return; case TAR_GROUP_OFFENSIVE: case TAR_GROUP_DEFENSIVE: case TAR_GROUP_ALL: case TAR_GROUP_OBJ: case TAR_GROUP_IGNORE: group_cast( sn, URANGE( 1, level, LEVEL_HERO ), ch, victim ? (void *)victim : (void *)obj ); return; case TAR_IGNORE: vo = NULL; break; case TAR_CHAR_OFFENSIVE: if ( IS_SET( ch->in_room->room_flags, ROOM_NO_OFFENSIVE ) ) { send_to_char( AT_BLUE, "The magic of the item fizzles.\n\r", ch ); return; } if ( !victim ) victim = ch->fighting; if ( !victim || ( !IS_NPC( victim ) && ch != victim ) ) { send_to_char(AT_BLUE, "You can't do that.\n\r", ch ); return; } if ( ( ( ch->clan == 0 ) || ( ch->clan == 0 ) ) && ( !IS_NPC( victim ) ) ) return; if ( IS_AFFECTED(victim, AFF_PEACE) ) { send_to_char(AT_WHITE, "A wave of peace overcomes you.\n\r", ch); return; } if ( IS_AFFECTED( ch, AFF_PEACE) ) { affect_strip( ch, skill_lookup("aura of peace") ); REMOVE_BIT( ch->affected_by, AFF_PEACE ); } if ( ( ( ch->level - 9 > victim->level ) || ( ch->level + 9 < victim->level ) ) && ( !IS_NPC(victim) ) ) { send_to_char(AT_WHITE, "That is not in the pkill range... valid range is +/- 8 levels.\n\r", ch ); return; } vo = (void *) victim; break; case TAR_CHAR_DEFENSIVE: if ( !victim ) victim = ch; vo = (void *) victim; break; case TAR_CHAR_SELF: vo = (void *) ch; break; case TAR_OBJ_INV: if ( !obj ) { send_to_char(AT_BLUE, "You can't do that.\n\r", ch ); return; } vo = (void *) obj; break; } /* target_name = "";*/ (*skill_table[sn].spell_fun) ( sn, level, ch, vo ); if ( vo ) { if ( skill_table[sn].target == TAR_OBJ_INV ) oprog_cast_sn_trigger( obj, ch, sn, vo ); rprog_cast_sn_trigger( ch->in_room, ch, sn, vo ); } if ( skill_table[sn].target == TAR_CHAR_OFFENSIVE && victim->master != ch && ch != victim ) { CHAR_DATA *vch; for ( vch = ch->in_room->people; vch; vch = vch->next_in_room ) { if ( vch->deleted ) continue; if ( victim == vch && !victim->fighting ) { multi_hit( victim, ch, TYPE_UNDEFINED ); break; } } } return; } /* * Spell functions. */ void spell_acid_blast( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; dam = dice( level, 8 ); dam = sc_dam( ch, dam ); if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_animate( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj = (OBJ_DATA *) vo; OBJ_DATA *obj_next; if ( obj->item_type != ITEM_CORPSE_NPC ) { send_to_char(AT_BLUE, "You cannot animate that.\n\r", ch ); return; } obj_next = obj->next; if (obj->deleted) return; magic_mob( ch, obj, obj->ac_vnum ); extract_obj(obj); return; } void spell_armor( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn ) ) return; af.type = sn; af.level = level; af.duration = 24; af.location = APPLY_AC; af.modifier = -25; af.bitvector = 0; affect_to_char( victim, &af ); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "You feel someone protecting you.\n\r", victim ); return; } void spell_astral( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim; CHAR_DATA *pet; if ( !( victim = get_char_world( ch, target_name ) ) || IS_SET( victim->in_room->room_flags, ROOM_SAFE ) || IS_SET( victim->in_room->room_flags, ROOM_PRIVATE ) || IS_SET( victim->in_room->room_flags, ROOM_SOLITARY ) || IS_SET( victim->in_room->room_flags, ROOM_NO_ASTRAL_IN ) || IS_SET( ch->in_room->room_flags, ROOM_NO_ASTRAL_OUT ) || IS_SET( victim->in_room->area->area_flags, AREA_PROTOTYPE ) || IS_SET( victim->act, ACT_NOASTRAL ) || IS_ARENA(ch) || victim->in_room->area == arena.area || IS_AFFECTED( victim, AFF_NOASTRAL ) ) { send_to_char(AT_BLUE, "You failed.\n\r", ch ); return; } for ( pet = ch->in_room->people; pet; pet = pet->next_in_room ) { if ( IS_NPC( pet ) ) if ( IS_SET( pet->act, ACT_PET ) && ( pet->master == ch ) ) break; } act(AT_BLUE, "$n vanishes in a flash of blinding light.", ch, NULL, NULL, TO_ROOM ); if ( ch != victim ) { if ( pet ) { act( AT_BLUE, "$n vanishes in a flash of blinding light.", pet, NULL, NULL, TO_ROOM ); char_from_room( pet ); } char_from_room( ch ); char_to_room( ch, victim->in_room ); } act(AT_BLUE, "$n appears in a flash of blinding light.", ch, NULL, NULL, TO_ROOM ); do_look( ch, "auto" ); if ( pet ) { char_to_room( pet, victim->in_room ); act( AT_BLUE, "$n appears in a flash of blinding light.", pet, NULL, NULL, TO_ROOM ); } return; } void spell_pass_plant ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim ; CHAR_DATA *pet; if ( IS_AFFECTED( ch, AFF_ANTI_FLEE ) ) { send_to_char( AT_WHITE, "You cannot walk through the plants in your condition!\n\r", ch ); return; } if ( ch->in_room->sector_type == SECT_INSIDE || ch->in_room->sector_type == SECT_CITY || ch->in_room->sector_type == SECT_AIR ) { send_to_char(AT_GREEN, "There are no plants here.\n\r", ch ); return; } if ( IS_SET( ch->in_room->room_flags, ROOM_NO_SHADOW ) ) { send_to_char(AT_GREEN, "The plants do not respond to your call.\n\r", ch); return; } if ( !( victim = get_char_world( ch, target_name ) ) || victim->in_room->area != ch->in_room->area || IS_SET( victim->in_room->room_flags, ROOM_PRIVATE ) || IS_SET( victim->in_room->room_flags, ROOM_SOLITARY ) || victim->in_room->sector_type == SECT_INSIDE || victim->in_room->sector_type == SECT_CITY || victim->in_room->sector_type == SECT_AIR || IS_AFFECTED( victim, AFF_NOASTRAL ) ) { send_to_char(AT_GREEN, "The plants do not reach there.\n\r", ch ); return; } for ( pet = ch->in_room->people; pet; pet = pet->next_in_room ) { if ( IS_NPC( pet ) ) if ( IS_SET( pet->act, ACT_PET ) && ( pet->master == ch ) ) break; } if ( ch != victim ) { act(AT_GREEN, "$n melts into the surrounding plant life.", ch, NULL, NULL, TO_ROOM ); char_from_room( ch ); char_to_room( ch, victim->in_room ); act(AT_GREEN, "$n steps out of the surrounding plant life.", ch, NULL, NULL, TO_ROOM ); if ( pet ) { act( AT_BLUE, "$n melts into the surrounding plant life.", pet, NULL, NULL, TO_ROOM ); char_from_room( pet ); char_to_room( pet, victim->in_room ); act( AT_BLUE, "$n steps out of the surrounding plant life.", pet, NULL, NULL, TO_ROOM ); } } do_look( ch, "auto" ); return; } void spell_aura( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_PEACE) ) return; af.type = sn; af.level = level; af.duration = number_fuzzy( level / 8 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_PEACE; affect_to_char( victim, &af ); send_to_char(AT_BLUE, "You feel a wave of peace flow lightly over your body.\n\r", victim ); act(AT_BLUE, "$n looks very peaceful.", victim, NULL, NULL, TO_ROOM ); return; } void spell_bless( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( victim->position == POS_FIGHTING || is_affected( victim, sn ) ) return; af.type = sn; af.level = level; af.duration = 6 + level; af.location = APPLY_HITROLL; af.modifier = level / 8; af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_SAVING_SPELL; af.modifier = 0 - level / 8; affect_to_char( victim, &af ); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "You feel righteous.\n\r", victim ); return; } void spell_darkbless( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( victim->position == POS_FIGHTING || is_affected( victim, sn ) ) return; af.type = sn; af.level = level; af.duration = 20 + level; af.location = APPLY_DAMROLL; af.modifier = level / 6; af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_HIT; af.modifier = level * 3; affect_to_char( victim, &af ); if ( ch != victim ) send_to_char(AT_BLUE, "You call forth the hand of oblivion.\n\r", ch ); send_to_char(AT_BLUE, "The hand of oblivion rests upon you.\n\r", victim ); return; } void spell_aid( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( victim->position == POS_FIGHTING || is_affected( victim, sn ) ) return; af.type = sn; af.level = level; af.duration = 8 + level; af.location = APPLY_HITROLL; af.modifier = level / 6; af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_SAVING_SPELL; af.modifier = 0 - level / 6; affect_to_char( victim, &af ); af.location = APPLY_HIT; af.modifier = level * 3; affect_to_char( victim, &af ); if ( ch != victim ) send_to_char(AT_BLUE, "You grant them divine aid.\n\r", ch ); send_to_char(AT_BLUE, "You feel divine aid reashure you.\n\r", victim ); return; } void spell_bio_acceleration( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( victim->position == POS_FIGHTING || is_affected( victim, sn ) ) return; af.type = sn; af.level = level; af.duration = 20 + level; af.location = APPLY_HIT; af.modifier = number_fuzzy ( level * 4 ); af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_MOVE; af.modifier = level * 2; affect_to_char( victim, &af ); send_to_char( AT_BLUE, "You greatly enhance your bio-functions.\n\r", ch ); act(AT_BLUE, "$n's body shudders briefly.", ch, NULL, NULL, TO_ROOM); return; } /*Decklarean*/ void spell_draw_strength( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( victim->position == POS_FIGHTING || is_affected( victim, sn ) ) return; af.type = sn; af.level = level; af.duration = 20 + level; af.location = APPLY_MANA; af.modifier = number_fuzzy ( level * 4 ); af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_HIT; af.modifier = -af.modifier; affect_to_char( victim, &af ); /* They still have hitpoints over there max hit points get ride of them */ if ( MAX_HIT(victim) < victim->hit ) victim->hit = MAX_HIT(victim); send_to_char( AT_BLUE, "You draw from your physical strength and increase your energy reserve.\n\r", ch ); act(AT_BLUE, "$n's body weakens.", ch, NULL, NULL, TO_ROOM); return; } /* void spell_barkskin( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, sn)) return; af.type = sn; af.duration = 35; af.location = APPLY_AC; af.modifier = -30; af.bitvector = 0; affect_to_char( victim, &af); af.location = APPLY_SAVING_SPELL; af.modifier = 0 - LEVEL / 12; affect_to_char( victim, &af); if ( ch != victim ) send_to_char( "Ok.\n\r", ch ); send_to_char( "Your skin turns into a bark-like texture.\n\r", victim, ); return; } */ void spell_blindness( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_BLIND ) || saves_spell( level, victim ) ) { send_to_char(AT_BLUE, "You have failed.\n\r", ch ); return; } af.type = sn; af.level = level; af.duration = 5; af.location = APPLY_HITROLL; af.modifier = -10; af.bitvector = AFF_BLIND; affect_to_char( victim, &af ); act(AT_WHITE, "$N is blinded!", ch, NULL, victim, TO_CHAR ); send_to_char(AT_WHITE, "You are blinded!\n\r", victim ); act(AT_WHITE, "$N is blinded!", ch, NULL, victim, TO_NOTVICT ); return; } void spell_blood_bath( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim; if ( blood_count( ch->in_room->contents, 5 ) < 2 ) { send_to_char( AT_RED, "There is not enough blood in the room.\n\r", ch ); return; } for ( victim = ch->in_room->people; victim; victim = victim->next_in_room ) { if ( victim->deleted ) continue; if ( IS_NPC( victim ) ) continue; victim->hit = UMIN( victim->hit + 250, MAX_HIT(victim) ); update_pos( victim ); act( AT_RED, "You bath $N in the life giving fluid.", ch, NULL, victim, TO_CHAR ); act( AT_RED, "$n baths $N in blood.", ch, NULL, victim, TO_ROOM ); act( AT_RED, "$n baths you in blood.", ch, NULL, victim, TO_VICT ); } send_to_char( AT_RED, "The blood bath is over.\n\r", ch ); return; } void spell_burning_hands( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 0, 0, 0, 0, 14, 17, 20, 23, 26, 29, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 51, 51, 51, 52, 52, 52, 53, 53, 53, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 57, 57, 58, 59, 60 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level] / 2, dam_each[level] * 2 ); dam = sc_dam( ch, dam ); if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_call_lightning( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *vch; int dam; if ( !IS_OUTSIDE( ch ) ) { send_to_char(AT_WHITE, "You must be out of doors.\n\r", ch ); return; } if ( weather_info.sky < SKY_RAINING ) { send_to_char(AT_WHITE, "You need bad weather.\n\r", ch ); return; } dam = dice( level / 2, 8 ); send_to_char(AT_WHITE, "Lightning slashes out of the sky to strike your foes!\n\r", ch ); act(AT_WHITE, "$n calls lightning from the sky to strike $s foes!", ch, NULL, NULL, TO_ROOM ); for ( vch = char_list; vch; vch = vch->next ) { if ( vch->deleted || !vch->in_room ) continue; if ( vch->in_room == ch->in_room ) { if ( vch != ch && ( IS_NPC( ch ) ? !IS_NPC( vch ) : IS_NPC( vch ) ) ) { dam = sc_dam( ch, dam ); damage( ch, vch, saves_spell( level, vch ) ? dam/2 : dam, sn ); } continue; } if ( vch->in_room->area == ch->in_room->area && IS_OUTSIDE( vch ) && IS_AWAKE( vch ) ) send_to_char(AT_LBLUE, "Lightning flashes in the sky.\n\r", vch ); } return; } void spell_cause_light( int sn, int level, CHAR_DATA *ch, void *vo ) { int dam = dice( 1, 8 ) + level / 3; dam = sc_dam( ch, dam ); damage( ch, (CHAR_DATA *) vo, dam, sn ); return; } void spell_cause_critical( int sn, int level, CHAR_DATA *ch, void *vo ) { int dam = dice( 3, 8 ) + level - 6; dam = sc_dam( ch, dam ); damage( ch, (CHAR_DATA *) vo, dam, sn ); return; } void spell_cause_serious( int sn, int level, CHAR_DATA *ch, void *vo ) { int dam = dice( 2, 8 ) + level / 2; dam = sc_dam( ch, dam ); damage( ch, (CHAR_DATA *) vo, dam, sn ); return; } void spell_change_sex( 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 = 10 * level; af.location = APPLY_SEX; do { af.modifier = number_range( 0, 2 ) - victim->sex; } while ( af.modifier == 0 ); af.bitvector = 0; affect_to_char( victim, &af ); if ( ch != victim ) send_to_char(AT_WHITE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "You feel different.\n\r", victim ); return; } void spell_charm_person( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( victim == ch ) { send_to_char(AT_BLUE, "You like yourself even better!\n\r", ch ); return; } if ( !IS_NPC( victim ) ) return; if ( IS_AFFECTED( victim, AFF_CHARM ) || IS_AFFECTED( ch, AFF_CHARM ) || level < victim->level || saves_spell( level, victim ) ) return; if(IS_SIMM(victim, IMM_CHARM)) return; if ( victim->master ) stop_follower( victim ); add_follower( victim, ch ); af.type = sn; af.level = level; af.duration = number_fuzzy( level / 6 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char( victim, &af ); send_to_char(AT_BLUE, "Ok.\n\r", ch ); act(AT_BLUE, "Isn't $n just so nice?", ch, NULL, victim, TO_VICT ); return; } void spell_chill_touch( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; static const int dam_each [ ] = { 0, 0, 0, 6, 7, 8, 9, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, 39, 40, 40, 40, 41, 41, 42, 43 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level] / 2, dam_each[level] * 2 ); dam = sc_dam( ch, dam ); if ( !saves_spell( level, victim ) ) { af.type = sn; af.level = level; af.duration = 6; af.location = APPLY_STR; af.modifier = -1; af.bitvector = 0; affect_join( victim, &af ); } else { dam /= 2; } damage( ch, victim, dam, sn ); return; } void spell_colour_spray( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 35, 40, 45, 50, 55, 55, 55, 56, 57, 58, 58, 59, 60, 61, 61, 62, 63, 64, 64, 65, 66, 67, 67, 68, 69, 70, 70, 71, 72, 73, 73, 74, 75, 76, 76, 77, 78, 79, 79, 79, 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87, 88, 88, 90, 90, 91, 91, 92, 92, 93, 93, 94, 94, 95, 95, 96, 96, 97, 97, 98, 98, 99, 99, 100, 100,101,102,102,103, 104,105,106,107,120 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level] / 2, dam_each[level] * 2 ); dam = sc_dam( ch, dam ); if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_continual_light( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *light; light = create_object( get_obj_index( OBJ_VNUM_LIGHT_BALL ), 0 ); obj_to_room( light, ch->in_room ); act(AT_BLUE, "You twiddle your thumbs and $p appears.", ch, light, NULL, TO_CHAR ); act(AT_BLUE, "$n twiddles $s thumbs and $p appears.", ch, light, NULL, TO_ROOM ); return; } void spell_control_weather( int sn, int level, CHAR_DATA *ch, void *vo ) { if ( !str_cmp( target_name, "better" ) ) weather_info.change += dice( level / 3, 4 ); else if ( !str_cmp( target_name, "worse" ) ) weather_info.change -= dice( level / 3, 4 ); else send_to_char (AT_BLUE, "Do you want it to get better or worse?\n\r", ch ); send_to_char(AT_BLUE, "Ok.\n\r", ch ); return; } void spell_create_food( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *mushroom; mushroom = create_object( get_obj_index( OBJ_VNUM_MUSHROOM ), 0 ); mushroom->value[0] = 5 + level; obj_to_room( mushroom, ch->in_room ); act(AT_ORANGE, "$p suddenly appears.", ch, mushroom, NULL, TO_CHAR ); act(AT_ORANGE, "$p suddenly appears.", ch, mushroom, NULL, TO_ROOM ); return; } void spell_create_spring( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *spring; spring = create_object( get_obj_index( OBJ_VNUM_SPRING ), 0 ); spring->timer = level; obj_to_room( spring, ch->in_room ); act(AT_BLUE, "$p flows from the ground.", ch, spring, NULL, TO_CHAR ); act(AT_BLUE, "$p flows from the ground.", ch, spring, NULL, TO_ROOM ); return; } void spell_create_water( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj = (OBJ_DATA *) vo; int water; if ( obj->item_type != ITEM_DRINK_CON ) { send_to_char(AT_BLUE, "It is unable to hold water.\n\r", ch ); return; } if ( obj->value[2] != LIQ_WATER && obj->value[1] != 0 ) { send_to_char(AT_BLUE, "It contains some other liquid.\n\r", ch ); return; } water = UMIN( level * ( weather_info.sky >= SKY_RAINING ? 4 : 2 ), obj->value[0] - obj->value[1] ); if ( water > 0 ) { obj->value[2] = LIQ_WATER; obj->value[1] += water; if ( !is_name( NULL, "water", obj->name ) ) { char buf [ MAX_STRING_LENGTH ]; sprintf( buf, "%s water", obj->name ); free_string( obj->name ); obj->name = str_dup( buf ); } act(AT_BLUE, "$p is filled.", ch, obj, NULL, TO_CHAR ); } 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 ) ) return; affect_strip( victim, gsn_blindness ); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_WHITE, "Your vision returns!\n\r", victim ); return; } void spell_cure_critical( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int heal; heal = dice( 3, 8 ) + level - 6; victim->hit = UMIN( victim->hit + heal, MAX_HIT(victim)) ; update_pos( victim ); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "You feel better!\n\r", victim ); return; } void spell_cure_light( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int heal; heal = dice( 1, 8 ) + level / 3; victim->hit = UMIN( victim->hit + heal, MAX_HIT(victim)); update_pos( victim ); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "You feel better!\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(AT_GREEN, "Ok.\n\r", ch ); send_to_char(AT_GREEN, "A warm feeling runs through your body.\n\r", victim ); act(AT_GREEN, "$N looks better.", ch, NULL, victim, TO_NOTVICT ); return; } void spell_cure_serious( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int heal; heal = dice( 2, 8 ) + level / 2 ; victim->hit = UMIN( victim->hit + heal, MAX_HIT(victim)); update_pos( victim ); send_to_char(AT_BLUE, "You feel better!\n\r", victim ); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); return; } void spell_curse( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_CURSE ) || saves_spell( level, victim ) ) { send_to_char(AT_RED, "You have failed.\n\r", ch ); return; } af.type = sn; af.level = level; af.duration = 4 * level; af.location = APPLY_HITROLL; af.modifier = -1; af.bitvector = AFF_CURSE; affect_to_char( victim, &af ); af.location = APPLY_SAVING_SPELL; af.modifier = 1; affect_to_char( victim, &af ); if ( ch != victim ) send_to_char(AT_RED, "Ok.\n\r", ch ); send_to_char(AT_RED, "You feel unclean.\n\r", victim ); return; } void spell_detect_evil( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_DETECT_EVIL ) ) return; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_DETECT_EVIL; affect_to_char( victim, &af ); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "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; if ( IS_AFFECTED( victim, AFF_DETECT_HIDDEN ) ) return; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_DETECT_HIDDEN; affect_to_char( victim, &af ); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "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; if ( IS_AFFECTED( victim, AFF_DETECT_INVIS ) ) return; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_DETECT_INVIS; affect_to_char( victim, &af ); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "Your eyes tingle.\n\r", victim ); return; } void spell_truesight( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED2( victim, AFF_TRUESIGHT ) ) return; af.type = sn; af.level = level; af.duration = level / 8; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_TRUESIGHT; affect_to_char2( victim, &af ); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "Your eyes tingle.\n\r", victim ); return; } void spell_detect_magic( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_DETECT_MAGIC ) ) return; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_DETECT_MAGIC; affect_to_char( victim, &af ); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "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(AT_GREEN, "You smell poisonous fumes.\n\r", ch ); else send_to_char(AT_GREEN, "It looks very delicious.\n\r", ch ); } else { send_to_char(AT_GREEN, "It looks very delicious.\n\r", ch ); } return; } /* Dispel Magic recoded by Thelonius for EnvyMud look for the improved version below void spell_dispel_magic ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA *paf; if ( (victim == ch) || !IS_NPC( ch ) && ( !IS_NPC( victim ) || ( IS_AFFECTED( victim, AFF_CHARM ) && is_same_group( ch, victim->master ) ) ) ) { for ( paf = victim->affected; paf; paf = paf->next ) { if ( paf->deleted ) continue; affect_remove( victim, paf ); } } if ( victim == ch ) { act(AT_BLUE, "You have removed all magic effects from yourself.", ch, NULL, NULL, TO_CHAR ); act(AT_BLUE, "$n has removed all magic effects from $mself.", ch, NULL, NULL, TO_ROOM ); } else { act(AT_BLUE, "You have removed all magic effects from $N.", ch, NULL, victim, TO_CHAR ); act(AT_BLUE, "$n has removed all magic effects from you.", ch, NULL, victim, TO_VICT ); act(AT_BLUE, "$n has removed all magic effects from $N.", ch, NULL, victim, TO_NOTVICT ); } return; } else { for ( paf = victim->affected; paf; paf = paf->next ) { if ( paf->deleted ) continue; if ( !saves_spell( level, victim ) ) { send_to_char(AT_BLUE, skill_table[paf->type].msg_off, victim ); send_to_char(AT_BLUE, "\n\r", victim ); act(AT_BLUE, "$n is no longer affected by '$t'.", victim, skill_table[paf->type].name, NULL, TO_ROOM ); affect_strip( victim, paf->type ); break; } } if ( IS_AFFECTED( victim, AFF_SANCTUARY) && !saves_spell( level, victim ) ) { REMOVE_BIT( victim->affected_by, AFF_SANCTUARY ); send_to_char(AT_GREY, "The white aura around your body fades.\n\r", victim ); act(AT_GREY, "The white aura around $n's body fades.", victim, NULL, NULL, TO_ROOM ); } if ( IS_AFFECTED( victim, AFF_FIRESHIELD) && !saves_spell( level, victim ) ) { REMOVE_BIT( victim->affected_by, AFF_FIRESHIELD ); send_to_char(AT_RED, "The flames about your body have been doused.\n\r", victim ); act(AT_RED, "The flames about $n's body burn out.", victim, NULL, NULL, TO_ROOM ); } if ( IS_AFFECTED( victim, AFF_SHOCKSHIELD) && !saves_spell( level, victim ) ) { REMOVE_BIT( victim->affected_by, AFF_SHOCKSHIELD ); send_to_char(AT_BLUE, "The electricity about your body flee's into the ground..\n\r", victim ); act(AT_BLUE, "The electricity about $n's body flee's into the ground.", victim, NULL, NULL, TO_ROOM ); } if ( IS_AFFECTED( victim, AFF_ICESHIELD) && !saves_spell( level, victim ) ) { REMOVE_BIT( victim->affected_by, AFF_ICESHIELD ); send_to_char(AT_LBLUE, "The icy crust about your body melts to a puddle..\n\r", victim ); act(AT_LBLUE, "The icy crust about $n's body melts to a puddle.", victim, NULL, NULL, TO_ROOM ); } if ( !victim->fighting || !is_same_group( ch, victim->fighting ) ) multi_hit( victim, ch, TYPE_UNDEFINED ); } return; } */ void spell_dispel_evil( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; if ( !IS_NPC( ch ) && IS_EVIL( ch ) ) { send_to_char(AT_RED, "You are too EVIL to cast this.\n\r", ch ); return; } if ( IS_GOOD( victim ) ) { act(AT_BLUE, "God protects $N.", ch, NULL, victim, TO_ROOM ); return; } if ( IS_NEUTRAL( victim ) ) { act(AT_BLUE, "$N does not seem to be affected.", ch, NULL, victim, TO_CHAR ); return; } dam = dice( level, 4 ); dam = sc_dam( ch, dam ); if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_earthquake( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *vch; send_to_char(AT_ORANGE, "The earth trembles beneath your feet!\n\r", ch ); act(AT_ORANGE, "$n makes the earth tremble and shiver.", ch, NULL, NULL, TO_ROOM ); for ( vch = char_list; vch; vch = vch->next ) { if ( vch->deleted || !vch->in_room ) continue; if ( vch->in_room == ch->in_room ) { if ( vch != ch && ( IS_NPC( ch ) ? !IS_NPC( vch ) : IS_NPC( vch ) ) ) damage( ch, vch, level + dice( 2, 8 ), sn ); continue; } if ( vch->in_room->area == ch->in_room->area ) send_to_char(AT_ORANGE, "The earth trembles and shivers.\n\r", vch ); } return; } void spell_chain_lightning( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *vch; send_to_char(AT_BLUE, "Bolts of electricity arc from your hands!\n\r", ch ); act(AT_BLUE, "Electrical energy bursts from $n's hands.", ch, NULL, NULL, TO_ROOM ); for ( vch = char_list; vch; vch = vch->next ) { if ( vch->deleted || !vch->in_room ) continue; if ( vch->in_room == ch->in_room ) { if ( vch != ch && ( IS_NPC( ch ) ? !IS_NPC( vch ) : IS_NPC( vch ) ) ) damage( ch, vch, level + dice( level, 6 ), sn ); continue; } if ( vch->in_room->area == ch->in_room->area ) send_to_char(AT_BLUE, "The air fills with static.\n\r", vch ); } return; } /* RT version of chain void spell_chain_lightning(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *) vo; CHAR_DATA *tmp_vict,*last_vict,*next_vict; bool found; int dam; * first strike * act(AT_BLUE, "A lightning bolt leaps from $n's hand and arcs to $N.", ch,NULL,victim,TO_ROOM); act(AT_BLUE, "A lightning bolt leaps from your hand and arcs to $N.", ch,NULL,victim,TO_CHAR); act(AT_BLUE, "A lightning bolt leaps from $n's hand and hits you!", ch,NULL,victim,TO_VICT); dam = level + dice(level,6); if (saves_spell(level,victim)) dam /= 3; damage(ch,victim,dam,sn);*,DAM_LIGHTNING);* last_vict = victim; level -= 4; * decrement damage * * new targets * while (level > 0) { found = FALSE; for (tmp_vict = ch->in_room->people; tmp_vict != NULL; tmp_vict = next_vict) { if(tmp_vect->deleted) continue; next_vict = tmp_vict->next_in_room; if (*!is_safe_spell(ch,tmp_vict,TRUE) &&* tmp_vict != last_vict) { found = TRUE; last_vict = tmp_vict; act(AT_BLUE, "The bolt arcs to $n!",tmp_vict,NULL,NULL,TO_ROOM); act(AT_BLUE, "The bolt hits you!",tmp_vict,NULL,NULL,TO_CHAR); dam = level + dice(level,6); if (saves_spell(level,tmp_vict)) dam /= 3; damage(ch,tmp_vict,dam,sn);*,DAM_LIGHTNING);* level -= 4; * decrement damage * } } * end target searching loop * if (!found) * no target found, hit the caster * { if (ch == NULL) return; if (last_vict == ch) * no double hits * { act(AT_BLUE, "The bolt seems to have fizzled out.",ch,NULL,NULL,TO_ROOM); act(AT_BLUE, "The bolt grounds out through your body.", ch,NULL,NULL,TO_CHAR); return; } last_vict = ch; act(AT_BLUE, "The bolt arcs to $n...whoops!",ch,NULL,NULL,TO_ROOM); send_to_char(AT_BLUE, "You are struck by your own lightning!\n\r",ch); dam = level + dice(level,6); if (saves_spell(level,ch)) dam /= 3; damage(ch,ch,dam,sn);*,DAM_LIGHTNING);* level -= 4; * decrement damage * if (ch == NULL) return; } * now go back and find more targets * } } */ void spell_meteor_swarm( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *vch; AFFECT_DATA af; send_to_char(AT_RED, "Flaming meteors fly forth from your outstreched hands!\n\r", ch ); act(AT_RED, "Hundreds of flaming meteors fly forth from $n's hands.", ch, NULL, NULL, TO_ROOM ); for ( vch = char_list; vch; vch = vch->next ) { if ( vch->deleted || !vch->in_room ) continue; if ( vch->in_room == ch->in_room ) { if ( vch != ch && ( IS_NPC( ch ) ? !IS_NPC( vch ) : IS_NPC( vch ) ) ) damage( ch, vch, level + dice( level, 8 ), sn ); if ( vch != ch ) { af.type = sn; af.level = level; af.duration = level / 8; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_FLAMING; affect_join( vch, &af ); send_to_char(AT_RED, "You body bursts into flame!\n\r", vch); } continue; } } return; } void spell_enchant_weapon( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj = (OBJ_DATA *) vo; AFFECT_DATA *paf; if ( obj->item_type != ITEM_WEAPON || IS_OBJ_STAT( obj, ITEM_MAGIC ) || ( obj->affected && !IS_OBJ_STAT( obj, ITEM_DWARVEN ) ) ) { send_to_char(AT_BLUE, "That item cannot be enchanted.\n\r", ch ); return; } if ( !affect_free ) { paf = alloc_perm( sizeof( *paf ) ); } else { paf = affect_free; affect_free = affect_free->next; } paf->type = sn; paf->duration = -1; paf->location = APPLY_HITROLL; paf->modifier = 1 + (level >= 18) + (level >= 25) + (level >= 45) + (level >= 65) +(level >= 90); paf->bitvector = 0; paf->next = obj->affected; obj->affected = paf; if ( !affect_free ) { paf = alloc_perm( sizeof( *paf ) ); } else { paf = affect_free; affect_free = affect_free->next; } paf->type = sn; paf->duration = -1; paf->location = APPLY_DAMROLL; paf->modifier = 1 + (level >= 18) + (level >= 25) + (level >= 45) + (level >= 65) +(level >= 90);; paf->bitvector = 0; paf->next = obj->affected; obj->affected = paf; if ( IS_GOOD( ch ) ) { SET_BIT( obj->extra_flags, ITEM_ANTI_EVIL); act(AT_BLUE, "$p glows.", ch, obj, NULL, TO_CHAR ); } else if ( IS_EVIL( ch ) ) { SET_BIT( obj->extra_flags, ITEM_ANTI_GOOD ); act(AT_RED, "$p glows", ch, obj, NULL, TO_CHAR ); } else { SET_BIT( obj->extra_flags, ITEM_ANTI_EVIL ); SET_BIT( obj->extra_flags, ITEM_ANTI_GOOD ); act(AT_YELLOW, "$p glows.", ch, obj, NULL, TO_CHAR ); } send_to_char(AT_BLUE, "Ok.\n\r", ch ); return; } void spell_flame_blade( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj = (OBJ_DATA *) vo; if ( obj->item_type != ITEM_WEAPON || IS_OBJ_STAT( obj, ITEM_MAGIC ) || IS_OBJ_STAT( obj, ITEM_FLAME ) || ( obj->affected && !IS_OBJ_STAT( obj, ITEM_DWARVEN ) ) ) { send_to_char(AT_RED, "That item cannot be enchanted.\n\r", ch ); return; } SET_BIT( obj->extra_flags, ITEM_MAGIC); SET_BIT( obj->extra_flags, ITEM_FLAME ); send_to_char(AT_RED, "Ok.\n\r", ch ); return; } void spell_chaos_blade( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj = (OBJ_DATA *) vo; if ( obj->item_type != ITEM_WEAPON || IS_OBJ_STAT( obj, ITEM_MAGIC ) || IS_OBJ_STAT( obj, ITEM_CHAOS ) || ( obj->affected && !IS_OBJ_STAT( obj, ITEM_DWARVEN ) ) ) { send_to_char(AT_YELLOW, "That item cannot be enchanted.\n\r", ch ); return; } SET_BIT( obj->extra_flags, ITEM_MAGIC); SET_BIT( obj->extra_flags, ITEM_CHAOS ); send_to_char(AT_YELLOW, "Ok.\n\r", ch ); return; } void spell_frost_blade( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj = (OBJ_DATA *) vo; if ( obj->item_type != ITEM_WEAPON || IS_OBJ_STAT( obj, ITEM_MAGIC ) || IS_OBJ_STAT( obj, ITEM_ICY ) || ( obj->affected && !IS_OBJ_STAT( obj, ITEM_DWARVEN ) ) ) { send_to_char(AT_LBLUE, "That item cannot be enchanted.\n\r", ch ); return; } SET_BIT( obj->extra_flags, ITEM_MAGIC); SET_BIT( obj->extra_flags, ITEM_ICY ); send_to_char(AT_LBLUE, "Ok.\n\r", ch ); return; } void spell_holysword( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj = (OBJ_DATA *) vo; AFFECT_DATA *paf; if ( obj->item_type != ITEM_WEAPON || IS_OBJ_STAT( obj, ITEM_MAGIC ) || ( obj->affected && !IS_OBJ_STAT( obj, ITEM_DWARVEN ) ) ) { send_to_char(AT_BLUE, "That item cannot be consecrated.\n\r", ch ); return; } if ( !affect_free ) { paf = alloc_perm( sizeof( *paf ) ); } else { paf = affect_free; affect_free = affect_free->next; } paf->type = sn; paf->duration = -1; paf->location = APPLY_HITROLL; paf->modifier = 6 + (level >= 18) + (level >= 25) + (level >= 40) + (level >= 60) +(level >= 90); paf->bitvector = 0; paf->next = obj->affected; obj->affected = paf; if ( !affect_free ) { paf = alloc_perm( sizeof( *paf )); } else { paf = affect_free; affect_free = affect_free->next; } paf->type = sn; paf->duration = -1; paf->location = APPLY_DAMROLL; paf->modifier = 6 + (level >= 18) + (level >= 25) + (level >= 45) + (level >= 65) +(level >= 90);; paf->bitvector = 0; paf->next = obj->affected; obj->affected = paf; if ( IS_GOOD( ch ) ) { SET_BIT( obj->extra_flags, ITEM_ANTI_EVIL); act(AT_BLUE, "$p glows.", ch, obj, NULL, TO_CHAR ); } else if ( IS_EVIL( ch ) ) { SET_BIT( obj->extra_flags, ITEM_ANTI_GOOD ); act(AT_RED, "$p glows", ch, obj, NULL, TO_CHAR ); } else { SET_BIT( obj->extra_flags, ITEM_ANTI_EVIL ); SET_BIT( obj->extra_flags, ITEM_ANTI_GOOD ); act(AT_YELLOW, "$p glows.", ch, obj, NULL, TO_CHAR ); } SET_BIT( obj->anti_class_flags, ITEM_ANTI_WARRIOR ); SET_BIT( obj->anti_class_flags, ITEM_ANTI_MAGE ); SET_BIT( obj->anti_class_flags, ITEM_ANTI_BARD ); SET_BIT( obj->anti_class_flags, ITEM_ANTI_RANGER ); SET_BIT( obj->anti_class_flags, ITEM_ANTI_VAMP ); SET_BIT( obj->anti_class_flags, ITEM_ANTI_DRUID ); SET_BIT( obj->anti_class_flags, ITEM_ANTI_PSI ); SET_BIT( obj->anti_class_flags, ITEM_ANTI_THIEF ); SET_BIT( obj->anti_class_flags, ITEM_ANTI_NECRO ); SET_BIT( obj->anti_class_flags, ITEM_ANTI_WWF ); SET_BIT( obj->anti_class_flags, ITEM_ANTI_MONK ); send_to_char(AT_BLUE, "Ok.\n\r", ch ); return; } /* * Drain XP, MANA, HP. * Caster gains HP. */ void spell_energy_drain( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; if ( saves_spell( level, victim ) ) return; /* ch->alignment = UMAX(-1000, ch->alignment - 200); */ if ( victim->level <= 2 ) { dam = ch->hit + 1; } else { victim->mana /= 2; victim->move /= 2; dam = dice( 4, level ); if ( ( ch->hit + dam ) > ( MAX_HIT(ch) + 200 ) ) ch->hit = ( MAX_HIT(ch) + 200 ); else ch->hit += dam; } dam = sc_dam( ch, dam ); damage( ch, victim, dam, sn ); return; } void spell_psychic_quake( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *vch; send_to_char(AT_YELLOW, "You let the chaos free from your mind!\n\r", ch ); act(AT_YELLOW, "$n's face becomes blank and concentrated.", ch, NULL, NULL, TO_ROOM ); for ( vch = char_list; vch; vch = vch->next ) { if ( vch->deleted || !vch->in_room ) continue; if ( vch->in_room == ch->in_room ) { if ( vch != ch && ( IS_NPC( ch ) ? !IS_NPC( vch ) : IS_NPC( vch ) ) ) if (vch != ch ) spell_energy_drain(sn, level/2, ch, vch); continue; } if ( vch->in_room->area == ch->in_room->area ) send_to_char(AT_BLUE, "A wave of chaos brushes your mind.\n\r", vch ); } return; } void spell_farsight( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim; ROOM_INDEX_DATA *blah; if ( !( victim = get_char_world( ch, target_name ) ) || IS_SET( victim->in_room->room_flags, ROOM_SAFE ) || IS_SET( victim->in_room->room_flags, ROOM_PRIVATE ) || IS_SET( victim->in_room->room_flags, ROOM_SOLITARY ) || IS_SET( victim->in_room->room_flags, ROOM_NO_ASTRAL_IN ) || IS_SET( ch->in_room->room_flags, ROOM_NO_ASTRAL_OUT ) ) { send_to_char(AT_BLUE, "You failed.\n\r", ch ); return; } blah = ch->in_room; if ( ch != victim ) { char_from_room( ch ); char_to_room( ch, victim->in_room ); } do_look( ch, "auto" ); if (ch != victim ) { char_from_room( ch ); char_to_room( ch, blah ); } return; } void spell_fireball( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 215, 220, 225, 230, 235, 240, 245, 250, 255, 260 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level] / 2, dam_each[level] * 7 ); dam = sc_dam( ch, dam ); if ( IS_AFFECTED( victim, AFF_FIRESHIELD ) ) dam /= 6; if ( IS_AFFECTED( victim, AFF_ICESHIELD ) ) dam += dam/2; if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_molecular_unbind( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; OBJ_DATA *obj_lose; OBJ_DATA *obj_next; if(saves_spell ( level, victim )) { send_to_char(AT_BLUE, "You failed.\n\r", ch ); return; } for ( obj_lose = victim->carrying; obj_lose; obj_lose = obj_next ) { char *msg; obj_next = obj_lose->next_content; if ( obj_lose->deleted ) continue; if ( obj_lose->wear_loc == WEAR_NONE ) continue; if ( IS_SET( obj_lose->extra_flags, ITEM_NO_DAMAGE ) ) continue; switch ( obj_lose->item_type ) { default: msg = "Your $p gets ruined!"; extract_obj( obj_lose ); break; case ITEM_DRINK_CON: case ITEM_POTION: case ITEM_CONTAINER: case ITEM_LIGHT: msg = "Your $p shatters!"; extract_obj( obj_lose ); break; case ITEM_WEAPON: case ITEM_ARMOR: { OBJ_DATA *pObj; OBJ_INDEX_DATA *pObjIndex; char *name; char buf[MAX_STRING_LENGTH]; pObjIndex = get_obj_index(4); pObj = create_object(pObjIndex, obj_lose->level); name = obj_lose->short_descr; sprintf(buf, pObj->description, name); free_string(pObj->description); pObj->description = str_dup(buf); pObj->weight = obj_lose->weight; pObj->timer = obj_lose->level; msg = "$p has been destroyed!"; extract_obj( obj_lose ); obj_to_room ( pObj, victim->in_room ); break; act(AT_YELLOW, msg, victim, obj_lose, NULL, TO_CHAR ); } } } return; } void spell_shatter( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; OBJ_DATA *obj_lose; OBJ_DATA *obj_next; if(saves_spell ( level, victim )) { send_to_char(AT_BLUE, "You failed.\n\r", ch ); return; } for ( obj_lose = victim->carrying; obj_lose; obj_lose = obj_next ) { char *msg; obj_next = obj_lose->next_content; if ( obj_lose->deleted ) continue; if ( obj_lose->wear_loc == WEAR_NONE ) continue; if ( IS_SET( obj_lose->extra_flags, ITEM_NO_DAMAGE ) ) continue; switch ( obj_lose->item_type ) { default: msg = "Your $p gets ruined!"; extract_obj( obj_lose ); break; case ITEM_DRINK_CON: case ITEM_POTION: case ITEM_CONTAINER: case ITEM_LIGHT: msg = "Your $p shatters!"; extract_obj( obj_lose ); break; case ITEM_WEAPON: case ITEM_ARMOR: { OBJ_DATA *pObj; OBJ_INDEX_DATA *pObjIndex; char *name; char buf[MAX_STRING_LENGTH]; pObjIndex = get_obj_index(4); pObj = create_object(pObjIndex, obj_lose->level); name = obj_lose->short_descr; sprintf(buf, pObj->description, name); free_string(pObj->description); pObj->description = str_dup(buf); pObj->weight = obj_lose->weight; pObj->timer = obj_lose->level; msg = "$p has been destroyed!"; extract_obj( obj_lose ); obj_to_room ( pObj, victim->in_room ); break; act(AT_YELLOW, msg, victim, obj_lose, NULL, TO_CHAR ); } } } return; } void spell_fireshield( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_FIRESHIELD ) ) return; af.type = sn; af.level = level; af.duration = number_fuzzy( level / 8 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_FIRESHIELD; affect_to_char( victim, &af ); send_to_char(AT_RED, "Your body is engulfed by unfelt flame.\n\r", victim ); act(AT_RED, "$n's body is engulfed in flames.", victim, NULL, NULL, TO_ROOM ); return; } void spell_flamestrike( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; dam = dice( 6, level/2 ); dam = sc_dam( ch, dam ); if ( IS_AFFECTED( victim, AFF_FIRESHIELD ) ) dam /= 2; if ( IS_AFFECTED( victim, AFF_ICESHIELD ) ) dam += dam/4; if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_faerie_fire( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_FAERIE_FIRE ) ) return; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_AC; af.modifier = 2 * level; af.bitvector = AFF_FAERIE_FIRE; affect_to_char( victim, &af ); af.location = APPLY_HITROLL; af.modifier = 0 - level/10; affect_to_char( victim, &af ); send_to_char(AT_PINK, "You are surrounded by a pink outline.\n\r", victim ); act(AT_PINK, "$n is surrounded by a pink outline.", victim, NULL, NULL, TO_ROOM ); return; } void spell_faerie_fog( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *ich; send_to_char(AT_PURPLE, "You conjure a cloud of purple smoke.\n\r", ch ); act(AT_PURPLE, "$n conjures a cloud of purple smoke.", ch, NULL, NULL, TO_ROOM ); for ( ich = ch->in_room->people; ich; ich = ich->next_in_room ) { if ( !IS_NPC( ich ) && IS_SET( ich->act, PLR_WIZINVIS ) ) continue; if ( ich == ch || saves_spell( level, ich ) ) continue; affect_strip ( ich, gsn_invis ); affect_strip ( ich, gsn_mass_invis ); affect_strip ( ich, gsn_sneak ); affect_strip ( ich, gsn_shadow ); affect_strip ( ich, skill_lookup("phase shift") ); affect_strip ( ich, skill_lookup("mist form") ); affect_strip ( ich, gsn_hide ); affect_strip ( ich, gsn_chameleon ); REMOVE_BIT ( ich->affected_by, AFF_HIDE ); REMOVE_BIT ( ich->affected_by, AFF_INVISIBLE ); REMOVE_BIT ( ich->affected_by, AFF_SNEAK ); REMOVE_BIT ( ich->affected_by2, AFF_PHASED ); act(AT_PURPLE, "$n is revealed!", ich, NULL, NULL, TO_ROOM ); send_to_char(AT_PURPLE, "You are revealed!\n\r", ich ); } return; } void spell_fly( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_FLYING ) ) return; af.type = sn; af.level = level; af.duration = level + 3; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_FLYING; affect_to_char( victim, &af ); send_to_char(AT_BLUE, "Your feet rise off the ground.\n\r", victim ); act(AT_BLUE, "$n's feet rise off the ground.", victim, NULL, NULL, TO_ROOM ); return; } void spell_gate( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *gch; int npccount = 0; int pccount = 0; for ( gch = ch->in_room->people; gch; gch = gch->next_in_room ) { if ( IS_NPC( gch ) && !IS_AFFECTED( gch, AFF_CHARM ) ) npccount++; if ( !IS_NPC( gch ) || ( IS_NPC( gch ) && IS_AFFECTED( gch, AFF_CHARM ) ) ) pccount++; } if ( npccount > pccount ) { do_say( ch, "There are too many of us here! One must die!" ); return; } do_say( ch, "Come brothers! Join me in this glorious bloodbath!" ); char_to_room( create_mobile( get_mob_index( MOB_VNUM_DEMON1 ) ), ch->in_room ); return; } /* * Spell for mega1.are from Glop/Erkenbrand. */ void spell_general_purpose( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; dam = number_range( 25, 100 ); dam = sc_dam( ch, dam ); if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_giant_strength( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn ) ) return; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_STR; af.modifier = 1 + (level >= 18) + (level >= 25); af.bitvector = 0; affect_to_char( victim, &af ); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "You feel stronger.\n\r", victim ); return; } void spell_eternal_intellect( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn ) ) return; af.type = sn; af.level = level; af.duration = level/2; af.location = APPLY_INT; af.modifier = 1 + (level >= 18) + (level >= 25); af.bitvector = 0; affect_to_char( victim, &af ); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "You feel an unsurpased intelligence.\n\r", victim ); return; } void spell_golden_aura( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *)vo; AFFECT_DATA af; if ( IS_AFFECTED2( victim, AFF_GOLDEN ) ) return; if ( !IS_NPC( ch ) && !can_use_skpell( ch, sn ) ) { send_to_char(AT_BLUE, "Nothing happens.\n\r", ch ); return; } af.type = sn; af.level = level; af.duration = number_fuzzy( level / 8 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_GOLDEN; affect_to_char2( victim, &af ); send_to_char( AT_YELLOW, "You are surrounded by a golden aura.\n\r", victim ); act(AT_YELLOW, "$n is surrounded by a golden aura.", victim, NULL, NULL, TO_ROOM ); return; } void spell_goodberry( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj = (OBJ_DATA *) vo; OBJ_DATA *berry; if ( obj->item_type != ITEM_FOOD || IS_OBJ_STAT( obj, ITEM_MAGIC ) ) { send_to_char(AT_BLUE, "You can do nothing to that item.\n\r", ch ); return; } act(AT_BLUE, "You pass your hand over $p slowly.", ch, obj, NULL, TO_CHAR ); act(AT_BLUE, "$n has created a goodberry.", ch, NULL, NULL, TO_ROOM ); berry = create_object( get_obj_index( OBJ_VNUM_BERRY ), 0 ); berry->timer = ch->level; berry->value[0] = ch->level * 3; berry->value[1] = ch->level * 8; extract_obj( obj ); obj_to_char( berry, ch ); return; } void spell_harm( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; dam = UMAX( 20, victim->hit - dice( 1,4 ) ); dam = sc_dam( ch, dam ); if ( saves_spell( level, victim ) ) dam = UMIN( 50, dam / 4 ); dam = UMIN( 175, dam ); damage( ch, victim, dam, sn ); return; } void spell_heal( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; victim->hit = UMIN( (victim->hit + (ch->level*5)), MAX_HIT(victim) ); update_pos( victim ); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "A warm feeling fills your body.\n\r", victim ); return; } /* * Spell for mega1.are from Glop/Erkenbrand. */ void spell_high_explosive( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; dam = number_range( 30, 120 ); dam = sc_dam( ch, dam ); if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_iceshield( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_ICESHIELD ) ) return; af.type = sn; af.level = level; af.duration = number_fuzzy( level / 3 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_ICESHIELD; affect_to_char( victim, &af ); send_to_char(AT_LBLUE, "An Icy crust forms about your body.\n\r", victim ); act(AT_LBLUE, "An icy crust forms about $n's body.", victim, NULL, NULL, TO_ROOM ); return; } void spell_icestorm( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; dam = dice( level, 10 ); dam = sc_dam( ch, dam ); if ( IS_AFFECTED( victim, AFF_ICESHIELD ) ) dam /= 2; if ( IS_AFFECTED( victim, AFF_FIRESHIELD ) ) dam += dam/4; if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_holy_fires( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; dam = dice( level, 10 ); dam = sc_dam( ch, dam ); if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_identify( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj = (OBJ_DATA *) vo; AFFECT_DATA *paf; char buf [ MAX_STRING_LENGTH ]; int spn; sprintf( buf, "Object '%s' is type %s, extra flags %s %s %s.\n\r", obj->name, item_type_name( obj ), obj->extra_flags ? extra_bit_name( obj->extra_flags ) : "", obj->anti_race_flags ? antirace_bit_name(obj->anti_race_flags) : "", obj->anti_class_flags ? anticlass_bit_name(obj->anti_class_flags) : ""); send_to_char(AT_CYAN, buf, ch ); #ifdef NEW_MONEY sprintf( buf, "Weight : %d, level : %d.\n\r", obj->weight, obj->level ); send_to_char( AT_CYAN, buf, ch ); sprintf( buf, "Gold Value: %d Silver Value: %d Copper Value: %d\n\r", obj->cost.gold, obj->cost.silver, obj->cost.copper ); #else sprintf( buf, "Weight : %d, value : %d, level : %d.\n\r", obj->weight, obj->cost, obj->level ); #endif send_to_char(AT_CYAN, buf, ch ); switch ( obj->item_type ) { case ITEM_PILL: case ITEM_SCROLL: case ITEM_POTION: sprintf( buf, "Level %d spells of:", obj->value[0] ); send_to_char(AT_CYAN, buf, ch ); if ( is_sn(obj->value[1]) ) { send_to_char(AT_CYAN, " '", ch ); send_to_char(AT_WHITE, skill_table[obj->value[1]].name, ch ); send_to_char(AT_CYAN, "'", ch ); } if ( is_sn(obj->value[2]) ) { send_to_char(AT_CYAN, " '", ch ); send_to_char(AT_WHITE, skill_table[obj->value[2]].name, ch ); send_to_char(AT_CYAN, "'", ch ); } if ( is_sn(obj->value[3]) ) { send_to_char(AT_CYAN, " '", ch ); send_to_char(AT_WHITE, skill_table[obj->value[3]].name, ch ); send_to_char(AT_CYAN, "'", ch ); } send_to_char(AT_CYAN, ".\n\r", ch ); break; case ITEM_WAND: case ITEM_LENSE: case ITEM_STAFF: if (!(obj->value[1] == -1 ) ) sprintf( buf, "Has %d(%d) charges of level %d", obj->value[1], obj->value[2], obj->value[0] ); else sprintf( buf, "Has unlimited charges of level %d", obj->value[0] ); send_to_char(AT_CYAN, buf, ch ); if ( is_sn(obj->value[3]) ) { send_to_char(AT_CYAN, " '", ch ); send_to_char(AT_WHITE, skill_table[obj->value[3]].name, ch ); send_to_char(AT_CYAN, "'", ch ); } send_to_char(AT_CYAN, ".\n\r", ch ); break; case ITEM_WEAPON: sprintf( buf, "Damage is %d to %d (average %d).\n\r", obj->value[1], obj->value[2], ( obj->value[1] + obj->value[2] ) / 2 ); send_to_char(AT_RED, buf, ch ); break; case ITEM_ARMOR: sprintf( buf, "Armor class is %d.\n\r", obj->value[0] ); send_to_char(AT_CYAN, buf, ch ); break; } if ( obj->ac_type != 0 ) { switch( obj->ac_type ) { default: send_to_char(AT_CYAN, "Invoke Type Unknown.\n\r", ch ); break; case 1 : { if ( obj->ac_charge[1] != -1 ) sprintf( buf, "Object creation invoke , with [%d/%d] charges.\n\r", obj->ac_charge[0], obj->ac_charge[1] ); else sprintf( buf, "Object creation invoke, with unlimited charges.\n\r" ); send_to_char(AT_CYAN, buf, ch ); break; } case 2 : { if ( obj->ac_charge[1] != -1 ) sprintf( buf, "Monster creation invoke, with [%d/%d] charges.\n\r", obj->ac_charge[0], obj->ac_charge[1] ); else sprintf( buf, "Monster creation invoke, with unlimited charges.\n\r" ); send_to_char(AT_CYAN, buf, ch ); break; } case 3 : { if ( obj->ac_charge[1] != -1 ) sprintf( buf, "Transfer invoke, with [%d/%d] charges.\n\r", obj->ac_charge[0], obj->ac_charge[1] ); else sprintf( buf, "Transfer invoke, with unlimited charges.\n\r" ); send_to_char(AT_CYAN, buf, ch ); break; } case 4 : { if ( obj->ac_charge[1] != -1 ) sprintf( buf, "Object morph invoke, with [%d/%d] charges.\n\r", obj->ac_charge[0], obj->ac_charge[1] ); else sprintf( buf, "Object morph invoke, with unlimited charges.\n\r" ); send_to_char(AT_CYAN, buf, ch ); break; } case 5 : { if ( obj->ac_charge[1] != -1 ) sprintf( buf, "Spell invoke, has [%d/%d] charges of ", obj->ac_charge[0], obj->ac_charge[1] ); else sprintf( buf, "Spell invoke, with unlimited charges of " ); send_to_char(AT_CYAN, buf, ch ); spn = skill_lookup( obj->ac_spell ); if ( is_sn(spn) ) { send_to_char(AT_CYAN, " '", ch ); send_to_char(AT_WHITE, spn ? obj->ac_spell : "(none)", ch ); send_to_char(AT_CYAN, "'\n\r", ch ); } break; } } } for ( paf = obj->pIndexData->affected; paf; paf = paf->next ) { if ( paf->location != APPLY_NONE && paf->modifier != 0 ) { sprintf( buf, "Affects %s by %d.\n\r", affect_loc_name( paf->location ), paf->modifier ); send_to_char(AT_BLUE, buf, ch ); } } for ( paf = obj->affected; paf; paf = paf->next ) { if ( paf->location != APPLY_NONE && paf->modifier != 0 ) { sprintf( buf, "Affects %s by %d.\n\r", affect_loc_name( paf->location ), paf->modifier ); send_to_char(AT_BLUE, buf, ch ); } } return; } void spell_vibrate( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_VIBRATING ) ) return; af.type = sn; af.level = level; af.duration = number_fuzzy( level / 8 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_VIBRATING; affect_to_char( victim, &af ); send_to_char(AT_LBLUE, "You set up a complex set of vibrations around your body.\n\r", victim ); act(AT_LBLUE, "$n's body begins to vibrate.", victim, NULL, NULL, TO_ROOM ); return; } void spell_infravision( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_INFRARED ) ) return; af.type = sn; af.level = level; af.duration = 2 * level; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_INFRARED; affect_to_char( victim, &af ); send_to_char(AT_RED, "Your eyes glow.\n\r", victim ); act(AT_RED, "$n's eyes glow.\n\r", ch, NULL, NULL, TO_ROOM ); return; } void spell_incinerate( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( saves_spell( level, victim ) ) return; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_FLAMING; affect_join( victim, &af ); if ( ch != victim ) send_to_char(AT_RED, "Ok.\n\r", ch ); send_to_char(AT_RED, "Your body bursts into flames!\n\r", victim ); return; } void spell_invis( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_INVISIBLE ) ) return; af.type = sn; af.level = level; af.duration = 24; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_INVISIBLE; affect_to_char( victim, &af ); send_to_char(AT_GREY, "You fade out of existence.\n\r", victim ); act(AT_GREY, "$n fades out of existence.", 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; if ( IS_AFFECTED2( victim, AFF_PHASED ) ) return; af.type = sn; af.level = level; af.duration = ch->level/6; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_PHASED; affect_to_char2( victim, &af ); send_to_char(AT_GREY, "You phase into another plane.\n\r", victim ); act(AT_GREY, "$n phases out of reality.", victim, NULL, NULL, TO_ROOM ); return; } void spell_mist_form( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED2( victim, AFF_PHASED ) ) return; af.type = sn; af.level = level; af.duration = ch->level/6; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_PHASED; affect_to_char2( victim, &af ); send_to_char(AT_GREY, "You seem to feel transparent.\n\r", victim ); act(AT_GREY, "$n takes on the form of a mist.", victim, NULL, NULL, TO_ROOM ); return; } void spell_know_alignment( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; char *msg; int ap; ap = victim->alignment; if ( ap > 700 ) msg = "$N has an aura as white as the driven snow."; else if ( ap > 350 ) msg = "$N is of excellent moral character."; else if ( ap > 100 ) msg = "$N is often kind and thoughtful."; else if ( ap > -100 ) msg = "$N doesn't have a firm moral commitment."; else if ( ap > -350 ) msg = "$N lies to $S friends."; else if ( ap > -700 ) msg = "$N's slash DISEMBOWELS you!"; else msg = "I'd rather just not say anything at all about $N."; act(AT_BLUE, msg, ch, NULL, victim, TO_CHAR ); return; } void spell_lightning_bolt( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 28, 31, 34, 37, 40, 40, 41, 42, 42, 43, 44, 44, 45, 46, 46, 47, 48, 48, 49, 50, 50, 51, 52, 52, 53, 54, 54, 55, 56, 56, 57, 58, 58, 59, 60, 60, 61, 62, 62, 63, 64, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100,102,104,106,108, 110,112,114,116,118, 120,122,124,126,128, 130,132,134,136,138, 140,142,144,146,148, 150,152,154,156,158, 160,162,164,166,170 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level] / 2, dam_each[level] * 2 ); dam = sc_dam( ch, dam ); if ( saves_spell( level, victim ) ) dam /= 2; if ( IS_AFFECTED( victim, AFF_SHOCKSHIELD ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_locate_object( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj; OBJ_DATA *in_obj; char buf [ MAX_INPUT_LENGTH ]; bool found; found = FALSE; for ( obj = object_list; obj; obj = obj->next ) { if ( !can_see_obj( ch, obj ) || !is_name( ch, target_name, obj->name ) ) continue; if ( IS_SET( obj->extra_flags, ITEM_NO_LOCATE) && ( get_trust( ch ) < L_APP ) ) continue; found = TRUE; for ( in_obj = obj; in_obj->in_obj; in_obj = in_obj->in_obj ) ; if ( in_obj->carried_by ) { sprintf( buf, "%s carried by %s.\n\r", obj->short_descr, PERS( in_obj->carried_by, ch ) ); } else if ( in_obj->stored_by ) { sprintf( buf, "%s in storage.\n\r", obj->short_descr ); } else { sprintf( buf, "%s in %s.\n\r", obj->short_descr, !in_obj->in_room ? "somewhere" : in_obj->in_room->name ); } buf[0] = UPPER( buf[0] ); send_to_char(AT_BLUE, buf, ch ); } if ( !found ) send_to_char(AT_WHITE, "Nothing like that in hell, earth, or heaven.\n\r", ch ); return; } void spell_magic_missile( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 3, 3, 4, 4, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 18, 18, 18, 18, 18, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 24, 24, 24, 24, 24, 26, 26, 26, 26, 26, 28, 28, 28, 28, 28, 30, 31, 32, 33, 40 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level] / 2, dam_each[level] * 2 ); dam = sc_dam( ch, dam ); if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_mana( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; victim->mana = UMIN( victim->mana + 70, MAX_MANA(victim) ); update_pos( victim ); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "You feel a surge of energy.\n\r", victim ); 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 ) || IS_AFFECTED( gch, AFF_INVISIBLE ) ) continue; send_to_char(AT_GREY, "You slowly fade out of existence.\n\r", gch ); act(AT_GREY, "$n slowly fades out of existence.", gch, NULL, NULL, TO_ROOM ); af.type = sn; af.level = level; af.duration = 24; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_INVISIBLE; affect_to_char( gch, &af ); } send_to_char(AT_BLUE, "Ok.\n\r", ch ); return; } void spell_null( int sn, int level, CHAR_DATA *ch, void *vo ) { send_to_char(AT_WHITE, "That's not a spell!\n\r", ch ); return; } void spell_pass_door( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED(victim, AFF_PASS_DOOR) ) return; af.type = sn; af.level = level; af.duration = number_fuzzy( level / 4 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_PASS_DOOR; affect_to_char( victim, &af ); send_to_char(AT_GREY, "You turn translucent.\n\r", victim ); act(AT_GREY, "$n turns translucent.", victim, NULL, NULL, TO_ROOM ); return; } void spell_permenancy( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj = (OBJ_DATA *) vo; /* AFFECT_DATA *paf;*/ if ( obj->item_type != ITEM_WAND && obj->item_type != ITEM_STAFF && obj->item_type != ITEM_LENSE ) { send_to_char(AT_BLUE, "You cannot make that item permenant.\n\r", ch ); return; } obj->value[2] = -1; obj->value[1] = -1; act(AT_BLUE, "You run your finger up $p, you can feel it's power growing.", ch, obj, NULL, TO_CHAR ); act(AT_BLUE, "$n slowly runs $s finger up $p.", ch, obj, NULL, TO_ROOM ); return; } void spell_poison( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( saves_spell( level, victim ) || victim->race == RACE_GHOUL ) return; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_STR; af.modifier = -2; af.bitvector = AFF_POISON; affect_join( victim, &af ); if ( ch != victim ) send_to_char(AT_GREEN, "Ok.\n\r", ch ); send_to_char(AT_GREEN, "You feel very sick.\n\r", victim ); return; } void spell_polymorph( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; char buf [MAX_STRING_LENGTH]; AFFECT_DATA af; if ( !(victim = get_char_world( ch, target_name ) ) || victim == ch || saves_spell( level, victim) || IS_AFFECTED( ch, AFF_POLYMORPH ) ) { send_to_char( AT_BLUE, "You failed.\n\r", ch ); return; } af.type = sn; af.level = level; af.duration = level/5; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_POLYMORPH; affect_to_char2( ch, &af ); if (!IS_NPC(victim)) { sprintf( buf, "%s %s", victim->name, victim->pcdata->title); free_string( ch->long_descr ); ch->long_descr = str_dup(buf); } else { sprintf( buf, "%s", victim->long_descr ); free_string( ch->long_descr ); ch->long_descr = str_dup(buf); } act(AT_BLUE, "$n's form wavers and then resolidifies.", ch, NULL, NULL, TO_ROOM); send_to_char(AT_BLUE, "You have succesfully polymorphed.\n\r", ch ); return; } void spell_portal( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; OBJ_DATA *gate1; OBJ_DATA *gate2; int duration; if ( !( victim = get_char_world( ch, target_name ) ) || victim == ch || !victim->in_room || IS_SET( victim->in_room->room_flags, ROOM_SAFE ) || IS_SET( victim->in_room->room_flags, ROOM_PRIVATE ) || IS_SET( victim->in_room->room_flags, ROOM_SOLITARY ) || IS_SET( victim->in_room->room_flags, ROOM_NO_ASTRAL_IN ) || IS_SET( ch->in_room->room_flags, ROOM_NO_ASTRAL_OUT ) || IS_ARENA(ch) || victim->in_room->area == arena.area || IS_SET( victim->in_room->area->area_flags, AREA_PROTOTYPE ) ) { send_to_char(AT_BLUE, "You failed.\n\r", ch ); return; } duration = level/10; gate1 = create_object( get_obj_index( OBJ_VNUM_PORTAL ), 0 ); gate2 = create_object( get_obj_index( OBJ_VNUM_PORTAL ), 0 ); gate1->timer = duration; gate2->timer = duration; gate2->value[0] = ch->in_room->vnum; gate1->value[0] = victim->in_room->vnum; act(AT_BLUE, "A huge shimmering gate rises from the ground.", ch, NULL, NULL, TO_CHAR ); act(AT_BLUE, "$n utters a few incantations and a gate rises from the ground.", ch, NULL, NULL, TO_ROOM ); obj_to_room( gate1, ch->in_room ); act(AT_BLUE, "A huge shimmering gate rises from the ground.", victim, NULL, NULL, TO_CHAR ); act(AT_BLUE, "A huge shimmering gate rises from the ground.", victim, NULL, NULL, TO_ROOM ); obj_to_room( gate2, victim->in_room ); return; } void spell_protection( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_PROTECT ) ) return; af.type = sn; af.level = level; af.duration = 24; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_PROTECT; affect_to_char( victim, &af ); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "You feel protected.\n\r", victim ); return; } void spell_refresh( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; victim->move = UMIN( victim->move + level + 50, MAX_MOVE(victim)); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "You feel less tired.\n\r", victim ); return; } /* Expulsion of ITEM_NOREMOVE addition by Katrina */ void spell_remove_curse( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj; CHAR_DATA *victim = (CHAR_DATA *) vo; int iWear, SkNum; int yesno = FALSE; for ( iWear = 0; iWear < MAX_WEAR; iWear ++ ) { if ( !( obj = get_eq_char( victim, iWear ) ) ) continue; if ( IS_SET( obj->extra_flags, ITEM_NODROP ) ) { REMOVE_BIT( obj->extra_flags, ITEM_NODROP ); send_to_char( AT_BLUE, "You feel a burden relieved.\n\r", ch ); yesno = TRUE; } if ( IS_SET( obj->extra_flags, ITEM_NOREMOVE ) ) { unequip_char( victim, obj ); obj_from_char( obj ); obj_to_room( obj, victim->in_room ); act(AT_BLUE, "You toss $p to the ground.", victim, obj, NULL, TO_CHAR ); act(AT_BLUE, "$n tosses $p to the ground.", victim, obj, NULL, TO_ROOM ); yesno = TRUE; } } SkNum=skill_lookup("incinerate"); if ( is_affected( victim, SkNum)) { affect_strip( victim, SkNum); send_to_char(AT_BLUE, "Your body has been extinguished.\n\r", ch); yesno = TRUE; } SkNum=skill_lookup("curse"); if ( is_affected( victim, SkNum)) { affect_strip( victim, SkNum); send_to_char(AT_BLUE, "You feel better.\n\r", victim ); yesno = TRUE; } if ( ch != victim && yesno ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); return; } void spell_sanctuary( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_SANCTUARY ) ) return; af.type = sn; af.level = level; af.duration = number_fuzzy( level / 8 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_SANCTUARY; affect_to_char( victim, &af ); send_to_char(AT_WHITE, "You are surrounded by a white aura.\n\r", victim ); act(AT_WHITE, "$n is surrounded by a white aura.", victim, NULL, NULL, TO_ROOM ); return; } void spell_web( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; char buf[MAX_STRING_LENGTH]; if ( IS_AFFECTED( victim, AFF_ANTI_FLEE ) ) return; af.type = sn; af.level = level; af.duration = number_fuzzy( level / 10 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_ANTI_FLEE; affect_to_char( victim, &af ); sprintf( buf, "%s lifts his hands and webs entanle you!\n\r", ch->name ); send_to_char(AT_WHITE, buf, victim ); act(AT_WHITE, "$n has been imobilized by a plethora of sticky webs.", victim, NULL, NULL, TO_ROOM ); return; } void spell_confusion( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; char buf[MAX_STRING_LENGTH]; if ( IS_AFFECTED2( victim, AFF_CONFUSED ) ) return; if ( saves_spell( level, victim ) ) { send_to_char( AT_BLUE, "You failed.\n\r", ch ); return; } af.type = sn; af.level = level; af.duration = number_fuzzy( level / 10 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_CONFUSED; affect_to_char2( victim, &af ); sprintf( buf, "You feel disorientated.\n\r" ); send_to_char(AT_WHITE, buf, victim ); act(AT_WHITE, "$n stares around blankly.", victim, NULL, NULL, TO_ROOM ); return; } void spell_fumble( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; char buf[MAX_STRING_LENGTH]; if ( IS_AFFECTED2( victim, AFF_FUMBLE ) ) return; if ( saves_spell( level, victim ) ) { send_to_char( AT_BLUE, "You failed.\n\r", ch ); return; } af.type = sn; af.level = level; af.duration = number_fuzzy( level / 10 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_FUMBLE; affect_to_char2( victim, &af ); af.location = APPLY_HITROLL; af.modifier = 0 - level / 5; af.bitvector = 0; affect_to_char( victim, &af ); sprintf( buf, "You feel clumsy.\n\r" ); send_to_char(AT_WHITE, buf, victim ); act(AT_WHITE, "$n looks very clumsy.", victim, NULL, NULL, TO_ROOM ); return; } void spell_mind_probe( int sn, int level, CHAR_DATA *ch, void *vo ) { AFFECT_DATA *paf; CHAR_DATA *victim; bool printed = FALSE; char buf [ MAX_STRING_LENGTH ]; char buf1 [ MAX_STRING_LENGTH ]; if (!(victim = get_char_room( ch, target_name ) ) ) { send_to_char(AT_BLUE, "You cannot find them.\n\r", ch ); return; } if ( victim->level >= LEVEL_IMMORTAL ) { sprintf(buf1, "%s attempted to probe your mind.", ch->name ); send_to_char(AT_RED, buf1, victim ); send_to_char(AT_BLUE, "The mind of an immortal is beyond your understanding.", ch ); return; } sprintf(buf1, "You send your conciousness into %s's mind.\n\r", victim->name); send_to_char(AT_RED, buf1, ch ); send_to_char(AT_RED, "You feel someone touch your mind.\n\r", victim ); buf1[0] = '\0'; if (IS_NPC(victim)) { send_to_char (AT_WHITE, "The mind is to chaotic to merge with.\n\r", ch ); return; } sprintf( buf, "You are %s%s.\n\r", victim->name, IS_NPC( victim ) ? "" : victim->pcdata->title ); send_to_char( AT_CYAN, buf, ch ); sprintf( buf, "Level &C%d&c, %d years old (%d hours).\n\r", victim->level, get_age( victim ), (get_age( victim ) - 17) * 4 ); send_to_char( AT_CYAN, buf, ch ); sprintf( buf, "You are a &Y%s&c and have chosen the vocation of a &Y%s&c.\n\r", (get_race_data(victim->race))->race_full, class_short( victim ) ); send_to_char( AT_CYAN, buf, ch ); if ( victim->clan ) { CLAN_DATA *clan; clan = get_clan_index( victim->clan ); sprintf( buf, "You belong to the clan %s.\n\r", clan->name ); send_to_char( AT_WHITE, buf, ch ); } if ( get_trust( victim ) != victim->level ) { sprintf( buf, "You have been granted the powers of a level &R%d&W.\n\r", get_trust( victim ) ); send_to_char( AT_WHITE, buf, ch ); } if (!IS_NPC( victim )) if ( get_trust( victim ) > LEVEL_IMMORTAL ) { sprintf( buf, "Bamfin&r: &w%s.\n\r", victim->pcdata->bamfin ); send_to_char( AT_RED, buf, ch ); sprintf( buf, "Bamfout&r: &w%s.\n\r", victim->pcdata->bamfout ); send_to_char( AT_RED, buf, ch ); sprintf( buf, "Bamfusee&r: &w%s.\n\r", ch->pcdata->bamfusee ); send_to_char( AT_RED, buf, ch ); sprintf( buf, "Transto&r: &w%s.\n\r", ch->pcdata->transto ); send_to_char( AT_RED, buf, ch ); sprintf( buf, "Transfrom&r: &w%s.\n\r", ch->pcdata->transfrom ); send_to_char( AT_RED, buf, ch ); sprintf( buf, "Transvict&r: &w%s.\n\r", ch->pcdata->transvict ); send_to_char( AT_RED, buf, ch ); sprintf( buf, "Slayusee&r: &w%s.\n\r", ch->pcdata->slayusee ); send_to_char( AT_RED, buf, ch ); sprintf( buf, "Slayroom&r: &w%s.\n\r", ch->pcdata->slayroom ); send_to_char( AT_RED, buf, ch ); sprintf( buf, "Slayvict&r: &w%s.\n\r", ch->pcdata->slayvict ); send_to_char( AT_RED, buf, ch ); } send_to_char( AT_CYAN, "You have", ch ); sprintf ( buf, " %d/%d(%d)", victim->hit,victim->perm_hit,MAX_HIT(victim) ); send_to_char( AT_YELLOW, buf, ch ); send_to_char( AT_CYAN, " hit, ", ch ); sprintf( buf, "%s%d/%d %s", is_class( victim, CLASS_VAMPIRE ) ? "&R" : "&C", MT( ch ), MT_MAX( ch ), is_class( victim, CLASS_VAMPIRE ) ? " blood, " : "mana, " ); /* if ( !is_class( victim, CLASS_VAMPIRE ) ) { sprintf ( buf, "%d/%d(%d)",victim->mana,victim->perm_mana,MAX_MANA(victim)); send_to_char( AT_LBLUE, buf, ch ); send_to_char( AT_CYAN, " mana, ", ch ); } else { sprintf ( buf, "%d/%d(%d)", victim->bp,victim->perm_bp, MAX_BP(victim)); send_to_char( AT_RED, buf, ch ); send_to_char( AT_CYAN, " blood, ", ch ); } */ sprintf ( buf, "%d/%d(%d)", victim->move, victim->perm_move, MAX_MOVE(victim)); send_to_char( AT_GREEN, buf, ch ); send_to_char( AT_CYAN, " movement, ", ch ); sprintf ( buf, "%d", victim->practice ); send_to_char( AT_WHITE, buf, ch ); send_to_char( AT_CYAN, " practices.\n\r", ch ); sprintf( buf, "You are carrying %d/%d items with weight %d/%d kg.\n\r", victim->carry_number, can_carry_n( victim ), victim->carry_weight, can_carry_w( victim ) ); send_to_char( AT_CYAN, buf, ch ); sprintf( buf, "Str: %d&p(&P%d&p)&P Int: %d&p(&P%d&p)&P Wis: %d&p(&P%d&p)&P Dex: %d&p(&P%d&p)&P Con: %d&p(&P%d&p)&P.\n\r", IS_NPC(victim) ? 13: victim->pcdata->perm_str, IS_NPC(victim) ? 13: get_curr_str( victim ), IS_NPC(victim) ? 13: victim->pcdata->perm_int, IS_NPC(victim) ? 13: get_curr_int( victim ), IS_NPC(victim) ? 13: victim->pcdata->perm_wis, IS_NPC(victim) ? 13: get_curr_wis( victim ), IS_NPC(victim) ? 13: victim->pcdata->perm_dex, IS_NPC(victim) ? 13: get_curr_dex( victim ), IS_NPC(victim) ? 13: victim->pcdata->perm_con, IS_NPC(victim) ? 13: get_curr_con( victim ) ); send_to_char( AT_PINK, buf, ch ); send_to_char( AT_CYAN, "You have scored ", ch ); #ifdef NEW_MONEY sprintf( buf, "&W%d &cexperience points.\n\r", victim->exp ); send_to_char( AT_WHITE, buf, ch ); sprintf( buf, "&cYou have accumulated &W%d &Ygold, &W%d &wsilver, &cand &W%d &Ocopper &ccoins.\n\r", victim->money.gold, victim->money.silver, victim->money.copper ); send_to_char( AT_WHITE, buf, ch ); #else sprintf( buf, "%d ", victim->exp ); send_to_char( AT_WHITE, buf, ch ); send_to_char( AT_CYAN, "exp, and have accumulated ", ch ); sprintf( buf, "%d ", victim->gold ); send_to_char( AT_YELLOW, buf, ch ); send_to_char( AT_CYAN, "gold coins.\n\r", ch ); #endif if ( !IS_NPC( victim ) && victim->pcdata->condition[COND_DRUNK] > 10 ) send_to_char( AT_GREY, "You are drunk.\n\r", ch ); if ( !IS_NPC( victim ) && victim->pcdata->condition[COND_THIRST] == 0 && victim->level >= LEVEL_IMMORTAL ) send_to_char( AT_BLUE, "You are thirsty.\n\r", ch ); if ( !IS_NPC( victim ) && victim->pcdata->condition[COND_FULL] == 0 && victim->level >= LEVEL_IMMORTAL ) send_to_char( AT_ORANGE, "You are hungry.\n\r", ch ); switch ( victim->position ) { case POS_DEAD: send_to_char( (AT_RED + AT_BLINK), "You are DEAD!!\n\r", ch ); break; case POS_MORTAL: send_to_char( AT_RED, "You are mortally wounded.\n\r", ch ); break; case POS_INCAP: send_to_char( AT_RED, "You are incapacitated.\n\r", ch ); break; case POS_STUNNED: send_to_char( AT_RED, "You are stunned.\n\r", ch ); break; case POS_SLEEPING: send_to_char( AT_LBLUE, "You are sleeping.\n\r", ch ); break; case POS_RESTING: send_to_char( AT_LBLUE, "You are resting.\n\r", ch ); break; case POS_STANDING: send_to_char( AT_GREEN, "You are standing.\n\r", ch ); break; case POS_FIGHTING: send_to_char( AT_BLOOD, "You are fighting.\n\r", ch ); break; } if ( ch->level >= 20 ) { sprintf( buf, "AC: %d. ", GET_AC( victim ) ); send_to_char( AT_CYAN, buf, ch ); } send_to_char( AT_GREEN, "You are ", ch ); if ( GET_AC( victim ) >= 101 ) send_to_char( AT_GREEN, "WORSE than naked!\n\r", ch ); else if ( GET_AC( victim ) >= 20 ) send_to_char( AT_GREEN, "naked.\n\r" , ch ); else if ( GET_AC( victim ) >= 0 ) send_to_char( AT_GREEN, "wearing clothes.\n\r" , ch ); else if ( GET_AC( victim ) >= - 50 ) send_to_char( AT_GREEN, "slightly armored.\n\r", ch ); else if ( GET_AC( victim ) >= -100 ) send_to_char( AT_GREEN, "somewhat armored.\n\r", ch ); else if ( GET_AC( victim ) >= -250 ) send_to_char( AT_GREEN, "armored.\n\r" , ch ); else if ( GET_AC( victim ) >= -500 ) send_to_char( AT_GREEN, "well armored.\n\r" , ch ); else if ( GET_AC( victim ) >= -750 ) send_to_char( AT_GREEN, "strongly armored.\n\r", ch ); else if ( GET_AC( victim ) >= -1000 ) send_to_char( AT_GREEN, "heavily armored.\n\r" , ch ); else if ( GET_AC( victim ) >= -1200 ) send_to_char( AT_GREEN, "superbly armored.\n\r", ch ); else if ( GET_AC( victim ) >= -1400 ) send_to_char( AT_GREEN, "divinely armored.\n\r", ch ); else send_to_char( AT_GREEN, "invincible!\n\r", ch ); if ( ch->level >= 12 ) { sprintf( buf, "Hitroll: " ); send_to_char(AT_BLOOD, buf, ch ); sprintf( buf, "%d", GET_HITROLL( victim ) ); send_to_char(AT_RED, buf, ch); sprintf( buf, " Damroll: " ); send_to_char( AT_BLOOD, buf, ch ); sprintf( buf, "%d.\n\r", GET_DAMROLL( victim ) ); send_to_char( AT_RED, buf, ch ); } if ( ch->level >= 8 ) { sprintf( buf, "Alignment: %d. ", victim->alignment ); send_to_char( AT_CYAN, buf, ch ); } send_to_char( AT_CYAN, "You are ", ch ); if ( victim->alignment > 900 ) send_to_char( AT_BLUE, "angelic.\n\r",ch ); else if ( victim->alignment > 700 ) send_to_char( AT_BLUE, "saintly.\n\r",ch ); else if ( victim->alignment > 350 ) send_to_char( AT_BLUE, "good.\n\r" ,ch ); else if ( victim->alignment > 100 ) send_to_char( AT_BLUE, "kind.\n\r" ,ch ); else if ( victim->alignment > -100 ) send_to_char( AT_YELLOW, "neutral.\n\r",ch ); else if ( victim->alignment > -350 ) send_to_char( AT_RED, "mean.\n\r" ,ch); else if ( victim->alignment > -700 ) send_to_char( AT_RED, "evil.\n\r" ,ch); else if ( victim->alignment > -900 ) send_to_char( AT_RED, "demonic.\n\r" ,ch); else send_to_char( AT_RED, "satanic.\n\r" ,ch); if ( !IS_NPC( victim ) && IS_IMMORTAL( victim ) ) { sprintf( buf, "WizInvis level: %d WizInvis is %s\n\r", victim->wizinvis, IS_SET( victim->act, PLR_WIZINVIS ) ? "ON" : "OFF" ); send_to_char( AT_YELLOW, buf, ch ); sprintf( buf, "Cloaked level: %d Cloaked is %s\n\r", victim->cloaked, IS_SET( victim->act, PLR_CLOAKED ) ? "ON" : "OFF" ); send_to_char( AT_YELLOW, buf, ch ); } if ( victim->affected ) { for ( paf = victim->affected; paf; paf = paf->next ) { if ( paf->deleted ) continue; if ( !printed ) { send_to_char( AT_CYAN, "You are affected by:\n\r", ch ); printed = TRUE; } sprintf( buf, "Spell: '%s'", skill_table[paf->type].name ); send_to_char( AT_WHITE, buf, ch ); if ( ch->level >= 20 ) { sprintf( buf, " modifies %s by %d for %d hours", affect_loc_name( paf->location ), paf->modifier, paf->duration ); send_to_char(AT_WHITE, buf, ch ); } send_to_char( AT_WHITE, ".\n\r", ch ); } } if ( victim->affected2 ) { for ( paf = victim->affected2; paf; paf = paf->next ) { if ( paf->deleted ) continue; if ( !printed ) { send_to_char( AT_CYAN, "You are affected by:\n\r", ch ); printed = TRUE; } sprintf( buf, "Spell: '%s'", skill_table[paf->type].name ); send_to_char( AT_WHITE, buf, ch ); if ( ch->level >= 20 ) { sprintf( buf, " modifies %s by %d for %d hours", affect_loc_name( paf->location ), paf->modifier, paf->duration ); send_to_char(AT_WHITE, buf, ch ); } send_to_char( AT_WHITE, ".\n\r", ch ); } } send_to_char( AT_RED, "The presence lifts from your mind.\n\r", victim ); return; } void spell_entangle( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; char buf[MAX_STRING_LENGTH]; if ( IS_AFFECTED( victim, AFF_ANTI_FLEE ) ) return; af.type = sn; af.level = level; af.duration = number_fuzzy( level / 10 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_ANTI_FLEE; affect_to_char( victim, &af ); sprintf( buf, "%s calls forth nature to hold you in place.\n\r", ch->name ); send_to_char(AT_GREEN, buf, victim ); act(AT_GREEN, "Hundreds of vines reach from the ground to entangle $n.", victim, NULL, NULL, TO_ROOM ); return; } void spell_scry( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_SCRY ) ) return; af.type = sn; af.level = level; af.duration = number_fuzzy( level / 4 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_SCRY; affect_to_char( victim, &af ); send_to_char(AT_BLUE, "Your vision improves.\n\r", victim ); return; } void spell_shield( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn ) ) return; af.type = sn; af.level = level; af.duration = 8 + level; af.location = APPLY_AC; af.modifier = -30; af.bitvector = 0; affect_to_char( victim, &af ); send_to_char(AT_BLUE, "You are surrounded by a force shield.\n\r", victim ); act(AT_BLUE, "$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; static const int dam_each [ ] = { 0, 0, 0, 0, 0, 0, 0, 20, 25, 29, 33, 36, 39, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101, 102,103,104,105,106 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level] / 2, dam_each[level] * 2 ); dam = sc_dam( ch, dam ); if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_shockshield( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_SHOCKSHIELD ) ) return; af.type = sn; af.level = level; af.duration = number_fuzzy( level / 6 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_SHOCKSHIELD; affect_to_char( victim, &af ); send_to_char(AT_BLUE, "Sparks of electricity flow into your body.\n\r", victim ); act(AT_BLUE, "Bolts of electricity flow from the ground into $n's body.", victim, NULL, NULL, TO_ROOM ); return; } void spell_sleep( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_SLEEP ) || level < victim->level || ( saves_spell(level + IS_SRES(victim, RES_MAGIC) ? -5 : 0, victim) && !(get_trust( ch ) > LEVEL_IMMORTAL) ) ) { send_to_char(AT_BLUE, "You failed.\n\r", ch ); return; } if(IS_SIMM(victim, IMM_MAGIC)) return; af.type = sn; af.level = level; af.duration = 4 + level; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_SLEEP; affect_join( victim, &af ); if ( IS_AWAKE( victim ) ) { send_to_char(AT_BLUE, "You feel very sleepy ..... zzzzzz.\n\r", victim ); if ( victim->position == POS_FIGHTING ) stop_fighting( victim, TRUE ); do_sleep( victim, "" ); } return; } void spell_spell_bind( int sn, int level, CHAR_DATA *ch, void *vo ) { bool Charged = 0; OBJ_DATA *obj = (OBJ_DATA *) vo; if ( obj->item_type == ITEM_WAND || obj->item_type == ITEM_STAFF || obj->item_type == ITEM_LENSE ) { if(obj->value[2] < obj->value[1]) { obj->value[2]=obj->value[1]; Charged++; } } else if (obj->ac_type==5 && obj->ac_spell) { if(obj->ac_charge[0] < obj->ac_charge[1] && obj->ac_charge[1]!=-1) { obj->ac_charge[0]++; Charged++; } } else { send_to_char(AT_BLUE, "You cannot bind magic to that item.\n\r", ch ); return; } if (!Charged) { send_to_char(AT_BLUE, "That item is at full charge.\n\r", ch ); return; } act(AT_BLUE, "You slowly pass your hand over $p, it vibrates slowly.", ch, obj, NULL, TO_CHAR ); act(AT_BLUE, "$n slowly passes $s hand over $p, it vibrates slowly.", ch, obj, 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; if ( is_affected( ch, sn ) ) return; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_AC; af.modifier = -45; af.bitvector = 0; affect_to_char( victim, &af ); send_to_char(AT_GREY, "Your skin turns to stone.\n\r", victim ); act(AT_GREY, "$n's skin turns to stone.", victim, NULL, NULL, TO_ROOM ); return; } /*Decklarean*/ void spell_bark_skin( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( ch, sn ) ) return; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_AC; af.modifier = -10 - level / 4; af.bitvector = 0; affect_to_char( victim, &af ); send_to_char(AT_GREY, "Your skin turns to bark.\n\r", victim ); act(AT_GREY, "$n's skin turns to bark.", victim, NULL, NULL, TO_ROOM ); return; } void spell_summon( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim; if ( !( victim = get_char_world( ch, target_name ) ) || victim == ch || ch->in_room->area == arena.area || IS_ARENA(victim) || !victim->in_room || IS_SET( victim->in_room->room_flags, ROOM_SAFE ) || IS_SET( victim->in_room->room_flags, ROOM_PRIVATE ) || IS_SET( victim->in_room->room_flags, ROOM_SOLITARY ) || IS_SET( victim->in_room->room_flags, ROOM_NO_RECALL ) || IS_SET( victim->in_room->room_flags, ROOM_NO_ASTRAL_OUT ) || victim->level >= level + 3 || victim->fighting || ( IS_NPC( victim ) && saves_spell( level, victim ) ) || IS_SET( victim->in_room->area->area_flags, AREA_PROTOTYPE ) || IS_AFFECTED( victim, AFF_NOASTRAL ) ) { send_to_char(AT_BLUE, "You failed.\n\r", ch ); return; } act(AT_BLUE, "$n disappears suddenly.", victim, NULL, NULL, TO_ROOM ); char_from_room( victim ); char_to_room( victim, ch->in_room ); act(AT_BLUE, "$n has summoned you!", ch, NULL, victim, TO_VICT ); act(AT_BLUE, "$n arrives suddenly.", victim, NULL, NULL, TO_ROOM ); send_to_char( AT_BLUE, "You feel a wave of nausia come over you.\n\r", ch ); ch->position = POS_STUNNED; update_pos( ch ); STUN_CHAR( ch, 3, STUN_COMMAND ); do_look( victim, "auto" ); return; } void spell_teleport( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; CHAR_DATA *pet; ROOM_INDEX_DATA *pRoomIndex; if ( !victim->in_room || IS_SET( victim->in_room->room_flags, ROOM_NO_RECALL) || IS_SET( victim->in_room->room_flags, ROOM_NO_ASTRAL_OUT) || IS_SET( victim->in_room->area->area_flags, AREA_PROTOTYPE ) || ( !IS_NPC( ch ) && victim->fighting ) || ( victim != ch && ( saves_spell( level, victim ) || saves_spell( level, victim ) ) ) ) { send_to_char(AT_BLUE, "You failed.\n\r", ch ); return; } for ( ; ; ) { pRoomIndex = get_room_index( number_range( 0, 32767 ) ); if ( pRoomIndex ) if ( !IS_SET( pRoomIndex->room_flags, ROOM_PRIVATE ) && !IS_SET( pRoomIndex->room_flags, ROOM_SOLITARY ) && !IS_SET( pRoomIndex->room_flags, ROOM_NO_ASTRAL_IN ) && !IS_SET( pRoomIndex->room_flags, ROOM_NO_RECALL) && !IS_SET( pRoomIndex->area->area_flags, AREA_PROTOTYPE ) ) break; } for ( pet = victim->in_room->people; pet; pet = pet->next_in_room ) { if ( IS_NPC( pet ) ) if ( IS_SET( pet->act, ACT_PET ) && ( pet->master == victim ) ) break; } act(AT_BLUE, "$n glimmers briefly, then is gone.", victim, NULL, NULL, TO_ROOM ); if ( pet ) { act( AT_BLUE, "$n glimmers briefly, then is gone.", pet, NULL, NULL, TO_ROOM ); char_from_room( pet ); } char_from_room( victim ); char_to_room( victim, pRoomIndex ); act(AT_BLUE, "The air starts to sparkle, then $n appears from nowhere.", victim, NULL, NULL, TO_ROOM ); do_look( victim, "auto" ); if ( pet ) { char_to_room( pet, pRoomIndex ); act( AT_BLUE, "The air starts to sparkle, then $n appears from nowhere.", pet, NULL, NULL, TO_ROOM ); } return; } void spell_ventriloquate( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *vch; char buf1 [ MAX_STRING_LENGTH ]; char buf2 [ MAX_STRING_LENGTH ]; char speaker [ MAX_INPUT_LENGTH ]; target_name = one_argument( target_name, speaker ); sprintf( buf1, "%s says '%s'.\n\r", speaker, target_name ); sprintf( buf2, "Someone makes %s say '%s'.\n\r", speaker, target_name ); buf1[0] = UPPER( buf1[0] ); for ( vch = ch->in_room->people; vch; vch = vch->next_in_room ) { if ( !is_name( NULL, speaker, vch->name ) ) send_to_char(AT_CYAN, saves_spell( level, vch ) ? buf2 : buf1, vch ); } return; } void spell_weaken( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn ) || saves_spell( level, victim ) ) return; af.type = sn; af.level = level; af.duration = level / 2; af.location = APPLY_STR; af.modifier = -2; af.bitvector = 0; affect_to_char( victim, &af ); if ( ch != victim ) send_to_char(AT_GREEN, "Ok.\n\r", ch ); send_to_char(AT_GREEN, "You feel weaker.\n\r", victim ); return; } /* * This is for muds that want scrolls of recall. */ void spell_word_of_recall( int sn, int level, CHAR_DATA *ch, void *vo ) { do_recall( (CHAR_DATA *) vo, "" ); return; } /* * NPC spells. */ void spell_acid_breath( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj_lose; OBJ_DATA *obj_next; CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; int hpch; if ( number_percent( ) < 2 * level && !saves_spell( level, victim ) ) { for ( obj_lose = victim->carrying; obj_lose; obj_lose = obj_next ) { obj_next = obj_lose->next_content; if ( obj_lose->deleted ) continue; if ( IS_SET( obj_lose->extra_flags, ITEM_NO_DAMAGE ) ) continue; if ( number_bits( 2 ) != 0 ) continue; switch ( obj_lose->item_type ) { case ITEM_ARMOR: if ( obj_lose->value[0] > 0 ) { act(AT_GREEN, "$p is pitted and etched!", victim, obj_lose, NULL, TO_CHAR ); /* if ( ( iWear = obj_lose->wear_loc ) != WEAR_NONE ) victim->armor -= apply_ac( obj_lose, iWear ); obj_lose->value[0] -= 1;*/ /* 5% -- Altrag */ #ifdef NEW_MONEY obj_lose->cost.gold = (obj_lose->cost.gold > 0) ? (obj_lose->cost.gold - (obj_lose->cost.gold/20)) : 0; obj_lose->cost.silver = (obj_lose->cost.silver > 0) ? (obj_lose->cost.silver - (obj_lose->cost.silver/20)) : 0; obj_lose->cost.copper = (obj_lose->cost.copper > 0) ? (obj_lose->cost.copper - (obj_lose->cost.copper/20)) : 0; #else obj_lose->cost -= (obj_lose->cost / 20); #endif /* if ( iWear != WEAR_NONE ) victim->armor += apply_ac( obj_lose, iWear );*/ } break; case ITEM_CONTAINER: act(AT_GREEN, "$p fumes and dissolves!", victim, obj_lose, NULL, TO_CHAR ); extract_obj( obj_lose ); break; } } } hpch = UMAX( 10, ch->hit ); dam = number_range( hpch / 8 + 1, hpch / 4 ); dam = sc_dam( ch, dam ); if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_fire_breath( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj_lose; OBJ_DATA *obj_next; CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; int hpch; if ( number_percent( ) < 2 * level && !saves_spell( level, victim ) ) { for ( obj_lose = victim->carrying; obj_lose; obj_lose = obj_next ) { char *msg; obj_next = obj_lose->next_content; if ( obj_lose->deleted ) continue; if ( IS_SET( obj_lose->extra_flags, ITEM_NO_DAMAGE ) ) continue; if ( number_bits( 2 ) != 0 ) continue; switch ( obj_lose->item_type ) { default: continue; case ITEM_CONTAINER: msg = "$p ignites and burns!"; break; case ITEM_POTION: msg = "$p bubbles and boils!"; break; case ITEM_SCROLL: msg = "$p crackles and burns!"; break; case ITEM_STAFF: msg = "$p smokes and chars!"; break; case ITEM_WAND: msg = "$p sparks and sputters!"; break; case ITEM_LENSE: msg = "$p shrivels and dries!"; break; case ITEM_FOOD: msg = "$p blackens and crisps!"; break; case ITEM_PILL: msg = "$p melts and drips!"; break; } act(AT_GREEN, msg, victim, obj_lose, NULL, TO_CHAR ); extract_obj( obj_lose ); } } hpch = UMAX( 10, ch->hit ); dam = number_range( hpch / 8 + 1, hpch / 4 ); dam = sc_dam( ch, dam ); if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_frost_breath( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj_lose; OBJ_DATA *obj_next; CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; int hpch; if ( number_percent( ) < 2 * level && !saves_spell( level, victim ) ) { for ( obj_lose = victim->carrying; obj_lose; obj_lose = obj_next ) { char *msg; obj_next = obj_lose->next_content; if ( obj_lose->deleted ) continue; if ( IS_SET( obj_lose->extra_flags, ITEM_NO_DAMAGE ) ) continue; if ( number_bits( 2 ) != 0 ) continue; switch ( obj_lose->item_type ) { default: continue; case ITEM_CONTAINER: case ITEM_DRINK_CON: case ITEM_POTION: msg = "$p freezes and shatters!"; break; } act(AT_WHITE, msg, victim, obj_lose, NULL, TO_CHAR ); extract_obj( obj_lose ); } } hpch = UMAX( 10, ch->hit ); dam = number_range( hpch / 8 + 1, hpch / 4 ); dam = sc_dam( ch, dam ); if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_gas_breath( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *vch; CHAR_DATA *vch_next; int dam; int hpch; for ( vch = ch->in_room->people; vch; vch = vch_next ) { vch_next = vch->next_in_room; if ( vch->deleted ) continue; if ( IS_NPC( ch ) ? !IS_NPC( vch ) : IS_NPC( vch ) ) { hpch = UMAX( 10, ch->hit ); dam = number_range( hpch / 8 + 1, hpch / 4 ); dam = sc_dam( ch, dam ); if ( saves_spell( level, vch ) ) dam /= 2; spell_poison( gsn_poison, level, ch, vch ); damage( ch, vch, dam, sn ); } } return; } void spell_lightning_breath( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; int hpch; hpch = UMAX( 10, ch->hit ); dam = number_range( hpch / 8 + 1, hpch / 4 ); dam = sc_dam( ch, dam ); if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } /* * 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; if ( is_affected( victim, sn ) ) return; af.type = sn; af.level = level; af.duration = level - 5; af.location = APPLY_DEX; af.modifier = 2; af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_CON; affect_to_char( victim, &af ); send_to_char(AT_BLUE, "You have given yourself an adrenaline rush!\n\r", ch ); act(AT_BLUE, "$n has given $mself an adrenaline rush!", ch, NULL, NULL, TO_ROOM ); return; } void spell_agitation ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 0, 0, 0, 0, 0, 12, 15, 18, 21, 24, 24, 24, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level] / 2, dam_each[level] * 2 ); dam = sc_dam( ch, dam ); if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_aura_sight ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; char *msg; int ap; ap = victim->alignment; if ( ap > 700 ) msg = "$N has an aura as white as the driven snow."; else if ( ap > 350 ) msg = "$N is of excellent moral character."; else if ( ap > 100 ) msg = "$N is often kind and thoughtful."; else if ( ap > -100 ) msg = "$N doesn't have a firm moral commitment."; else if ( ap > -350 ) msg = "$N lies to $S friends."; else if ( ap > -700 ) msg = "Don't bring $N home to meet your family."; else msg = "Uh, check please!"; act(AT_BLUE, msg, ch, NULL, victim, TO_CHAR ); } void spell_awe ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; if ( victim->fighting == ch && !saves_spell( level, victim ) ) { stop_fighting ( victim, TRUE); act(AT_BLUE, "$N is in AWE of you!", ch, NULL, victim, TO_CHAR ); act(AT_BLUE, "You are in AWE of $n!",ch, NULL, victim, TO_VICT ); act(AT_BLUE, "$N is in AWE of $n!", ch, NULL, victim, TO_NOTVICT ); } return; } void spell_ballistic_attack ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 3, 4, 4, 5, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level] / 2, dam_each[level] * 2 ); dam = sc_dam( ch, dam ); if ( saves_spell( level, victim ) ) dam /= 2; act(AT_BLUE, "You chuckle as a stone strikes $N.", ch, NULL, victim, TO_CHAR ); damage( ch, victim, dam, sn); return; } void spell_biofeedback ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_SANCTUARY ) ) return; af.type = sn; af.level = level; af.duration = number_fuzzy( level / 8 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_SANCTUARY; affect_to_char( victim, &af ); send_to_char(AT_WHITE, "You are surrounded by a white aura.\n\r", victim ); act(AT_WHITE, "$n is surrounded by a white aura.", 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; int SkNum; if ( is_affected( victim, gsn_poison ) ) { affect_strip( victim, gsn_poison ); send_to_char(AT_BLUE, "A warm feeling runs through your body.\n\r", victim ); act(AT_BLUE, "$N looks better.", ch, NULL, victim, TO_NOTVICT ); } SkNum = skill_lookup("curse"); if ( is_affected( victim, SkNum ) ) { affect_strip( victim, SkNum ); send_to_char(AT_BLUE, "You feel better.\n\r", victim ); } send_to_char(AT_BLUE, "Ok.\n\r", ch ); return; } void spell_chaosfield( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_CHAOS ) ) return; af.type = sn; af.level = level; af.duration = number_fuzzy( level / 6 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_CHAOS; affect_to_char( victim, &af ); send_to_char(AT_YELLOW, "You call forth an instance of chaos from the order around you.\n\r", victim ); act(AT_YELLOW, "$n's body is veiled in an instance or pure chaos.", victim, NULL, NULL, TO_ROOM ); return; } void spell_bladebarrier( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED2( victim, AFF_BLADE ) ) return; af.type = sn; af.level = level; af.duration = number_fuzzy( level / 6 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_BLADE; affect_to_char2( victim, &af ); send_to_char(AT_GREY, "You bring forth thousands of tiny spinning blades about your body.\n\r", victim ); act(AT_GREY, "$n's body is surrounded by thousands of spinning blades.", victim, NULL, NULL, TO_ROOM ); return; } void spell_dancing_lights( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED2( victim, AFF_DANCING ) ) return; if ( IS_AFFECTED( victim, AFF_BLIND ) || saves_spell( level, victim ) ) { send_to_char(AT_BLUE, "You have failed.\n\r", ch ); return; } af.type = sn; af.level = level; af.duration = number_fuzzy( level / 6 ); af.location = APPLY_HITROLL; af.modifier = level/6; af.bitvector = AFF_DANCING; affect_to_char2( victim, &af ); act(AT_WHITE, "&.Thou&.sand&.s &.of &.danci&.ng &.ligh&.ts &.surr&.ound &.you&.!&w", victim, NULL, victim, TO_VICT ); act(AT_GREY, "&W$n's &.body &.is &.surr&.ounded &.by d&.anci&.ng l&.ights.", 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; if ( is_affected( victim, sn ) ) { if ( victim == ch ) send_to_char(AT_BLUE, "You already understand battle tactics.\n\r", victim ); else act(AT_BLUE, "$N already understands battle tactics.", ch, NULL, victim, TO_CHAR ); return; } af.type = sn; af.level = level; af.duration = level + 3; af.location = APPLY_HITROLL; af.modifier = level / 5; af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_AC; af.modifier = - level/2 - 10; affect_to_char( victim, &af ); if ( victim != ch ) send_to_char(AT_BLUE, "OK.\n\r", ch ); send_to_char(AT_BLUE, "You gain a keen understanding of battle tactics.\n\r", victim ); return; } /* psi people shouldn't have this powerful healing */ void spell_complete_healing ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; /* victim->hit = MAX_HIT(victim);*/ victim->hit = UMIN( victim->hit + 600, MAX_HIT(victim) ); update_pos( victim ); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "Ahhhhhh...You feel MUCH better!\n\r", victim ); send_to_char(AT_BLUE, "Have a nice day.\n\r", victim); /* send_to_char(AT_BLUE, "Ahhhhhh...You are completely healed!\n\r", victim ); */ return; } void spell_control_flames ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 0, 0, 0, 0, 0, 0, 0, 16, 20, 24, 28, 32, 35, 38, 40, 42, 44, 45, 45, 45, 46, 46, 46, 47, 47, 47, 48, 48, 48, 49, 49, 49, 50, 50, 50, 51, 51, 51, 52, 52, 52, 53, 53, 53, 54, 54, 54, 55, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 62, 63, 63, 63, 64, 64, 64, 65, 65, 65, 72, 73, 73, 73, 74, 74, 74, 75, 75, 75, 82, 83, 83, 83, 84, 84, 84, 85, 85, 85, 92, 93, 93, 93, 94, 94, 94, 95, 95, 95 }; int dam; if ( !get_eq_char( ch, WEAR_LIGHT ) ) { send_to_char(AT_RED, "You must be carrying a light source.\n\r", ch ); return; } level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level] / 2, dam_each[level] * 2 ); dam = sc_dam( ch, dam ); if ( IS_AFFECTED( victim, AFF_FIRESHIELD ) ) dam /= 2; if ( IS_AFFECTED( victim, AFF_ICESHIELD ) ) dam += dam/4; if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_create_sound ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *vch; char buf1 [ MAX_STRING_LENGTH ]; char buf2 [ MAX_STRING_LENGTH ]; char speaker [ MAX_INPUT_LENGTH ]; target_name = one_argument( target_name, speaker ); sprintf( buf1, "%s says '%s'.\n\r", speaker, target_name ); sprintf( buf2, "Someone makes %s say '%s'.\n\r", speaker, target_name ); buf1[0] = UPPER( buf1[0] ); for ( vch = ch->in_room->people; vch; vch = vch->next_in_room ) { if ( !is_name( NULL, speaker, vch->name ) ) send_to_char(AT_RED, saves_spell( level, vch ) ? buf2 : buf1, vch ); } return; } void spell_death_field ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *vch; /* CHAR_DATA *vch_next; */ int dam; int hpch; if ( !IS_EVIL( ch ) ) { send_to_char(AT_RED, "You are not evil enough to do that!\n\r", ch); return; } send_to_char(AT_DGREY, "A black haze emanates from you!\n\r", ch ); act (AT_DGREY, "A black haze emanates from $n!", ch, NULL, ch, TO_ROOM ); for ( vch = ch->in_room->people; vch; vch = vch->next_in_room ) /*vch = vch_next ) */ { /* vch_next = vch->next_in_room;*/ if ( vch->deleted ) continue; if ( IS_NPC( ch ) ) continue; if ( ch == vch ) continue; if ( !IS_NPC( ch ) ? IS_NPC( vch ) : IS_NPC( vch ) ) { hpch = URANGE( 10, ch->hit, 999 ); if ( !saves_spell( level, vch ) && ( level <= vch->level + 5 && level >= vch->level - 5 ) ) { send_to_char(AT_DGREY, "The haze envelops you!\n\r", vch ); act(AT_DGREY, "The haze envelops $N!", ch, NULL, vch, TO_NOTVICT ); dam = 4; /* Enough to compensate for sanct. and prot. */ vch->hit = 1; damage( ch, vch, dam, sn ); update_pos( vch ); } else { dam = number_range( hpch / 16 + 1, hpch / 8 ); dam = sc_dam( ch, dam ); damage( ch, vch, dam, sn ); } } } return; } void spell_detonate ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; if ( ch->race == RACE_ILLITHID ) ch->wait /= 2; dam = dice( level, 13 ); dam = sc_dam( ch, dam ); if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_disintegrate ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; OBJ_DATA *obj_lose; OBJ_DATA *obj_next; if ( !IS_NPC(victim) ) { send_to_char(AT_BLUE, "You failed.\n\r", ch); return; } if ( number_percent( ) < 2 * level && !saves_spell( level, victim ) ) for ( obj_lose = victim->carrying; obj_lose; obj_lose = obj_next ) { obj_next = obj_lose->next_content; if ( obj_lose->deleted ) continue; if ( number_bits( 2 ) != 0 ) continue; act(AT_WHITE, "$p disintegrates!", victim, obj_lose, NULL, TO_CHAR ); act(AT_WHITE, "$n's $p disintegrates!", victim, obj_lose, NULL, TO_ROOM ); extract_obj( obj_lose ) ; } if ( !saves_spell( level, victim ) ) /* * Disintegrate char, do not generate a corpse, do not * give experience for kill. Extract_char will take care * of items carried/wielded by victim. Needless to say, * it would be bad to be a target of this spell! * --- Thelonius (Monk) */ { act(AT_WHITE, "You have DISINTEGRATED $N!", ch, NULL, victim, TO_CHAR ); act(AT_WHITE, "You have been DISINTEGRATED by $n!", ch, NULL, victim, TO_VICT ); act(AT_WHITE, "$n's spell DISINTEGRATES $N!", ch, NULL, victim, TO_ROOM ); if ( IS_NPC( victim ) ) extract_char( victim, TRUE ); else extract_char( victim, FALSE ); } return; } void spell_disrupt( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; CHAR_DATA *vch; AFFECT_DATA af; bool negchar = FALSE; /* Is a negative value good..? */ int val = 0; af.type = sn; af.duration = (level * 2) / 3; af.level = level; af.bitvector = 0; while ( !val ) { af.location = number_range( 1, 26 ); switch (af.location) { case APPLY_STR: case APPLY_DEX: case APPLY_INT: case APPLY_WIS: case APPLY_CON: val = (level / 34) + 1; break; case APPLY_MANA: val = ((level * 3) / 2) + 1; break; case APPLY_AC: val = ((level * 3) / 2) + 1; negchar = TRUE; break; case APPLY_HITROLL: case APPLY_DAMROLL: val = (level / 2) + 1; break; case APPLY_SAVING_PARA: case APPLY_SAVING_ROD: case APPLY_SAVING_PETRI: case APPLY_SAVING_BREATH: case APPLY_SAVING_SPELL: val = ((level * 2) / 5) + 1; negchar = TRUE; break; case APPLY_BP: val = ((level * 3) / 10) + 1; break; } } for ( af.modifier = number_range( -val, val ); af.modifier == 0; af.modifier = number_range( -val, val ) ); if ( negchar ) { if ( af.modifier < 0 ) vch = ch; else vch = victim; } else { if ( af.modifier < 0 ) vch = victim; else vch = ch; } if ( af.location == APPLY_MANA && is_class( vch, CLASS_VAMPIRE ) ) { af.modifier /= 4; af.location = APPLY_BP; } if ( af.location == APPLY_BP && !is_class( vch, CLASS_VAMPIRE ) ) { if ( af.modifier > 0 ) af.modifier = number_range( 1, (level * 3) / 2 ); else af.modifier = number_range( -((level * 3) / 2), -1 ); af.location = APPLY_MANA; } if ( !is_affected( vch, sn ) && (vch != victim || !saves_spell( level, victim )) && number_bits( 8 ) == 0 ) { affect_to_char( vch, &af ); if ( ch == vch ) { act( AT_PINK, "You disrupt yourself!", ch, NULL, NULL, TO_CHAR ); act( AT_PINK, "$n disrupts $mself!", ch, NULL, NULL, TO_ROOM ); } else { act( AT_PURPLE, "You disrupt $N!", ch, NULL, victim, TO_CHAR ); act( AT_PURPLE, "$n disrupts $N!", ch, NULL, victim, TO_NOTVICT ); act( AT_PURPLE, "$n disrupts you!", ch, NULL, victim, TO_VICT ); switch( af.location ) { case APPLY_MANA: vch->mana = URANGE( 0, vch->mana, MAX_MANA(vch)); break; case APPLY_BP: vch->bp = URANGE( 0, vch->bp, MAX_BP(vch)); break; } } } damage( ch, victim, number_range( (level * 2) / 3, level ), sn ); return; } void spell_displacement ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn ) ) return; af.type = sn; af.level = level; af.duration = level - 4; af.location = APPLY_AC; af.modifier = 4 - level; af.bitvector = 0; affect_to_char( victim, &af ); send_to_char(AT_GREY, "Your form shimmers, and you appear displaced.\n\r", victim ); act(AT_GREY, "$N shimmers and appears in a different location.", ch, NULL, victim, TO_NOTVICT ); return; } void spell_domination ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( victim == ch ) { send_to_char(C_DEFAULT, "Dominate yourself? You're weird.\n\r", ch ); return; } if ( !IS_NPC( victim ) ) return; if ( IS_AFFECTED( victim, AFF_CHARM ) || IS_AFFECTED( ch, AFF_CHARM ) || level < victim->level || saves_spell( level, victim ) ) return; if ( victim->master ) stop_follower( victim ); add_follower( victim, ch ); af.type = sn; af.level = level; af.duration = number_fuzzy( level / 4 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char( victim, &af ); act(AT_BLUE, "Your will dominates $N!", ch, NULL, victim, TO_CHAR ); act(AT_BLUE, "Your will is dominated by $n!", ch, NULL, victim, TO_VICT ); return; } void spell_ectoplasmic_form ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_PASS_DOOR ) ) return; af.type = sn; af.level = level; af.duration = number_fuzzy( level / 4 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_PASS_DOOR; affect_to_char( victim, &af ); send_to_char(AT_GREY, "You turn translucent.\n\r", victim ); act(AT_GREY, "$n turns translucent.", victim, NULL, NULL, TO_ROOM ); return; } void spell_ego_whip ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn ) || saves_spell( level, victim ) ) return; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_HITROLL; af.modifier = -2; af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_SAVING_SPELL; af.modifier = 2; affect_to_char( victim, &af ); af.location = APPLY_AC; af.modifier = level / 2; affect_to_char( victim, &af ); act(AT_BLUE, "You ridicule $N about $S childhood.", ch, NULL, victim, TO_CHAR ); send_to_char(AT_BLUE, "Your ego takes a beating.\n\r", victim ); act(AT_BLUE, "$N's ego is crushed by $n!", ch, NULL, victim, TO_NOTVICT ); return; } void spell_energy_containment ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn ) ) return; af.type = sn; af.level = level; af.duration = level / 2 + 7; af.modifier = -level / 3; af.location = APPLY_SAVING_SPELL; af.bitvector = 0; affect_to_char( victim, &af ); send_to_char(AT_BLUE, "You can now absorb some forms of energy.\n\r", ch ); return; } void spell_enhance_armor (int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj = (OBJ_DATA *) vo; AFFECT_DATA *paf; if ( obj->item_type != ITEM_ARMOR || IS_OBJ_STAT( obj, ITEM_MAGIC ) || obj->affected ) { send_to_char(AT_BLUE, "That item cannot be enhanced.\n\r", ch ); return; } if ( !affect_free ) { paf = alloc_perm( sizeof( *paf ) ); } else { paf = affect_free; affect_free = affect_free->next; } paf->type = sn; paf->duration = -1; paf->location = APPLY_AC; paf->bitvector = 0; paf->next = obj->affected; obj->affected = paf; if ( number_percent() < ch->pcdata->learned[sn]/2 + 3 * ( ch->level - obj->level ) ) /* Good enhancement */ { paf->modifier = -level / 5; if ( IS_GOOD( ch ) ) { SET_BIT( obj->extra_flags, ITEM_ANTI_EVIL ); act(AT_BLUE, "$p glows.", ch, obj, NULL, TO_CHAR ); } else if ( IS_EVIL( ch ) ) { SET_BIT( obj->extra_flags, ITEM_ANTI_GOOD ); act(AT_RED, "$p glows.", ch, obj, NULL, TO_CHAR ); } else { SET_BIT( obj->extra_flags, ITEM_ANTI_EVIL ); SET_BIT( obj->extra_flags, ITEM_ANTI_GOOD ); act(AT_YELLOW, "$p glows.", ch, obj, NULL, TO_CHAR ); } send_to_char(AT_BLUE, "Ok.\n\r", ch ); } else /* Bad Enhancement ... opps! :) */ { paf->modifier = level / 8; #ifdef NEW_MONEY obj->cost.gold = obj->cost.silver = obj->cost.copper = 0; #else obj->cost = 0; #endif SET_BIT( obj->extra_flags, ITEM_NODROP ); act(AT_DGREY, "$p turns black.", ch, obj, NULL, TO_CHAR ); } return; } void spell_enhanced_strength ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn ) ) return; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_STR; af.modifier = 1 + ( level >= 15 ) + ( level >= 25 ); af.bitvector = 0; affect_to_char( victim, &af ); send_to_char(AT_BLUE, "You are HUGE!\n\r", victim ); return; } void spell_flesh_armor ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn ) ) return; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_AC; af.modifier = -45; af.bitvector = 0; affect_to_char( victim, &af ); send_to_char(AT_BLUE, "Your flesh turns to steel.\n\r", victim ); act(AT_BLUE, "$N's flesh turns to steel.", ch, NULL, victim, TO_NOTVICT); 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 ) || IS_AFFECTED2( gch, AFF_INERTIAL ) ) continue; act(AT_BLUE, "An inertial barrier forms around $n.", gch, NULL, NULL, TO_ROOM ); send_to_char(AT_BLUE, "An inertial barrier forms around you.\n\r", gch ); af.type = sn; af.level = level; af.duration = 24; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_INERTIAL; affect_to_char2( gch, &af ); } return; } void spell_inflict_pain ( int sn, int level, CHAR_DATA *ch, void *vo ) { int dam = dice( 2, 10 ) + level / 2; dam = sc_dam( ch, dam ); damage( ch, (CHAR_DATA *) vo, dam, sn ); 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 ) || is_affected( gch, sn ) ) continue; send_to_char(AT_BLUE, "A virtual fortress forms around you.\n\r", gch ); act(AT_BLUE, "A virtual fortress forms around $N.", gch, NULL, gch, TO_ROOM ); af.type = sn; af.level = level; af.duration = 24; af.location = APPLY_AC; af.modifier = -40; af.bitvector = 0; affect_to_char( gch, &af ); } 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(AT_BLUE, "Lend health to yourself? Easily done.\n\r", ch ); return; } hpch = UMIN( 50, MAX_HIT(victim) - victim->hit ); if ( hpch == 0 ) { act(AT_BLUE, "Nice thought, but $N doesn't need healing.", ch, NULL, victim, TO_CHAR ); return; } if ( ch->hit-hpch < 50 ) { send_to_char(AT_BLUE, "You aren't healthy enough yourself!\n\r", ch ); return; } victim->hit += hpch; ch->hit -= hpch; update_pos( victim ); update_pos( ch ); act(AT_BLUE, "You lend some of your health to $N.", ch, NULL, victim, TO_CHAR ); act(AT_BLUE, "$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; if ( IS_AFFECTED( victim, AFF_FLYING ) ) return; af.type = sn; af.level = level; af.duration = level + 3; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_FLYING; affect_to_char( victim, &af ); send_to_char(AT_BLUE, "Your feet rise off the ground.\n\r", victim ); act(AT_BLUE, "$n's feet rise off the ground.", victim, NULL, NULL, TO_ROOM ); return; } void spell_mental_barrier ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn ) ) return; af.type = sn; af.level = level; af.duration = 24; af.location = APPLY_AC; af.modifier = -20; af.bitvector = 0; affect_to_char( victim, &af ); send_to_char(AT_BLUE, "You erect a mental barrier around yourself.\n\r", victim ); return; } void spell_mind_thrust ( int sn, int level, CHAR_DATA *ch, void *vo ) { int dam = dice( 1, 10 ) + level / 2; dam = sc_dam( ch, dam ); damage( ch, (CHAR_DATA *) vo, dam, sn ); return; } void spell_project_force ( int sn, int level, CHAR_DATA *ch, void *vo ) { int dam = dice( 4, 6 ) + level; damage( ch, (CHAR_DATA *) vo, dam, sn ); return; } void spell_psionic_blast ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 50, 55, 60, 64, 68, 72, 76, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 100, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level] / 2, dam_each[level] ); dam = sc_dam( ch, dam ); if ( saves_spell( level, victim ) && ch->race != RACE_ILLITHID ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_psychic_crush ( int sn, int level, CHAR_DATA *ch, void *vo ) { int dam = dice( 3, 5 ) + level; damage( ch, (CHAR_DATA *) vo, dam, sn ); return; } void spell_psychic_drain ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn ) || saves_spell( level, victim ) ) return; af.type = sn; af.level = level; af.duration = level / 2; af.location = APPLY_STR; af.modifier = -1 - ( level >= 10 ) - ( level >= 20 ) - ( level >= 30 ); af.bitvector = 0; affect_to_char( victim, &af ); send_to_char(AT_GREEN, "You feel drained.\n\r", victim ); act(AT_BLUE, "$n appears drained of strength.", victim, NULL, NULL, TO_ROOM ); 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, MAX_HIT(victim) ); update_pos( victim ); send_to_char(AT_BLUE, "You feel better!\n\r", victim ); 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(AT_BLUE, "You can't share strength with yourself.\n\r", ch ); return; } if ( is_affected( victim, sn ) ) { act(AT_BLUE, "$N already shares someone's strength.", ch, NULL, victim, TO_CHAR ); return; } if ( get_curr_str( ch ) <= 5 ) { send_to_char(AT_BLUE, "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 ); af.bitvector = 0; affect_to_char( victim, &af ); af.modifier = -1 - ( level >= 20 ) - ( level >= 30 ); affect_to_char( ch, &af ); act(AT_BLUE, "You share your strength with $N.", ch, NULL, victim, TO_CHAR ); act(AT_BLUE, "$n shares $s strength with you.", ch, NULL, victim, TO_VICT ); return; } void spell_thought_shield ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn ) ) return; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_AC; af.modifier = -20; af.bitvector = 0; affect_to_char( victim, &af ); send_to_char(AT_BLUE, "You have created a shield around yourself.\n\r", ch ); return; } void spell_ultrablast ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *vch; CHAR_DATA *vch_next; int dam; int hpch; for ( vch = ch->in_room->people; vch; vch = vch_next ) { vch_next = vch->next_in_room; if ( vch->deleted ) continue; if ( IS_NPC( ch ) ? !IS_NPC( vch ) : IS_NPC( vch ) ) { hpch = UMAX( 10, ch->hit ); dam = number_range( hpch / 8, hpch / 3 ); dam = sc_dam( ch, dam ); if ( saves_spell( level, vch ) ) dam /= 2; damage( ch, vch, dam, sn ); } } return; } /* XORPHOX summon mobs */ void spell_summon_swarm(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; char buf [ MAX_STRING_LENGTH ]; int mana; if(ch->summon_timer > 0) { send_to_char(AT_BLUE, "You casted the spell, but nothing appears.\n\r", ch); return; } mob = create_mobile(get_mob_index(MOB_VNUM_INSECTS)); mob->level = URANGE(15, level, 55) - 5; mob->perm_hit = mob->level * 20 + dice(1,mob->level); mob->hit = MAX_HIT(mob); mob->summon_timer = level/5; ch->summon_timer = 10; char_to_room(mob, ch->in_room); act(AT_BLUE, "You summon $N.", ch, NULL, mob, TO_CHAR); mana = is_class( ch, CLASS_VAMPIRE ) ? level / 2 : level * 2; if ( MT( ch ) < mana ) { sprintf( buf, "%sYou don't have enough %s to bind $N!", (is_class( ch, CLASS_VAMPIRE )) ? "&r" : "&R", (is_class( ch, CLASS_VAMPIRE )) ? "blood" : "mana" ); act(AT_WHITE, buf, ch, NULL, mob, TO_CHAR ); extract_char( mob, TRUE ); return; } MT( ch ) -= mana; act(AT_GREEN, "$n summons $N.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_BLUE, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_BLUE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); fch->fighting = mob; mob->fighting = fch; /* set_fighting(mob, fch); set_fighting(fch, mob);*/ } return; } void spell_summon_pack(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; char buf [ MAX_STRING_LENGTH ]; int mana; if(ch->summon_timer > 0) { send_to_char(AT_BLUE, "You casted the spell, but nothing appears.\n\r", ch); return; } mob = create_mobile(get_mob_index(MOB_VNUM_WOLFS)); mob->level = URANGE(31, level, 90) - 5; mob->perm_hit = mob->level * 20 + dice(1,mob->level); mob->hit = MAX_HIT(mob); mob->summon_timer = level/8; ch->summon_timer = 15; char_to_room(mob, ch->in_room); act(AT_GREEN, "You summon $N.", ch, NULL, mob, TO_CHAR); mana = is_class( ch, CLASS_VAMPIRE ) ? level / 2 : level * 2; if ( MT( ch ) < mana ) { sprintf( buf, "%sYou don't have enough %s to bind $N!", is_class( ch, CLASS_VAMPIRE ) ? "&r" : "&R", is_class( ch, CLASS_VAMPIRE ) ? "blood" : "mana" ); act(AT_WHITE, buf, ch, NULL, mob, TO_CHAR ); extract_char( mob, TRUE ); return; } MT( ch ) -= mana; act(AT_GREEN, "$N comes to $n aid.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_BLUE, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_BLUE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return; } void spell_summon_demon(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; char buf [ MAX_STRING_LENGTH ]; int mana; if(ch->summon_timer > 0) { send_to_char(AT_RED, "You casted the spell, but nothing appears.\n\r", ch); return; } mob = create_mobile(get_mob_index(MOB_VNUM_DEMON)); mob->level = URANGE(51, level, 100) - 5; mob->perm_hit = mob->level * 20 + dice(1,mob->level); mob->hit = MAX_HIT(mob); mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_RED, "You summon $N from the abyss.", ch, NULL, mob, TO_CHAR); mana = is_class( ch, CLASS_VAMPIRE ) ? level / 2 : level * 2; if ( MT( ch ) < mana ) { sprintf( buf, "%sYou don't have enough %s to bind $N!", is_class( ch, CLASS_VAMPIRE ) ? "&r" : "&R", is_class( ch, CLASS_VAMPIRE ) ? "blood" : "mana" ); act(AT_WHITE, buf, ch, NULL, mob, TO_CHAR ); extract_char( mob, TRUE ); return; } MT( ch ) -= mana; act(AT_RED, "$n summons $N from the abyss.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_RED, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_RED, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return; } void spell_summon_angel(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; char buf[ MAX_STRING_LENGTH ]; int mana; if(ch->summon_timer > 0) { send_to_char(AT_WHITE, "You casted the spell, but nothing appears.\n\r", ch); return; } mob = create_mobile(get_mob_index(MOB_VNUM_ANGEL)); mob->level = URANGE(51, level, 100) - 5; mob->perm_hit = mob->level * 20 + dice(10,mob->level); mob->hit = MAX_HIT(mob); mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_WHITE, "You summon $N from heaven.", ch, NULL, mob, TO_CHAR); mana = is_class( ch, CLASS_VAMPIRE ) ? level / 2 : level * 2; if ( MT( ch ) < mana ) { sprintf( buf, "%sYou don't have enough %s to bind $N!", is_class( ch, CLASS_VAMPIRE ) ? "&r" : "&R", is_class( ch, CLASS_VAMPIRE ) ? "blood" : "mana" ); act(AT_WHITE, buf, ch, NULL, mob, TO_CHAR ); extract_char( mob, TRUE ); return; } MT( ch ) -= mana; act(AT_WHITE, "$n calls forth $N from Heaven.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_WHITE, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_WHITE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return; } void spell_summon_shadow(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; char buf[MAX_STRING_LENGTH]; int mana; if(ch->summon_timer > 0) { send_to_char(AT_WHITE, "You casted the spell, but nothing appears.\n\r", ch); return; } mob = create_mobile(get_mob_index(MOB_VNUM_SHADOW)); mob->level = URANGE(51, level, 100) - 20; mob->perm_hit = mob->level * 20 + dice(10,mob->level); mob->hit = MAX_HIT(mob); mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_GREY, "You summon $N from the shadow plane.", ch, NULL, mob, TO_CHAR); mana = is_class( ch, CLASS_VAMPIRE ) ? level / 2 : level * 2; if ( MT( ch ) < mana ) { sprintf( buf, "%sYou don't have enough %s to bind $N!", is_class( ch, CLASS_VAMPIRE ) ? "&r" : "&R", is_class( ch, CLASS_VAMPIRE ) ? "blood" : "mana" ); act(AT_WHITE, buf, ch, NULL, mob, TO_CHAR ); extract_char( mob, TRUE ); return; } MT( ch ) -= mana; act(AT_GREY, "$n calls forth $N from the shadow plane.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_WHITE, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_WHITE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return; } void spell_summon_trent(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; char buf[MAX_STRING_LENGTH]; int mana; if(ch->summon_timer > 0) { send_to_char(AT_WHITE, "You casted the spell, but nothing appears.\n\r", ch); return; } mob = create_mobile(get_mob_index(MOB_VNUM_TRENT)); mob->level = URANGE(51, level, 100) - 10; mob->perm_hit = mob->level * 20 + dice(20,mob->level); mob->hit = MAX_HIT(mob); mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_ORANGE, "You summon $N from the plane of nature.", ch, NULL, mob, TO_CHAR); mana = is_class( ch, CLASS_VAMPIRE ) ? level / 2 : level * 2; if ( MT( ch ) < mana ) { sprintf( buf, "%sYou don't have enough %s to bind $N!", is_class( ch, CLASS_VAMPIRE ) ? "&r" : "&R", is_class( ch, CLASS_VAMPIRE ) ? "blood" : "mana" ); act(AT_WHITE, buf, ch, NULL, mob, TO_CHAR ); extract_char( mob, TRUE ); return; } MT( ch ) -= mana; act(AT_ORANGE, "$n calls forth $N from the plane of nature.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_WHITE, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_WHITE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return; } void spell_summon_beast(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; char buf[MAX_STRING_LENGTH]; int mana; char *beast; if(ch->summon_timer > 0) { send_to_char(AT_WHITE, "You casted the spell, but nothing appears.\n\r", ch); return; } switch (number_bits( 4 ) ) { case 0: beast = "horse"; break; case 1: beast = "cow"; break; case 2: beast = "bear"; break; case 3: beast = "lion"; break; case 4: beast = "bobcat"; break; case 5: beast = "mongoose"; break; case 6: beast = "rattle snake"; break; case 7: beast = "monkey"; break; default: beast = "tigeress"; break; } mob = create_mobile(get_mob_index(MOB_VNUM_BEAST)); sprintf(buf, mob->short_descr, beast); free_string( mob->short_descr ); mob->short_descr = str_dup(buf); sprintf(buf, mob->long_descr, beast, ch->name); free_string( mob->long_descr ); mob->long_descr = str_dup(buf); mob->level = URANGE(51, level, 100) - 20; mob->perm_hit = mob->level * 20 + dice(10,mob->level); mob->hit = MAX_HIT(mob); mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_GREEN, "You call $N from the forests.", ch, NULL, mob, TO_CHAR); mana = is_class( ch, CLASS_VAMPIRE ) ? level / 2 : level * 2; if ( MT( ch ) < mana ) { sprintf( buf, "%sYou don't have enough %s to bind $N!", is_class( ch, CLASS_VAMPIRE ) ? "&r" : "&R", is_class( ch, CLASS_VAMPIRE ) ? "blood" : "mana" ); act(AT_WHITE, buf, ch, NULL, mob, TO_CHAR ); extract_char( mob, TRUE ); return; } MT( ch ) -= mana; act(AT_GREEN, "$n calls forth $N from the forests.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_WHITE, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_WHITE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return; } void perm_spell(CHAR_DATA *victim, int sn) { AFFECT_DATA *af; if(is_affected(victim, sn)) { for(af = victim->affected; af != NULL; af = af->next) { if(af->type == sn) { af->duration = -1; } } } return; } int spell_duration(CHAR_DATA *victim, int sn) { AFFECT_DATA *af; if(is_affected(victim, sn)) { for(af = victim->affected; af != NULL; af = af->next) { if(af->type == sn) { return af->duration; } } } return -2; } /* RT save for dispels */ /* modified for envy -XOR */ bool saves_dispel(int dis_level, int spell_level, int duration) { int save; if(duration == -1) spell_level += 5;/* very hard to dispel permanent effects */ save = 50 + (spell_level - dis_level) * 5; save = URANGE( 5, save, 95 ); return number_percent() < save; } /* co-routine for dispel magic and cancellation */ bool check_dispel(int dis_level, CHAR_DATA *victim, int sn) { AFFECT_DATA *af; if (is_affected(victim, sn)) { for(af = victim->affected; af != NULL; af = af->next) { if(af->type == sn) { if ( !saves_spell(dis_level,victim) ) /* if(!saves_dispel(dis_level,victim->level,af->duration))*/ { affect_strip(victim,sn); if(skill_table[sn].msg_off) { send_to_char(C_DEFAULT, skill_table[sn].msg_off, victim ); send_to_char(C_DEFAULT, "\n\r", victim ); if(skill_table[sn].room_msg_off) { act(C_DEFAULT, skill_table[sn].room_msg_off, victim, NULL, NULL, TO_ROOM); } } return TRUE; } else af->level--; } } } return FALSE; } /* Mobs built with spells only have the flag. * These function dispels those spells * -Decklarean */ void check_dispel_aff( CHAR_DATA *victim, bool * found, int level, const char * spell, long vector ) { int sn; sn = skill_lookup(spell); if(IS_AFFECTED(victim,vector) && !saves_spell(level, victim) /* && !saves_dispel(level, victim->level,1) */ && !is_affected(victim,sn) ) { *found = TRUE; REMOVE_BIT(victim->affected_by,vector); if(skill_table[sn].msg_off) { act(C_DEFAULT, skill_table[sn].msg_off, victim, NULL, NULL, TO_CHAR); if(skill_table[sn].room_msg_off) { act(C_DEFAULT, skill_table[sn].room_msg_off, victim, NULL, NULL, TO_ROOM); } } if ( vector == AFF_FLYING ) check_nofloor( victim ); } } void check_dispel_aff2( CHAR_DATA *victim, bool * found, int level, const char * spell, long vector ) { int sn; sn = skill_lookup(spell); if(IS_AFFECTED2(victim,vector) && !saves_dispel(level, victim->level,-1) && !is_affected(victim,sn) ) { *found = TRUE; REMOVE_BIT(victim->affected_by2,vector); if(skill_table[sn].msg_off) { act(C_DEFAULT, skill_table[sn].msg_off, victim, NULL, NULL, TO_CHAR); if(skill_table[sn].room_msg_off) { act(C_DEFAULT, skill_table[sn].room_msg_off, victim, NULL, NULL, TO_ROOM); } } if ( vector == AFF_FLYING ) check_nofloor( victim ); } } bool dispel_flag_only_spells( int level, CHAR_DATA * victim ) { bool found; found = FALSE; check_dispel_aff ( victim, &found, level, "blindness",AFF_BLIND); check_dispel_aff ( victim, &found, level, "charm person",AFF_CHARM); check_dispel_aff ( victim, &found, level, "curse",AFF_CURSE); check_dispel_aff ( victim, &found, level, "detect evil",AFF_DETECT_EVIL); check_dispel_aff ( victim, &found, level, "detect hidden",AFF_DETECT_HIDDEN); check_dispel_aff ( victim, &found, level, "detect invis",AFF_DETECT_INVIS); check_dispel_aff ( victim, &found, level, "detect magic",AFF_DETECT_MAGIC); check_dispel_aff ( victim, &found, level, "faerie fire",AFF_FAERIE_FIRE ); check_dispel_aff ( victim, &found, level, "fireshield", AFF_FIRESHIELD ); check_dispel_aff ( victim, &found, level, "flaming",AFF_FLAMING ); check_dispel_aff ( victim, &found, level, "fly",AFF_FLYING); check_dispel_aff ( victim, &found, level, "haste",AFF_HASTE); check_dispel_aff ( victim, &found, level, "iceshield",AFF_ICESHIELD ); check_dispel_aff ( victim, &found, level, "infravision",AFF_INFRARED ); check_dispel_aff ( victim, &found, level, "invis",AFF_INVISIBLE ); check_dispel_aff ( victim, &found, level, "pass door",AFF_PASS_DOOR ); check_dispel_aff ( victim, &found, level, "protection evil",AFF_PROTECT ); check_dispel_aff ( victim, &found, level, "sanctuary",AFF_SANCTUARY ); check_dispel_aff ( victim, &found, level, "shockshield",AFF_SHOCKSHIELD ); check_dispel_aff ( victim, &found, level, "sleep",AFF_SLEEP); check_dispel_aff2( victim, &found, level, "detect good",AFF_DETECT_GOOD ); check_dispel_aff2( victim, &found, level, "field of decay", AFF_FIELD); check_dispel_aff2( victim, &found, level, "protection good",AFF_PROTECTION_GOOD ); check_dispel_aff2( victim, &found, level, "true sight",AFF_TRUESIGHT ); return found; } /* New dispel magic by Decklarean * The old way was just to stupid. :> * This will dispel all magic spells. */ void spell_dispel_magic ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA *paf; bool found; if (saves_spell(level, victim)) { send_to_char(AT_RED, "You feel a brief tingling sensation.\n\r",victim); send_to_char(AT_RED, "The spell failed.\n\r",ch); return; } found = FALSE; /* Check dispel of spells that mobs where built with */ if (IS_NPC( victim ) ) found = dispel_flag_only_spells( level, victim ); /* Check dispel of spells cast */ for( paf = victim->affected; paf; paf = paf->next ) { if (paf->deleted) continue; if ( skill_table[paf->type].spell_fun != spell_null && skill_table[paf->type].dispelable == TRUE ) if(check_dispel(level,victim,paf->type)) found = TRUE; } for( paf = victim->affected2; paf; paf = paf->next ) { if (paf->deleted) continue; if ( skill_table[paf->type].spell_fun != spell_null && skill_table[paf->type].dispelable == TRUE ) if(check_dispel(level,victim,paf->type)) found = TRUE; } if(found) { send_to_char(AT_RED, "You feel a brief tingling sensation.\n\r",victim); send_to_char(AT_YELLOW, "Unraveled magical energy ripple away at your succes.\n\r",ch); } else send_to_char(AT_RED, "The spell failed.\n\r",ch); } /* modified by XOR */ /* Rom2 modified for enhanced use */ /* void spell_dispel_magic ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; bool found = FALSE; if(saves_spell(level, victim)) { send_to_char(C_DEFAULT, "You feel a brief tingling sensation.\n\r",victim); send_to_char(C_DEFAULT, "You failed.\n\r", ch); } */ /* begin running through the spells */ /* if(check_dispel(level,victim,skill_lookup("armor"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("bless"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("blindness"))) { found = TRUE; act(C_DEFAULT, "$n is no longer blinded.",victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("change sex"))) { found = TRUE; act(C_DEFAULT, "$n looks more like $mself again.",victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("charm person"))) { found = TRUE; act(C_DEFAULT, "$n regains $s free will.",victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("chill touch"))) { found = TRUE; act(C_DEFAULT, "$n looks warmer.",victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("curse"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("detect evil"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("detect hidden"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("detect invis"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("detect magic"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("faerie fire"))) { found = TRUE; act(C_DEFAULT, "$n's outline fades.",victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("fly"))) { found = TRUE; act(C_DEFAULT, "$n falls to the ground!",victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("giant strength"))) { found = TRUE; act(C_DEFAULT, "$n no longer looks so mighty.",victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("infravision"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("invis"))) { found = TRUE; act(C_DEFAULT, "$n fades into existance.",victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("mass invis"))) { found = TRUE; act(C_DEFAULT, "$n fades into existance.",victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("pass door"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("protection"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("sanctuary"))) { found = TRUE; act(C_DEFAULT, "The white aura around $n's body vanishes.", victim,NULL,NULL,TO_ROOM); } if(IS_AFFECTED(victim,AFF_SANCTUARY) && !saves_dispel(level, victim->level,-1) && !is_affected(victim,skill_lookup("sanctuary"))) { found = TRUE; REMOVE_BIT(victim->affected_by,AFF_SANCTUARY); act(C_DEFAULT, "The white aura around $n's body vanishes.", victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("shield"))) { found = TRUE; act(C_DEFAULT, "The shield protecting $n vanishes.", victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("sleep"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("stone skin"))) { act(C_DEFAULT, "$n's skin regains its normal texture.", victim,NULL,NULL,TO_ROOM); found = TRUE; } if(check_dispel(level,victim,skill_lookup("weaken"))) { act(C_DEFAULT, "$n looks stronger.",victim,NULL,NULL,TO_ROOM); found = TRUE; } if(check_dispel(level,victim,skill_lookup("fireshield"))) { found = TRUE; act(AT_RED, "The flames about $n's body burn out.", victim, NULL, NULL, TO_ROOM ); } if(IS_AFFECTED(victim,AFF_FIRESHIELD) && !saves_dispel(level, victim->level,-1) && !is_affected(victim,skill_lookup("fireshield"))) { found = TRUE; REMOVE_BIT(victim->affected_by,AFF_FIRESHIELD); act(AT_RED, "The flames about $n's body burn out.", victim, NULL, NULL, TO_ROOM ); } if(check_dispel(level,victim,skill_lookup("shockshield"))) { found = TRUE; act(AT_BLUE, "The electricity about $n's body flee's into the ground.", victim, NULL, NULL, TO_ROOM ); } if(IS_AFFECTED(victim,AFF_SHOCKSHIELD) && !saves_dispel(level, victim->level,-1) && !is_affected(victim,skill_lookup("shockshield"))) { found = TRUE; REMOVE_BIT(victim->affected_by,AFF_SHOCKSHIELD); act(AT_BLUE, "The electricity about $n's body flee's into the ground.", victim, NULL, NULL, TO_ROOM ); } if(check_dispel(level,victim,skill_lookup("iceshield"))) { found = TRUE; act(AT_LBLUE, "The icy crust about $n's body melts to a puddle.", victim, NULL, NULL, TO_ROOM); } if(IS_AFFECTED(victim,AFF_ICESHIELD) && !saves_dispel(level, victim->level,-1) && !is_affected(victim,skill_lookup("iceshield"))) { found = TRUE; REMOVE_BIT(victim->affected_by,AFF_ICESHIELD); act(AT_LBLUE, "The icy crust about $n's body melts to a puddle.", victim, NULL, NULL, TO_ROOM ); } if(found) send_to_char(C_DEFAULT, "Ok.\n\r",ch); else send_to_char(C_DEFAULT, "Spell failed.\n\r",ch); */ /* if ( !victim->fighting || !is_same_group( ch, victim->fighting ) ) multi_hit( victim, ch, TYPE_UNDEFINED ); */ /* return; }*/ /* New cancellation by Decklarean * The old way was just to stupid. :> * This will dispell all magic spells. */ void spell_cancellation(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA *paf; bool found; if((!IS_NPC(ch) && IS_NPC(victim) && !(IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim)) || (IS_NPC(ch) && !IS_NPC(victim)) || !is_same_group(ch, victim)) { send_to_char(C_DEFAULT, "You failed, try dispel magic.\n\r",ch); return; } found = FALSE; /* Check dispel of spells that mobs where built with */ if (IS_NPC( victim ) ) found = dispel_flag_only_spells( level, victim ); /* Check dispel of spells cast */ for( paf = victim->affected; paf; paf = paf->next ) { if ( skill_table[paf->type].spell_fun != spell_null && skill_table[paf->type].spell_fun != spell_poison ) if( check_dispel(level,victim,paf->type) ) found = TRUE; } for( paf = victim->affected2; paf; paf = paf->next ) { if ( skill_table[paf->type].spell_fun != spell_null && skill_table[paf->type].spell_fun != spell_poison ) if( check_dispel(level,victim,paf->type) ) found = TRUE; } if(found) send_to_char(AT_YELLOW, "Unraveled magical energy ripple away at your succes.\n\r",ch); else send_to_char(AT_RED, "The spell failed.\n\r",ch); } /* void spell_cancellation(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *) vo; bool found = FALSE; level += 2; if((!IS_NPC(ch) && IS_NPC(victim) && !(IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim)) || (IS_NPC(ch) && !IS_NPC(victim)) || !is_same_group(ch, victim)) { send_to_char(C_DEFAULT, "You failed, try dispel magic.\n\r",ch); return; } */ /* unlike dispel magic, victim gets NO save */ /* begin running through the spells */ /* if(check_dispel(level,victim,skill_lookup("armor"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("bless"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("blindness"))) { found = TRUE; act(C_DEFAULT, "$n is no longer blinded.",victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("change sex"))) { found = TRUE; act(C_DEFAULT, "$n looks more like $mself again.",victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("charm person"))) { found = TRUE; act(C_DEFAULT, "$n regains $s free will.",victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("chill touch"))) { found = TRUE; act(C_DEFAULT, "$n looks warmer.",victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("curse"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("detect evil"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("detect hidden"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("detect invis"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("detect magic"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("faerie fire"))) { found = TRUE; act(C_DEFAULT, "$n's outline fades.",victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("fly"))) { found = TRUE; act(C_DEFAULT, "$n falls to the ground!",victim,NULL,NULL,TO_ROOM); check_nofloor( ch ); } if(check_dispel(level,victim,skill_lookup("giant strength"))) { found = TRUE; act(C_DEFAULT, "$n no longer looks so mighty.",victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("infravision"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("invis"))) { found = TRUE; act(C_DEFAULT, "$n fades into existance.",victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("mass invis"))) { found = TRUE; act(C_DEFAULT, "$n fades into existance.",victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("pass door"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("protection"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("sanctuary"))) { found = TRUE; act(C_DEFAULT, "The white aura around $n's body vanishes.", victim,NULL,NULL,TO_ROOM); } if(IS_AFFECTED(victim,AFF_SANCTUARY) && !saves_dispel(level, victim->level,-1) && !is_affected(victim,skill_lookup("sanctuary"))) { found = TRUE; REMOVE_BIT(victim->affected_by,AFF_SANCTUARY); act(C_DEFAULT, "The white aura around $n's body vanishes.", victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("shield"))) { found = TRUE; act(C_DEFAULT, "The shield protecting $n vanishes.", victim,NULL,NULL,TO_ROOM); } if(check_dispel(level,victim,skill_lookup("sleep"))) found = TRUE; if(check_dispel(level,victim,skill_lookup("stone skin"))) { act(C_DEFAULT, "$n's skin regains its normal texture.", victim,NULL,NULL,TO_ROOM); found = TRUE; } if(check_dispel(level,victim,skill_lookup("weaken"))) { act(C_DEFAULT, "$n looks stronger.",victim,NULL,NULL,TO_ROOM); found = TRUE; } if(check_dispel(level,victim,skill_lookup("fireshield"))) { found = TRUE; act(AT_RED, "The flames about $n's body burn out.", victim, NULL, NULL, TO_ROOM ); } if(IS_AFFECTED(victim,AFF_FIRESHIELD) && !saves_dispel(level, victim->level,-1) && !is_affected(victim,skill_lookup("fireshield"))) { found = TRUE; REMOVE_BIT(victim->affected_by,AFF_FIRESHIELD); act(AT_RED, "The flames about $n's body burn out.", victim, NULL, NULL, TO_ROOM ); } if(check_dispel(level,victim,skill_lookup("shockshield"))) { found = TRUE; act(AT_BLUE, "The electricity about $n's body flee's into the ground.", victim, NULL, NULL, TO_ROOM ); } if(IS_AFFECTED(victim,AFF_SHOCKSHIELD) && !saves_dispel(level, victim->level,-1) && !is_affected(victim,skill_lookup("shockshield"))) { found = TRUE; REMOVE_BIT(victim->affected_by,AFF_SHOCKSHIELD); act(AT_BLUE, "The electricity about $n's body flee's into the ground.", victim, NULL, NULL, TO_ROOM ); } if(check_dispel(level,victim,skill_lookup("iceshield"))) { found = TRUE; act(AT_LBLUE, "The icy crust about $n's body melts to a puddle.", victim, NULL, NULL, TO_ROOM); } if(IS_AFFECTED(victim,AFF_ICESHIELD) && !saves_dispel(level, victim->level,-1) && !is_affected(victim,skill_lookup("iceshield"))) { found = TRUE; REMOVE_BIT(victim->affected_by,AFF_ICESHIELD); act(AT_LBLUE, "The icy crust about $n's body melts to a puddle.", victim, NULL, NULL, TO_ROOM ); } if(found) send_to_char(C_DEFAULT, "Ok.\n\r",ch); else send_to_char(C_DEFAULT, "Spell failed.\n\r",ch); return; }*/ /* * Turn undead and mental block by Altrag */ void spell_turn_undead( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int chance; if ( !IS_NPC(victim) || !IS_SET(victim->act, ACT_UNDEAD)) { send_to_char(C_DEFAULT, "Spell failed.\n\r", ch ); return; } chance = (level * (10 + IS_GOOD(ch) ? 15 : IS_EVIL(ch) ? 0 : 10) ); chance /= victim->level; if (number_percent( ) < chance && !saves_spell( level, victim )) { act(AT_WHITE,"$n has turned $N!",ch,NULL,victim,TO_ROOM); act(AT_WHITE,"You have turned $N!",ch,NULL,victim,TO_CHAR); raw_kill(ch,victim); return; } send_to_char(C_DEFAULT,"Spell failed.\n\r",ch); return; } void spell_mental_block( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected(victim,sn) ) return; af.type = sn; af.level = level; af.duration = number_range( level / 4, level / 2 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_NOASTRAL; affect_to_char( victim, &af ); send_to_char( AT_BLUE, "Your mind feels free of instrusion.\n\r",victim); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r",ch); } /* END */ void spell_protection_good(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *)vo; AFFECT_DATA af; if ( IS_AFFECTED2(ch, AFF_PROTECTION_GOOD) ) return; af.type = sn; af.level = level; af.duration = 24; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_PROTECTION_GOOD; affect_to_char2( victim, &af ); if ( ch != victim ) send_to_char( AT_BLUE, "Ok.\n\r",ch); send_to_char(AT_BLUE, "You feel protected.\n\r",victim); return; } void spell_detect_good(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *)vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_DETECT_GOOD ) ) return; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_DETECT_GOOD; affect_to_char2(ch, &af); if ( ch != victim) send_to_char(AT_BLUE, "Ok.\n\r",ch); send_to_char(AT_BLUE, "Your eyes tingle.\n\r",victim); return; } void spell_holy_strength(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if(victim->position == POS_FIGHTING || is_affected(victim, sn)) return; af.type = sn; af.level = level; af.duration = 6 + level; af.location = APPLY_HITROLL; af.modifier = level / 4; af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_DAMROLL; af.modifier = level / 4; affect_to_char( victim, &af ); af.location = APPLY_STR; af.modifier = level / 50; affect_to_char( victim, &af ); if(ch != victim) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "The strength of the gods fills you.\n\r", victim); return; } void spell_curse_of_nature(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected(victim, sn) ) { send_to_char(AT_RED, "You have failed.\n\r", ch ); return; } af.type = sn; af.level = level; af.duration = 6 + level; af.location = APPLY_HITROLL; af.modifier = 0 - level * 2 / 3; af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_DAMROLL; af.modifier = 0 - level * 2 / 3; affect_to_char( victim, &af ); af.location = APPLY_STR; af.modifier = 0 - level / 30; affect_to_char( victim, &af ); if(ch != victim) send_to_char(AT_GREEN, "Ok.\n\r", ch ); send_to_char(AT_GREEN, "The wrath of nature wrecks you.\n\r", victim); return; } void spell_enchanted_song(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *)vo; CHAR_DATA *rch = get_char(ch); if ( ch == victim ) { act( AT_BLUE, "$n sings an enchanting song.", ch, NULL, NULL, TO_ROOM ); send_to_char(AT_BLUE, "You sing a song.\n\r", ch ); } act( AT_BLUE, "Your song pacifies $N.", ch, NULL, victim, TO_CHAR ); act( AT_BLUE, "$n's song pacifies $N.", ch, NULL, victim, TO_NOTVICT ); act( AT_BLUE, "$n's song slows your reactions.", ch, NULL, victim, TO_VICT ); STUN_CHAR( victim, 1, STUN_TOTAL ); for ( rch = ch->in_room->people; rch; rch = rch->next_in_room ) { if ( rch->fighting ) stop_fighting( rch, TRUE ); } return; } /* RT haste spell */ void spell_haste( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn ) || IS_AFFECTED(victim,AFF_HASTE) /* || IS_SET(victim->off_flags,OFF_FAST)*/) { if (victim == ch) send_to_char(C_DEFAULT, "You can't move any faster!\n\r",ch); else act(C_DEFAULT, "$N is already moving as fast as $e can.", ch,NULL,victim,TO_CHAR); return; } af.type = sn; af.level = level; if (victim == ch) af.duration = level/2; else af.duration = level/4; af.location = APPLY_DEX; af.modifier = 1 + (level >= 18) + (level >= 25) + (level >= 32); af.bitvector = AFF_HASTE; affect_to_char( victim, &af ); send_to_char(C_DEFAULT, "You feel yourself moving more quickly.\n\r", victim ); act(C_DEFAULT, "$n is moving more quickly.",victim,NULL,NULL,TO_ROOM); if ( ch != victim ) send_to_char(C_DEFAULT, "Ok.\n\r", ch ); return; } void spell_healing_hands( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *)vo; int divisor = 1; int heal = 0; if ( ch == victim ) { int mana; /* Refund mana lost by casting. Make it seem like a new target type. */ mana = SPELL_COST( ch, sn ); MT( ch ) -= mana; send_to_char(AT_BLUE, "You cannot cast this spell on yourself.\n\r", ch ); return; } if ( victim->hit >= MAX_HIT(victim) ) { act(AT_BLUE, "You heal $N.", ch, NULL, victim, TO_CHAR ); return; } if ( IS_NEUTRAL( ch ) ) divisor = 2; if ( IS_EVIL( ch ) ) divisor = 4; /* divisos += 2;*/ heal = (MAX_HIT(victim) - victim->hit) / divisor; victim->hit += heal; act(AT_BLUE, "You heal $N.", ch, NULL, victim, TO_CHAR); act(AT_BLUE, "$n heals you.", ch, NULL, victim, TO_VICT); act(AT_BLUE, "$n heals $N.", ch, NULL, victim, TO_NOTVICT); return; } void spell_hex( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED( victim, AFF_BLIND + AFF_CURSE ) && IS_AFFECTED2( victim, AFF_CONFUSED ) ) { act( AT_DGREY, "$N is already hexed.", ch, NULL, victim, TO_CHAR ); return; } if ( saves_spell( level, victim ) ) { act( AT_DGREY, "$N resists the hex.", ch, NULL, victim, TO_CHAR ); return; } af.type = sn; af.level = level; af.duration = ( 2 * level / 3 + 20 ) / 2; af.location = APPLY_HITROLL; af.modifier = -10; af.bitvector = AFF_BLIND; affect_to_char( victim, &af ); af.location = APPLY_HITROLL; af.modifier = -1; af.bitvector = AFF_CURSE; affect_to_char( victim, &af ); af.location = APPLY_SAVING_SPELL; af.modifier = 1; af.bitvector = AFF_CURSE; affect_to_char( victim, &af ); af.location = APPLY_STR; af.modifier = -1 - ( level >= 20 ) - ( level >= 40 ) - ( level >= 60 ) - ( level >= 80 ); affect_to_char( victim, &af ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_CONFUSED; affect_to_char2( victim, &af ); send_to_char( AT_DGREY, "You have hexed your opponent.\n\r", ch ); send_to_char( AT_DGREY, "A hex has been placed upon your soul.\n\r", victim ); return; } void spell_dark_ritual( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj; int mana; bool found = FALSE; for ( obj = ch->in_room->contents; obj; obj = obj->next ) { if ( obj->deleted ) continue; if ( obj->item_type == ITEM_CORPSE_NPC ) { found = TRUE; break; } } if ( found == TRUE ) { mana = UMAX( 30, number_fuzzy( level / 2 ) ); ch->mana += mana; ch->mana = UMIN( MAX_MANA(ch), ch->mana ); send_to_char( AT_DGREY, "You extract the last of the energy from the corpse.\n\r", ch ); act( AT_DGREY, "$n saps away the last of the mystical energies from the $p.", ch, obj, NULL, TO_ROOM ); extract_obj( obj ); } else send_to_char( AT_DGREY, "You must have a corpse to sacrifice to perform a dark ritual.\n\r", ch ); return; } void spell_field_of_decay( int sn, int level, CHAR_DATA *ch, void *vo ) { AFFECT_DATA af; if ( IS_AFFECTED2( ch, AFF_FIELD ) ) return; af.type = sn; af.level = level; af.duration = number_fuzzy( level / 5 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_FIELD; affect_to_char2( ch, &af ); send_to_char( AT_DGREY, "You summon the power of the dead and a black haze envelops you.\n\r", ch ); act( AT_DGREY, "A black haze emanates from $n's body and envelops $m.", ch, NULL, NULL, TO_ROOM ); return; } void spell_stench_of_decay( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 215, 220, 225, 230, 235, 240, 245, 250, 255, 260 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level] / 2, dam_each[level] * 7 ); dam = sc_dam( ch, dam ); if ( IS_AFFECTED2( victim, AFF_FIELD ) ) dam /= 6; if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return; } void spell_soul_bind( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; OBJ_DATA *soulgem; if ( !IS_NPC(victim) || saves_spell( level, victim ) ) { send_to_char(AT_BLUE, "You failed.\n\r", ch); return; } soulgem = create_object( get_obj_index( OBJ_VNUM_SOULGEM ), 0 ); soulgem->ac_vnum = victim->pIndexData->vnum; soulgem->level = ch->level; soulgem->timer = ch->level / 4; #ifdef NEW_MONEY soulgem->cost.silver = soulgem->cost.copper = 0; soulgem->cost.gold = victim->level * 1000; #else soulgem->cost = victim->level * 1000; #endif soulgem->ac_charge[0] = soulgem->ac_charge[1] = 1; obj_to_char( soulgem , ch ); act(AT_BLUE, "You tear out $Ns soul, binding it to form a Soulgem.", ch, NULL, victim, TO_CHAR); act(AT_BLUE, "$n tears out $Ns soul, binding it to form a Soulgem.", ch, NULL, victim, TO_ROOM); act(AT_BLUE, "$N screams in agony as it slowly dissipates into nothingness!", ch, NULL, victim, TO_CHAR); act(AT_BLUE, "$N screams in agony as it slowly dissipates into nothingness!", ch, NULL, victim, TO_ROOM); act(AT_WHITE, "Your SOUL is STOLEN by $n!", ch, NULL, victim, TO_VICT); if ( IS_NPC( victim ) ) extract_char( victim, TRUE ); else extract_char( victim, FALSE ); return; } /* MONK SPELLS */ void spell_iron_skin( int sn, int level, CHAR_DATA *ch, void *vo ) { AFFECT_DATA af; if ( is_affected( ch, sn ) ) return; send_to_char( AT_GREY, "Your skin turns to iron.\n\r", ch ); act( AT_GREY, "$n's skin turns to iron.", ch, NULL, NULL, TO_ROOM ); af.type = sn; af.level = ch->level; af.duration = ch->level / 6; af.location = APPLY_AC; af.modifier = 0 - number_fuzzy( ch->level ) / 2; af.bitvector = AFF_INERTIAL; affect_to_char2( ch, &af ); return; } void spell_chi_shield( int sn, int level, CHAR_DATA *ch, void *vo ) { AFFECT_DATA af; if ( is_affected( ch, sn ) ) return; send_to_char( AT_BLUE, "You tap into your chi and use it to raise a chi shield.\n\r", ch ); act( AT_BLUE, "$n is surrounded by a chi shield.", ch, NULL, NULL, TO_ROOM ); af.type = sn; af.level = ch->level * 2; af.duration = ch->level / 4; af.location = APPLY_SAVING_SPELL; af.modifier = 0 - ch->level/4; af.bitvector = AFF_PROTECT; affect_to_char( ch, &af ); af.location = APPLY_SAVING_BREATH; af.modifier = 0 - ch->level / 4; af.bitvector = AFF_PROTECTION_GOOD; affect_to_char2( ch, &af ); return; } /* Adds + dam to spells for having spellcraft skill */ int sc_dam( CHAR_DATA *ch, int dam ) { float mod; if ( ch->level < 50 ) mod = 82.6; /* x1.15 */ else if ( ch->level < 60 ) mod = 73.07; /* x1.3 */ else if ( ch->level < 70 ) mod = 65.51; /* x1.45 */ else if ( ch->level < 80 ) mod = 55.88; /* x1.7 */ else if ( ch->level < 90 ) mod = 51.35; /* x1.85 */ else if ( ch->level < 95 ) mod = 47.5; /* x2 */ else mod = 38; /* x2.5 */ if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_spellcraft] > 0 ) dam += dam * ch->pcdata->learned[gsn_spellcraft] / mod; return dam; } void spell_thunder_strike( int sn, int level, CHAR_DATA *ch, void *vo ) { AFFECT_DATA af; CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 155, 160, 165, 170, 175, 185, 190, 195, 200, 205, 207, 209, 211, 213, 215, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 247, 249, 251, 253, 255, 257, 259, 261, 263, 265, 272, 274, 276, 278, 280, 282, 284, 286, 288, 290, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 322, 324, 326, 328, 330, 332, 334, 336, 338, 340, 347, 349, 351, 353, 355, 357, 359, 361, 363, 365, 375, 380, 385, 390, 395, 400, 405, 410, 415, 420 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1); level = UMAX( 0, level ); dam = number_range( dam_each[level], dam_each[level] * 8 ); dam = sc_dam( ch, dam ); if ( IS_AFFECTED( victim, AFF_SHOCKSHIELD) ) dam /= 2; if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); if ( IS_AFFECTED( victim, AFF_BLIND ) && IS_AFFECTED2( victim, AFF_CONFUSED ) ) { return; } af.type = sn; af.level = level; af.duration = level / 50; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_BLIND; affect_to_char( victim, &af ); act( AT_YELLOW, "A brilliant flash of lightning strikes $N !", ch, NULL, victim, TO_CHAR ); send_to_char(AT_YELLOW, "A flash of lightning makes everything dark!\n\r", victim ); act(AT_YELLOW, "A tremendous bolt of lightning has blinded $N !", ch, NULL, victim, TO_NOTVICT ); af.type = sn; af.level = level; af.duration = 2; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_CONFUSED; affect_to_char2( victim, &af ); STUN_CHAR( ch, 3, STUN_COMMAND ); act(AT_WHITE, "Booming thunder causes momentary confusion to $N!", ch,NULL, victim, TO_CHAR ); send_to_char(AT_WHITE, "Loud thunder wracks your ears and leaves you confused in the midst of battle!\n\r", victim ); act(AT_WHITE, "$N looks confused!", ch, NULL, victim, TO_NOTVICT ); return; } /* * Bard spells -- Thanks Arkhane :> */ void spell_inspiration( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; char buf [ MAX_STRING_LENGTH ]; act( AT_YELLOW, "$n sings a song about great battles and brave heros.", ch, NULL, NULL, TO_ROOM ); for( victim = ch->in_room->people; victim; victim = victim->next_in_room ) { if ( ( victim->deleted ) || !is_same_group( ch, victim ) ) continue; if ( IS_NPC( victim ) ) continue; if( is_affected( victim, sn ) ) { if( victim == ch ) send_to_char( AT_WHITE, "You have already been inspired.\n\r", victim ); else act( AT_WHITE, "$N has been inspired already.", ch, NULL, victim, TO_CHAR ); /* return; (still want to loop through rest of chars so just continue) */ continue; } af.type = sn; af.level = level; af.duration = level; af.location = APPLY_HITROLL; af.modifier = level / 6; af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_DAMROLL; af.modifier = level / 6; affect_to_char( victim, &af ); af.location = APPLY_SAVING_SPELL; af.modifier = - level / 2; affect_to_char( victim, &af ); if ( victim != ch) { sprintf( buf, "You become inspired by %s's song.\n\r", ch->name ); send_to_char( AT_CYAN, buf, victim ); sprintf( buf, "%s becomes inspired by your song.\n\r", victim->name ); send_to_char( AT_CYAN, buf, ch ); } else send_to_char( AT_CYAN, "You inspire yourself to greater heights.\n\r", ch ); } return; } void spell_war_cry( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; act( AT_BLOOD, "$n's cry for the death of $s enemies pierces through the room!", ch, NULL, NULL, TO_ROOM ); if ( saves_spell( level, victim ) ) { act( AT_WHITE, "$N ignores your cry for blood.", ch, NULL, victim, TO_CHAR ); return; } af.type = sn; af.level = level; af.duration = 3; af.location = APPLY_HITROLL; af.modifier = - level / 20; af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_DAMROLL; af.modifier = - level / 20; affect_to_char( victim, &af ); if ( ch != victim ) send_to_char( AT_BLOOD, "Your cry for war sends fear into your opponent!\n\r", ch ); send_to_char( AT_BLOOD, "A bloodthirsty cry sends shivers down your spine.\n\r", victim ); return; } void spell_group_healing( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; act( AT_WHITE, "$n sings a soothing song.", ch, NULL, NULL, TO_ROOM ); for( victim = ch->in_room->people; victim; victim = victim->next_in_room ) { if ( IS_NPC( victim ) || ( victim->deleted ) || ( !is_same_group( ch, victim ) ) ) continue; victim->hit = UMIN( victim->hit + 150, MAX_HIT(victim) + 50 ); update_pos( victim ); if( ch != victim ) send_to_char( AT_BLUE, "Ok.\n\r", ch ); } send_to_char( AT_BLUE, "You have completed your song.\n\r", ch ); return; } void spell_chant( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; send_to_char(AT_BLUE, "You begin your loud chant of destruction!\n\r", ch ); act(AT_BLUE, "$n's chant wreaks havoc everywhere!", ch, NULL, NULL, TO_ROOM ); for ( victim = ch->in_room->people; victim; victim = victim->next_in_room ) { if ( victim->deleted ) continue; if ( victim != ch && ( IS_NPC( ch ) ? !IS_NPC( victim ) : IS_NPC( victim ) ) ) damage( ch, victim, 1.5 * level + dice( level, 6 ), sn ); } return; } /*Decklarean*/ void spell_blur ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn ) ) return; af.type = sn; af.level = level; af.duration = 3 + level; af.location = APPLY_AC; af.modifier = 0 - level/2; af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_SAVING_SPELL; af.modifier = 0 - level / 3; affect_to_char( victim, &af ); send_to_char(AT_GREY, "Your form blurs.\n\r", victim ); act(AT_GREY, "$N form becomes blurred, shifting and wavering before you.", ch, NULL, victim, TO_NOTVICT ); return; } /*Decklarean*/ void spell_firewall( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *vch; if ( IS_SET( ch->in_room->room_flags, ROOM_SAFE ) || IS_SET( ch->in_room->room_flags, ROOM_NO_OFFENSIVE ) ) send_to_char( AT_BLUE, "The spell fails to ignite.", ch ); send_to_char(AT_RED, "A wall of fire explodes out in all direction from you!\n\r", ch ); act(AT_RED, "A wall of fire explodes out from $n!", ch, NULL, NULL, TO_ROOM ); for ( vch = ch->in_room->people; vch; vch = vch->next_in_room ) { if ( vch->deleted ) continue; if ( vch != ch ) damage( ch, vch, level + dice( level, 20 ), sn ); } return; }