/*************************************************************************** * 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 "newclan.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( OBJ_DATA *list, CHAR_DATA *ch, bool fShort, bool fShowNothing ); void show_char_to_char( CHAR_DATA *list, CHAR_DATA *ch ); extern char *target_name; extern char *third_name; bool check_dispel( int dis_level, CHAR_DATA *victim, int sn); extern void raw_kill(CHAR_DATA * victim, CHAR_DATA * killer); extern void group_gain(CHAR_DATA * ch, CHAR_DATA * victim); int sorcery_dam( int num, int dice, CHAR_DATA *ch); int sorcery_dam2(int dam); bool check_sorcery(CHAR_DATA *ch, int sn); int focus_level(long total); int cast_level; 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 (!can_gate(ch, victim = get_char_world(ch, target_name), level, TRUE, TRUE)) { 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; if (!can_gate(ch, victim = get_char_world(ch, target_name), level, FALSE, TRUE)) { send_to_char("You failed.\n\r", ch); return; } from_room = ch->in_room; to_room = victim->in_room; 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, ((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; cast_level = ch->level + tier_spell_bonus(ch); 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 || ch->class == CLASS_ARCHMAGE)//breehere { 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 = cast_level * 3 / 2; pet->damroll = cast_level * 7 / 2; 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 = cast_level * 3 / 2; pet->damroll = cast_level * 7 / 2; 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 = cast_level * 3 / 2; pet->damroll = cast_level * 7 / 2; 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 = cast_level * 3 / 2; pet->damroll = cast_level * 7 / 2; 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->questpoints += 300; send_to_char("{YYou've gained 300 {RQuest Points{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); damage_resonance(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); damage_resonance(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); damage_resonance(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); damage_resonance(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 / 4; af.location = APPLY_DEX; af.modifier = -1 - (level / 8); 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); damage_resonance(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) { CHAR_DATA *victim; ROOM_INDEX_DATA *pRoomIndex; char buf[MSL]; 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; } if (victim == ch) { send_to_char("You are here!\n\r", ch); return; } // Start search send_to_char("You extend your wizards eye...\n\r", ch); // Does (s)he make it?! if (saves_spell((victim->level+tier_spell_bonus(victim))*3/2, ch, DAM_OTHER )) { /* ok. now the hard bit. */ if (IS_AFFECTED(victim, AFF_DISPLACE)) { pRoomIndex = get_random_room(victim); sprintf(buf, "vnum %d", pRoomIndex->vnum); do_look(ch, buf); victim = pRoomIndex->people; if (!(victim == NULL)) { sprintf(buf, "The visage of %s shimmers above.\n\r", ch->name); send_to_room(buf, victim); } return; } // No displace! Hit them! pRoomIndex = victim->in_room; sprintf(buf, "vnum %d", pRoomIndex->vnum); do_look(ch, buf); sprintf(buf, "The visage of %s shimmers above.\n\r", ch->name); //send_to_char(buf, victim); send_to_room(buf, victim); return; } else { sprintf(buf, "The face of %s begins to form above, but quickly disperses.\n\r", ch->name); //send_to_char(buf, victim); send_to_room(buf, victim); } if ((IS_AFFECTED(victim, AFF_DETECT_LOCATION)) && (saves_spell((ch->level+tier_spell_bonus(ch))*2, victim, DAM_OTHER ))) { // They failed, we didn't. Return fire! send_to_char("You deflect the attack and trace the source!\n\r", victim); send_to_char("Wild magic surges back through the connection! You've been found!\n\r", ch); pRoomIndex = ch->in_room; sprintf(buf, "vnum %d", pRoomIndex->vnum); do_look(victim, buf); } else if (IS_AFFECTED(victim, AFF_DETECT_LOCATION)) { // We failed :(. send_to_char("You deflect the attack, but fail to trace the source.\n\r", victim); send_to_char("You reach out with your mind, and are rebuffed!\n\r", ch); return; } else { // No detect location. Failed. send_to_char("You are unable to penetrate their defenses.\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 totaldam = 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); dam = dice(vch->level + tier_spell_bonus(vch), 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); totaldam += dam * 1.3; // damage_resonance(ch, victim, dam * 1.3, sn, DAM_MENTAL, TRUE); ch->mana -= vch->level + tier_spell_bonus(vch) / 5; totalhits++; } } damage_resonance(ch, victim, totaldam, sn, DAM_MENTAL,TRUE); 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; }*/ 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) { 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); damage_resonance(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, level); damage(ch, victim, dam, gsn_turn_undead, DAM_HOLY, TRUE, 0); damage_resonance(ch, victim, dam, gsn_turn_undead, DAM_HOLY, TRUE); } } 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)) { printf_system( "%s killed by %s at %d", victim->name, (IS_NPC (ch) ? ch->short_descr : ch->name), ch->in_room->vnum); } } else { dam = dice(20, level); damage(ch, victim, dam, gsn_turn_undead, DAM_HOLY, TRUE, 0); damage_resonance(ch, victim, dam, gsn_turn_undead, DAM_HOLY, TRUE); } } 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(level, level * 4 / 2); guard->hitroll += (level * 3); guard->damroll += (level * 2); guard->max_hit = number_range(ch->max_hit / 5, (ch->max_hit * 3 / 5.5)); 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 (level < 30 && control > 12) { send_to_char("You already control as many undead as you can.\n\r", ch); return; } else if (level < 55 && control > 17) { send_to_char("You already control as many undead as you can.\n\r", ch); return; } else if (level < 70 && control > 24) { send_to_char("You already control as many undead as you can.\n\r", ch); return; } else if (level < 92 && control > 35) { send_to_char("You already control as many undead as you can.\n\r", ch); return; } else if (level <= 101 && control > 42) { send_to_char("You already control as many undead as you can.\n\r", ch); return; } else if (level > 101 && control >= 45) { 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 (level < corpse->level) { chance += (3 * 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 = 3; //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 = 1; //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 (level < corpse->level) { chance += (4 * level); chance -= (3 * corpse->level); } chance = URANGE(10,chance,95); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 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 = 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 (level < corpse->level) { chance += (2 * 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 = 3;// 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 = 1; //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 = level * 10; af.bitvector = 0; affect_to_char(ch, &af); af.location = APPLY_MANA; af.modifier = level * -11; 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 = level / 10; affect_to_obj(obj, &af); af.location = APPLY_HITROLL; af.modifier = 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 (level - victim->level + IS_NPC(ch) ? 50 : (10 - tier_spell_bonus(victim)) > 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 = 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 >= level / 10) parts = level / 10; z_level = 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); damage_resonance(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); damage_resonance(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 invigorated 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 setting 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; } /* Hunters can sector a room as forest for a little while */ void spell_overgrowth(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; if (IS_SET(ch->in_room->affected_by,ROOM_AFF_OVERGROWN) || ch->in_room->sector_type == SECT_FOREST) { send_to_char("You are already in a forest!\n\r", ch); ch->mana += 200; return; } af.where = TO_ROOM_AFF; af.type = sn; af.level = level; af.duration = level / 15; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = ROOM_AFF_OVERGROWN; affect_to_room(ch->in_room, &af); act( "$n begins to chant as vines and trees burst into existence throughout the room!\n\r", ch, NULL, NULL, TO_ROOM ); send_to_char( "Vines and trees burst into existence throughout the room!\n\r", ch); return; }