/**************************************************************************/ // magic_qu.cpp - spells/skills written by Quenrelthaer /*************************************************************************** * The Dawn of Time v1.69r (c)1997-2004 Michael Garratt * * >> A number of people have contributed to the Dawn codebase, with the * * majority of code written by Michael Garratt - www.dawnoftime.org * * >> To use this source code, you must fully comply with the dawn license * * in licenses.txt... In particular, you may not remove this copyright * * notice. * **************************************************************************/ /*************************************************************************** * FILE: magic_q.c - spells written by Quenrelthaer * * * * cutting_wind - air, evocation & wild magic (area attack) * * decay - evocation & necromancy * * downdraft - air & evocation * * fling - air & alteration * * shaping_the_chaos - conjuration, summoning & wild magic * * spirit_walk - divination, summoning * * disorientation - illusion * * ***************************************************************************/ #include "include.h" #include "magic.h" /********************************/ /* START OF FUNCTION PROTOTYPES */ DECLARE_DO_FUN(do_bug); DECLARE_DO_FUN(do_look); /* END OF FUNCTION PROTOTYPES */ /********************************/ /*************************************************************************** * spell_cutting_wind - by Quenrelthaer August 97 - modified by kalahn * ***************************************************************************/ SPRESULT spell_cutting_wind(int sn,int level,char_data *ch,void *,int ) { char_data *vch; char_data *vch_next; int dam, pdam, random; random = dice(1,level/3)+2; dam = dice((level/2)+1, random); for ( vch = ch->in_room->people; vch; vch = vch_next ) { vch_next=vch->next_in_room; pdam = dam; if (vch == ch) continue; if ( is_safe_spell(ch,vch,true)) continue; if ( saves_spell( level, vch, DAMTYPE(sn)) ) { pdam /= 2; } damage_spell( ch, vch, pdam, sn, DAMTYPE(sn),true); } return FULL_MANA; } /**************************************************************************** * spell_decay - by Quenrelthaer August 97, * * - modified by Kalahn Nov 97, made it not destroy items inside containers * ****************************************************************************/ SPRESULT spell_decay(int sn,int level,char_data *ch,void *vo,int target) { OBJ_DATA *decay, *decay_next; OBJ_DATA *obj; OBJ_DATA *obj_next; char_data *victim=(char_data*)vo; int dam, random; if (target == TARGET_OBJ) { decay = get_obj_carry(ch,target_name); if (decay == NULL) { ch->println("You do not see that here."); return NO_MANA; } if ( IS_SET( decay->extra2_flags, OBJEXTRA2_NODECAY )) { ch->println("Nothing seemed to happen."); return HALF_MANA; } decay->timer = (30/level)+1; act( "$p slowly starts to break apart.", ch, decay, NULL, TO_ROOM ); act( "$p slowly starts to break apart as the decay sets in.", ch, decay, NULL, TO_CHAR ); return FULL_MANA; } dam = dice(level, 8); if ( saves_spell( level, victim, DAMTYPE(sn)) ) dam /= 2; damage_spell( ch, victim, dam, sn, DAMTYPE(sn),true); if (dam<level*4) { random = dice(2,10)-1; for ( decay = victim->carrying; decay != NULL; decay = decay_next) { decay_next = decay->next_content; if (decay->wear_loc == random) break; } if (decay == NULL) return FULL_MANA; if ( IS_SET( decay->extra2_flags, OBJEXTRA2_NODECAY )) { ch->println("Nothing seemed to happen."); return HALF_MANA; } act("$p suddenly falls apart, decaying into dust just before it hits the ground!",ch,decay,NULL,TO_ROOM); act("The magic sets upon $p, grinding it to dust.",ch,decay,NULL,TO_CHAR); switch ( decay->item_type ) { default: extract_obj(decay); break; case ITEM_CAULDRON: case ITEM_CONTAINER: case ITEM_FLASK: case ITEM_MORTAR: case ITEM_CORPSE_NPC: case ITEM_CORPSE_PC: for ( obj = decay->contains; obj != NULL; obj = obj_next ) { obj_next = obj->next_content; obj_from_obj(obj); if (number_range(1,10)==1) { obj_to_char( obj, ch ); act("You manage to catch $p as before it hits the ground.", ch, obj, NULL, TO_CHAR); } else { obj_to_room(obj, ch->in_room); act("$p falls to the ground.", ch, obj, NULL, TO_ROOM); act("The $p falls to your feet.", ch, obj, NULL, TO_CHAR); } } } obj_from_char(decay); extract_obj(decay); } return FULL_MANA; } /**************************************************************************** * spell_disorientation - by Quenrelthaer - August 97 * ****************************************************************************/ SPRESULT spell_disorientation(int ,int ,char_data *ch,void *vo,int ) { char_data *victim=(char_data*)vo; ROOM_INDEX_DATA *pRoomIndex; ROOM_INDEX_DATA *original; OBJ_DATA *on; pRoomIndex = get_random_room(victim); victim->println("You have been teleported!"); act("$n looks very confused all of a sudden.", victim, ch, NULL,TO_ROOM); if (victim != ch) act("$n looks very confused all of a sudden.", victim, ch, NULL,TO_CHAR); original = victim->in_room; on = victim->on; char_from_room( victim ); char_to_room( victim, pRoomIndex ); do_look(victim,"auto"); char_from_room( victim ); char_to_room( victim, original ); victim->on = on; return FULL_MANA; } /**************************************************************************** * spell_downdraft - by Quenrelthaer August 97 * ****************************************************************************/ SPRESULT spell_downdraft(int sn,int level,char_data *ch,void *vo,int ) { OBJ_DATA *obj, *obj_next; char_data *victim=(char_data*)vo; int dam, random; dam = dice(level,3)+4; if ( saves_spell( level, victim, DAMTYPE(sn)) ) dam /= 2; damage_spell( ch, victim, dam, sn, DAMTYPE(sn),true); if (dam>level*2) { random = dice(2,10)-1; for ( obj = victim->carrying; obj != NULL; obj = obj_next) { obj_next = obj->next_content; if (obj->wear_loc == random) break; } if (obj == NULL) return FULL_MANA; act("The force of the wind blows $p to the ground.",ch,obj,NULL,TO_ROOM); act("The force of the wind blows $p to the ground.",ch,obj,NULL,TO_CHAR); obj_from_char(obj); obj_to_room(obj,ch->in_room); } return FULL_MANA; } /**************************************************************************** * spell_fling - by Quenrelthaer August 97, updated by Kalahn Sept 97 * ****************************************************************************/ SPRESULT spell_fling(int sn,int level,char_data *ch,void *vo,int ) { char_data *victim=(char_data*)vo; OBJ_DATA *obj, *obj_next; int dam, max; for (obj = ch->carrying; obj != NULL; obj = obj_next) { obj_next = obj->next_content; if (obj->wear_loc != WEAR_NONE){ continue; } // can't fling what you can't see/tokens if( !can_see_obj(ch, obj) || obj->item_type == ITEM_TOKEN){ continue; } // can't fling nodrop items to get rid of them if ( !can_drop_obj( ch, obj ) ){ act("You can't seem to fling $p, you decide to try something else!",ch,obj,NULL,TO_CHAR); continue; } // we have something potentially flingable break; } if (obj == NULL) { ch->println("You must be carrying something to fling."); return NO_MANA; } max = ((obj->weight)/10)+1; if (max>level+5) { act("$p is too heavy for you to fling.",ch,obj,NULL,TO_CHAR); return HALF_MANA; } act("Your magic flings $p into the air!",ch,obj,NULL,TO_CHAR); dam = dice(max,4); if ( saves_spell( level, victim, DAMTYPE(sn)) ) dam /= 2; damage_spell( ch, victim, dam, sn, DAMTYPE(sn),true); act("$p flies up into the air, then plummets downward, striking heavily.",ch,obj,NULL,TO_ROOM); act("$p hits the ground with a thud.",ch,obj,NULL,TO_ROOM); act("$p hits the ground with a thud.",ch,obj,NULL,TO_CHAR); obj_from_char( obj ); obj_to_room(obj,ch->in_room); return FULL_MANA; } /**************************************************************************** * spell_shaping_the_chaos - by Quenrelthaer & Kalahn August 97 * ****************************************************************************/ SPRESULT spell_shaping_the_chaos(int ,int level,char_data *ch,void *,int ) { OBJ_INDEX_DATA *pObjIndex; MOB_INDEX_DATA *pMobIndex; OBJ_DATA *obj_chaos; char_data *mob_chaos; char buf[MSL]; int random, max; ch->println("You reach into the chaos with your mind and attempt\r\nto shape it into something..."); int value =0; // default type is an object // in rooms that are 'law' objects only summoned if(ch->in_room && !IS_SET(ch->in_room->room_flags,ROOM_LAW)){ value =number_range(0,1); } switch (value) { case 0: // CREATE CHAOS OBJECT max = dice(1,level)+5; if (max > SPELL_SHAPING_THE_CHAOS_NUMBER_OF_OBJECTS) max = SPELL_SHAPING_THE_CHAOS_NUMBER_OF_OBJECTS; random = dice(1,max); if ((pObjIndex = // check for object vnum get_obj_index(SPELL_SHAPING_THE_CHAOS_FIRST_OBJECT_VNUM+random))) { obj_chaos= create_object(pObjIndex); obj_to_room(obj_chaos,ch->in_room); obj_chaos->timer = (ch->level/4)+1; act("Suddenly, $p appears in midair and falls to the ground.",ch,obj_chaos,NULL,TO_ROOM); act("The chaos forms itself into $p, which appears in midair\r\n" "and falls to the ground.",ch,obj_chaos,NULL,TO_CHAR); } else /* object with the vnum not found */ { sprintf(buf,"BUG: in spell_shaping_the_chaos - missing object vnum %d!\r\n", 49+random); wiznet(buf,NULL,NULL,WIZ_BUGS,0,AVATAR); /* put it on the bug wiznet channel */ log_string( buf ); /* log the bug in the logs */ do_bug ( ch, buf); /* report the bug into the bug file */ ch->printf( "%s", buf ); /* tell the char what happened */ return NO_MANA; } break; case 1: /* CREATE CHAOS MOB */ max = dice(1,level)+5; if (max > SPELL_SHAPING_THE_CHAOS_NUMBER_OF_MOBS) max = SPELL_SHAPING_THE_CHAOS_NUMBER_OF_MOBS; random = dice(1,max); if ((pMobIndex = // make sure mob exists get_mob_index(SPELL_SHAPING_THE_CHAOS_FIRST_MOB_VNUM+random))) { mob_chaos = create_mobile(pMobIndex,0); // create the mobile mob_chaos->level = ch->level; mob_chaos->no_xp = true; // can't get xp for killing it char_to_room( mob_chaos ,ch->in_room); act("Suddenly, $N appears in midair and falls to the ground, landing solidly.",ch,NULL,mob_chaos,TO_ROOM); act("The chaos takes the form of $N, which appears in midair\nand falls to the ground, landing on its feet.",ch,NULL,mob_chaos,TO_CHAR); } else // mob with the vnum not found { sprintf(buf,"BUG: in spell_shaping_the_chaos - missing mob vnum %d!\r\n", 49+random); wiznet(buf,NULL,NULL,WIZ_BUGS,0,AVATAR); // put it on the bug wiznet channel log_string( buf ); // log the bug in the logs do_bug ( ch, buf); // report the bug into the bug file ch->printf( "%s", buf ); return NO_MANA; } break; } return FULL_MANA; } /**************************************************************************** * spell_spirit_walk - by Quenrelthaer - August 97 * ****************************************************************************/ SPRESULT spell_spirit_walk(int sn,int level,char_data *ch,void *vo,int ) { char buf[MSL]; char_data *victim=(char_data*)vo; char_data *spirit; MOB_INDEX_DATA *pMobIndex; if(IS_SWITCHED(ch)){ ch->println("You can't control two forms at once."); return NO_MANA; } if ( ( victim = get_char_world( ch, target_name ) ) == NULL || victim->in_room == NULL || IS_SET(ch->in_room->room_flags, ROOM_SAFE) || IS_SET(victim->in_room->room_flags, ROOM_SAFE) || victim->level >= level + 3 || (!IS_NPC(victim) && victim->level >= LEVEL_IMMORTAL) || (IS_NPC(victim) && IS_SET(victim->imm_flags,IMM_SUMMON)) || (IS_NPC(victim) && saves_spell( level, victim,DAMTYPE(sn)))) { ch->println("You could not hold your spirit there."); return FULL_MANA; } pMobIndex = get_mob_index(SPELL_SPIRIT_WALK_SPIRIT_MOB); if (!pMobIndex) // mob with the vnum not found { sprintf(buf,"BUG: in spell_spirit_walk - missing host mob!!! <vnum %d>\r\n", SPELL_SPIRIT_WALK_SPIRIT_MOB); wiznet(buf,NULL,NULL,WIZ_BUGS,0,AVATAR); // put it on the bug wiznet channel log_string( buf ); // log the bug in the logs do_bug ( ch, buf); // report the bug into the bug file ch->printf( "%s", buf ); return NO_MANA; } spirit = create_mobile(pMobIndex, 0); char_to_room(spirit, victim->in_room); ch->desc->character = spirit; ch->desc->original = ch; spirit->desc = ch->desc; ch->desc = NULL; ch->controlling = spirit; // so switched ppl aren't marked as idle/linkdead // change communications to match if (ch->prompt != NULL) spirit->prompt = str_dup(ch->prompt); spirit->comm = ch->comm; spirit->lines = ch->lines; spirit->timer = ch->level/40+1; //set how long the spirit will last spirit->println("Your spirit pulls away from your body..."); spirit->println("You find yourself somewhere else..."); do_look(spirit,"auto"); return FULL_MANA; } /***************************************************************************/