/*************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * Envy Diku Mud improvements copyright (C) 1994 by Michael Quan, David * * Love, Guilherme 'Willie' Arnold, and Mitchell Tse. * * * * In order to use any part of this Envy Diku Mud, you must comply with * * the original Diku license in 'license.doc', the Merc license in * * 'license.txt', as well as the Envy license in 'license.nvy'. * * In particular, you may not remove either of these copyright notices. * * * * Much time and thought has gone into this software and you are * * benefitting. We hope that you share your changes too. What goes * * around, comes around. * ***************************************************************************/ /*$Id: magic3.c,v 1.32 2005/04/10 16:29:00 tyrion Exp $*/ #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" char *target_name; extern void set_fighting args( ( CHAR_DATA *ch, CHAR_DATA *victim ) ); int spell_summon_shadow(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; if(ch->summon_timer > 0) { send_to_char(AT_WHITE, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } /* the following block disables the summon_shadow spell */ /* temp patch until the mob vnum exists -- REK */ /* Enabled. if(ch->summon_timer <= 0) { send_to_char(AT_WHITE, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } */ mob = create_mobile(get_mob_index(MOB_VNUM_SHADOW)); mob->level = URANGE(51, level, 100) - 20; mob->max_hit = mob->level * 20 + dice(10,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_GREY, "You summon $N from the shadow plane.", ch, NULL, mob, TO_CHAR); if(ch->bp < level/2 ) { act(AT_RED, "You don't have enough blood to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } ch->bp -= level /2; act(AT_GREY, "$n calls forth $N from the shadow plane.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_WHITE, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_WHITE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } int spell_summon_trent(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; if(ch->summon_timer > 0) { send_to_char(AT_WHITE, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } mob = create_mobile(get_mob_index(MOB_VNUM_TRENT)); mob->level = URANGE(51, level, 100) - 10; mob->max_hit = mob->level * 40 + dice(20,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_ORANGE, "You summon $N from the plane of nature.", ch, NULL, mob, TO_CHAR); if(ch->mana < level * 2 ) { act(AT_WHITE, "You don't have enough mana to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } ch->mana -= level * 2; act(AT_ORANGE, "$n calls forth $N from the plane of nature.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_WHITE, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_WHITE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } int spell_summon_beast(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; char buf[MAX_STRING_LENGTH]; char *beast; if(ch->summon_timer > 0) { send_to_char(AT_WHITE, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } /* the following block disables the summon_beast spell */ /* temp patch until the mob vnum exists -- REK */ /* Enabled. if(ch->summon_timer <= 0) { send_to_char(AT_WHITE, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } */ switch (number_bits( 4 ) ) { case 0: beast = "horse"; break; case 1: beast = "cow"; break; case 2: beast = "bear"; break; case 3: beast = "lion"; break; case 4: beast = "bobcat"; break; case 5: beast = "mongoose"; break; case 6: beast = "rattle snake"; break; case 7: beast = "monkey"; break; default: beast = "tigeress"; break; } mob = create_mobile(get_mob_index(MOB_VNUM_BEAST)); sprintf(buf, mob->short_descr, beast); free_string( mob->short_descr ); mob->short_descr = str_dup(buf); sprintf(buf, mob->long_descr, beast, ch->name); free_string( mob->long_descr ); mob->long_descr = str_dup(buf); mob->level = URANGE(51, level, 100) - 20; mob->max_hit = mob->level * 20 + dice(10,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_GREEN, "You call $N from the forests.", ch, NULL, mob, TO_CHAR); if(ch->mana < level * 2 ) { act(AT_WHITE, "You don't have enough mana to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } ch->mana -= level * 2; act(AT_GREEN, "$n calls forth $N from the forests.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_WHITE, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_WHITE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } void perm_spell(CHAR_DATA *victim, int sn) { AFFECT_DATA *af; if(is_affected(victim, sn)) { for(af = victim->affected; af != NULL; af = af->next) { if(af->type == sn) { af->duration = -1; return; } } for(af = victim->affected2; af != NULL; af = af->next) { if(af->type == sn) { af->duration = -1; return; } } for(af = victim->affected3; af != NULL; af = af->next) { if(af->type == sn) { af->duration = -1; return; } } for(af = victim->affected4; af != NULL; af = af->next) { if(af->type == sn) { af->duration = -1; return; } } for(af = victim->affected_powers; af != NULL; af = af->next) { if(af->type == sn) { af->duration = -1; return; } } for(af = victim->affected_weaknesses; af != NULL; af = af->next) { if(af->type == sn) { af->duration = -1; return; } } } return; } int spell_duration(CHAR_DATA *victim, int sn) { AFFECT_DATA *af; if(is_affected(victim, sn)) { for(af = victim->affected; af != NULL; af = af->next) { if(af->type == sn) { return af->duration; } } for(af = victim->affected2; af != NULL; af = af->next) { if(af->type == sn) { return af->duration; } } for(af = victim->affected3; af != NULL; af = af->next) { if(af->type == sn) { return af->duration; } } for(af = victim->affected4; af != NULL; af = af->next) { if(af->type == sn) { return af->duration; } } } return -2; } /* RT save for dispels */ /* modified for envy -XOR */ bool saves_dispel(int dis_level, int spell_level, int duration) { int save; if(duration == -1) spell_level += 5;/* very hard to dispel permanent effects */ save = 50 + (spell_level - dis_level) * 5; save = URANGE( 5, save, 95 ); return number_percent() < save; } /* co-routine for dispel magic and cancellation */ bool check_dispel(int dis_level, CHAR_DATA *victim, int sn) { AFFECT_DATA *af; if (is_affected(victim, sn)) { for(af = victim->affected; af != NULL; af = af->next) { if(af->type == sn) { if(!saves_dispel(dis_level,af->level,af->duration)) { affect_strip(victim,sn); if(skill_table[sn].msg_off) { send_to_char(C_DEFAULT, skill_table[sn].msg_off, victim ); send_to_char(C_DEFAULT, "\n\r", victim ); } if ( af->type == AFF_FLYING ) check_nofloor( victim ); return TRUE; } else af->level--; } } } return FALSE; } /* first of functions to try to dispel a bit off each of the affected loc'tns -- .._aff1, _aff2, _aff3 _aff4 are the indentical functions cept they work on different bit fields.--Manaux*/ void check_dispel_aff( CHAR_DATA *victim, bool * found, int level, const char * spell, long vector ) { int sn; sn = skill_lookup(spell); if (!skill_table[sn].dispel_bit) return; if(IS_AFFECTED(victim,vector) && !saves_spell(level, victim) && !is_affected(victim,sn) ) { *found = TRUE; REMOVE_BIT(victim->affected_by,vector); if(skill_table[sn].msg_off) { act(C_DEFAULT, skill_table[sn].msg_off, victim, NULL, NULL, TO_CHAR); if(skill_table[sn].msg_off_room) { act(C_DEFAULT, skill_table[sn].msg_off_room, victim, NULL, NULL, TO_ROOM); } } if ( vector == AFF_FLYING ) check_nofloor( victim ); } } void check_dispel_aff2( CHAR_DATA *victim, bool * found, int level, const char * spell, long vector ) { int sn; sn = skill_lookup(spell); if(!skill_table[sn].dispel_bit) return; if(IS_AFFECTED2(victim,vector) && !saves_spell(level, victim) && !is_affected(victim,sn) ) { *found = TRUE; REMOVE_BIT(victim->affected_by2,vector); if(skill_table[sn].msg_off) { act(C_DEFAULT, skill_table[sn].msg_off, victim, NULL, NULL, TO_CHAR); if(skill_table[sn].msg_off_room) { act(C_DEFAULT, skill_table[sn].msg_off_room, victim, NULL, NULL, TO_ROOM); } } } } void check_dispel_aff3( CHAR_DATA *victim, bool * found, int level, const char * spell, long vector ) { int sn; sn = skill_lookup(spell); if (!skill_table[sn].dispel_bit) return; if(IS_AFFECTED3(victim,vector) && !saves_spell(level, victim) && !is_affected(victim,sn) ) { *found = TRUE; REMOVE_BIT(victim->affected_by3,vector); if(skill_table[sn].msg_off) { act(C_DEFAULT, skill_table[sn].msg_off, victim, NULL, NULL, TO_CHAR); if(skill_table[sn].msg_off_room) { act(C_DEFAULT, skill_table[sn].msg_off_room, victim, NULL, NULL, TO_ROOM); } } } } void check_dispel_aff4( CHAR_DATA *victim, bool * found, int level, const char * spell, long vector ) { int sn; sn = skill_lookup(spell); if (!skill_table[sn].dispel_bit) return; if(IS_AFFECTED4(victim,vector) && !saves_spell(level, victim) && !is_affected(victim,sn) ) { *found = TRUE; REMOVE_BIT(victim->affected_by4,vector); if(skill_table[sn].msg_off) { act(C_DEFAULT, skill_table[sn].msg_off, victim, NULL, NULL, TO_CHAR); if(skill_table[sn].msg_off_room) { act(C_DEFAULT, skill_table[sn].msg_off_room, victim, NULL, NULL, TO_ROOM); } } } } bool dispel_flag_only_spells(int level, CHAR_DATA *vo); bool dispel_flag_only_spells( int level, CHAR_DATA * victim ) { bool found; found = FALSE; /*check_dispel_aff ( victim, &found, level, "detect evil", AFF_DETECT_EVIL);*/ check_dispel_aff ( victim, &found, level, "invis", AFF_INVISIBLE); check_dispel_aff ( victim, &found, level, "detect invis", AFF_DETECT_INVIS); check_dispel_aff ( victim, &found, level, "detect hidden", AFF_DETECT_HIDDEN); check_dispel_aff ( victim, &found, level, "sanctuary", AFF_SANCTUARY); check_dispel_aff ( victim, &found, level, "protection evil", AFF_PROTECT); check_dispel_aff ( victim, &found, level, "hide", AFF_HIDE); check_dispel_aff ( victim, &found, level, "fly", AFF_FLYING); check_dispel_aff ( victim, &found, level, "fireshield", AFF_FIRESHIELD); check_dispel_aff ( victim, &found, level, "shockshield", AFF_SHOCKSHIELD); check_dispel_aff ( victim, &found, level, "iceshield", AFF_ICESHIELD); check_dispel_aff ( victim, &found, level, "chaos field", AFF_CHAOS); check_dispel_aff2( victim, &found, level, "unholy strength", AFF_UNHOLY_STRENGTH); check_dispel_aff2( victim, &found, level, "blade barrier", AFF_BLADE); check_dispel_aff2( victim, &found, level, "protection good", AFF_PROTECTION_GOOD); check_dispel_aff2( victim, &found, level, "phase shift", AFF_PHASED); check_dispel_aff2( victim, &found, level, "golden armor", AFF_GOLDEN_ARMOR); check_dispel_aff2( victim, &found, level, "ghost shield", AFF_GHOST_SHIELD); check_dispel_aff2( victim, &found, level, "mist", AFF_MIST); check_dispel_aff2( victim, &found, level, "shadow image", AFF_SHADOW_IMAGE); check_dispel_aff2( victim, &found, level, "improved invis", AFF_IMPROVED_INVIS); check_dispel_aff3( victim, &found, level, "circle of fire", AFF_COFIRE); check_dispel_aff3( victim, &found, level, "satanic inferno", AFF_SATANIC_INFERNO); check_dispel_aff3( victim, &found, level, "bloodshield", AFF_BLOODSHIELD); check_dispel_aff3( victim, &found, level, "randomshield", AFF_RANDOMSHIELD); check_dispel_aff3( victim, &found, level, "acidshield", AFF_ACIDSHIELD); check_dispel_aff3( victim, &found, level, "demonshield", AFF_DEMONSHIELD); check_dispel_aff4( victim, &found, level, "golden sanctuary",AFF_GOLDEN_SANCTUARY); check_dispel_aff4( victim, &found, level, "biofeedback",AFF_BIOFEEDBACK); check_dispel_aff4( victim, &found, level, "earthshield", AFF_EARTHSHIELD); check_dispel_aff4( victim, &found, level, "leaf shield", AFF_LEAF_SHIELD); check_dispel_aff4( victim, &found, level, "luck shield", AFF_LUCK_SHIELD); check_dispel_aff4( victim, &found, level, "tongues", AFF_TONGUES); check_dispel_aff4( victim, &found, level, "liquid skin", AFF_LIQUID_SKIN); check_dispel_aff4( victim, &found, level, "force of nature", AFF_FORCE_OF_NATURE); check_dispel_aff4( victim, &found, level, "essence of gaia", AFF_ESSENCE_OF_GAIA); return found; } /* modified by XOR */ /* Rom2 modified for enhanced use */ int spell_dispel_magic ( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; bool found = FALSE; /*flag to see if we have dispeled something yet*/ AFFECT_DATA *paf; /*pointer to affect to count through, this will allows us to count through only the affects that the character has --Manaux */ if(saves_spell(level, victim)) { send_to_char(C_DEFAULT, "You feel a brief tingling sensation.\n\r",victim); send_to_char(AT_BLUE, "You failed.\n\r", ch); return SKPELL_MISSED; } if ( IS_AFFECTED3( victim, AFF_HOLY_PROTECTION ) ) { if( number_percent() < ch->level - 29 ) { send_to_char(AT_WHITE, "Your holy protection withstands.\n\r", victim ); send_to_char(AT_WHITE, "You failed to penetrate the holy protection.\n\r", ch); return SKPELL_MISSED; } send_to_char(AT_WHITE, "Your holy protection has failed.\n\r", victim ); send_to_char(AT_WHITE, "You have breached the holy protection.\n\r", ch ); REMOVE_BIT(victim->affected_by3, AFF_HOLY_PROTECTION); return SKPELL_MISSED; } for ( paf = victim->affected; paf; paf = paf->next ) { if ( paf->deleted ) continue; if ( skill_table[ (int) paf->type].dispel_bit == TRUE ) { if(saves_spell(level, victim)) continue; if(!saves_dispel(ch->level,paf->level,paf->duration)) { affect_strip(victim,(int) paf->type); if(skill_table[paf->type].msg_off) { send_to_char(C_DEFAULT, skill_table[paf->type].msg_off, victim ); send_to_char(C_DEFAULT, "\n\r", victim ); } if(skill_table[paf->type].shield_bit) { victim->shields -= 1; } found = TRUE; act(C_DEFAULT, skill_table[paf->type].msg_off_room, victim,NULL,NULL,TO_NOTVICT); if ( paf->type == AFF_FLYING ) check_nofloor( victim ); } } } for ( paf = victim->affected2; paf; paf = paf->next ) { if ( paf->deleted ) continue; if ( skill_table[ (int) paf->type].dispel_bit == TRUE ) { if(saves_spell(level, victim) ) continue; if(!saves_dispel(ch->level,paf->level,paf->duration)) { affect_strip(victim,(int) paf->type); if(skill_table[paf->type].msg_off) { send_to_char(C_DEFAULT, skill_table[paf->type].msg_off, victim ); send_to_char(C_DEFAULT, "\n\r", victim ); } if(skill_table[paf->type].shield_bit) { victim->shields -= 1; } found = TRUE; act(C_DEFAULT, skill_table[paf->type].msg_off_room, victim,NULL,NULL,TO_NOTVICT); if ( paf->type == AFF_FLYING ) check_nofloor( victim ); } } } for ( paf = victim->affected3; paf; paf = paf->next ) { if ( paf->deleted ) continue; if ( skill_table[ (int) paf->type].dispel_bit == TRUE ) { if(saves_spell(level, victim)) continue; if(!saves_dispel(ch->level,paf->level,paf->duration)) { affect_strip(victim,(int) paf->type); if(skill_table[paf->type].msg_off) { send_to_char(C_DEFAULT, skill_table[paf->type].msg_off, victim ); send_to_char(C_DEFAULT, "\n\r", victim ); } if(skill_table[paf->type].shield_bit) { victim->shields -= 1; } found = TRUE; act(C_DEFAULT, skill_table[paf->type].msg_off_room, victim,NULL,NULL,TO_NOTVICT); if ( paf->type == AFF_FLYING ) check_nofloor( victim ); } } } for ( paf = victim->affected4; paf; paf = paf->next ) { if ( paf->deleted ) continue; if ( skill_table[ (int) paf->type].dispel_bit == TRUE ) { if(saves_spell(level, victim)) continue; if(!saves_dispel(ch->level,paf->level,paf->duration)) { affect_strip(victim,(int) paf->type); if(skill_table[paf->type].msg_off) { send_to_char(C_DEFAULT, skill_table[paf->type].msg_off, victim ); send_to_char(C_DEFAULT, "\n\r", victim ); } if(skill_table[paf->type].shield_bit) { victim->shields -= 1; } found = TRUE; act(C_DEFAULT, skill_table[paf->type].msg_off_room, victim,NULL,NULL,TO_NOTVICT); if (paf->type == AFF_FLYING ) check_nofloor( victim ); } } } found = found || dispel_flag_only_spells(level, victim); if (found == FALSE) { send_to_char(AT_BLUE, "You Failed.\n\r", ch); } else { send_to_char(AT_BLUE, "You have succeeded!\n\r", ch); act(AT_BLUE, "Some of $N's magic is removed!", ch, NULL, victim, TO_NOTVICT); } return SKPELL_NO_DAMAGE; } int spell_cancellation(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *) vo; bool found = FALSE; AFFECT_DATA *paf ; level += 2; if( sn == skill_lookup("cancellation") ) { if((!IS_NPC(ch) && IS_NPC(victim) && !(IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim)) || (IS_NPC(ch) && !IS_NPC(victim)) || !is_same_group(ch, victim)) { send_to_char(C_DEFAULT, "You failed, try dispel magic.\n\r",ch); return SKPELL_MISSED; } } if( ch->fighting || victim->fighting ) { send_to_char(C_DEFAULT, "You failed.\n\r", ch ); return SKPELL_MISSED; } /*Ok, here's the new improved cancellation routine --Manaux */ for ( paf = victim->affected; paf; paf = paf->next ) { if ( paf->deleted ) continue; if ( skill_table[ (int) paf->type].cancel_bit == TRUE ) { if(saves_spell(level - 20, victim)) /* -20 so it's easier to make */ continue; /* saves vs yourself */ /* This will make having a really good savings not neccessarily a good thing */ affect_strip(victim,(int) paf->type); if(skill_table[paf->type].msg_off) { send_to_char(C_DEFAULT, skill_table[paf->type].msg_off, victim ); send_to_char(C_DEFAULT, "\n\r", victim ); } if(skill_table[paf->type].shield_bit) { victim->shields -= 1; } found = TRUE; act(C_DEFAULT, skill_table[paf->type].msg_off_room, victim,NULL,NULL,TO_NOTVICT); if ( paf->type == AFF_FLYING ) check_nofloor( victim ); } } for ( paf = victim->affected2; paf; paf = paf->next ) { if ( paf->deleted ) continue; if ( skill_table[ (int) paf->type].cancel_bit == TRUE ) { if(saves_spell(level - 20, victim)) /* -20 so it's easier to make */ continue; /* saves vs yourself */ /* This will make having a really good savings not neccessarily a good thing */ affect_strip(victim,(int) paf->type); if(skill_table[paf->type].msg_off) { send_to_char(C_DEFAULT, skill_table[paf->type].msg_off, victim ); send_to_char(C_DEFAULT, "\n\r", victim ); } if(skill_table[paf->type].shield_bit) { victim->shields -= 1; } found = TRUE; act(C_DEFAULT, skill_table[paf->type].msg_off_room, victim,NULL,NULL,TO_NOTVICT); if ( paf->type == AFF_FLYING ) check_nofloor( victim ); } } for ( paf = victim->affected3; paf; paf = paf->next ) { if ( paf->deleted ) continue; if ( skill_table[ (int) paf->type].cancel_bit == TRUE ) { if(saves_spell(level - 20, victim)) /* -20 so it's easier to make */ continue; /* saves vs yourself */ /* This will make having a really good savings not neccessarily a good thing */ affect_strip(victim,(int) paf->type); if(skill_table[paf->type].msg_off) { send_to_char(C_DEFAULT, skill_table[paf->type].msg_off, victim ); send_to_char(C_DEFAULT, "\n\r", victim ); } if(skill_table[paf->type].shield_bit) { victim->shields -= 1; } found = TRUE; act(C_DEFAULT, skill_table[paf->type].msg_off_room, victim,NULL,NULL,TO_NOTVICT); if ( paf->type == AFF_FLYING ) check_nofloor( victim ); } } for ( paf = victim->affected4; paf; paf = paf->next ) { if ( paf->deleted ) continue; if ( skill_table[ (int) paf->type].cancel_bit == TRUE ) { if(saves_spell(level - 20, victim)) /* -20 so it's easier to make */ continue; /* saves vs yourself */ /* This will make having a really good savings not neccessarily a good thing */ affect_strip(victim,(int) paf->type); if(skill_table[paf->type].msg_off) { send_to_char(C_DEFAULT, skill_table[paf->type].msg_off, victim ); send_to_char(C_DEFAULT, "\n\r", victim ); } if(skill_table[paf->type].shield_bit) { victim->shields -= 1; } found = TRUE; act(C_DEFAULT, skill_table[paf->type].msg_off_room, victim,NULL,NULL,TO_NOTVICT); if ( paf->type == AFF_FLYING ) check_nofloor( victim ); } } if(found) send_to_char(C_DEFAULT, "Ok.\n\r",ch); else send_to_char(C_DEFAULT, "Spell failed.\n\r",ch); return SKPELL_NO_DAMAGE; } /* * Turn undead and mental block by Altrag */ int spell_turn_undead( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int chance; if ( !IS_NPC(victim) || !IS_SET(victim->act, ACT_UNDEAD)) { send_to_char(C_DEFAULT, "Spell failed.\n\r", ch ); return SKPELL_MISSED; } chance = (level * (10 + IS_GOOD(ch) ? 15 : IS_EVIL(ch) ? 0 : 10) ); chance /= victim->level; if (number_percent( ) < chance && !saves_spell( level, victim )) { act(AT_WHITE,"$n has turned $N!",ch,NULL,victim,TO_ROOM); act(AT_WHITE,"You have turned $N!",ch,NULL,victim,TO_CHAR); raw_kill(ch,victim); return SKPELL_NO_DAMAGE; } send_to_char(C_DEFAULT,"Spell failed.\n\r",ch); return SKPELL_MISSED; } int spell_mental_block( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected(victim,sn) ) return SKPELL_MISSED; af.type = sn; af.level = level; af.duration = number_range( level / 4, level / 2 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_NOASTRAL; affect_to_char( victim, &af ); send_to_char( AT_BLUE, "Your mind feels free of instrusion.\n\r",victim); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r",ch); return SKPELL_NO_DAMAGE; } /* END */ int spell_protection_good(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *)vo; AFFECT_DATA af; if ( IS_AFFECTED2(ch, AFF_PROTECTION_GOOD) ) return SKPELL_MISSED; af.type = sn; af.level = level; af.duration = 24; af.location = APPLY_DAM_HOLY; af.modifier = 20; af.bitvector = AFF_PROTECTION_GOOD; affect_to_char2( victim, &af ); if ( ch != victim ) send_to_char( AT_BLUE, "Ok.\n\r",ch); send_to_char(AT_BLUE, "You feel protected.\n\r",victim); return SKPELL_NO_DAMAGE; } int spell_detect_good(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *)vo; AFFECT_DATA af; if ( IS_AFFECTED2( victim, AFF_DETECT_GOOD ) ) return SKPELL_MISSED; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_DETECT_GOOD; affect_to_char2(ch, &af); if ( ch != victim) send_to_char(AT_BLUE, "Ok.\n\r",ch); send_to_char(AT_BLUE, "Your eyes tingle.\n\r",victim); return SKPELL_NO_DAMAGE; } int spell_holy_strength(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if(victim->position == POS_FIGHTING || is_affected(victim, sn)) return SKPELL_MISSED; af.type = sn; af.level = level; af.duration = 6 + level; af.location = APPLY_HITROLL; af.modifier = level / 4; af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_DAMROLL; af.modifier = level / 4; affect_to_char( victim, &af ); af.location = APPLY_STR; af.modifier = level / 50; affect_to_char( victim, &af ); if(ch != victim) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "The strength of the gods fills you.\n\r", victim); return SKPELL_NO_DAMAGE; } int spell_curse_of_nature(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; int loss; if(IS_AFFECTED2( victim, AFF_CURSE_NATURE) || saves_spell(level, victim)) { send_to_char(AT_RED, "You have failed.\n\r", ch ); return SKPELL_MISSED; } loss = number_fuzzy ( ch->level * 2 / 3 ); af.type = sn; af.level = level; af.duration = level / 6; af.location = APPLY_HITROLL; af.modifier = 0 - loss; af.bitvector = AFF_CURSE_NATURE; affect_to_char2( victim, &af ); af.location = APPLY_DAMROLL; af.modifier = 0 - loss; af.bitvector = AFF_CURSE; affect_to_char2( victim, &af ); af.location = APPLY_STR; af.modifier = 0 - level / 30; affect_to_char2( victim, &af ); if(ch != victim) send_to_char(AT_GREEN, "Ok.\n\r", ch ); send_to_char(AT_GREEN, "The wrath of nature wrecks you.\n\r", victim); return SKPELL_NO_DAMAGE; } int spell_enchanted_song(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *)vo; if ( ch == victim ) { act( AT_BLUE, "$n sings an enchanting song.", ch, NULL, NULL, TO_ROOM ); send_to_char(AT_BLUE, "You sing a song.\n\r", ch ); } if ( victim->position == POS_STUNNED || IS_STUNNED( ch, STUN_TO_STUN ) ) return SKPELL_MISSED; act( AT_BLUE, "Your song pacifies $N.", ch, NULL, victim, TO_CHAR ); act( AT_BLUE, "$n's song pacifies $N.", ch, NULL, victim, TO_NOTVICT ); act( AT_BLUE, "$n's song slows your reactions.", ch, NULL, victim, TO_VICT ); STUN_CHAR( ch, 5, STUN_TO_STUN ); STUN_CHAR( victim, 1, STUN_TOTAL ); victim->position = POS_STUNNED; return SKPELL_NO_DAMAGE; } /* RT haste spell */ int spell_haste( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn ) || IS_AFFECTED(victim,AFF_HASTE)) { if (victim == ch) send_to_char(C_DEFAULT, "You can't move any faster!\n\r",ch); else act(C_DEFAULT, "$N is already moving as fast as they can.", ch,NULL,victim,TO_CHAR); return SKPELL_MISSED; } af.type = sn; af.level = level; if (victim == ch) af.duration = level/2; else af.duration = level/4; af.location = APPLY_DEX; af.modifier = 1 + (level >= 18) + (level >= 25) + (level >= 32); af.bitvector = AFF_HASTE; affect_to_char( victim, &af ); send_to_char(C_DEFAULT, "You feel yourself moving more quickly.\n\r", victim ); act(C_DEFAULT, "$n is moving more quickly.",victim,NULL,NULL,TO_ROOM); if ( ch != victim ) send_to_char(C_DEFAULT, "Ok.\n\r", ch ); return SKPELL_NO_DAMAGE; } int spell_swiftness( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn ) || IS_AFFECTED(victim,AFF_HASTE)) { if (victim == ch) send_to_char(C_DEFAULT, "You can't move any faster!\n\r",ch); else act(C_DEFAULT, "$N is already moving as fast as $e can.", ch,NULL,victim,TO_CHAR); return SKPELL_MISSED; } af.type = sn; af.level = level; if (victim == ch) af.duration = level/2; else af.duration = level/4; af.location = APPLY_DEX; af.modifier = 1 + (level >= 18) + (level >= 25) + (level >= 32); af.bitvector = AFF_HASTE; affect_to_char( victim, &af ); send_to_char(C_DEFAULT, "You feel yourself moving more quickly.\n\r", victim ); act(C_DEFAULT, "$n is moving more quickly.",victim,NULL,NULL,TO_ROOM); if ( ch != victim ) send_to_char(C_DEFAULT, "Ok.\n\r", ch ); return SKPELL_NO_DAMAGE; } int spell_plague(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; int hr, dr; if(is_affected(victim, sn)|| saves_spell(level, victim)) { send_to_char(AT_RED, "You have failed.\n\r", ch ); return SKPELL_MISSED; } hr = GET_HITROLL(victim); dr = GET_DAMROLL(victim); af.type = sn; af.level = level; af.duration = level / 20; af.location = APPLY_HITROLL; af.modifier = 0 - hr / 4; af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_DAMROLL; af.modifier = 0 - dr / 4; affect_to_char( victim, &af ); af.location = APPLY_STR; af.modifier = 0 - level / 15; affect_to_char( victim, &af ); af.location = APPLY_HIT; af.modifier = 0 - level * 4; affect_to_char( victim, &af ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_CURSE; affect_to_char( victim, &af ); if(ch != victim) send_to_char(AT_GREEN, "Ok.\n\r", ch ); send_to_char(AT_GREEN, "You feel the wrath of the Plague.\n\r", victim); return SKPELL_NO_DAMAGE; } int spell_unholy_curse( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; int hr, dr; if ( saves_spell( level + (ch->race == 15 ? 20 : 0), victim ) ) { send_to_char(AT_BLUE, "You have failed.\n\r", ch ); return SKPELL_MISSED; } if (is_affected( victim, sn ) ) { send_to_char(AT_BLUE, "You have failed.\n\r", ch ); return SKPELL_MISSED; } hr = GET_HITROLL(victim); dr = 2 * GET_DAMROLL(victim); af.type = sn; af.level = level; af.duration = level / 20; af.location = APPLY_HITROLL; af.modifier = 0 - hr / 3; af.bitvector = AFF_BLIND; affect_to_char( victim, &af ); af.location = APPLY_DAMROLL; af.modifier = 0 - dr / 3; affect_to_char( victim, &af ); af.location = APPLY_AC; af.modifier = level * 2 ; af.bitvector = AFF_CURSE; affect_to_char( victim, &af ); act(AT_WHITE, "$N has been cursed!", ch, NULL, victim, TO_CHAR ); send_to_char(AT_WHITE, "You feel the wrath of an unholy curse!\n\r", victim ); act(AT_WHITE, "$N has been cursed!", ch, NULL, victim, TO_NOTVICT ); return SKPELL_NO_DAMAGE; } int spell_unholy_prayer(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if(victim->position == POS_FIGHTING || is_affected(victim, sn)) return SKPELL_MISSED; af.type = sn; af.level = level; af.duration = 6 + level; af.location = APPLY_HITROLL; af.modifier = level / 5; af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_DAMROLL; af.modifier = level / 3; affect_to_char( victim, &af ); af.location = APPLY_STR; af.modifier = level / 30; affect_to_char( victim, &af ); af.location = APPLY_HIT; af.modifier = level * 5; affect_to_char( victim, &af ); if(ch != victim) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "The strength of demons fill you.\n\r", victim); return SKPELL_NO_DAMAGE; } int spell_unholy_wrath( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 50, 55, 60, 70, 80, 90, 95, 105, 110, 120, 123, 126, 129, 132, 135, 138, 141, 144, 147, 150, 153, 156, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, 189, 192, 195, 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, 240, 243, 246, 249, 252, 255, 258, 261, 264, 267, 270, 273, 276, 279, 282, 285, 288, 291, 294, 297, 300, 303, 306, 309, 312, 315, 318, 321, 324, 327, 330, 335, 340, 345, 350, 350 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level] / 2, dam_each[level] * 5 ); if ( saves_spell( level, victim ) ) dam /= 2; //damage( ch, victim, dam, sn ); return dam; } int spell_chi_blast( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 32, 37, 42, 46, 50, 54, 58, 63, 67, 72, 75, 76, 77, 79, 81, 83, 85, 87, 89, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 110, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 205, 210, 215, 220, 225, 230, 235, 240, 245, 250 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level] / 2, dam_each[level] * 7 ); if ( saves_spell( level, victim ) ) dam /= 2; //damage( ch, victim, dam, sn ); return dam; } int spell_chi_storm( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96, 102, 104, 106, 107, 108, 110, 113, 115, 117, 120, 122, 124, 127, 129, 132, 134, 137, 139, 142, 144, 147, 149, 152, 154, 157, 159, 162, 164, 167, 169, 172, 174, 177, 179, 182, 184, 187, 189, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 242, 244, 246, 248, 250, 255, 260 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level] / 2, dam_each[level] * 7 ); if ( saves_spell( level, victim ) ) dam /= 2; //damage( ch, victim, dam, sn ); return dam; } int spell_sunburst( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252, 256, 260, 264, 268, 272, 276, 280, 284, 288, 292, 296, 300, 305, 310, 315, 320, 325, 330, 335, 340, 345, 350, 355, 360, 365, 370, 375, 380, 385, 390, 395, 400, 405, 410, 415, 420, 425, 430, 435, 440, 445, 450, 460, 470, 480, 490, 500, 510, 520, 530, 540, 550 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( (int) (dam_each[level] * 1.5), dam_each[level] * 7 ); if ( saves_spell( level, victim ) ) dam /= 2; // damage( ch, victim, dam, sn ); return dam; } int spell_chi_wave( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *vch; AFFECT_DATA af; send_to_char(AT_RED, "You send your soul into the world!\n\r", ch ); act(AT_RED, "$n is surrounded by Chi energy!", ch, NULL, NULL, TO_ROOM ); for ( vch = char_list; vch; vch = vch->next ) { if ( vch->deleted || !vch->in_room ) continue; if ( vch->in_room == ch->in_room ) { if ( vch != ch && ( IS_NPC( ch ) ? !IS_NPC( vch ) : IS_NPC( vch ) ) ) damage( ch, vch, level + dice( level, 12 ), sn ); if ( vch != ch ) { af.type = sn; af.level = level; af.duration = level / 10; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_CURSE; affect_join( vch, &af ); send_to_char(AT_RED, "You feel the wrath of the Chi Wave!\n\r", vch); } continue; } } return SKPELL_NO_DAMAGE; } int spell_chi_healing( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int heal; heal = (int)(victim->max_hit * 0.1); victim->hit = UMIN( victim->hit + heal, victim->max_hit ); update_pos( victim ); if ( ch != victim ) send_to_char(AT_BLUE, "Ok.\n\r", ch ); send_to_char(AT_BLUE, "The feeling of Chi fills your body.\n\r", victim ); return SKPELL_NO_DAMAGE; } int spell_phantom_form( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED(victim, AFF_PASS_DOOR) ) return SKPELL_MISSED; af.type = sn; af.level = level; af.duration = number_fuzzy( level / 5 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_PASS_DOOR; affect_to_char( victim, &af ); send_to_char(AT_GREY, "You take on a phantom form.\n\r", victim ); act(AT_GREY, "$n takes on a phantom form.", victim, NULL, NULL, TO_ROOM ); return SKPELL_NO_DAMAGE; } int spell_spark( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 3, 3, 4, 4, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 18, 18, 18, 18, 18, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 24, 24, 24, 24, 24, 26, 26, 26, 26, 26, 28, 28, 28, 28, 28, 30, 31, 32, 33, 40 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level] / 2, dam_each[level] * 5 ); if ( saves_spell( level, victim ) ) dam /= 2; //damage( ch, victim, dam, sn ); return dam; } int spell_ghost_shield( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED2( victim, AFF_GHOST_SHIELD ) ) { affect_strip(victim, sn); if(skill_table[sn].msg_off) { send_to_char(C_DEFAULT, skill_table[sn].msg_off, victim ); send_to_char(C_DEFAULT, "\n\r", victim ); } act(C_DEFAULT, skill_table[sn].msg_off_room, victim, NULL, NULL, TO_NOTVICT); victim->shields -= 1; return SKPELL_NO_DAMAGE; } if ( !IS_SHIELDABLE( victim ) ) return SKPELL_MISSED; af.type = sn; af.level = level; af.duration = -1; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_GHOST_SHIELD; affect_to_char2( victim, &af ); victim->shields += 1; send_to_char(AT_GREY, "You conjure hundreds of ghosts to surround you.\n\r", victim ); act(AT_GREY, "$n's body is protected by hundreds of ghosts.", victim, NULL, NULL, TO_ROOM ); return SKPELL_NO_DAMAGE; } /* int spell_flaming_fists( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED2( victim, AFF_FLAMING_FISTS ) ) return SKPELL_MISSED; af.type = sn; af.level = level; af.duration = number_fuzzy( level / 5 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_FLAMING_FISTS; affect_to_char2( victim, &af ); send_to_char(AT_RED, "You set your fists on fire!\n\r", victim ); act(AT_RED, "$n's hands burst into flames!", victim, NULL, NULL, TO_ROOM ); return SKPELL_MISSED; } */ int spell_mist( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED2( victim, AFF_MIST ) ) { affect_strip(victim, sn); if(skill_table[sn].msg_off) { send_to_char(C_DEFAULT, skill_table[sn].msg_off, victim ); send_to_char(C_DEFAULT, "\n\r", victim ); } act(C_DEFAULT, skill_table[sn].msg_off_room, victim, NULL, NULL, TO_NOTVICT); victim->shields -= 1; return SKPELL_NO_DAMAGE; } if ( !IS_SHIELDABLE( victim ) ) return SKPELL_MISSED; af.type = sn; af.level = level; af.duration = -1; af.location = APPLY_AC; af.modifier = ch->level * -1; af.bitvector = AFF_MIST; affect_to_char2( victim, &af ); victim->shields += 1; send_to_char(AT_GREY, "You create a mist about yourself.\n\r", victim ); act(AT_GREY, "$n's body is shrouded by a heavy mist.", victim, NULL, NULL, TO_ROOM ); return SKPELL_NO_DAMAGE; } int spell_scrye( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim; ROOM_INDEX_DATA *blah; if ( !( victim = get_char_world( ch, target_name ) ) || IS_SET( victim->in_room->room_flags, ROOM_PRIVATE ) || IS_SET( victim->in_room->room_flags, ROOM_SOLITARY ) ) { send_to_char(AT_BLUE, "You failed.\n\r", ch ); return SKPELL_MISSED; } if (IS_NPC(victim) && victim->pIndexData->vnum == 7) { send_to_char(AT_BLUE, "You failed.\n\r", ch ); return SKPELL_MISSED; } if ( IS_SET(ch->in_room->area->area_flags, AREA_PRESENT) && (IS_SET( victim->in_room->area->area_flags, AREA_FUTURE ) || IS_SET( victim->in_room->area->area_flags, AREA_PAST ) ) ) { send_to_char(AT_BLUE, "You cannot!!!!!!!\n\r", ch ); return SKPELL_MISSED; } if ( IS_SET(ch->in_room->area->area_flags, AREA_FUTURE) && (IS_SET( victim->in_room->area->area_flags, AREA_PRESENT ) || IS_SET( victim->in_room->area->area_flags, AREA_PAST ) ) ) { send_to_char(AT_BLUE, "You cannot!!!!!!!\n\r", ch ); return SKPELL_MISSED; } if ( IS_SET(ch->in_room->area->area_flags, AREA_PAST) && (IS_SET( victim->in_room->area->area_flags, AREA_FUTURE ) || IS_SET( victim->in_room->area->area_flags, AREA_PRESENT ) ) ) { send_to_char(AT_BLUE, "You cannot!!!!!!!\n\r", ch ); return SKPELL_MISSED; } if ( IS_AFFECTED4( victim, AFF_DECEPTION ) && (ch!=victim) && ( number_percent( ) <= ( number_fuzzy( victim->pcdata->learned[skill_lookup("deception of aura")])/2 ) + get_curr_int( victim ) ) ) { int vnum = 0; ROOM_INDEX_DATA* room = NULL; ROOM_INDEX_DATA* victim_room = NULL; while (!room) { vnum = number_range(1, 31000); room = get_room_index( vnum ); if (!room) { continue; } if (IS_SET(room->area->area_flags, AREA_PRESENT) && !IS_SET(ch->in_room->area->area_flags, AREA_PRESENT)) { room = NULL; continue; } if (IS_SET(room->area->area_flags, AREA_FUTURE) && !IS_SET(ch->in_room->area->area_flags, AREA_FUTURE)) { room = NULL; continue; } if (IS_SET(room->area->area_flags, AREA_PAST) && !IS_SET(ch->in_room->area->area_flags, AREA_PAST)) { room = NULL; continue; } } victim_room = victim->in_room; char_from_room( victim ); char_to_room ( victim, room ); blah = ch->in_room; char_from_room( ch ); char_to_room ( ch, room ); do_look(ch, "auto"); char_from_room( victim ); char_from_room( ch ); char_to_room ( victim, victim_room); char_to_room ( ch, blah ); return SKPELL_NO_DAMAGE; } blah = ch->in_room; if ( ch != victim ) { char_from_room( ch ); char_to_room( ch, victim->in_room ); } do_look( ch, "auto" ); if (ch != victim ) { char_from_room( ch ); char_to_room( ch, blah ); } return SKPELL_NO_DAMAGE; } int spell_visions( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim; ROOM_INDEX_DATA *blah; if ( !( victim = get_char_world( ch, target_name ) ) ) { send_to_char(AT_BLUE, "You failed.\n\r", ch ); return SKPELL_MISSED; } // Supermob sanity check - Ahsile if ( IS_NPC(victim) && victim->pIndexData->vnum == 7) { send_to_char(AT_BLUE, "You failed.\n\r", ch); return SKPELL_MISSED; } /* Changed to work through time, to make it different than Scrye */ /* if ( IS_SET(ch->in_room->area->area_flags, AREA_PRESENT) && (IS_SET( victim->in_room->area->area_flags, AREA_FUTURE ) || IS_SET( victim->in_room->area->area_flags, AREA_PAST ) ) ) { send_to_char(AT_BLUE, "You cannot!!!!!!!\n\r", ch ); return SKPELL_MISSED; } if ( IS_SET(ch->in_room->area->area_flags, AREA_FUTURE) && (IS_SET( victim->in_room->area->area_flags, AREA_PRESENT ) || IS_SET( victim->in_room->area->area_flags, AREA_PAST ) ) ) { send_to_char(AT_BLUE, "You cannot!!!!!!!\n\r", ch ); return SKPELL_MISSED; } if ( IS_SET(ch->in_room->area->area_flags, AREA_PAST) && (IS_SET( victim->in_room->area->area_flags, AREA_FUTURE ) || IS_SET( victim->in_room->area->area_flags, AREA_PRESENT ) ) ) { send_to_char(AT_BLUE, "You cannot!!!!!!!\n\r", ch ); return SKPELL_MISSED; } */ if ( IS_AFFECTED4( victim, AFF_DECEPTION ) && (ch!=victim) && ( number_percent( ) <= ( number_fuzzy( victim->pcdata->learned[skill_lookup("deception of aura")])/2 ) + get_curr_int( victim ) ) ) { int vnum = 0; ROOM_INDEX_DATA* room = NULL; ROOM_INDEX_DATA* victim_room = NULL; while (!room) { vnum = number_range(1, 31000); room = get_room_index( vnum ); } victim_room = victim->in_room; char_from_room( victim ); char_to_room ( victim, room ); blah = ch->in_room; char_from_room( ch ); char_to_room ( ch, room ); do_look(ch, "auto"); char_from_room( victim ); char_from_room( ch ); char_to_room ( victim, victim_room); char_to_room ( ch, blah ); return SKPELL_NO_DAMAGE; } blah = ch->in_room; if ( ch != victim ) { char_from_room( ch ); char_to_room( ch, victim->in_room ); } do_look( ch, "auto" ); if (ch != victim ) { char_from_room( ch ); char_to_room( ch, blah ); } return SKPELL_NO_DAMAGE; } int spell_shadow_image( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED2( victim, AFF_SHADOW_IMAGE ) ) { affect_strip(victim, sn); if(skill_table[sn].msg_off) { send_to_char(C_DEFAULT, skill_table[sn].msg_off, victim ); send_to_char(C_DEFAULT, "\n\r", victim ); } act(C_DEFAULT, skill_table[sn].msg_off_room, victim, NULL, NULL, TO_NOTVICT); victim->shields -= 1; return SKPELL_NO_DAMAGE; } if ( !IS_SHIELDABLE( victim ) ) return SKPELL_MISSED; af.type = sn; af.level = level; af.duration = -1; af.location = APPLY_AC; af.modifier = (ch->level / 4) * -1; af.bitvector = AFF_SHADOW_IMAGE; affect_to_char2( victim, &af ); victim->shields += 1; send_to_char(AT_BLUE, "You appear to be in more than one location..\n\r", victim ); act(AT_BLUE, "$n's body appears to be in more than one location.", victim, NULL, NULL, TO_ROOM ); return SKPELL_NO_DAMAGE; } int spell_malignify(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if(saves_spell(level, victim)) { send_to_char(AT_RED, "You have failed.\n\r", ch ); return SKPELL_MISSED; } af.type = sn; af.level = level; af.duration = level / 25; af.location = APPLY_DEX; af.modifier = -1; af.bitvector = AFF_MALIGNIFY; affect_to_char2( victim, &af ); af.location = APPLY_STR; af.modifier = -1; affect_to_char2( victim, &af ); af.location = APPLY_CON; af.modifier = -1; affect_to_char2( victim, &af ); af.location = APPLY_INT; af.modifier = -1; affect_to_char2( victim, &af ); if(ch != victim) send_to_char(AT_BLOOD, "You malignify them.\n\r", ch ); send_to_char(AT_BLOOD, "You have been hit with malignification.\n\r", victim); return SKPELL_NO_DAMAGE; } int spell_age(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED3( victim, AFF_AGE ) || saves_spell( level, victim ) ) { send_to_char(AT_RED, "You have failed.\n\r", ch ); return SKPELL_MISSED; } af.type = sn; af.level = level; af.duration = number_fuzzy( level ); af.location = APPLY_DEX; af.modifier = -2; af.bitvector = AFF_AGE; affect_to_char3( victim, &af ); af.location = APPLY_STR; af.modifier = -4; affect_to_char( victim, &af ); af.location = APPLY_WIS; af.modifier = 3; affect_to_char( victim, &af ); af.location = APPLY_CON; af.modifier = -1; affect_to_char( victim, &af ); af.location = APPLY_INT; af.modifier = 3; affect_to_char( victim, &af ); if(ch != victim) send_to_char(AT_BLOOD, "You age them.\n\r", ch ); send_to_char(AT_BLOOD, "You appear to be older.\n\r", victim); return SKPELL_NO_DAMAGE; } int spell_iceball( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 215, 220, 225, 230, 235, 240, 245, 250, 255, 260 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level] / 2, dam_each[level] * 7 ); if ( saves_spell( level, victim ) ) dam /= 2; //damage( ch, victim, dam, sn ); return dam; } int spell_solidify( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; char buf[MAX_STRING_LENGTH]; if ( is_affected( victim, sn ) ) return SKPELL_MISSED; af.type = sn; af.level = level; af.duration = number_fuzzy( level / 40 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_ANTI_FLEE; affect_to_char( victim, &af ); sprintf( buf, "%s lifts his hands your legs are frozen!\n\r", ch->name ); send_to_char(AT_LBLUE, buf, victim ); act(AT_LBLUE, "$n has been immobilized by a chunk of ice.", victim, NULL, NULL, TO_ROOM ); return SKPELL_NO_DAMAGE; } int spell_winters_chill( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252, 256, 260, 264, 268, 272, 276, 280, 284, 288, 292, 296, 300, 305, 310, 315, 320, 325, 330, 335, 340, 345, 350, 355, 360, 365, 370, 375, 380, 385, 390, 395, 400, 405, 410, 415, 420, 425, 430, 435, 440, 445, 450, 460, 470, 480, 490, 500, 510, 520, 530, 540, 550 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level], dam_each[level] * 8 ); if ( saves_spell( level, victim ) ) dam /= 2; // damage( ch, victim, dam, sn ); return dam; } int spell_summon_ice_elemental(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; if(ch->summon_timer > 0) { send_to_char(AT_RED, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } mob = create_mobile(get_mob_index(MOB_VNUM_ICE_ELEMENTAL)); mob->level = URANGE(51, level, 100) - 5; mob->max_hit = mob->level * 20 + dice(1,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_RED, "You summon $N from the arctic.", ch, NULL, mob, TO_CHAR); if(ch->mana < level * 2 && ((ch->class != 9)||(ch->class != 11))) { act(AT_RED, "You don't have enough mana to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } if(ch->bp < level / 2 && ((ch->class == 9)||(ch->class == 11))) { act(AT_BLOOD, "You don't have enough blood to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } if((ch->class != 9) || (ch->class != 11)) ch->mana -= level * 2; else ch->bp -= level / 2; act(AT_RED, "$n summons $N from the arctic.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_RED, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_RED, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } int spell_summon_fire_elemental(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; if(ch->summon_timer > 0) { send_to_char(AT_RED, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } mob = create_mobile(get_mob_index(MOB_VNUM_FIRE_ELEMENTAL)); mob->level = URANGE(51, level, 100) - 5; mob->max_hit = mob->level * 50 + dice(1,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_RED, "You summon $N from a blazing inferno.", ch, NULL, mob, TO_CHAR); if(ch->mana < level * 2 && ((ch->class != 9)||(ch->class != 11))) { act(AT_RED, "You don't have enough mana to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } if(ch->bp < level / 2 && ((ch->class == 9)||(ch->class == 11))) { act(AT_BLOOD, "You don't have enough blood to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } if((ch->class != 9) || (ch->class != 11)) ch->mana -= level * 2; else ch->bp -= level / 2; act(AT_RED, "$n summons $N from a blazing inferno.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_RED, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_RED, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } int spell_summon_greater_demon(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; if(ch->summon_timer > 0) { send_to_char(AT_RED, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } mob = create_mobile(get_mob_index(MOB_VNUM_GREATER_DEMON)); mob->level = URANGE(51, level, 100) - 5; mob->max_hit = mob->level * 90 + dice(1,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_RED, "You summon $N from the bowels of hell.", ch, NULL, mob, TO_CHAR); if(ch->mana < level * 2 && ((ch->class != 9)||(ch->class != 11))) { act(AT_RED, "You don't have enough mana to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } if(ch->bp < level / 2 && ((ch->class == 9)||(ch->class == 11))) { act(AT_BLOOD, "You don't have enough blood to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } if((ch->class != 9) || (ch->class != 11)) ch->mana -= level * 2; else ch->bp -= level / 2; act(AT_RED, "$n summons $N from the bowels of hell.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_RED, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_RED, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } int spell_cone_of_frost( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *vch; if ( IS_SET( ch->in_room->room_flags, ROOM_SAFE)) { send_to_char(AT_WHITE, "You are in a safe room!!!!", ch); return SKPELL_MISSED; } send_to_char(AT_LBLUE, "A huge cone of frost stretches forth from your hands!\n\r", ch ); act(AT_LBLUE, "A huge cone of frost stretches forth from $n's hands.", ch, NULL, NULL, TO_ROOM ); for ( vch = char_list; vch; vch = vch->next ) { if ( vch->deleted || !vch->in_room ) continue; if ( vch->in_room == ch->in_room && vch != ch ) { damage( ch, vch, level + dice( level/3, level ), sn ); continue; } } return SKPELL_NO_DAMAGE; } int spell_icequake( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *vch; send_to_char(AT_LBLUE, "The earth trembles as the ground is rocked with ice!\n\r", ch ); act(AT_LBLUE, "$n causes the earth to tremble as it is rocked with ice.", ch, NULL, NULL, TO_ROOM ); for ( vch = char_list; vch; vch = vch->next ) { if ( vch->deleted || !vch->in_room ) continue; if ( vch->in_room == ch->in_room ) { if ( vch != ch && ( IS_NPC( ch ) ? !IS_NPC( vch ) : IS_NPC( vch ) ) ) damage( ch, vch, level + dice( 3, 9 ), sn ); continue; } if ( vch->in_room->area == ch->in_room->area ) send_to_char(AT_LBLUE, "The earth trembles as it is rocked with ice.\n\r", vch ); } return SKPELL_NO_DAMAGE; } int spell_cloud_of_cold( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *vch; AFFECT_DATA af; if ( IS_SET( ch->in_room->room_flags, ROOM_SAFE)) { send_to_char(AT_WHITE, "You are in a safe room!!!!", ch); return SKPELL_MISSED; } send_to_char(AT_LBLUE, "You conjure a giant cloud of cold.\n\r", ch ); act(AT_LBLUE, "$n conjures a giant cloud of cold!", ch, NULL, NULL, TO_ROOM ); for ( vch = char_list; vch; vch = vch->next ) { if ( vch->deleted || !vch->in_room ) continue; if ( vch->in_room == ch->in_room && vch != ch ) { damage( ch, vch, level + dice( level/2, level/3 ), sn ); if ( vch != ch ) { af.type = sn; af.level = level; af.duration = 5; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_CURSE; affect_join( vch, &af ); send_to_char(AT_LBLUE, "Your eyes are affected by the cloud!\n\r", vch); } continue; } } return SKPELL_NO_DAMAGE; } int spell_tomb_rot( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn) || saves_spell( level, victim ) ) { send_to_char(AT_RED, "You have failed.\n\r", ch ); return SKPELL_MISSED; } af.type = sn; af.level = level; af.duration = level / 20; af.location = APPLY_HITROLL; af.modifier = -80; af.bitvector = AFF_CURSE; affect_to_char( victim, &af ); spell_poison( skill_lookup("poison"), ch->level, ch, victim ); af.location = APPLY_SAVING_SPELL; af.modifier = 50; affect_to_char( victim, &af ); if ( ch != victim ) send_to_char(AT_RED, "You have inflicted the tomb rot.\n\r", ch ); send_to_char(AT_RED, "You have been afflicted by the tomb rot.\n\r", victim ); return SKPELL_NO_DAMAGE; } int spell_flash_burn( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( is_affected( victim, sn ) || saves_spell( level, victim ) || IS_AFFECTED2( victim, AFF_BLINDFOLD ) ) { send_to_char(AT_BLUE, "You have failed.\n\r", ch ); return SKPELL_MISSED; } af.type = sn; af.level = level; af.duration = level / 20; af.location = APPLY_HITROLL; af.modifier = -50; af.bitvector = AFF_BLIND; affect_to_char( victim, &af ); act(AT_RED, "$N is blinded by the flash burn!", ch, NULL, victim, TO_CHAR ); send_to_char(AT_RED, "You are blinded by a flash burn!\n\r", victim ); act(AT_RED, "$N is blinded by a flash burn!", ch, NULL, victim, TO_NOTVICT ); return SKPELL_NO_DAMAGE; } int spell_daemonic_might( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( !IS_EVIL( ch ) ) { send_to_char(AT_RED, "You are not evil enough to do that!\n\r", ch); return SKPELL_MISSED; } if ( victim->position == POS_FIGHTING || is_affected( victim, sn ) ) return SKPELL_MISSED; af.type = sn; af.level = level; af.duration = level - 40; af.location = APPLY_DAMROLL; af.modifier = level / 4; af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_HITROLL; af.modifier = level / 4; affect_to_char( victim, &af ); af.location = APPLY_STR; af.modifier = 3; affect_to_char( victim, &af ); if ( ch != victim ) send_to_char(AT_RED, "You conjure the strength of demons.\n\r", ch ); send_to_char(AT_RED, "You feel the touch of demons rest upon you.\n\r", victim ); return SKPELL_NO_DAMAGE; } int spell_blood_omen( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( !IS_EVIL( ch ) ) { send_to_char(AT_RED, "You are not evil enough to do that!\n\r", ch); return SKPELL_MISSED; } if ( is_affected( victim, sn ) ) return SKPELL_MISSED; af.type = sn; af.level = level; af.duration = level / 10; af.location = APPLY_DAMROLL; af.modifier = 0 - level / 3 * 2; af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_HITROLL; af.modifier = 0 - level / 3 * 2; affect_to_char( victim, &af ); af.location = APPLY_STR; af.modifier = -3; affect_to_char( victim, &af ); if ( ch != victim ) send_to_char(AT_RED, "You have placed a blood omen hex.\n\r", ch ); send_to_char(AT_RED, "You are hexed by the powers of the blood omen.\n\r", victim ); return SKPELL_NO_DAMAGE; } int spell_daemonic_possession( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( !IS_EVIL( ch ) ) { send_to_char(AT_RED, "You are not evil enough to do that!\n\r", ch); return SKPELL_MISSED; } if ( victim == ch ) { send_to_char(C_DEFAULT, "Possess yourself? You're weird.\n\r", ch ); return SKPELL_MISSED; } if ( !IS_NPC( victim ) ) return SKPELL_MISSED; if ( IS_AFFECTED( victim, AFF_CHARM ) || IS_AFFECTED( ch, AFF_CHARM ) || level < victim->level || saves_spell( level, victim ) ) return SKPELL_MISSED; if(IS_SIMM(victim, IMM_CHARM)) return SKPELL_MISSED; if ( victim->master ) stop_follower( victim ); add_follower( victim, ch ); af.type = sn; af.level = level; af.duration = number_fuzzy( level / 4 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char( victim, &af ); act(AT_RED, "The demons take control of $N and transfer the control to you!", ch, NULL, victim, TO_CHAR ); act(AT_RED, "Demons have taken control of you.", ch, NULL, victim, TO_VICT ); return SKPELL_NO_DAMAGE; } int spell_circle_of_fire( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED3( victim, AFF_COFIRE ) ) { affect_strip(victim, sn); if(skill_table[sn].msg_off) { send_to_char(C_DEFAULT, skill_table[sn].msg_off, victim ); send_to_char(C_DEFAULT, "\n\r", victim ); } act(C_DEFAULT, skill_table[sn].msg_off_room, victim, NULL, NULL, TO_NOTVICT); victim->shields -= 1; return SKPELL_NO_DAMAGE; } if ( !IS_SHIELDABLE( victim ) ) return SKPELL_MISSED; af.type = sn; af.level = level; af.duration = -1; af.location = APPLY_DAM_WATER; af.modifier = 25; af.bitvector = AFF_COFIRE; affect_to_char3( victim, &af ); victim->shields += 1; send_to_char(AT_RED, "Your body is surrounded by a circle of fire.\n\r", victim ); act(AT_RED, "$n's body is surrounded by a circle of fire.", victim, NULL, NULL, TO_ROOM ); return SKPELL_NO_DAMAGE; } int spell_tortured_soul( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( !IS_EVIL( ch ) ) { send_to_char(AT_RED, "You are not evil enough to do that!\n\r", ch); return SKPELL_MISSED; } if ( IS_AFFECTED3( victim, AFF_TORTURE ) ) return SKPELL_MISSED; af.type = sn; af.level = level; af.duration = level / 10; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_TORTURE; affect_to_char3( victim, &af ); if ( ch != victim ) send_to_char(AT_RED, "You have tortured their soul.\n\r", ch ); send_to_char(AT_RED, "Your soul has been damned by pure evil.\n\r", victim ); return SKPELL_NO_DAMAGE; } int spell_demonfire( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 244, 248, 252, 256, 260, 262, 262, 264, 264, 266, 266, 268, 268, 270, 270, 275, 275, 280, 280, 285, 285, 290, 290, 295, 295, 300, 305, 310, 315, 320, 325, 330, 345, 340, 345, 350, 355, 360, 365, 370, 375, 380, 385, 390, 395, 400, 410, 420, 430, 440, 450, 460, 470, 480, 490, 500 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level] / 2, dam_each[level] * 5 ); if ( IS_AFFECTED( victim, AFF_SANCTUARY ) ) dam += (int)(dam*1.3); if ( IS_AFFECTED4( victim, AFF_GOLDEN_SANCTUARY ) ) dam += (int)(dam*1.15); if ( saves_spell( level, victim ) ) dam /= 2; damage( ch, victim, dam, sn ); return SKPELL_MISSED; } int spell_summon_air_elemental(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; if(ch->summon_timer > 0) { send_to_char(AT_RED, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } mob = create_mobile(get_mob_index(MOB_VNUM_AIR_ELEMENTAL)); mob->level = URANGE(51, level, 100) - 5; mob->max_hit = mob->level * 50 + dice(1,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_RED, "You summon $N from the skies.", ch, NULL, mob, TO_CHAR); if(ch->mana < level * 2 && ((ch->class != 9)||(ch->class != 11))) { act(AT_RED, "You don't have enough mana to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } if(ch->bp < level / 2 && ((ch->class == 9)||(ch->class == 11))) { act(AT_BLOOD, "You don't have enough blood to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } if((ch->class != 9) || (ch->class != 11)) ch->mana -= level * 2; else ch->bp -= level / 2; act(AT_RED, "$n summons $N from the skies.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_RED, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_RED, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } int spell_summon_water_elemental(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; if(ch->summon_timer > 0) { send_to_char(AT_RED, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } mob = create_mobile(get_mob_index(MOB_VNUM_WATER_ELEMENTAL)); mob->level = URANGE(51, level, 100) - 5; mob->max_hit = mob->level * 50 + dice(1,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_RED, "You summon $N from the oceans.", ch, NULL, mob, TO_CHAR); if(ch->mana < level * 2 && ((ch->class != 9)||(ch->class != 11))) { act(AT_RED, "You don't have enough mana to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } if(ch->bp < level / 2 && ((ch->class == 9)||(ch->class == 11))) { act(AT_BLOOD, "You don't have enough blood to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } if((ch->class != 9) || (ch->class != 11)) ch->mana -= level * 2; else ch->bp -= level / 2; act(AT_RED, "$n summons $N from the oceans.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_RED, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_RED, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } int spell_summon_earth_elemental(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; if(ch->summon_timer > 0) { send_to_char(AT_RED, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } mob = create_mobile(get_mob_index(MOB_VNUM_EARTH_ELEMENTAL)); mob->level = URANGE(51, level, 100) - 5; mob->max_hit = mob->level * 50 + dice(1,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_RED, "You summon $N from the planet core.", ch, NULL, mob, TO_CHAR); if(ch->mana < level * 2 && ((ch->class != 9)||(ch->class != 11))) { act(AT_RED, "You don't have enough mana to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } if(ch->bp < level / 2 && ((ch->class == 9)||(ch->class == 11))) { act(AT_BLOOD, "You don't have enough blood to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } if((ch->class != 9) || (ch->class != 11)) ch->mana -= level * 2; else ch->bp -= level / 2; act(AT_RED, "$n summons $N from the planet core.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_RED, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_RED, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } int spell_summon_dust_elemental(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; if(ch->summon_timer > 0) { send_to_char(AT_RED, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } mob = create_mobile(get_mob_index(MOB_VNUM_ICE_ELEMENTAL)); mob->level = URANGE(51, level, 100) - 5; mob->max_hit = mob->level * 45 + dice(1,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_RED, "You summon $N from the dust around you.", ch, NULL, mob, TO_CHAR); if(ch->mana < level * 2 && ((ch->class != 9)||(ch->class != 11))) { act(AT_RED, "You don't have enough mana to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } if(ch->bp < level / 2 && ((ch->class == 9)||(ch->class == 11))) { act(AT_BLOOD, "You don't have enough blood to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } if((ch->class != 9) || (ch->class != 11)) ch->mana -= level * 2; else ch->bp -= level / 2; act(AT_RED, "$n summons $N from the dust around you.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_RED, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_RED, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } int spell_summon_dragon(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; if(ch->summon_timer > 0) { send_to_char(AT_RED, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } mob = create_mobile(get_mob_index(MOB_VNUM_DRAGON)); mob->level = URANGE(51, level, 100) - 5; mob->max_hit = mob->level * 75 + dice(1,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_RED, "You summon $N from the draconic plane.", ch, NULL, mob, TO_CHAR); if(ch->mana < level * 2 && ((ch->class != 9)||(ch->class != 11))) { act(AT_RED, "You don't have enough mana to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } if(ch->bp < level / 2 && ((ch->class == 9)||(ch->class == 11))) { act(AT_BLOOD, "You don't have enough blood to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } if((ch->class != 9) || (ch->class != 11)) ch->mana -= level * 2; else ch->bp -= level / 2; act(AT_RED, "$n summons $N from the draconic plane.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_RED, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_RED, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } int spell_shockwave(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *)vo; int dam; if ( ch == victim ) { send_to_char(C_DEFAULT, "Cast shockwave on yourself? Are you stupid?\n\r", ch); return SKPELL_MISSED; } if (!IS_NPC( victim ) ) { dam = UMAX( 20, victim->hit - dice( 1,4 ) ); dam = UMIN( 175, dam); //damage( ch, victim, dam, sn ); return dam; } act( AT_BLUE, "Your shockwave stuns $N.", ch, NULL, victim, TO_CHAR ); act( AT_BLUE, "$n's shockwave stuns $N.", ch, NULL, victim, TO_NOTVICT ); send_to_char( AT_BLUE, "You are stunned by a shockwave.", victim ); STUN_CHAR( victim, UMIN( level / 50, 1 * PULSE_VIOLENCE ), STUN_TOTAL ); return SKPELL_NO_DAMAGE; } int spell_control_dragon(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; char buf [ MAX_STRING_LENGTH ]; if(ch->summon_timer > 0) { send_to_char(AT_RED, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } mob = create_mobile(get_mob_index(MOB_VNUM_DRAGON)); mob->level = URANGE(51, level, 100) - 5; mob->max_hit = mob->level * 75 + dice(1,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_RED, "You summon $N from the draconic plane.", ch, NULL, mob, TO_CHAR); if(ch->mana < level * 2 && ((ch->class != 9)||(ch->class != 11))) { act(AT_RED, "You don't have enough mana to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } if(ch->bp < level / 2 && ((ch->class == 9)||(ch->class == 11))) { act(AT_BLOOD, "You don't have enough blood to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } if((ch->class != 9) || (ch->class != 11)) ch->mana -= level * 2; else ch->bp -= level / 2; act(AT_RED, "$n summons $N from the draconic plane.", ch, NULL, mob, TO_ROOM); af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); sprintf( buf, "Control Dragon: (%s)", ch->name ); log_string( buf, CHANNEL_GOD, -1 ); do_control_switch( ch, mob->name ); act(AT_WHITE, "$n takes control of the dragon!!", ch,NULL, NULL, TO_ROOM ); send_to_char(AT_WHITE, "You take control of the dragon!", ch ); send_to_char(AT_WHITE, "Ok.\n\r", ch ); return SKPELL_NO_DAMAGE; if(ch->position == POS_FIGHTING) { act(AT_RED, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_RED, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } int spell_control_trent(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; char buf [ MAX_STRING_LENGTH ]; if(ch->summon_timer > 0) { send_to_char(AT_WHITE, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } mob = create_mobile(get_mob_index(MOB_VNUM_TRENT)); mob->level = URANGE(51, level, 100) - 10; mob->max_hit = mob->level * 40 + dice(20,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_ORANGE, "You summon $N from the plane of nature.", ch, NULL, mob, TO_CHAR); if(ch->mana < level * 2 ) { act(AT_WHITE, "You don't have enough mana to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } ch->mana -= level * 2; act(AT_ORANGE, "$n calls forth $N from the plane of nature.", ch, NULL, mob, TO_ROOM); af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); sprintf( buf, "Control Trent: (%s)", ch->name ); log_string( buf, CHANNEL_GOD, -1 ); do_control_switch( ch, mob->name ); act(AT_WHITE, "$n takes control of the Trent!!", ch,NULL, NULL, TO_ROOM ); send_to_char(AT_WHITE, "You take control of the Trent!", ch ); send_to_char(AT_WHITE, "Ok.\n\r", ch ); return SKPELL_NO_DAMAGE; if(ch->position == POS_FIGHTING) { act(AT_WHITE, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_WHITE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } int spell_control_wolf(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; char buf [ MAX_STRING_LENGTH ]; if(ch->summon_timer > 0) { send_to_char(AT_WHITE, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } mob = create_mobile(get_mob_index(MOB_VNUM_WOLF)); mob->level = URANGE(31, level, 60) - 10; mob->max_hit = mob->level * 20 + dice(20,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_ORANGE, "You summon $N from the plane of nature.", ch, NULL, mob, TO_CHAR); if(ch->mana < level * 2 ) { act(AT_WHITE, "You don't have enough mana to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } ch->mana -= level * 2; act(AT_ORANGE, "$n calls forth $N from the plane of nature.", ch, NULL, mob, TO_ROOM); af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); sprintf( buf, "Control Wolf: (%s)", ch->name ); log_string( buf, CHANNEL_GOD, -1 ); do_control_switch( ch, mob->name ); act(AT_WHITE, "$n takes control of the Wolf!!", ch,NULL, NULL, TO_ROOM ); send_to_char(AT_WHITE, "You take control of the Wolf!", ch ); send_to_char(AT_WHITE, "Ok.\n\r", ch ); return SKPELL_NO_DAMAGE; if(ch->position == POS_FIGHTING) { act(AT_WHITE, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_WHITE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } int spell_summon_wolf(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; if(ch->summon_timer > 0) { send_to_char(AT_WHITE, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } mob = create_mobile(get_mob_index(MOB_VNUM_WOLF)); mob->level = URANGE(31, level, 60) - 10; mob->max_hit = mob->level * 20 + dice(20,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_ORANGE, "You summon $N from the plane of nature.", ch, NULL, mob, TO_CHAR); if(ch->mana < level * 2 ) { act(AT_WHITE, "You don't have enough mana to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } ch->mana -= level * 2; act(AT_ORANGE, "$n calls forth $N from the plane of nature.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_WHITE, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_WHITE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } int spell_control_hawk(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; char buf [ MAX_STRING_LENGTH ]; if(ch->summon_timer > 0) { send_to_char(AT_WHITE, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } mob = create_mobile(get_mob_index(MOB_VNUM_HAWK)); mob->level = URANGE(31, level, 60) - 10; mob->max_hit = mob->level * 30 + dice(20,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_ORANGE, "You summon $N from the plane of nature.", ch, NULL, mob, TO_CHAR); if(ch->mana < level * 2 ) { act(AT_WHITE, "You don't have enough mana to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } ch->mana -= level * 2; act(AT_ORANGE, "$n calls forth $N from the plane of nature.", ch, NULL, mob, TO_ROOM); af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); sprintf( buf, "Control Hawk: (%s)", ch->name ); log_string( buf, CHANNEL_GOD, -1 ); do_control_switch( ch, mob->name ); act(AT_WHITE, "$n takes control of the Hawk!!", ch,NULL, NULL, TO_ROOM ); send_to_char(AT_WHITE, "You take control of the Hawk!", ch ); send_to_char(AT_WHITE, "Ok.\n\r", ch ); return SKPELL_NO_DAMAGE; if(ch->position == POS_FIGHTING) { act(AT_WHITE, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_WHITE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } int spell_summon_hawk(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; if(ch->summon_timer > 0) { send_to_char(AT_WHITE, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } mob = create_mobile(get_mob_index(MOB_VNUM_HAWK)); mob->level = URANGE(31, level, 60) - 10; mob->max_hit = mob->level * 30 + dice(20,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_ORANGE, "You summon $N from the plane of nature.", ch, NULL, mob, TO_CHAR); if(ch->mana < level * 2 ) { act(AT_WHITE, "You don't have enough mana to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } ch->mana -= level * 2; act(AT_ORANGE, "$n calls forth $N from the plane of nature.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_WHITE, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_WHITE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } int spell_summon_tiger(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; if(ch->summon_timer > 0) { send_to_char(AT_WHITE, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } mob = create_mobile(get_mob_index(MOB_VNUM_TIGER)); mob->level = URANGE(41, level, 70) - 10; mob->max_hit = mob->level * 30 + dice(20,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_ORANGE, "You summon $N from the plane of nature.", ch, NULL, mob, TO_CHAR); if(ch->mana < level * 2 ) { act(AT_WHITE, "You don't have enough mana to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } ch->mana -= level * 2; act(AT_ORANGE, "$n calls forth $N from the plane of nature.", ch, NULL, mob, TO_ROOM); mob->master = ch; mob->leader = ch; af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); if(ch->position == POS_FIGHTING) { act(AT_WHITE, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_WHITE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } int spell_control_tiger(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; char buf [ MAX_STRING_LENGTH ]; if(ch->summon_timer > 0) { send_to_char(AT_WHITE, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } mob = create_mobile(get_mob_index(MOB_VNUM_TIGER)); mob->level = URANGE(41, level, 70) - 10; mob->max_hit = mob->level * 30 + dice(20,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_ORANGE, "You summon $N from the plane of nature.", ch, NULL, mob, TO_CHAR); if(ch->mana < level * 2 ) { act(AT_WHITE, "You don't have enough mana to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } ch->mana -= level * 2; act(AT_ORANGE, "$n calls forth $N from the plane of nature.", ch, NULL, mob, TO_ROOM); af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); sprintf( buf, "Control Tiger: (%s)", ch->name ); log_string( buf, CHANNEL_GOD, -1 ); do_control_switch( ch, mob->name ); act(AT_WHITE, "$n takes control of the Tiger!!", ch,NULL, NULL, TO_ROOM ); send_to_char(AT_WHITE, "You take control of the Tiger!", ch ); send_to_char(AT_WHITE, "Ok.\n\r", ch ); return SKPELL_NO_DAMAGE; if(ch->position == POS_FIGHTING) { act(AT_WHITE, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_WHITE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } int spell_divining( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *spring; spring = create_object( get_obj_index( OBJ_VNUM_SPRING ), 0); spring->timer = level; obj_to_room( spring, ch->in_room ); act(AT_BLUE, "$p flows from a hole in the ground.", ch, spring, NULL, TO_CHAR); act(AT_BLUE, "$p flows from a hole in the ground.", ch, spring, NULL, TO_ROOM ); return SKPELL_NO_DAMAGE; } int spell_unholy_fires( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; dam = dice( level, 20 ); if ( saves_spell( level, victim ) ) dam /= 2; // damage( ch, victim, dam, sn ); return dam; } int spell_stigeon_mists(int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *vch; if ( IS_SET( ch->in_room->room_flags, ROOM_SAFE)) { send_to_char(AT_WHITE, "You are in a safe room!!!!", ch); return SKPELL_MISSED; } send_to_char(AT_LBLUE, "You conjure a cloud of mist.\n\r", ch ); act(AT_LBLUE, "$n congures a poisonous mist!", ch, NULL, NULL, TO_ROOM ); for ( vch = char_list; vch; vch = vch->next ) { if ( vch->deleted || !vch->in_room ) continue; if ( vch->in_room == ch->in_room && vch != ch) { damage( ch, vch, level + dice( level/2, level/4 ), sn ); if ( vch != ch && !IS_AFFECTED4(vch,AFF_BURROW)) { spell_poison( skill_lookup("poison"), ch->level, ch, vch ); } continue; } } return SKPELL_NO_DAMAGE; } int spell_satanic_caress( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( victim->position == POS_FIGHTING || is_affected( victim, sn ) ) return SKPELL_MISSED; af.type = sn; af.level = level; af.duration = 10 + level; af.location = APPLY_DAMROLL; af.modifier = level / 5; af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_HITROLL; af.modifier = level / 5; affect_to_char( victim, &af ); af.location = APPLY_HIT; af.modifier = level * 2; affect_to_char( victim, &af ); if ( ch != victim ) { send_to_char(AT_RED, "You pray for Satan's blessing.\n\r", ch ); } send_to_char(AT_RED, "Satan's blessing is bestowed upon you.\n\r", victim ); return SKPELL_NO_DAMAGE; } int spell_control_undead(int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *mob; CHAR_DATA *fch; AFFECT_DATA af; char buf [ MAX_STRING_LENGTH ]; if(ch->summon_timer > 0) { send_to_char(AT_WHITE, "You cast the spell, but nothing appears.\n\r", ch); return SKPELL_MISSED; } mob = create_mobile(get_mob_index(MOB_VNUM_UNDEAD)); mob->level = URANGE(31, level, 60) - 10; mob->max_hit = mob->level * 20 + dice(20,mob->level); mob->hit = mob->max_hit; mob->summon_timer = level/10; ch->summon_timer = 16; char_to_room(mob, ch->in_room); act(AT_ORANGE, "You summon $N from the Abyss.", ch, NULL, mob, TO_CHAR); if(ch->mana < level * 2 ) { act(AT_WHITE, "You don't have enough mana to bind $N!", ch, NULL, mob, TO_CHAR); extract_char(mob, TRUE); return SKPELL_MISSED; } ch->mana -= level * 2; act(AT_ORANGE, "$n calls forth $N from the Abyss.", ch, NULL, mob, TO_ROOM); af.type = skill_lookup("charm person"); af.level = level; af.duration = -1; af.location = 0; af.bitvector = AFF_CHARM; affect_to_char(mob, &af); sprintf( buf, "Control Undead: (%s)", ch->name ); log_string( buf, CHANNEL_GOD, -1 ); do_control_switch( ch, mob->name ); act(AT_WHITE, "$n tikes control of the Undead!!", ch,NULL, NULL, TO_ROOM ); send_to_char(AT_WHITE, "You take control of the Undead!", ch ); send_to_char(AT_WHITE, "Ok.\n\r", ch ); return SKPELL_NO_DAMAGE; if(ch->position == POS_FIGHTING) { act(AT_WHITE, "$n rescues you!", mob, NULL, ch, TO_VICT ); act(AT_WHITE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT ); fch = ch->fighting; stop_fighting(fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting(mob, fch); set_fighting(fch, mob); } return SKPELL_NO_DAMAGE; } int spell_satanic_inferno( int sn, int level, CHAR_DATA *ch, void *vo) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED3( victim, AFF_SATANIC_INFERNO ) ) { affect_strip(victim, sn); if(skill_table[sn].msg_off) { send_to_char(C_DEFAULT, skill_table[sn].msg_off, victim ); send_to_char(C_DEFAULT, "\n\r", victim ); } act(C_DEFAULT, skill_table[sn].msg_off_room, victim, NULL, NULL, TO_NOTVICT); victim->shields -= 1; return SKPELL_NO_DAMAGE; } if ( !IS_SHIELDABLE( victim ) ) return SKPELL_MISSED; af.type = sn; af.level = level; af.duration = -1; af.location = APPLY_DAM_HOLY; af.modifier = 30; af.bitvector = AFF_SATANIC_INFERNO; affect_to_char3( victim, &af ); send_to_char(AT_RED, "You summon Satan's mighty inferno to protect you.\n\r", ch ); act(AT_RED, "$n's body is ingulfed by a satanic inferno.", victim, NULL, NULL, TO_ROOM ); victim->shields += 1; return SKPELL_NO_DAMAGE; } int spell_spark_blade( int sn, int level, CHAR_DATA *ch, void *vo ) { OBJ_DATA *obj = (OBJ_DATA *) vo; if ( obj->item_type != ITEM_WEAPON || IS_OBJ_STAT( obj, ITEM_MAGIC ) || IS_OBJ_STAT2( obj, ITEM_SPARKING ) || obj->affected ) { send_to_char(AT_DBLUE, "That item cannot be enchanted.\n\r", ch ); return SKPELL_MISSED; } SET_BIT( obj->extra_flags, ITEM_MAGIC); SET_BIT( obj->extra_flags2, ITEM_SPARKING); send_to_char(AT_RED, "Ok.\n\r", ch ); return SKPELL_NO_DAMAGE; } int spell_pestilence( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( saves_spell( level, victim ) ) return SKPELL_MISSED; af.type = sn; af.level = level; af.duration = level/10; af.location = APPLY_STR; af.modifier = -4; af.bitvector = AFF_PESTILENCE; affect_to_char3( victim, &af ); if( ch != victim ) send_to_char(AT_GREEN, "Ok.\n\r", ch ); send_to_char(AT_GREEN, "You have been infected.\n\r", victim ); return SKPELL_NO_DAMAGE; } int spell_shadow_bolt( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 215, 220, 225, 230, 235, 240, 245, 250, 255, 260 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level] / 2, dam_each[level] * 6 ); if ( saves_spell( level, victim ) ) dam /= 2; //damage( ch, victim, dam, sn ); return dam; } int spell_shadow_storm( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *vch; AFFECT_DATA af; send_to_char(AT_RED, "You send your shadows into the world!\n\r", ch ); act(AT_RED, "$n is surrounded by shadows!", ch, NULL, NULL, TO_ROOM ); for ( vch = char_list; vch; vch = vch->next ) { if ( vch->deleted || !vch->in_room ) continue; if ( vch->in_room == ch->in_room ) { if ( vch != ch && ( IS_NPC( ch ) ? !IS_NPC( vch ) : IS_NPC( vch ) ) ) damage( ch, vch, level + dice( level, 12 ), sn ); if ( vch != ch ) { af.type = sn; af.level = level; af.duration = level / 10; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_CURSE; affect_join( vch, &af ); send_to_char(AT_RED, "You feel the wrath of shadows!\n\r", vch); } continue; } } return SKPELL_NO_DAMAGE; }