/*************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * Much time and thought has gone into this software and you are * * benefitting. We hope that you share your changes too. What goes * * around, comes around. * ***************************************************************************/ /*************************************************************************** * ROM 2.4 is copyright 1993-1995 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@pacinfo.com) * * Gabrielle Taylor (gtaylor@pacinfo.com) * * Brian Moore (rom@rom.efn.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * ***************************************************************************/ /*************************************************************************** * ROT 1.4 is copyright 1996-1997 by Russ Walsh * * By using this code, you have agreed to follow the terms of the * * ROT license, in the file doc/rot.license * ***************************************************************************/ #if defined(macintosh) #include <types.h> #else #include <sys/types.h> #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "merc.h" #include "magic.h" #include "tables.h" #include "clan.h" #include "recycle.h" DECLARE_DO_FUN(do_scan ); DECLARE_DO_FUN(do_look ); DECLARE_DO_FUN(do_get ); DECLARE_DO_FUN(do_sacrifice); DECLARE_DO_FUN(do_flee); BUFFER * show_list_to_char args( ( OBJ_DATA *list, CHAR_DATA *ch, bool fShort, bool fShowNothing ) ); void show_char_to_char args( ( CHAR_DATA *list, CHAR_DATA *ch ) ); extern char *target_name; extern char *third_name; bool check_dispel args ( ( int dis_level, CHAR_DATA *victim, int sn) ); extern void raw_kill args ((CHAR_DATA * victim, CHAR_DATA * killer)); extern void group_gain args ((CHAR_DATA * ch, CHAR_DATA * victim)); int sorcery_dam args( ( int num, int dice, CHAR_DATA *ch) ); int sorcery_dam2 args( (int dam) ); bool check_sorcery args( (CHAR_DATA *ch, int sn) ); void spell_farsight(int sn,int level,CHAR_DATA *ch,void *vo,int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED(victim, AFF_FARSIGHT) ) { if (victim == ch) send_to_char("Your eyes are already as good as they get.\n\r",ch); else act("$N can see just fine.",ch,NULL,victim,TO_CHAR); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_FARSIGHT; affect_to_char( victim, &af ); send_to_char( "Your eyes jump into focus.\n\r", victim ); if ( ch != victim ) send_to_char( "Ok.\n\r", ch ); return; } void spell_protection_voodoo(int sn,int level,CHAR_DATA *ch,void *vo,int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED(victim, SHD_PROTECT_VOODOO) || is_affected(victim, sn) ) { send_to_char("They are already protected from voodoo magic.\n\r",ch); return; } af.where = TO_SHIELDS; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = SHD_PROTECT_VOODOO; affect_to_char( victim, &af ); return; } void spell_portal( int sn, int level, CHAR_DATA *ch, void *vo,int target) { CHAR_DATA *victim; OBJ_DATA *portal, *stone; if ( ( victim = get_char_world( ch, target_name ) ) == NULL || victim == ch || victim->in_room == NULL || !can_see_room(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_RECALL) || IS_SET(ch->in_room->room_flags, ROOM_NO_RECALL) || victim->level >= level + 3 || (!IS_NPC(victim) && victim->level > LEVEL_HERO) /* NOT trust */ || (IS_NPC(victim) && IS_SET(victim->imm_flags,IMM_SUMMON)) || (IS_NPC(victim) && saves_spell( level, victim,DAM_NONE) ) || IS_SET(victim->in_room->area->area_flags, AREA_RESTRICTED) || (is_clan(victim) && (!is_same_clan(ch,victim) || clan_table[victim->clan].independent))) { send_to_char( "You failed.\n\r", ch ); return; } if(ch->fight_timer > 0) { send_to_char("In some kind of hurry?\n\r",ch); return; } if ( strstr( victim->in_room->area->builders, "Unlinked" ) ) { send_to_char( "You can't gate to areas that aren't linked!\n\r",ch ); return; } if (victim->in_room->area->continent != ch->in_room->area->continent) { send_to_char( "You fail.\n\r",ch); return; } printf( "Gating to mob in area %s, flags %d\n", victim->in_room->area->name, victim->in_room->area->area_flags ); if (global_quest && IS_NPC(victim) && victim->on_quest) { send_to_char( "You failed.\n\r", ch ); return; } stone = get_eq_char(ch,WEAR_HOLD); if (!IS_IMMORTAL(ch) && (stone == NULL || stone->item_type != ITEM_WARP_STONE)) { send_to_char("You lack the proper component for this spell.\n\r",ch); return; } if (stone != NULL && stone->item_type == ITEM_WARP_STONE) { act("You draw upon the power of $p.",ch,stone,NULL,TO_CHAR); act("It flares brightly and vanishes!",ch,stone,NULL,TO_CHAR); extract_obj(stone); } portal = create_object(get_obj_index(OBJ_VNUM_PORTAL),0); portal->timer = 2 + level / 25; portal->value[3] = victim->in_room->vnum; obj_to_room(portal,ch->in_room); act("$p rises up from the ground.",ch,portal,NULL,TO_ROOM); act("$p rises up before you.",ch,portal,NULL,TO_CHAR); } void spell_nexus( int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim; OBJ_DATA *portal, *stone; ROOM_INDEX_DATA *to_room, *from_room; from_room = ch->in_room; if ( ( victim = get_char_world( ch, target_name ) ) == NULL || victim == ch || (to_room = victim->in_room) == NULL || !can_see_room(ch,to_room) || !can_see_room(ch,from_room) || IS_SET(to_room->room_flags, ROOM_SAFE) || IS_SET(from_room->room_flags,ROOM_SAFE) || IS_SET(to_room->room_flags, ROOM_PRIVATE) || IS_SET(to_room->room_flags, ROOM_SOLITARY) || IS_SET(to_room->room_flags, ROOM_NO_RECALL) || IS_SET(from_room->room_flags,ROOM_NO_RECALL) || victim->level >= level + 3 || (!IS_NPC(victim) && victim->level > LEVEL_HERO) /* NOT trust */ || (IS_NPC(victim) && IS_SET(victim->imm_flags,IMM_SUMMON)) || (IS_NPC(victim) && saves_spell( level, victim,DAM_NONE) ) || is_affected(ch,gsn_martial_arts)//Screw you monks! || IS_SET(victim->in_room->area->area_flags, AREA_RESTRICTED) || (is_clan(victim) && (!is_same_clan(ch,victim) || clan_table[victim->clan].independent))) { send_to_char( "You failed.\n\r", ch ); return; } if(ch->fight_timer > 0) { send_to_char("In some kind of hurry?\n\r",ch); return; } if ( strstr( victim->in_room->area->builders, "Unlinked" ) ) { send_to_char( "You can't gate to areas that aren't linked!\n\r",ch ); return; } stone = get_eq_char(ch,WEAR_HOLD); if (!IS_IMMORTAL(ch) && (stone == NULL || stone->item_type != ITEM_WARP_STONE)) { send_to_char("You lack the proper component for this spell.\n\r",ch); return; } if (stone != NULL && stone->item_type == ITEM_WARP_STONE) { act("You draw upon the power of $p.",ch,stone,NULL,TO_CHAR); act("It flares brightly and vanishes!",ch,stone,NULL,TO_CHAR); extract_obj(stone); } /* portal one */ portal = create_object(get_obj_index(OBJ_VNUM_PORTAL),0); portal->timer = 1 + level / 10; portal->value[3] = to_room->vnum; obj_to_room(portal,from_room); act("$p rises up from the ground.",ch,portal,NULL,TO_ROOM); act("$p rises up before you.",ch,portal,NULL,TO_CHAR); /* no second portal if rooms are the same */ if (to_room == from_room) return; /* portal two */ portal = create_object(get_obj_index(OBJ_VNUM_PORTAL),0); portal->timer = 1 + level/10; portal->value[3] = from_room->vnum; obj_to_room(portal,to_room); if (to_room->people != NULL) { act("$p rises up from the ground.",to_room->people,portal,NULL,TO_ROOM); act("$p rises up from the ground.",to_room->people,portal,NULL,TO_CHAR); } } void spell_empower( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { OBJ_DATA *object; char buf[MAX_STRING_LENGTH]; char *name; int new_sn; int mana; int newmana; int newtarget; if ( ( new_sn = find_spell( ch,target_name ) ) < 0 || ( !IS_NPC(ch) && (ch->level < skill_table[new_sn].skill_level[ch->class] || ch->pcdata->learned[new_sn] == 0))) { send_to_char( "What spell do you wish to bind?\n\r", ch ); return; } name = skill_table[new_sn].name; if (!strcmp(name, "empower") ) { send_to_char( "You failed.\n\r", ch ); return; } if (skill_table[new_sn].spell_fun == spell_null) { send_to_char( "That's not a spell.\n\r", ch ); return; } newtarget = skill_table[new_sn].target; if (ch->level + 2 == skill_table[sn].skill_level[ch->class]) mana = 50; else mana = UMAX( skill_table[sn].min_mana, 100 / ( 2 + ch->level - skill_table[sn].skill_level[ch->class] ) ); if (ch->level + 2 == skill_table[new_sn].skill_level[ch->class]) newmana = 50; else newmana = UMAX( skill_table[new_sn].min_mana, 100 / ( 2 + ch->level - skill_table[new_sn].skill_level[ch->class] ) ); if ( (ch->mana - mana - newmana) < 0) { send_to_char( "You do not have enough mana.\n\r", ch ); return; } ch->mana -= newmana; if ((newtarget == TAR_CHAR_DEFENSIVE) || (newtarget == TAR_CHAR_SELF)) { object = create_object(get_obj_index(OBJ_VNUM_POTION), 0); } else { object = create_object(get_obj_index(OBJ_VNUM_SCROLL), 0); } object->value[0] = ch->level; object->value[1] = new_sn; object->level = ch->level-5; sprintf( buf, "%s %s", object->name, name); free_string(object->name); object->name = str_dup(buf); sprintf( buf, "%s%s", object->short_descr, name); free_string(object->short_descr); object->short_descr = str_dup(buf); if ((newtarget == TAR_CHAR_DEFENSIVE) || (newtarget == TAR_CHAR_SELF)) { sprintf( buf, "$n has created a potion of %s!",name); act(buf,ch,object,NULL,TO_ROOM); sprintf( buf, "You create a potion of %s!\n\r",name); send_to_char(buf,ch); } else { sprintf( buf, "$n has created a scroll of %s!",name); act(buf,ch,object,NULL,TO_ROOM); sprintf( buf, "You create a scroll of %s!\n\r",name); send_to_char(buf,ch); } obj_to_char(object,ch); return; } // Quench Spell by Bree /* void spell_quench( int sn, int level, CHAR_DATA *ch, void *vo ) { if ( IS_NPC(ch) ) return; ch->pcdata->condition[COND_THIRST] = 30; send_to_char( "You have quenched your thirst.\n\r", ch ); return; } // Sate spell by Bree void spell_sate( int sn, int level, CHAR_DATA *ch, void *vo ) { if ( IS_NPC(ch) ) return; ch->pcdata->condition[COND_HUNGER] = 24; send_to_char( "You have sated your hunger.\n\r", ch ); return; } */ //Betray Spell by Bree /* void spell_betray( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( !ch->fighting ) { send_to_char( "You may only cast betray during combat.", ch ); if ( victim == ch ) { send_to_char( "Betray yourself? You're weird.\n\r", ch ); return; } if ( IS_AFFECTED( victim, AFF_CHARM ) || IS_AFFECTED( ch, AFF_CHARM ) || level < victim->level || saves_spell( level, victim ) ) return; if ( victim->fighting == ch ) stop_fighting( victim, TRUE ); if ( victim->master ) stop_follower( victim ); add_follower( victim, ch ); af.type = sn; af.duration = number_fuzzy( level / 4 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char( victim, &af ); act( "$N has betrayed!", ch, NULL, victim, TO_CHAR ); act( "You now follow $n!", ch, NULL, victim, TO_VICT ); return; } */ void spell_resurrect( int sn, int level, CHAR_DATA *ch, void *vo, int target) { char buf[MAX_STRING_LENGTH]; char arg[MAX_STRING_LENGTH]; MOB_INDEX_DATA *pMobIndex; OBJ_DATA *obj; OBJ_DATA *cobj; OBJ_DATA *obj_next; CHAR_DATA *pet; int length; if ( ( obj = get_obj_here( ch, "corpse" ) ) == NULL ) { send_to_char( "There's no corpse here.\n\r", ch ); return; } if ( ch->pet != NULL ) { send_to_char("You failed.\n\r",ch); return; } pMobIndex = get_mob_index( MOB_VNUM_CORPSE ); pet = create_mobile( pMobIndex ); if (!IS_SET(pet->act, ACT_PET) ) SET_BIT(pet->act, ACT_PET); if (!IS_SET(pet->affected_by, AFF_CHARM) ) SET_BIT(pet->affected_by, AFF_CHARM); pet->comm = COMM_NOTELL|COMM_NOSHOUT|COMM_NOCHANNELS; sprintf( buf, "%s{GThe mark of %s is on it's forehead.{x.\n\r", pet->description, ch->name ); free_string( pet->description ); pet->description = str_dup( buf ); free_string( pet->short_descr ); pet->short_descr = str_dup( str_replace(obj->short_descr, "corpse", "zombie") ); sprintf( buf, "%s", str_replace(obj->description, "corpse", "zombie") ); length = strlen(buf)-12; strncpy( arg, buf, length); arg[length] = '\0'; sprintf( buf, "%s standing here.\n\r", arg); free_string( pet->long_descr ); pet->long_descr = str_dup( buf ); char_to_room( pet, ch->in_room ); add_follower( pet, ch ); pet->leader = ch; ch->pet = pet; pet->alignment = ch->alignment; pet->level = UMAX(1, UMIN(109, ((ch->level/2)+(obj->level)))); pet->max_hit = pet->level * 20; pet->hit = pet->max_hit; pet->armor[0] = pet->level; pet->armor[1] = pet->level; pet->armor[2] = pet->level; pet->armor[3] = pet->level; for ( cobj = obj->contains; cobj != NULL; cobj = obj_next ) { obj_next = cobj->next_content; obj_from_obj( cobj ); obj_to_room( cobj, ch->in_room ); } extract_obj( obj ); sprintf( buf, "%s stands up and starts following you.\n\r", pet->short_descr); send_to_char( buf, ch); sprintf( buf, "%s stands up and starts following $n.", pet->short_descr); act( buf, ch, NULL, NULL, TO_ROOM); return; } void spell_conjure( int sn, int level, CHAR_DATA *ch, void *vo, int target) { char buf[MAX_STRING_LENGTH]; MOB_INDEX_DATA *pMobIndex; OBJ_DATA *stone; if (IS_NPC(ch)) return; stone = get_eq_char(ch,WEAR_HOLD); if (!IS_IMMORTAL(ch) && (stone == NULL || stone->item_type != ITEM_DEMON_STONE)) { send_to_char("You lack the proper component for this spell.\n\r",ch); return; } if ( ch->pet != NULL ) { send_to_char("You failed.\n\r",ch); return; } /*if (stone != NULL && stone->item_type == ITEM_DEMON_STONE) { if (stone->value[0] < 1) { act("You draw upon the power of $p.",ch,stone,NULL,TO_CHAR); act("$n draws upon the power of $p.",ch,stone,NULL,TO_ROOM); act("It flares brightly and explodes into dust.",ch,stone,NULL,TO_CHAR); act("It flares brightly and explodes into dust.",ch,stone,NULL,TO_ROOM); extract_obj( stone ); return; } }*/ if(ch->class == CLASS_VOODAN || ch->class == CLASS_FORSAKEN || ch->class == CLASS_WIZARD || ch->class == CLASS_MAGE) { CHAR_DATA *pet; pMobIndex = get_mob_index( MOB_VNUM_DEMON ); pet = create_mobile( pMobIndex ); if (!IS_SET(pet->act, ACT_PET) ) SET_BIT(pet->act, ACT_PET); if (!IS_SET(pet->affected_by, AFF_CHARM) ) SET_BIT(pet->affected_by, AFF_CHARM); pet->comm = COMM_NOTELL|COMM_NOSHOUT|COMM_NOCHANNELS; sprintf( buf, "%s{GThe mark of %s is on it's forehead.{x.\n\r", pet->description, ch->name ); free_string( pet->description ); pet->description = str_dup( buf ); char_to_room( pet, ch->in_room ); if (stone != NULL && stone->item_type == ITEM_DEMON_STONE) { /*stone->value[0] = UMAX(0, stone->value[0]-1);*/ act("You draw upon the power of $p.",ch,stone,NULL,TO_CHAR); act("$n draws upon the power of $p.",ch,stone,NULL,TO_ROOM); act("It flares brightly and $N appears.",ch,stone,pet,TO_CHAR); act("It flares brightly and $N appears.",ch,stone,pet,TO_ROOM); extract_obj( stone ); } else { act("$N suddenly appears in the room.",ch,NULL,pet,TO_CHAR); act("$N suddenly appears in the room.",ch,NULL,pet,TO_ROOM); } add_follower( pet, ch ); pet->leader = ch; ch->pet = pet; pet->alignment = ch->alignment; pet->level = ch->level*3/2; pet->damroll = ch->level*4; pet->max_hit = pet->level * 80; pet->hit = pet->max_hit; pet->armor[0] = pet->level; pet->armor[1] = pet->level; pet->armor[2] = pet->level; pet->armor[3] = pet->level; } if(ch->class == CLASS_ALCHEMIST || ch->class == CLASS_SHAMAN || ch->class == CLASS_SAGE) { CHAR_DATA *pet; pMobIndex = get_mob_index( 3195 ); pet = create_mobile( pMobIndex ); if (!IS_SET(pet->act, ACT_PET) ) SET_BIT(pet->act, ACT_PET); if (!IS_SET(pet->affected_by, AFF_CHARM) ) SET_BIT(pet->affected_by, AFF_CHARM); pet->comm = COMM_NOTELL|COMM_NOSHOUT|COMM_NOCHANNELS; sprintf( buf, "%s{GThe mark of %s is on it's forehead.{x.\n\r", pet->description, ch->name ); free_string( pet->description ); pet->description = str_dup( buf ); char_to_room( pet, ch->in_room ); if (stone != NULL && stone->item_type == ITEM_DEMON_STONE) { /*stone->value[0] = UMAX(0, stone->value[0]-1);*/ act("You draw upon the power of $p.",ch,stone,NULL,TO_CHAR); act("$n draws upon the power of $p.",ch,stone,NULL,TO_ROOM); act("It flares brightly and $N appears.",ch,stone,pet,TO_CHAR); act("It flares brightly and $N appears.",ch,stone,pet,TO_ROOM); extract_obj( stone ); } else { act("$N suddenly appears in the room.",ch,NULL,pet,TO_CHAR); act("$N suddenly appears in the room.",ch,NULL,pet,TO_ROOM); } add_follower( pet, ch ); pet->leader = ch; ch->pet = pet; pet->alignment = ch->alignment; pet->level = ch->level*3/2; pet->damroll = ch->level*4; pet->max_hit = pet->level * 80; pet->hit = pet->max_hit; pet->armor[0] = pet->level; pet->armor[1] = pet->level; pet->armor[2] = pet->level; pet->armor[3] = pet->level; } if(ch->class == CLASS_SAINT || ch->class == CLASS_PRIEST ) { CHAR_DATA *pet; pMobIndex = get_mob_index( 3196 ); pet = create_mobile( pMobIndex ); if (!IS_SET(pet->act, ACT_PET) ) SET_BIT(pet->act, ACT_PET); if (!IS_SET(pet->affected_by, AFF_CHARM) ) SET_BIT(pet->affected_by, AFF_CHARM); pet->comm = COMM_NOTELL|COMM_NOSHOUT|COMM_NOCHANNELS; sprintf( buf, "%s{GThe mark of %s is on it's forehead.{x.\n\r", pet->description, ch->name ); free_string( pet->description ); pet->description = str_dup( buf ); char_to_room( pet, ch->in_room ); if (stone != NULL && stone->item_type == ITEM_DEMON_STONE) { /*stone->value[0] = UMAX(0, stone->value[0]-1);*/ act("You draw upon the power of $p.",ch,stone,NULL,TO_CHAR); act("$n draws upon the power of $p.",ch,stone,NULL,TO_ROOM); act("It flares brightly and $N appears.",ch,stone,pet,TO_CHAR); act("It flares brightly and $N appears.",ch,stone,pet,TO_ROOM); extract_obj( stone ); } else { act("$N suddenly appears in the room.",ch,NULL,pet,TO_CHAR); act("$N suddenly appears in the room.",ch,NULL,pet,TO_ROOM); } add_follower( pet, ch ); pet->leader = ch; ch->pet = pet; pet->alignment = ch->alignment; pet->level = ch->level*3/2; pet->damroll = ch->level*4; pet->max_hit = pet->level * 80; pet->hit = pet->max_hit; pet->armor[0] = pet->level; pet->armor[1] = pet->level; pet->armor[2] = pet->level; pet->armor[3] = pet->level; } if(ch->class == CLASS_CONJURER) { CHAR_DATA *pet; pMobIndex = get_mob_index( 3197 ); pet = create_mobile( pMobIndex ); if (!IS_SET(pet->act, ACT_PET) ) SET_BIT(pet->act, ACT_PET); if (!IS_SET(pet->affected_by, AFF_CHARM) ) SET_BIT(pet->affected_by, AFF_CHARM); pet->comm = COMM_NOTELL|COMM_NOSHOUT|COMM_NOCHANNELS; sprintf( buf, "%s{GThe mark of %s is on it's forehead.{x.\n\r", pet->description, ch->name ); free_string( pet->description ); pet->description = str_dup( buf ); char_to_room( pet, ch->in_room ); if (stone != NULL && stone->item_type == ITEM_DEMON_STONE) { /*stone->value[0] = UMAX(0, stone->value[0]-1);*/ act("You draw upon the power of $p.",ch,stone,NULL,TO_CHAR); act("$n draws upon the power of $p.",ch,stone,NULL,TO_ROOM); act("It flares brightly and $N appears.",ch,stone,pet,TO_CHAR); act("It flares brightly and $N appears.",ch,stone,pet,TO_ROOM); extract_obj( stone ); } else { act("$N suddenly appears in the room.",ch,NULL,pet,TO_CHAR); act("$N suddenly appears in the room.",ch,NULL,pet,TO_ROOM); } add_follower( pet, ch ); pet->leader = ch; ch->pet = pet; pet->alignment = ch->alignment; pet->level = ch->level*3/2; pet->damroll = ch->level*4; pet->max_hit = pet->level * 95; pet->hit = pet->max_hit; pet->armor[0] = pet->level; pet->armor[1] = pet->level; pet->armor[2] = pet->level; pet->armor[3] = pet->level; } return; } void spell_animate( int sn, int level, CHAR_DATA *ch, void *vo, int target) { char buf[MAX_STRING_LENGTH]; char arg[MAX_STRING_LENGTH]; MOB_INDEX_DATA *pMobIndex; OBJ_DATA *obj = (OBJ_DATA *) vo; CHAR_DATA *pet; int length; if ((obj->pIndexData->vnum > 17) || (obj->pIndexData->vnum < 12)) { send_to_char( "That's not a body part!\n\r", ch ); return; } pMobIndex = get_mob_index( MOB_VNUM_ANIMATE ); pet = create_mobile( pMobIndex ); SET_BIT(pet->affected_by, AFF_CHARM); pet->comm = COMM_NOTELL|COMM_NOSHOUT|COMM_NOCHANNELS; sprintf( buf, "%s{GIt's branded with the mark of %s.{x.\n\r", obj->description, ch->name ); free_string( pet->description ); pet->description = str_dup( buf ); free_string( pet->short_descr ); pet->short_descr = str_dup( obj->short_descr ); free_string( pet->name ); pet->name = str_dup( obj->name ); sprintf( buf, "%s", obj->description); length = strlen(buf)-12; strncpy( arg, buf, length); arg[length] = '\0'; sprintf( buf, "%s floating here.\n\r", arg); free_string( pet->long_descr ); pet->long_descr = str_dup( buf ); char_to_room( pet, ch->in_room ); add_follower( pet, ch ); pet->leader = ch; obj_from_char( obj ); sprintf( buf, "%s floats up and starts following you.\n\r", pet->short_descr); send_to_char( buf, ch); sprintf( buf, "%s floats up and starts following $n.", pet->short_descr); act( buf, ch, NULL, NULL, TO_ROOM); return; } void spell_iceshield( int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (IS_SHIELDED(victim, SHD_ICE)) { if(victim == ch) send_to_char("You are already surrounded by an {Cicy{x shield.\n\r", ch); else act("$N is already surrounded by an {Cicy{x shield.",ch,NULL,victim,TO_CHAR); return; } if (IS_NPC(victim)) { send_to_char("You failed.\n\r", ch); return; } if ( (skill_table[sn].skill_level[victim->class] > LEVEL_HERO) && (victim->level < LEVEL_IMMORTAL) ) { send_to_char("You are surrounded by an {Cicy{x shield.\n\r", victim); act("$n is surrounded by an {Cicy{x shield.",victim, NULL,NULL,TO_ROOM); send_to_char("Your {Cicy{x shield quickly melts away.\n\r", victim); act("$n's {Cicy{x shield quickly melts away.",victim, NULL,NULL,TO_ROOM); return; } af.where = TO_SHIELDS; af.type = sn; af.level = level; af.duration = level/4; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = SHD_ICE; affect_to_char(victim, &af); send_to_char("You are surrounded by an {Cicy{x shield.\n\r", victim); act("$n is surrounded by an {Cicy{x shield.",victim, NULL,NULL,TO_ROOM); return; } void spell_fireshield(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (IS_SHIELDED(victim, SHD_FIRE)) { if (victim == ch) send_to_char("You are already surrounded by a {Rfirey{x shield.\r\n", ch); else act("$N is already surrounded by a {Rfiery{x shield.",ch,NULL,victim,TO_CHAR); return; } if (IS_NPC(victim)) { send_to_char("You failed.\n\r", ch); return; } if ( (skill_table[sn].skill_level[victim->class] > LEVEL_HERO) && (victim->level < LEVEL_IMMORTAL) ) { send_to_char("You are surrounded by a {Rfiery{x shield.\n\r", victim); act("$n is surrounded by a {Rfiery{x shield.",victim, NULL,NULL,TO_ROOM); send_to_char("Your {Rfirey{x shield gutters out.\n\r", victim); act("$n's {Rfirey{x shield gutters out.",victim, NULL,NULL,TO_ROOM); return; } af.where = TO_SHIELDS; af.type = sn; af.level = level; af.duration = level/4; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = SHD_FIRE; affect_to_char(victim, &af); send_to_char("You are surrounded by a {Rfiery{x shield.\n\r", victim); act("$n is surrounded by a {Rfiery{x shield.",victim, NULL,NULL,TO_ROOM); return; } void spell_shockshield(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (IS_SHIELDED(victim, SHD_SHOCK)) { if (victim == ch) send_to_char("You are already surrounded in a {Bcrackling{x shield.\n\r", ch); else act("$N is already surrounded by a {Bcrackling{x shield.",ch, NULL, victim, TO_CHAR); return; } if (IS_NPC(victim)) { send_to_char("You failed.\n\r", ch); return; } if ( (skill_table[sn].skill_level[victim->class] > LEVEL_HERO) && (victim->level < LEVEL_IMMORTAL) ) { send_to_char("You are surrounded by a {Bcrackling{x shield.\n\r", victim); act("$n is surrounded by a {Bcrackling{x shield.",victim, NULL,NULL,TO_ROOM); send_to_char("Your {Bcrackling{x shield sizzles and fades.\n\r", victim); act("$n's {Bcrackling{x shield sizzles and fades.",victim, NULL,NULL,TO_ROOM); return; } af.where = TO_SHIELDS; af.type = sn; af.level = level; af.duration = level/4; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = SHD_SHOCK; affect_to_char(victim, &af); send_to_char("You are surrounded by a {Bcrackling{x field.\n\r",victim); act("$n is surrounded by a {Bcrackling{x shield.",victim, NULL,NULL, TO_ROOM); return; } void spell_deathshield(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (IS_SHIELDED(victim, SHD_DEATH)) { if (victim == ch) send_to_char("You are already surrounded in a {Ddeath{x shield.\n\r", ch); else act("$N is already surrounded by a {Ddeath{x shield.",ch, NULL, victim, TO_CHAR); return; } if (IS_NPC(victim)) { send_to_char("You failed.\n\r", ch); return; } if ( (skill_table[sn].skill_level[victim->class] > LEVEL_HERO) && (victim->level < LEVEL_IMMORTAL) ) { send_to_char("You are surrounded by a {Ddeath{x shield.\n\r", victim); act("$n is surrounded by a {Ddeath{x shield.",victim, NULL,NULL,TO_ROOM); send_to_char("Your {Ddeath{x shield sizzles and fades.\n\r", victim); act("$n's {Ddeath{x shield sizzles and fades.",victim, NULL,NULL,TO_ROOM); return; } af.where = TO_SHIELDS; af.type = sn; af.level = level; af.duration = level/6; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = SHD_DEATH; affect_to_char(victim, &af); send_to_char("You are surrounded by a {Ddeath{x field.\n\r",victim); act("$n is surrounded by a {Ddeath{x shield.",victim, NULL,NULL, TO_ROOM); return; } void spell_quest_pill( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { CHAR_DATA *victim = (CHAR_DATA *) vo; if (IS_NPC(victim)) return; victim->qps++; send_to_char( "{YYou've gained a {RQuest Point{Y!{x\n\r", victim ); if ( ch != victim ) send_to_char( "Ok.\n\r", ch ); return; } void spell_voodoo( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { char name[MAX_INPUT_LENGTH]; char buf[MAX_STRING_LENGTH]; OBJ_DATA *bpart; OBJ_DATA *doll; bpart = get_eq_char(ch,WEAR_HOLD); if ((bpart == NULL) || (bpart->pIndexData->vnum < 12) || (bpart->pIndexData->vnum > 17)) /* || bpart->pIndexData->vnum != 30) */ { send_to_char("You are not holding a body part.\n\r",ch); return; } if (bpart->value[4] == 0) { send_to_char("This body part is from a mobile.\n\r",ch); return; } one_argument(bpart->name, name); doll = create_object(get_obj_index(OBJ_VNUM_VOODOO), 0); sprintf( buf, doll->short_descr, name ); free_string( doll->short_descr ); doll->short_descr = str_dup( buf ); sprintf( buf, doll->description, name ); free_string( doll->description ); doll->description = str_dup( buf ); sprintf( buf, doll->name, name ); free_string( doll->name ); doll->name = str_dup( buf ); act( "$p morphs into a voodoo doll",ch,bpart,NULL,TO_CHAR); obj_from_char( bpart ); obj_to_char(doll,ch); equip_char(ch,doll,WEAR_HOLD); act( "$n has created $p!", ch, doll, NULL, TO_ROOM ); return; } /* by Airius WWW */ void send_hue_mess(char *clmess, char *clcode, CHAR_DATA *ch, CHAR_DATA *victim) { char buf[MAX_STRING_LENGTH]; CHAR_DATA *vch; CHAR_DATA *vch_next; if(IS_SET(ch->act, PLR_COLOUR)) sprintf(buf, "%sA %s hue strikes you!%s\n\r", clcode, clmess, CLEAR); else sprintf(buf,"A %s hue strikes you!\n\r", clmess); send_to_char(buf, victim); for ( vch = char_list; vch!=NULL; vch = vch_next ) { vch_next=vch->next; if (vch->in_room == NULL) continue ; if ( vch->in_room == ch->in_room ) { if ( vch != victim ) { if(IS_SET(vch->act, PLR_COLOUR)) sprintf(buf, "%sA %s hue strikes %s!%s\n\r", clcode, clmess, victim->short_descr, CLEAR); else sprintf(buf, "A %s hue strikes0%s!Ln\r", clmess, victim->short_descr); send_to_char(buf, vch); } continue ; } } } /* by Airius WWW */ void strike_with_hue( int sn, int level, CHAR_DATA *ch, CHAR_DATA *victim) { int dtoss; ROOM_INDEX_DATA *pRoomIndex; AFFECT_DATA af; dtoss=dice(1,7); switch (dtoss) { case 1 : send_hue_mess("red", C_B_RED, ch, victim); damage_old(ch, victim, saves_spell( level, victim, DAM_FIRE) ? 50 : 25, sn, DAM_FIRE, TRUE); break; case 2 : send_hue_mess("cyan", C_B_CYAN, ch, victim); damage_old(ch, victim, saves_spell( level, victim, DAM_ENERGY) ? 100 : 50, sn, DAM_ENERGY, TRUE); break; case 3 : send_hue_mess("yellow", C_B_YELLOW, ch, victim); damage_old(ch, victim, saves_spell( level, victim, DAM_LIGHT) ? 150 : 75, sn, DAM_LIGHT, TRUE); break; case 4 : send_hue_mess("green", C_B_GREEN, ch, victim); if(!saves_spell(level, victim, DAM_POISON)) { af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_STR; af.modifier = -4; af.bitvector = AFF_POISON; affect_join( victim, &af ); send_to_char( "You feel very sick.\n\r", victim ); act("$n looks very ill.",victim,NULL,NULL,TO_ROOM); } else damage_old(ch, victim, 20, sn, DAM_POISON, TRUE); break; case 5 : send_hue_mess("blue", C_B_BLUE, ch, victim); if ( victim->in_room == NULL || IS_SET(victim->in_room->room_flags, ROOM_NO_RECALL) || ( victim != ch && IS_SET(victim->imm_flags,IMM_SUMMON)) || ( victim != ch && ( saves_spell( level - 10, victim,DAM_OTHER)))) { break; } pRoomIndex = get_random_room(victim); if (victim != ch) send_to_char("You have been teleported!\n\r",victim); act( "$n vanishes!", victim, NULL, NULL, TO_ROOM ); char_from_room( victim ); char_to_room( victim, pRoomIndex ); act( "$n slowly fades into existence.", victim, NULL, NULL, TO_ROOM ); do_look( victim, "auto" ); break; case 6 : send_hue_mess("indigo", C_MAGENTA, ch, victim); if (saves_spell(level,victim,DAM_OTHER) || IS_SET(victim->imm_flags,IMM_MAGIC)) { if (victim != ch) send_to_char("Nothing seemed to happen.\n\r",ch); send_to_char("You feel momentarily lethargic.\n\r",victim); break; } if (IS_AFFECTED(victim,AFF_HASTE)) { if (!check_dispel(level,victim,skill_lookup("haste"))) { if (victim != ch) send_to_char("Spell failed.\n\r",ch); affect_to_char( victim, &af ); send_to_char( "You feel yourself slowing d o w n...\n\r", victim ); act("$n starts to move in slow motion.",victim,NULL,NULL,TO_ROOM); send_to_char("You feel momentarily slower.\n\r",victim); break; } act("$n is moving less quickly.",victim,NULL,NULL,TO_ROOM); break; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level/2; af.location = APPLY_DEX; af.modifier = -1 - (level/5); af.bitvector = AFF_SLOW; affect_join( victim, &af ); send_to_char( "You feel yourself slowing d o w n...\n\r", victim ); act("$n starts to move in slow motion.",victim,NULL,NULL,TO_ROOM); break; case 7 : send_hue_mess("violet", C_B_MAGENTA, ch, victim); damage_old(ch, victim, saves_spell( level, victim, DAM_NEGATIVE) ? 200 : 150, sn, DAM_NEGATIVE, TRUE); send_to_char( "You feel your life slipping away\n\r", victim ); act("$n seems slightly weaker.",victim,NULL,NULL,TO_ROOM); break; } return ; } /* by Airius WWW */ void spell_prismatic_spray( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { CHAR_DATA *vch, *vch_next; int i, number_hits; send_to_char( "You put out your hands and send forth a dazzling pristmatic spray!\n\r", ch ); act( "$n raises $s hands and sends out a dazzling prismatic spray!", ch, NULL, NULL, TO_ROOM ); for ( vch = ch->in_room->people; vch != NULL; vch = vch_next ) { vch_next = vch->next_in_room; if ( vch == ch || is_same_group( ch, vch ) || is_safe_spell( ch, vch, TRUE ) ) continue; number_hits = dice( 1, 8 ) == 8 ? 2 : 1; number_hits += dice( 1, 8 ) == 8 ? 2 : 1; for ( i = 1; i <= number_hits; i++ ) strike_with_hue( sn, level, ch, vch ); } } void spell_wizard_eye( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { EXIT_DATA *pexit; int door=0; int attempt; CHAR_DATA *victim; victim = get_char_world( ch, target_name ); if (IS_AFFECTED(ch,AFF_BLIND)) { send_to_char("Maybe it would help if you could see?\n\r",ch); return; } if ( victim == NULL || victim->level > LEVEL_HERO ) { send_to_char("Failed.\n\r",ch); return; } /*Unsaveable. Let's do it. if (saves_spell(level + 5,victim,DAM_OTHER)) { send_to_char("Failed.\n\r",ch); return; }*/ if ( victim == ch ) { send_to_char("You are here!\n\r",ch); return; } if ( IS_AFFECTED(victim, AFF_DETECT_LOCATION) && (saves_spell( victim->level, ch, DAM_OTHER ) || number_percent() < 30)) act("$N just located you!", victim, NULL, ch, TO_CHAR); if ( !IS_AFFECTED(victim, AFF_DISPLACE) || saves_spell( victim->level, ch, DAM_OTHER ) ) { BUFFER *final; send_to_char( victim->in_room->name, ch ); send_to_char( "\n\r ", ch ); send_to_char( victim->in_room->description, ch ); final = show_list_to_char( victim->in_room->contents, ch, FALSE, FALSE ); send_to_char( final->string, ch ); free_buf( final ); show_char_to_char( victim->in_room->people, ch ); return; } /* ok. now the hard bit. */ for ( attempt = 0; attempt < 6; attempt++ ) { door = attempt; pexit = victim->in_room->exit[door]; if ( pexit == 0 || pexit->u1.to_room == NULL || IS_SET(pexit->exit_info, EX_CLOSED) ) door = 7; else break; } if ( door < 7 && door >= 0 ) { BUFFER * final; send_to_char( pexit->u1.to_room->name, ch ); send_to_char( "\n\r ", ch ); send_to_char( pexit->u1.to_room->description, ch ); final = show_list_to_char( pexit->u1.to_room->contents, ch, FALSE, FALSE ); send_to_char( final->string, ch ); free_buf( final ); show_char_to_char( pexit->u1.to_room->people, ch ); return; } else { send_to_char("Failed.\n\r",ch); return; } return; } void spell_detect_location( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { AFFECT_DATA af; if ( IS_AFFECTED(ch, AFF_DETECT_LOCATION) ) { send_to_char("You already have a sixth sense.\n\r",ch); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_DETECT_LOCATION; affect_to_char( ch, &af ); send_to_char("You feel your body becoming more aware of its surroundings.\n\r",ch); return; } void spell_displace( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { AFFECT_DATA af; if ( IS_AFFECTED(ch, AFF_DISPLACE) ) { send_to_char("You are already displaced.\n\r",ch); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_DISPLACE; affect_to_char( ch, &af ); send_to_char("You begin to distort the world around you.\n\r",ch); return; } void spell_feeble_mind(int sn,int level,CHAR_DATA *ch,void *vo,int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn ) ) { if (victim == ch) send_to_char("You stare and are not sure quite whats going on!\n\r",ch); else act("$N already looks pretty stupid.",ch,NULL,victim,TO_CHAR); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level/2; af.location = APPLY_INT; af.modifier = 0 - 8 - (level >= 10) - (level >= 15) - (level >= 20) - (level >= 25) - (level >= 30) - (level >= 35) - (level >= 40); af.bitvector = 0; affect_to_char( victim, &af ); if(victim->fighting != NULL) stop_fighting(victim,TRUE); send_to_char( "You forget what you were supposed to be doing!\n\r", victim ); act("$n's face goes blank and he begins to drool.",victim,NULL,NULL,TO_ROOM); return; } void spell_unite(int sn,int level,CHAR_DATA *ch,void *vo,int target) { CHAR_DATA *vch; CHAR_DATA *vch_next; CHAR_DATA *victim = (CHAR_DATA *) vo; int totalhits = 0; int dam = 0; int idice; char buf[MSL]; if ( ( ch->fighting == NULL ) && ( !IS_NPC( ch ) ) && ( !IS_NPC( victim ) ) ) { ch->attacker = TRUE; victim->attacker = FALSE; } send_to_char( "You unite the world under your banner.. CHARGE!\n\r", ch ); act( "$n raises $s hands to the sky, uniting a global army to serve his ends!", ch, NULL, NULL, TO_ROOM ); for ( vch = char_list; vch != NULL; vch = vch_next ) { vch_next = vch->next; if (ch->mana <= 0) { ch->mana = 0; // Reset to 0, no negatives. continue; } if (totalhits >= 7) continue; if ( vch->level <= LEVEL_HERO && vch != ch && vch != victim && !IS_NPC(vch) ) { idice = number_range(12,18); if (check_sorcery(ch,sn)) dam = sorcery_dam(vch->level,idice,ch); else dam = dice(vch->level,idice); sprintf(buf,"The illusionary arm of %s claws madly at %s!", capitalize(vch->name),victim->name); act(buf,ch,NULL,victim,TO_CHAR); act(buf,ch,NULL,victim,TO_NOTVICT); sprintf(buf,"The illusionary arm of %s claws madly at you!", capitalize(vch->name)); act(buf,ch,NULL,victim,TO_VICT); damage_old (ch, victim, dam*1.3, sn, DAM_MENTAL, TRUE); ch->mana -= vch->level/5; totalhits++; } } WAIT_STATE( ch, ((totalhits+3)*2) ); } void spell_wrath_of_god (int sn, int level, CHAR_DATA *ch, void *vo,int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; char *god = god_table[ch->god].name; char buf[MAX_STRING_LENGTH/8]; if (victim != ch) { sprintf(buf,"$n calls the wrath of %s down upon $N!",god); act(buf,ch,NULL,victim,TO_ROOM); sprintf(buf,"You call down the wrath of %s upon $N!",god); act(buf,ch,NULL,victim,TO_CHAR); } /*if ((IS_GOOD(victim) && IS_GOOD(ch)) || (IS_EVIL(victim) && IS_EVIL(ch))) { act("$n seems unharmed by the wrath.",victim,NULL,victim,TO_ROOM); send_to_char("The light seems powerless to affect you.\n\r",victim); return; }*/ if (check_sorcery(ch,sn)) dam = sorcery_dam(level,8,ch); else dam = dice(level, 8); if (level <= 25) dam += dice(level, 2); else if (level <= 45) dam += dice(level, 6); else if (level < 65) dam += dice(level, 10); else if (level < 80) dam += dice(level, 14); else if (level < 100) dam += dice(level*2, 10); else { if(ch->class == CLASS_SAINT) { if (check_sorcery(ch,sn)) dam += sorcery_dam(level * 6,12,ch); else dam += dice(level * 5, 12); } else dam += dice(level * 2, 12); } if (saves_spell(level,victim,DAM_HOLY) || saves_spell(level + 5, victim,DAM_HOLY)) dam /= 2; if ( ( ch->fighting == NULL ) && ( !IS_NPC( ch ) ) && ( !IS_NPC( victim ) ) ) { ch->attacker = TRUE; victim->attacker = FALSE; } damage_old(ch,victim,dam,sn,DAM_ENERGY,TRUE); if (number_range(0,2) != 0) return; spell_curse(gsn_curse,level,ch,(void *) victim, TARGET_CHAR); } /* Saint Spell - Skyntil - */ void spell_divine_protection (int sn, int level, CHAR_DATA *ch, void *vo,int target) { char *god = god_table[ch->god].name; char buf[MAX_STRING_LENGTH/10]; int resistance = -1; AFFECT_DATA af; if(is_affected(ch,gsn_divine_protection)) { sprintf(buf,"%s has already given your divine protection.\n\r",god); send_to_char(buf,ch); return; } if (!str_cmp(third_name, "bash")) resistance = RES_BASH; if (!str_cmp(third_name, "pierce")) resistance = RES_PIERCE; if (!str_cmp(third_name, "slash")) resistance = RES_SLASH; if (!str_cmp(third_name, "fire")) resistance = RES_FIRE; if (!str_cmp(third_name, "cold")) resistance = RES_COLD; if (!str_cmp(third_name, "lightning")) resistance = RES_LIGHTNING; if (!str_cmp(third_name, "acid")) resistance = RES_ACID; if (!str_cmp(third_name, "poison")) resistance = RES_POISON; if (!str_cmp(third_name, "negative")) resistance = RES_NEGATIVE; if (!str_cmp(third_name, "energy")) resistance = RES_ENERGY; if (!str_cmp(third_name, "mental")) resistance = RES_MENTAL; if (!str_cmp(third_name, "disease")) resistance = RES_DISEASE; if (!str_cmp(third_name, "drowning")) resistance = RES_DROWNING; if (!str_cmp(third_name, "charm")) resistance = RES_CHARM; if (!str_cmp(third_name, "sound")) resistance = RES_SOUND; if (resistance == -1) { sprintf(buf,"%s doesn't seem to understand your prayer.\n\r",capitalize(god)); send_to_char(buf,ch); return; } af.where = TO_RESIST; af.type = sn; af.level = level; af.duration = level/8; af.location = APPLY_NONE; af.modifier = 1; af.bitvector = resistance; affect_to_char( ch, &af ); sprintf(buf,"$n kneels down and utters a prayer to %s.",capitalize(god)); act( buf, ch, NULL, NULL,TO_ROOM); sprintf(buf,"%s protects your from %s.\n\r",capitalize(god),third_name); send_to_char( buf, ch ); return; } void spell_hold_align(int sn, int level, CHAR_DATA *ch, void *vo,int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if(victim != ch) { send_to_char("You cannot cast this on another.\n\r",ch); return; } if(is_affected(victim,gsn_hold_align)) { send_to_char("You are already constant in your worship.",ch); return; } if(is_affected(victim,gsn_martial_arts) && (ch->class == CLASS_MONK)) { send_to_char("You must first put your mind at peace.\n\r",ch); return; } act("$n looks more sullen.",victim,NULL,NULL,TO_ROOM); act("You feel closer to $g.",victim,NULL,NULL,TO_CHAR); /* Alignment Changes */ if(victim->alignment > 200) if(god_table[ch->god].pc_good) victim->alignment = 1000; if(victim->alignment < -200 ) if(god_table[ch->god].pc_evil) victim->alignment = -1000; if(victim->alignment < 200 && victim->alignment > -200) if(god_table[ch->god].pc_neutral) victim->alignment = 0; af.where = TO_AFFECTS; af.location = APPLY_NONE; af.type = gsn_hold_align; af.modifier = 0; af.bitvector = 0; af.duration = victim->level/12; affect_to_char(victim, &af); return; } void spell_turn_undead(int sn, int level, CHAR_DATA *ch, void *vo,int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int chance,dam; COOLDOWN_DATA cd; if(victim == ch) { send_to_char("You feel a zap from above.\n\r",ch); return; } if(victim == NULL) return; if(IS_NPC(victim)) { if(!IS_SET(victim->act,ACT_UNDEAD)) { send_to_char("Use this on undead.\n\r",ch); return; } chance = get_skill(ch,gsn_turn_undead); chance += get_curr_stat(ch,STAT_WIS) * 4; if(ch->alignment < 0) return; /* Cooldown check */ if (ch->fighting != NULL && on_cooldown(ch, gsn_turn_undead)) { send_to_char ("Turn Undead is still on cooldown.\n\r", ch); return; } /* Apply cooldown */ cd.type = skill_lookup("turn_undead"); cd.duration = skill_table[gsn_turn_undead].cooldown; cooldown_on( ch, &cd ); chance += ch->alignment/10; act("$n intones holy words and shadows disperse!",ch,NULL,NULL,TO_ROOM); act("You chant holy words and the undead falter.",ch,NULL,NULL,TO_CHAR); /* Max of 300 normal around 250 */ if(number_percent() < chance/8) /* 30-40% */ { act("$N screams as $E crumbles into dust!",ch,NULL,victim,TO_ROOM); raw_kill(victim,ch); group_gain(ch, victim); if (!IS_NPC (ch) && IS_NPC (victim)) { OBJ_DATA *coins, *corpse; corpse = get_obj_list (ch, "corpse", ch->in_room->contents); if (IS_SET (ch->act, PLR_AUTOLOOT) && corpse && corpse->contains) /* exists and not empty */ do_get (ch, "all corpse"); if (IS_SET (ch->act, PLR_AUTOGOLD) && corpse && corpse->contains && /* exists and not empty */ !IS_SET (ch->act, PLR_AUTOLOOT)) if ((coins = get_obj_list (ch, "gcash", corpse->contains)) != NULL) do_get (ch, "all.gcash corpse"); if (IS_SET (ch->act, PLR_AUTOSAC)) { if (IS_SET (ch->act, PLR_AUTOLOOT) && corpse && corpse->contains) { return; } else do_sacrifice (ch, "corpse"); } } } else { dam = dice(20,ch->level); damage(ch,victim,dam,gsn_turn_undead,DAM_HOLY,TRUE,0); } } if(!IS_NPC(victim)) { /* if(!IS_SET(victim->act,ACT_UNDEAD)) { send_to_char("Use this on undead.\n\r",ch); return; } */ if (!( victim->class == CLASS_FADE || victim->class == CLASS_LICH || victim->class == CLASS_NECROMANCER || victim->class == CLASS_SHADE || victim->class == CLASS_BANSHEE || IS_SET(victim->act,ACT_UNDEAD))) { send_to_char("Use this on undead.\n\r",ch); return; } chance = get_skill(ch,gsn_turn_undead); chance += get_curr_stat(ch,STAT_WIS) * 4; chance -= get_curr_stat(victim,STAT_WIS) * 3; if(ch->alignment < 0) return; chance += ch->alignment/10; if(victim->alignment > -1) return; chance -= victim->alignment/20; /* The more evil, the better chance */ act("$n intones holy words and shadows disperse!",ch,NULL,NULL,TO_ROOM); act("You chant holy words and the undead falter.",ch,NULL,NULL,TO_CHAR); /* Max of 275 normal around 200 */ if(number_percent() < chance/20) /* 20-27% lower now, don't know the %, was /10 now /20*/ { act("You scream in horror as $n turns you back to the grave.",ch,NULL,victim,TO_VICT); act("$N screams as $E crumbles into dust!",ch,NULL,victim,TO_NOTVICT); raw_kill(victim,ch); if (!IS_NPC (victim)) { sprintf (log_buf, "%s killed by %s at %d", victim->name, (IS_NPC (ch) ? ch->short_descr : ch->name), ch->in_room->vnum); log_string (log_buf); } } else { dam = dice(20,ch->level); damage(ch,victim,dam,gsn_turn_undead,DAM_HOLY,TRUE,0); } } return; } void spell_protective_aura(int sn, int level, CHAR_DATA *ch, void *vo,int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; /* AFFECT_DATA af; */ if(victim != ch) { send_to_char("You cannot cast this on another.\n\r",ch); return; } if(is_affected(victim,gsn_protective_aura)) { send_to_char("You are already surrounded by a protective aura",victim); return; } act("$n is surrounded by a golden aura.",victim,NULL,NULL,TO_ROOM); act("You are granted protection by $g.",victim,NULL,NULL,TO_CHAR); SET_BIT(ch->shielded_by,SHD_PROTECT_AURA); ch->shd_aura_timer = 5; return; } void spell_enforcer(int sn,int level, CHAR_DATA *ch,void *vo,int target) { CHAR_DATA *guard; AFFECT_DATA af; CHAR_DATA *check; int i; if (is_affected(ch,sn)) { send_to_char("You cannot call for more enforcers yet.\n\r",ch); return; } if(ch->in_room->sector_type != SECT_CITY) { send_to_char("You can only summon enforcers within a city.\n\r",ch); return; } for (check = char_list; check != NULL; check = check->next) { if (IS_NPC(check)) if ( (check->master == ch) && (check->spec_fun == spec_lookup("spec_cloaked_enforcer")) ) { send_to_char("You still have guards under your command!\n\r",ch); return; } } af.where = TO_AFFECTS; af.level = level; af.location = 0; af.modifier = 0; af.duration = 10; af.bitvector = 0; af.type = sn; affect_to_char(ch,&af); act("$n shouts, 'Aid me Citizens!'",ch,0,0,TO_ROOM); send_to_char("You call the citizens to arms!\n\r",ch); send_to_char("Enforcer guards arrive to aid you.\n\r",ch); for ( i = 0; i < 2; i++) { guard = create_mobile(get_mob_index(41098) ); guard->level = number_range(ch->level,ch->level*4/4); guard->hitroll += (level*5/10); guard->damroll += (level*9/10); guard->max_hit = number_range(ch->max_hit/8,(ch->max_hit*3/8)); guard->hit = guard->max_hit; guard->max_move = ch->max_move; guard->move = guard->max_move; char_to_room(guard,ch->in_room); add_follower(guard, ch); guard->leader = ch; guard->spec_fun = spec_lookup("spec_cloaked_enforcer"); SET_BIT(guard->affected_by, AFF_CHARM); SET_BIT(guard->affected_by, AFF_DETECT_INVIS); guard->name = str_dup("order enforcer guard"); guard->short_descr = str_dup("an enforcer of order"); guard->long_descr = str_dup("A guard has come to aid the law.\n\r"); af.where = TO_AFFECTS; af.level = level; af.location = 0; af.modifier = 0; af.duration = -1; af.bitvector = AFF_DETECT_MOTION; af.type = gsn_acute_vision; affect_to_char(guard,&af); } act("Enforcers of Order respond to $n's call.",ch,0,0,TO_ROOM); return; } /* * New Dead Animation -- Skyntil */ void spell_animate_dead( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { CHAR_DATA *zombie; OBJ_DATA *corpse; OBJ_DATA *obj_next; OBJ_DATA *obj; CHAR_DATA *search; AFFECT_DATA af; char *name; char *last_name; char *obj_name; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; int chance; int z_level; int control, extra = 0; int l_chance = 20; if ( is_affected(ch,sn) ) { send_to_char("You have not yet regained your powers over the dead.\n\r",ch); return; } control = 0; for (search = char_list; search != NULL; search = search->next) { if (IS_NPC(search) && (search->master == ch) && search->spec_fun == spec_lookup("spec_necro_zombie")) control += 6; else if (IS_NPC(search) && (search->master == ch) && search->spec_fun == spec_lookup("spec_necro_skeleton")) control += 4; else if (IS_NPC(search) && (search->master == ch) && search->spec_fun == spec_lookup("spec_necro_mummy")) control += 12; } if (ch->level < 30 && control > 12) { send_to_char("You already control as many undead as you can.\n\r",ch); return; } else if (ch->level < 55 && control > 17) { send_to_char("You already control as many undead as you can.\n\r",ch); return; } else if (ch->level < 70 && control > 24) { send_to_char("You already control as many undead as you can.\n\r",ch); return; } else if (ch->level < 92 && control > 35) { send_to_char("You already control as many undead as you can.\n\r",ch); return; } else if (ch->level <= 101 && control >= 42) { send_to_char("You already control as many undead as you can.\n\r",ch); return; } if (target_name[0] == '\0') { send_to_char("Which corpse do you wish to animate?\n\r",ch); return; } obj_name = str_dup(target_name); corpse = get_obj_here(ch,obj_name); if (corpse == NULL) { send_to_char("You can't animate that.\n\r",ch); return; } if ((corpse->item_type != ITEM_CORPSE_NPC) || (corpse->item_type == ITEM_CORPSE_PC) ) { send_to_char("You can't animate that.\n\r",ch); return; } name = corpse->short_descr; for (obj = corpse->contains; obj != NULL; obj = obj_next) { obj_next = obj->next_content; obj_from_obj(obj); obj_to_room(obj,ch->in_room); } chance = get_skill(ch,sn); if (ch->level < corpse->level) { chance += (3*ch->level); chance -= (3*corpse->level); } if(is_obj_affected(corpse,gsn_embalm)) { l_chance = 25; chance += 5; } chance = URANGE(l_chance,chance,90); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = ch->level/14; af.modifier = 0; af.location = 0; af.bitvector = 0; if (number_percent() > chance) { act("You fail and destroy $p",ch,corpse,NULL,TO_CHAR); act("$n chants dark words, $p is destroyed.",ch,NULL,NULL,TO_ROOM); extract_obj(corpse); af.duration = ch->level/25; affect_to_char(ch,&af); return; } affect_to_char(ch,&af); act("$n chants dark words and life seeps back into $p.",ch, corpse, NULL,TO_ROOM); act("$p's eyes glow red. $p comes to life!",ch, corpse, NULL,TO_ROOM); act("You call upon the powers of the dark to give life to $p.",ch, corpse, NULL,TO_CHAR); zombie = create_mobile(get_mob_index(MOB_VNUM_ANIMATE)); char_to_room(zombie,ch->in_room); z_level = UMAX(1,corpse->level - number_range(10,18)); if(is_obj_affected(corpse,gsn_embalm)) { z_level += number_range(8,16); extra = number_range(1,4); } zombie->level = z_level; zombie->max_hit = (dice(z_level, (22+extra))); zombie->max_hit += (z_level * (22+extra)); zombie->hit = zombie->max_hit; zombie->damroll += (z_level*4/4)*2+(extra*10); zombie->hitroll += (z_level*4/4)+(extra*8); zombie->alignment = -1000; last_name = name; last_name = one_argument(corpse->short_descr, name); last_name = one_argument(last_name,name); last_name = one_argument(last_name,name); name = last_name; extract_obj(corpse); sprintf( buf1, "the zombie of %s", name); sprintf( buf2, "A zombie of %s is standing here.\n\r", name); free_string(zombie->short_descr); free_string(zombie->long_descr); zombie->short_descr = str_dup(buf1); zombie->long_descr = str_dup(buf2); zombie->name = str_dup(buf1); add_follower(zombie,ch); zombie->leader = ch; af.duration = -1; af.bitvector = AFF_CHARM; affect_to_char(zombie,&af); zombie->spec_fun = spec_lookup("spec_necro_zombie"); return; } /* * Skeletons -- More fun for necros. */ void spell_animate_skeleton( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { CHAR_DATA *skeleton; OBJ_DATA *corpse; OBJ_DATA *obj_next; OBJ_DATA *obj; CHAR_DATA *search; AFFECT_DATA af; char *name; char *last_name; char *obj_name; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; int chance; int z_level; int control; if ( is_affected(ch,sn) ) { send_to_char("You have not yet regained your powers to animate bones.\n\r",ch); return; } control = 0; for (search = char_list; search != NULL; search = search->next) { if (IS_NPC(search) && (search->master == ch) && search->spec_fun == spec_lookup("spec_necro_zombie")) control += 6; else if (IS_NPC(search) && (search->master == ch) && search->spec_fun == spec_lookup("spec_necro_skeleton")) control += 4; else if (IS_NPC(search) && (search->master == ch) && search->spec_fun == spec_lookup("spec_necro_mummy")) control += 12; } if ((ch->level < 30 && control > 12) || (ch->level < 55 && control > 18) || (ch->level < 70 && control > 24) || (ch->level < 92 && control > 30) || (ch->level <= 101 && control >= 36)) { send_to_char("You already control as many undead as you can.\n\r",ch); return; } if (target_name[0] == '\0') { send_to_char("Which skeleton do you wish to animate?\n\r",ch); return; } obj_name = str_dup(target_name); corpse = get_obj_here(ch,obj_name); if (corpse == NULL || corpse->item_type != ITEM_SKELETON) { send_to_char("You can't animate that.\n\r",ch); return; } name = corpse->short_descr; for (obj = corpse->contains; obj != NULL; obj = obj_next) { obj_next = obj->next_content; obj_from_obj(obj); obj_to_room(obj,ch->in_room); } chance = get_skill(ch,sn); if (ch->level < corpse->level) { chance += (4*ch->level); chance -= (3*corpse->level); } chance = URANGE(10,chance,95); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = ch->level/12; af.modifier = 0; af.location = 0; af.bitvector = 0; if (number_percent() > chance) { act("You fail and destroy $p",ch,corpse,NULL,TO_CHAR); act("$n utters dark words. $p is destroyed.",ch,NULL,NULL,TO_ROOM); extract_obj(corpse); af.duration = ch->level/24; affect_to_char(ch,&af); return; } affect_to_char(ch,&af); act("$n chants dark words and $p slowly rises to it's feet.",ch, corpse,NULL,TO_ROOM); act("You chant dark words of death and $p slowly rises to it's feet.",ch, corpse, NULL,TO_CHAR); skeleton = create_mobile(get_mob_index(MOB_VNUM_ANIMATE)); char_to_room(skeleton,ch->in_room); z_level = UMAX(1,corpse->level - number_range(16,26)); skeleton->level = z_level; skeleton->max_hit = (dice(z_level, 18)); skeleton->max_hit += (z_level * 18); skeleton->hit = skeleton->max_hit; skeleton->damroll += (z_level*3/4)*2; skeleton->hitroll += (z_level*3/4); skeleton->alignment = -1000; last_name = name; last_name = one_argument(corpse->short_descr, name); last_name = one_argument(last_name,name); last_name = one_argument(last_name,name); name = last_name; extract_obj(corpse); sprintf( buf1, "the skeleton of %s", name); sprintf( buf2, "A skeleton of %s is standing here.\n\r", name); free_string(skeleton->short_descr); free_string(skeleton->long_descr); skeleton->short_descr = str_dup(buf1); skeleton->long_descr = str_dup(buf2); skeleton->name = str_dup(buf1); add_follower(skeleton,ch); skeleton->leader = ch; af.type = skill_lookup("animate skeleton"); af.duration = -1; af.bitvector = AFF_CHARM; affect_to_char(skeleton,&af); skeleton->spec_fun = spec_lookup("spec_necro_skeleton"); return; } /* * More powerful zombie */ void spell_mummify( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { CHAR_DATA *mummy; OBJ_DATA *corpse; OBJ_DATA *obj_next; OBJ_DATA *obj; CHAR_DATA *search; AFFECT_DATA af; char *name; char *last_name; char *obj_name; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; int chance, l_chance; int z_level; int control; int extra = 0; if ( is_affected(ch,sn) ) { send_to_char("You have not yet regained your powers to over the dead.\n\r",ch); return; } control = 0; for (search = char_list; search != NULL; search = search->next) { if (IS_NPC(search) && (search->master == ch) && search->spec_fun == spec_lookup("spec_necro_zombie")) { control += 6; //sprintf(buf1,"Control1: %d",control); //wiznet(buf1,NULL,NULL,WIZ_DEBUG,0,0); } else if (IS_NPC(search) && (search->master == ch) && search->spec_fun == spec_lookup("spec_necro_skeleton")) { control += 4; //sprintf(buf1,"Control2: %d",control); //wiznet(buf1,NULL,NULL,WIZ_DEBUG,0,0); } else if (IS_NPC(search) && (search->master == ch) && search->spec_fun == spec_lookup("spec_necro_mummy")) { control += 12; //sprintf(buf1,"Control3: %d",control); //wiznet(buf1,NULL,NULL,WIZ_DEBUG,0,0); } } //sprintf(buf1,"ControlT: %d",control); //wiznet(buf1,NULL,NULL,WIZ_DEBUG,0,0); if ((ch->level < 30 && control > 12) || (ch->level < 55 && control > 18) || (ch->level < 70 && control > 24) || (ch->level < 92 && control > 30) || (ch->level <= 101 && control >= 36)) { send_to_char("You already control as many undead as you can.\n\r",ch); return; } if (target_name[0] == '\0') { send_to_char("Which corpse do you wish to Mummify?\n\r",ch); return; } obj_name = str_dup(target_name); corpse = get_obj_here(ch,obj_name); if (corpse == NULL) { send_to_char("You can't mummify that.\n\r",ch); return; } if ((corpse->item_type != ITEM_CORPSE_NPC) || (corpse->item_type == ITEM_CORPSE_PC) ) { send_to_char("You can't mummify or animate that.\n\r",ch); return; } name = corpse->short_descr; for (obj = corpse->contains; obj != NULL; obj = obj_next) { obj_next = obj->next_content; obj_from_obj(obj); obj_to_room(obj,ch->in_room); } chance = get_skill(ch,sn); if (ch->level < corpse->level) { chance += (2*ch->level); chance -= (2*(corpse->level+5)); } l_chance = 10; if(is_obj_affected(corpse,gsn_embalm)) { l_chance = 15; chance += 5; } chance = URANGE(10,chance,85); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = ch->level/6; af.modifier = 0; af.location = 0; af.bitvector = 0; if (number_percent() > chance) { act("You fail and destroy $p",ch,corpse,NULL,TO_CHAR); act("$n chants dark words, $p is destroyed.",ch,corpse,NULL,TO_ROOM); extract_obj(corpse); af.duration = ch->level/12; affect_to_char(ch,&af); return; } affect_to_char(ch,&af); act("$n chants dark words and $p slowly rises to it's feet.",ch,corpse,NULL,TO_ROOM); act("You chant evil words and $p slowly rises to it's feet.",ch,corpse,NULL,TO_CHAR); mummy = create_mobile(get_mob_index(MOB_VNUM_ANIMATE)); char_to_room(mummy,ch->in_room); z_level = UMAX(1,corpse->level - number_range(8,15)); if(is_obj_affected(corpse,gsn_embalm)) { z_level += number_range(8,15); extra = number_range(2,6); } mummy->level = z_level; mummy->max_hit = (dice(z_level, (25 + extra))); mummy->max_hit += (z_level * (25 + extra)); mummy->hit = mummy->max_hit; mummy->damroll += (z_level*5/4)*2 + (extra*10); mummy->hitroll += (z_level*5/4) + (extra*8); mummy->alignment = -1000; last_name = name; last_name = one_argument(corpse->short_descr, name); last_name = one_argument(last_name,name); last_name = one_argument(last_name,name); name = last_name; extract_obj(corpse); sprintf( buf1, "the mummy of %s", name); sprintf( buf2, "A torn and shredded mummy of %s is standing here.\n\r", name); free_string(mummy->short_descr); free_string(mummy->long_descr); mummy->short_descr = str_dup(buf1); mummy->long_descr = str_dup(buf2); mummy->name = str_dup(buf1); add_follower(mummy,ch); mummy->leader = ch; af.type = skill_lookup("mummify"); af.duration = -1; af.bitvector = AFF_CHARM; affect_to_char(mummy,&af); mummy->spec_fun = spec_lookup("spec_necro_mummy"); return; } /* * Alrighty...Lets make skeletons */ void spell_decay_corpse(int sn,int level,CHAR_DATA *ch,void *vo,int target) { OBJ_DATA *corpse; OBJ_DATA *obj; OBJ_DATA *obj_next; OBJ_DATA *skeleton; char *obj_name; char *name; char *last_name; int chance; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; if (target_name[0] == '\0') { send_to_char("Which corpse would you like to decay?\n\r",ch); return; } obj_name = str_dup(target_name); corpse = get_obj_here(ch,obj_name); if (corpse == NULL) { send_to_char("You can't find that object.\n\r",ch); return; } if ((corpse->item_type != ITEM_CORPSE_NPC) && (corpse->item_type != ITEM_CORPSE_PC) ) { send_to_char("You can't decay that.\n\r",ch); return; } name = corpse->short_descr; for (obj = corpse->contains; obj != NULL; obj = obj_next) { obj_next = obj->next_content; obj_from_obj(obj); obj_to_room(obj,ch->in_room); } chance = get_skill(ch,sn); if (number_percent() > chance) { act("You chant dark words of decay but destroy $p.",ch,corpse,NULL,TO_CHAR); act("$n chants dark words, $p is reduced to ashes.",ch,corpse,NULL,TO_ROOM); extract_obj(corpse); return; } act("$n decays the flesh off $p.",ch,corpse,NULL,TO_ROOM); act("You decay the flesh off $p and are left with a skeleton.",ch,corpse,NULL,TO_CHAR); skeleton = create_object(get_obj_index(OBJ_VNUM_GENERIC), 1); obj_to_room(skeleton,ch->in_room); skeleton->level = corpse->level; last_name = name; last_name = one_argument(corpse->short_descr, name); last_name = one_argument(last_name,name); last_name = one_argument(last_name,name); name = last_name; extract_obj(corpse); sprintf( buf1, "the skeleton of %s", name); sprintf( buf2, "A skeleton of %s is lying here in a puddle of decayed flesh.", name); free_string(skeleton->short_descr); free_string(skeleton->description); skeleton->name = str_dup(buf1); skeleton->short_descr = str_dup(buf1); skeleton->description = str_dup(buf2); skeleton->item_type = ITEM_SKELETON; SET_BIT(skeleton->wear_flags, ITEM_TAKE); return; } void spell_steel_flesh( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (IS_SHIELDED(victim, SHD_STEEL)) { if (victim == ch) send_to_char("Your skin is already as hard as a rock.\n\r",ch); else act("$N is already as hard as can be.",ch,NULL,victim,TO_CHAR); return; } af.where = TO_SHIELDS; af.type = sn; af.level = level; af.duration = level/2; af.location = APPLY_AC; af.modifier = -20; af.bitvector = SHD_STEEL; affect_to_char( victim, &af ); act( "$n's flesh turns to steel.", victim, NULL, NULL, TO_ROOM ); send_to_char( "Your flesh turns to steel.\n\r", victim ); return; } void spell_mana_shield( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { AFFECT_DATA af; if ( is_affected( ch, sn )) { send_to_char("You cannot handle the mental pressure of transfering mana yet.\n\r",ch); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level/5; af.location = APPLY_HIT; af.modifier = ch->level * 10; af.bitvector = 0; affect_to_char( ch, &af ); af.location = APPLY_MANA; af.modifier = ch->level * -15; affect_to_char( ch, &af ); act( "$n concentrates and looks healthier.", ch, NULL, NULL, TO_ROOM ); send_to_char( "You feel life surge through your limbs.\n\r", ch ); return; } void spell_darken_blade( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { OBJ_DATA *obj; AFFECT_DATA af; obj=(OBJ_DATA *) vo; if(!IS_EVIL(ch)) { send_to_char("You are not quite wicked enough to do that.\n\r",ch); return ; } if(obj->item_type != ITEM_WEAPON) { send_to_char("You can only target sharp weapons.\n\r",ch); return ; } else { if(obj->value[0]!= WEAPON_SWORD && obj->value[0]!= WEAPON_DAGGER && obj->value[0]!= WEAPON_SPEAR && obj->value[0]!= WEAPON_AXE && obj->value[0]!= WEAPON_POLEARM && obj->value[0]!= WEAPON_EXOTIC) { send_to_char("You must target a sharp weapon.\n\r",ch); return; } else { if(IS_WEAPON_STAT(obj,WEAPON_VAMPIRIC)) { send_to_char("That weapon is already quite evil.\n\r", ch); return ; } if(IS_OBJ_STAT(obj,ITEM_BLESS)) { send_to_char("That weapon is too holy to be touched by your magic.\n\r", ch); return ; } if(!IS_OBJ_STAT(obj,ITEM_EVIL)) SET_BIT(obj->extra_flags, ITEM_EVIL); if(!IS_OBJ_STAT(obj,ITEM_ANTI_GOOD)) SET_BIT(obj->extra_flags, ITEM_ANTI_GOOD); if(!IS_OBJ_STAT(obj,ITEM_ANTI_NEUTRAL)) SET_BIT(obj->extra_flags, ITEM_ANTI_NEUTRAL); af.where = TO_WEAPON; af.type = sn; af.level = level/2; af.duration = level/2; af.location = 0; af.modifier = 0; af.bitvector= WEAPON_VAMPIRIC; affect_to_obj(obj, &af); af.location = APPLY_DAMROLL; af.modifier = ch->level/10; affect_to_obj(obj, &af); af.location = APPLY_HITROLL; af.modifier = ch->level/10; affect_to_obj(obj, &af); act("$p becomes dark and evil.",ch,obj,NULL,TO_ALL); return; } } return ; } void spell_empower_blade( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { OBJ_DATA *obj; AFFECT_DATA af; obj=(OBJ_DATA *) vo; if(obj->item_type != ITEM_WEAPON) { send_to_char("You can only target sharp weapons.\n\r",ch); return ; } else { if(obj->value[0]!=WEAPON_SWORD && obj->value[0]!=WEAPON_DAGGER && obj->value[0]!=WEAPON_SPEAR && obj->value[0]!=WEAPON_AXE && obj->value[0]!=WEAPON_POLEARM && obj->value[0]!=WEAPON_EXOTIC) { send_to_char("You can only target sharp weapons.\n\r",ch); return ; } else { if(IS_WEAPON_STAT(obj,WEAPON_SHOCKING)) { send_to_char("That weapon is already imbued with power.\n\r", ch); return ; } af.where = TO_WEAPON; af.type = sn; af.level = level/2; af.duration = level; af.location = 0; af.modifier = 0; af.bitvector= WEAPON_SHOCKING; affect_to_obj(obj, &af); af.location = APPLY_DAMROLL; af.modifier = 1; affect_to_obj(obj, &af); af.location = APPLY_HITROLL; af.modifier = 1; affect_to_obj(obj, &af); act("$p sparks with electricity.",ch,obj,NULL,TO_ALL); return ; } } return ; } void spell_flame_blade( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { OBJ_DATA *obj; AFFECT_DATA af; obj=(OBJ_DATA *) vo; if(obj->item_type != ITEM_WEAPON) { send_to_char("You can only target sharp weapons.\n\r",ch); return ; } else { if(obj->value[0]!=WEAPON_SWORD && obj->value[0]!=WEAPON_DAGGER && obj->value[0]!=WEAPON_SPEAR && obj->value[0]!=WEAPON_AXE && obj->value[0]!=WEAPON_POLEARM && obj->value[0]!=WEAPON_EXOTIC) { send_to_char("You can only target sharp weapons.\n\r",ch); return ; } else { if(IS_WEAPON_STAT(obj,WEAPON_FLAMING)) { send_to_char("That weapon is already flaming.\n\r", ch); return ; } if(IS_WEAPON_STAT(obj,WEAPON_FROST)) { send_to_char("That weapon is too cold to accept the magic.\n\r", ch); return ; } af.where = TO_WEAPON; af.type = sn; af.level = level/2; af.duration = level*2; af.location = 0; af.modifier = 0; af.bitvector= WEAPON_FLAMING; affect_to_obj(obj, &af); af.location = APPLY_DAMROLL; af.modifier = 1; affect_to_obj(obj, &af); af.location = APPLY_HITROLL; af.modifier = 5; affect_to_obj(obj, &af); act("$p gets a fiery aura.",ch,obj,NULL,TO_ALL); return ; } } return ; } void spell_frost_blade( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { OBJ_DATA *obj; AFFECT_DATA af; obj=(OBJ_DATA *) vo; if(obj->item_type != ITEM_WEAPON) { send_to_char("You can only target sharp weapons.\n\r",ch); return ; } else { if(obj->value[0]!=WEAPON_SWORD && obj->value[0]!=WEAPON_DAGGER && obj->value[0]!=WEAPON_SPEAR && obj->value[0]!=WEAPON_AXE && obj->value[0]!=WEAPON_POLEARM && obj->value[0]!=WEAPON_EXOTIC) return ; else { if(IS_WEAPON_STAT(obj,WEAPON_FROST)) { send_to_char("That weapon is already wickedly cold.\n\r", ch); return ; } if(IS_WEAPON_STAT(obj,WEAPON_FLAMING)) { send_to_char("That weapon is too warm to accept the magic.\n\r", ch); return ; } af.where = TO_WEAPON; af.type = sn; af.level = level/2; af.duration = level*2; af.location = 0; af.modifier = 0; af.bitvector= WEAPON_FROST; affect_to_obj(obj, &af); af.location = APPLY_DAMROLL; af.modifier = 5; affect_to_obj(obj, &af); af.location = APPLY_HITROLL; af.modifier = 1; affect_to_obj(obj, &af); act("$p grows wickedly cold.",ch,obj,NULL,TO_ALL); return ; } } return ; } void spell_acid_blade( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { OBJ_DATA *obj; AFFECT_DATA af; obj=(OBJ_DATA *) vo; if(obj->item_type != ITEM_WEAPON) { send_to_char("You can only target sharp weapons.\n\r",ch); return ; } else { if(obj->value[0]!=WEAPON_SWORD && obj->value[0]!=WEAPON_DAGGER && obj->value[0]!=WEAPON_SPEAR && obj->value[0]!=WEAPON_AXE && obj->value[0]!=WEAPON_POLEARM && obj->value[0]!=WEAPON_EXOTIC) return ; else { if(IS_WEAPON_STAT(obj,WEAPON_ACIDIC)) { send_to_char("That weapon is already corrosive.\n\r", ch); return ; } if(IS_WEAPON_STAT(obj,WEAPON_FLAMING)) { send_to_char("That weapon is too warm to accept the magic.\n\r", ch); return ; } af.where = TO_WEAPON; af.type = sn; af.level = level/2; af.duration = level; af.location = 0; af.modifier = 0; af.bitvector= WEAPON_ACIDIC; affect_to_obj(obj, &af); af.location = APPLY_DAMROLL; af.modifier = 1; affect_to_obj(obj, &af); af.location = APPLY_HITROLL; af.modifier = 1; affect_to_obj(obj, &af); act("$p grows wickedly corrosive.",ch,obj,NULL,TO_ALL); return ; } } return ; } void spell_illusion_armor( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if(!is_affected(victim,sn)) { af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level/6; af.location = APPLY_HIT; af.modifier = level*8; af.bitvector = 0; affect_to_char( victim, &af ); af.modifier = level*5; af.location = APPLY_MANA; affect_to_char( victim, &af ); send_to_char( "You appear mightier then you are!\n\r", victim ); act( "$n grows in stature and appears very mighty!\n\r", victim, NULL, NULL, TO_ROOM ); } else send_to_char("You are already affected by the illusion.\n\r", victim ); return ; } /* Necromancer -- preserve a limb for use later with making golems -Skyn */ void spell_preserve_limb(int sn,int level,CHAR_DATA *ch,void *vo,int target) { OBJ_DATA *obj = (OBJ_DATA *) vo; int vnum, chance; vnum = obj->pIndexData->vnum; if (vnum != OBJ_VNUM_SEVERED_HEAD && vnum != OBJ_VNUM_TORN_HEART && vnum != OBJ_VNUM_SLICED_ARM && vnum != OBJ_VNUM_SLICED_LEG && vnum != OBJ_VNUM_GUTS && vnum != OBJ_VNUM_BRAINS) { send_to_char("You cannot preserve that item.\n\r",ch); return; } if (obj->timer > 10) { send_to_char("It's already in very well preserved condition.\n\r",ch); return; } chance = get_skill(ch,sn); chance = (chance * 9) / 10; if (number_percent() > chance) { act("$n destroys $p.",ch,obj,NULL,TO_ROOM); act("You fail and destroy $p.",ch,obj,NULL,TO_CHAR); extract_obj(obj); return; } act("You cover $p in a magical shell to slow it's decay.",ch,obj,NULL,TO_CHAR); act("$p glows with a sickly green aura.",ch,obj,NULL,TO_ROOM); obj->timer += number_range(level/4,level/3); return; } /* Vampire/Necro classes -- Scare someone stiff? -Skyn */ void spell_fear(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; bool bad_fail, utter_fail; int range; bad_fail = FALSE; utter_fail = FALSE; if (victim == NULL) { send_to_char("Bug -- null victim.\n\r",ch); return; } if (victim == ch) { send_to_char("Want to scare yourself? Go look in a mirror.\n\r",ch); return; } if (ch->fighting != NULL) { send_to_char("You can't concentrate enough.\n\r",ch); return; } act("$n points at $N and intones loudly 'Furcht!'",ch,0,victim,TO_NOTVICT); act("$n points at you and intones loudly 'Furcht!'",ch,0,victim,TO_VICT); act("You point at $N and intone loudly 'Furcht!'",ch,0,victim,TO_CHAR); if (!IS_AWAKE(victim)) { act("$n shivers for a moment.",victim,0,0,TO_ROOM); send_to_char("You feel an icy hand brush your soul, but fall back into a deep dream.\n\r",victim); return; } if (is_affected(victim,sn)) { send_to_char("They are already fear you!\n\r",ch); send_to_char("You feel a small shiver pass through you.\n\r",victim); return; } // No affecting clan guards if (IS_NPC(victim)) { if ( IS_SET(victim->off_flags,OFF_CLAN_GUARD) ) { act("$n shivers for a moment.",victim,0,0,TO_ROOM); send_to_char("You feel the chill of terror for a moment.\n\r", victim); return; } } if (saves_spell(level,victim,DAM_MENTAL)) { act("$n shivers for a moment.",victim,0,0,TO_ROOM); send_to_char("You feel the chill of terror for a moment.\n\r", victim); return; } if (!saves_spell(level - 2,victim,DAM_OTHER)) { bad_fail = TRUE; if (!saves_spell(level - 5,victim,DAM_OTHER)) if (!saves_spell(level,victim,DAM_OTHER)) utter_fail = TRUE; } /* Insta-kill */ if (ch->level - victim->level + IS_NPC(ch) ? 50 : 10 > number_percent()) { if (utter_fail && ((!IS_NPC(victim) && number_percent() > 90) || IS_NPC(victim))) { act("$n's eyes widen and $s heart ruptures from shock!",victim,0,0,TO_ROOM); send_to_char("You feel a terror so intense your heart stops dead!\n\r",victim); raw_kill(victim,ch); group_gain(ch,victim); return; } } act("$n's eyes widen in shock and $s entire body freezes in momentary terror.",victim,NULL,NULL,TO_ROOM); send_to_char("You feel an overwhelming terror and you shudder in momentary shock.\n\r",victim); range = level/12; af.where = TO_AFFECTS; af.type = sn; af.level = level; af.bitvector = 0; af.duration = (number_range(1,5) + range); af.location = APPLY_CON; af.modifier = -number_range(2,range + 1); affect_to_char(victim,&af); af.location = APPLY_STR; af.modifier = -number_range(2,range + 1); affect_to_char(victim,&af); af.location = APPLY_DEX; af.modifier = -number_range(1,range); affect_to_char(victim,&af); af.location = APPLY_HIT; af.modifier = -number_range(2,range); affect_to_char(victim,&af); af.location = APPLY_DAMROLL; af.modifier = -number_range(2,range); affect_to_char(victim,&af); if (victim->position == POS_FIGHTING) do_flee(victim,""); if (victim->position == POS_FIGHTING) do_flee(victim,""); if (victim->position == POS_FIGHTING) do_flee(victim,""); if( bad_fail ) { WAIT_STATE(victim,12); } return; } /* Necromancer -- create a more advanced golem -Skyn */ void spell_greater_golem(int sn, int level, CHAR_DATA *ch, void *vo,int target) { CHAR_DATA *golem; AFFECT_DATA af; OBJ_DATA *part; OBJ_DATA *part_next; int parts = 0; CHAR_DATA *check; int z_level; if (is_affected(ch,sn)) { send_to_char("You are not rested enough to make another golem yet.\n\r",ch); return; } for (check = char_list; check != NULL; check = check->next) { if (IS_NPC(check)) if ( (check->master == ch) && (check->spec_fun == spec_lookup("spec_necro_igolem")) ) { send_to_char("You already have a golem under your command.\n\r",ch); return; } } for (part = ch->carrying; part != NULL; part = part_next) { part_next = part->next_content; if (part->pIndexData->vnum != OBJ_VNUM_SEVERED_HEAD && part->pIndexData->vnum != OBJ_VNUM_TORN_HEART && part->pIndexData->vnum != OBJ_VNUM_SLICED_ARM && part->pIndexData->vnum != OBJ_VNUM_SLICED_LEG && part->pIndexData->vnum != OBJ_VNUM_GUTS && part->pIndexData->vnum != OBJ_VNUM_BRAINS) continue; parts++; } if (parts == 0) { send_to_char("You don't have any body parts to create a golem with!\n\r",ch); return; } else if (parts <= 2) { send_to_char("You don't have enough limbs to make a golem.\n\r",ch); return; } for (part = ch->carrying; part != NULL; part = part_next) { part_next = part->next_content; if (part->pIndexData->vnum != OBJ_VNUM_SEVERED_HEAD && part->pIndexData->vnum != OBJ_VNUM_TORN_HEART && part->pIndexData->vnum != OBJ_VNUM_SLICED_ARM && part->pIndexData->vnum != OBJ_VNUM_SLICED_LEG && part->pIndexData->vnum != OBJ_VNUM_GUTS && part->pIndexData->vnum != OBJ_VNUM_BRAINS) continue; extract_obj(part); } /*for (part = ch->carrying; part != NULL; part = part_next) { part_next = part->next_content; if (part->pIndexData->item_type != ITEM_ARMOR) continue; parts++; } if (parts < 1) { send_to_char("You must have some metal armor to make the golem.\n\r",ch); return; } for (part = ch->carrying; part != NULL; part = part_next) { part_next = part->next_content; if (part->pIndexData->item_type != ITEM_ARMOR) continue; extract_obj(part); }*/ af.where = TO_AFFECTS; af.level = level; af.location = 0; af.modifier = 0; af.duration = 35; af.bitvector = 0; af.type = sn; affect_to_char(ch,&af); act("$n takes some spare body parts and creates an iron golem!",ch,0,0,TO_ROOM); send_to_char("You use some preserved limbs to fashion an iron golem to serve you!\n\r",ch); golem = create_mobile(get_mob_index(MOB_VNUM_IGOLEM)); z_level = ch->level + number_range(-10,15); golem->level = z_level; golem->max_hit = (dice(z_level, 30)); golem->max_hit += (z_level * 30); golem->max_move = ch->max_move; golem->move = golem->max_move; golem->hit = golem->max_hit; golem->damroll += (z_level*5/4)*2; golem->hitroll += (z_level*11/8); golem->alignment = -1000; char_to_room(golem,ch->in_room); add_follower(golem,ch); golem->leader = ch; af.type = sn; af.duration = -1; af.bitvector = AFF_CHARM; affect_to_char(golem,&af); golem->spec_fun = spec_lookup("spec_necro_igolem"); return; } /* Necromancer -- create a basic golem -Skyn */ void spell_lesser_golem(int sn,int level, CHAR_DATA *ch,void *vo,int target) { CHAR_DATA *golem; AFFECT_DATA af; CHAR_DATA *check; OBJ_DATA *part; OBJ_DATA *part_next; int parts = 0; int z_level; if (is_affected(ch,sn)) { send_to_char("You are not ready to build another golem yet.\n\r",ch); return; } for (check = char_list; check != NULL; check = check->next) { if (IS_NPC(check)) if ( (check->master == ch) && (check->spec_fun == spec_lookup("spec_necro_fgolem")) ) { send_to_char("You already have a flesh golem under your command.\n\r",ch); return; } } for (part = ch->carrying; part != NULL; part = part_next) { part_next = part->next_content; if (part->pIndexData->vnum != OBJ_VNUM_SEVERED_HEAD && part->pIndexData->vnum != OBJ_VNUM_TORN_HEART && part->pIndexData->vnum != OBJ_VNUM_SLICED_ARM && part->pIndexData->vnum != OBJ_VNUM_SLICED_LEG && part->pIndexData->vnum != OBJ_VNUM_GUTS && part->pIndexData->vnum != OBJ_VNUM_BRAINS) continue; parts++; } if (parts == 0) { send_to_char("You don't have any body parts to create a golem with!\n\r",ch); return; } else if (parts <= 2) { send_to_char("You don't have enough limbs to make a golem.\n\r",ch); return; } for (part = ch->carrying; part != NULL; part = part_next) { part_next = part->next_content; if (part->pIndexData->vnum != OBJ_VNUM_SEVERED_HEAD && part->pIndexData->vnum != OBJ_VNUM_TORN_HEART && part->pIndexData->vnum != OBJ_VNUM_SLICED_ARM && part->pIndexData->vnum != OBJ_VNUM_SLICED_LEG && part->pIndexData->vnum != OBJ_VNUM_GUTS && part->pIndexData->vnum != OBJ_VNUM_BRAINS) continue; extract_obj(part); } if (parts >= ch->level/10) parts = ch->level/10; z_level = ch->level + number_range(-6,8); z_level += parts; af.where = TO_AFFECTS; af.level = level; af.location = 0; af.modifier = 0; af.duration = 35; af.bitvector = 0; af.type = sn; affect_to_char(ch,&af); act("$n pieces some severed limbs and dead flesh together and creates a flesh golem!",ch,0,0,TO_ROOM); send_to_char("You build a flesh golem to serve you!\n\r",ch); golem = create_mobile(get_mob_index(MOB_VNUM_FGOLEM)); golem->level = z_level; golem->max_hit = (dice(z_level, (18+parts/2) )); golem->max_hit += (z_level * (18+parts/2)); golem->max_move = ch->max_move; golem->move = golem->max_move; golem->hit = golem->max_hit; golem->damroll += (z_level*4/4)*2 + parts * 3; golem->hitroll += (z_level*4/4) + parts; golem->alignment = -1000; char_to_room(golem,ch->in_room); add_follower(golem, ch); golem->leader = ch; af.type = sn; af.duration = -1; af.bitvector = AFF_CHARM; affect_to_char(golem,&af); golem->spec_fun = spec_lookup("spec_necro_fgolem"); return; } /* Necromancer -- light a fire? :) -Skyn */ void spell_cremate(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; if (check_sorcery(ch,sn)) dam = sorcery_dam(level,19,ch); else dam = dice(level,21); act("$n is enveloped by searing fire!",victim,0,0,TO_ROOM); send_to_char("You are enveloped in a searing fire!\n\r",victim); if ( saves_spell( level, victim, DAM_FIRE ) ) dam /= 2; damage_old( ch, victim, dam, sn, DAM_FIRE, TRUE); if( number_percent( ) < 10 ) { dam = number_range(1,level / 5 + 6); act("$n is covered in flames!",victim,NULL,NULL,TO_ROOM); act("You are enveloped in flames!",victim,NULL,NULL,TO_CHAR); fire_effect( (void *) victim,level/1.5,dam,TARGET_CHAR); damage_old(ch,victim,dam,0,DAM_FIRE,FALSE); } return; } void spell_courage( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (is_affected(victim, sn)) { if (victim == ch) send_to_char("You are already envigorated with courage.\n\r",ch); else act("$N is already courageous.",ch,NULL,victim,TO_CHAR); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 10; //to use wisdom af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char( victim, &af ); send_to_char("You lift your face with renewed vigor ready to face all obstaces to come.\n\r",victim); affect_strip(victim,skill_lookup("fear aura")); if ( ch != victim ) act("$N shifts their stance settling into a pose implying strength and resolve.",ch,NULL,victim,TO_CHAR); return; } void spell_imbue_weapon(int sn, int level, CHAR_DATA *ch, void *vo, int target) { return; } void spell_restore(int sn, int level, CHAR_DATA *ch, void *vo, int target) { return; } //Martyr spell for Saints. Automatically aggies everything in the room on them. Fesdor 1-20-09 void spell_martyr(int sn,int level,CHAR_DATA *ch,void *vo,int target) { CHAR_DATA *vch; CHAR_DATA *vch_next; CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; int marker = 0; if (victim != ch) { //TAR_CHAR_DEFENSIVE would normally allow casting on another. I chose it so they can still use this during combat. send_to_char("Sacrifice someone else and take the credit? Yeah right.\n\r",ch); return; } if (is_affected(ch,sn)) { send_to_char("You cannot martyr yourself again so soon!\n\r",ch); return; } for (vch = ch->in_room->people; vch != NULL; vch = vch_next) { vch_next = vch->next_in_room; if ((is_safe_spell(ch,vch,TRUE) || (is_same_group(ch,vch)) || (vch == ch)) && (ch->fighting != vch || vch->fighting != ch)) continue; if ( ( ch->fighting == NULL ) && ( !IS_NPC( ch ) ) && ( !IS_NPC( vch ) ) ) { ch->attacker = FALSE; vch->attacker = TRUE; } char buf[MAX_STRING_LENGTH]; sprintf(buf,"%s draws your attention, forcing you to attack them!\n\r",ch->short_descr); send_to_char(buf,vch); vch->fighting = ch; marker = 1;//We have a taker! } if(marker) { send_to_char("You sacrifice yourself for the good of the cause!\n\r",ch); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 1;//Once every 2 ticks. af.bitvector= 0; af.modifier = -100;//A little defense boost with all the tanking they're about to do af.location = APPLY_AC; affect_to_char( ch, &af ); } return; }