/**************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * Much time and thought has gone into this software and you are * * benefitting. We hope that you share your changes too. What goes * * around, comes around. * ***************************************************************************/ /**************************************************************************** * ROM 2.4 is copyright 1993-1998 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@hypercube.org) * * Gabrielle Taylor (gtaylor@hypercube.org) * * Brian Moore (zump@rom.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * ***************************************************************************/ /**************************************************************************** * Demon's Dance MUD, and source code are property of Eric Goetschalckx * * By compiling this code, you agree to include the following in your * * login screen: * * Derivative of Demon's Dance, by Enzo/Stan * ***************************************************************************/ /* * Draconian Skill File */ #if defined(macintosh) #include <types.h> #else #include <sys/types.h> #endif #include <stdio.h> #include <string.h> #include <time.h> #include "merc.h" #include "arena.h" #include "interp.h" #include "tables.h" #include "olc.h" #include "recycle.h" #include "lookup.h" /* ******************************************************************** This is the find familiar skill. April 4 1998 by Gothar This skill allows your players to have a companion like those loveable pets in the pet shops. Email me if you use it. Leave this header to say Gothar had a great idea there. gothar@magma.ca mcco0055@algonquinc.on.ca * ******************************************************************** */ void do_find_dragon ( CHAR_DATA *ch, char *argument) { MOB_INDEX_DATA *pMobIndex; CHAR_DATA *pet; int i; int chance; if (( chance = get_skill(ch,gsn_find_dragon)) == 0 || (!IS_NPC(ch) && ch->level < skill_table[gsn_find_dragon].skill_level[ch->class])) { send_to_char("You don't know where to start.\n\r",ch); return; } if ( ch->pet != NULL ) { send_to_char("You already a companion.\n\r",ch); return; } if(ch->position == POS_FIGHTING) { send_to_char("You can't study the ritual while in combat!\n\r",ch); return; } if ( ( pMobIndex = get_mob_index(MOB_VNUM_DRAGON) ) == NULL ) { send_to_char( "The dragon mob doesn't exist.\n\r", ch ); return; } /* can't cast the spell in these sectors */ if (ch->in_room->sector_type == SECT_WATER_NOSWIM) { send_to_char("You are feeling too sick to concentrate.\n\r",ch); return; } pet = create_mobile( pMobIndex ); pet->level = number_fuzzy(ch->level / 2); pet->mana = pet->max_mana = 0; pet->hit = pet->max_hit = number_fuzzy(ch->max_hit); for(i = 0; i < 4; i++) pet->armor[i] = number_fuzzy(ch->armor[i] - 10); pet->hitroll = number_fuzzy(ch->level*2); pet->damroll = number_fuzzy(ch->level*2); pet->damage[DICE_NUMBER] += number_range((ch->level/20)-3,(ch->level/15)+3); pet->damage[DICE_TYPE] += number_range((ch->level/20)-2,(ch->level/15)+3); /* free up the old mob names */ free_string(pet->description); free_string(pet->name); free_string(pet->short_descr); free_string(pet->long_descr); /* terrain */ switch(ch->in_room->sector_type) { case(SECT_CITY): /*ahzi dahaka earth dragon */ case(SECT_FIELD): pet->description = str_dup("You have summoned Ahzi Dahakra the Earth Dragon\n\r"); pet->short_descr = str_dup("Ahzi Dahakra"); pet->long_descr = str_dup("Ahzi Dahakra the Earth Dragon is here.\n\r"); pet->name = str_dup("dragon earth ahzi dahakra"); pet->dam_type = 10; /* bite */ break; case(SECT_FOREST): /*tirzanth the green dragon */ case(SECT_HILLS): pet->description = str_dup("You have summoned Tirzanth the Green Dragon\n\r"); pet->short_descr = str_dup("Tirzanth"); pet->long_descr = str_dup("Tirzanth the Green Dragon is here.\n\r"); pet->name = str_dup("dragon green tirzanth"); pet->dam_type = 5; /* claw */ break; case(SECT_MOUNTAIN): /*quetzalcoatl thunder dragon */ pet->description = str_dup("You have summoned Quetzalcoatl the Thunder Dragon\n\r"); pet->short_descr = str_dup("Quetzalcoatl"); pet->long_descr = str_dup("Quetzalcoatl the Thunder Dragon is here.\n\r"); pet->name = str_dup("dragon thunder Quetzalcoatl"); pet->dam_type = 10; /* bite */ break; case(SECT_DESERT): /* sandworm */ pet->description = str_dup("You have summoned a gigantic Sandworm\n\r"); pet->short_descr = str_dup("Shai Hulud"); pet->long_descr = str_dup("A gigantic Sandworm is here.\n\r"); pet->name = str_dup("sandworm worm shai hulud"); pet->dam_type = 12; /* suction */ break; case(SECT_AIR):/*phantasmal wyvern*/ pet->description = str_dup("You have summoned a majestive wyvern of the illusionary realm\n\r"); pet->short_descr = str_dup("a Phantasmal Wyvern"); pet->long_descr = str_dup("A phantasmal Wyvern is here.\n\r"); pet->name = str_dup("illsuionary phantasmal wyvern"); pet->dam_type = 6; /*blast*/ break; case(SECT_WATER_SWIM):/*7-headed hydra*/ pet->description = str_dup("You have summoned a 7-headed Hydra\n\r"); pet->short_descr = str_dup("the Hydra"); pet->long_descr = str_dup("A seven headed Hydra is here.\n\r"); pet->name = str_dup("seven headed hydra"); pet->dam_type = 30; /*frbite*/ break; case(SECT_INSIDE):/*tiamut, dragon of death*/ pet->description = str_dup("You have summoned Tiamut, the dragon of death\n\r"); pet->short_descr = str_dup("Tiamut"); pet->long_descr = str_dup("Tiamut, the dragon of death is here\n\r"); pet->name = str_dup("tiamut dragon death"); pet->dam_type = 41; /*banshee wail*/ break; } /* player seen stuff here */ do_sit(ch,""); char_to_room( pet, ch->in_room ); act( "You begin to chant and call to $N!.",ch,NULL,pet,TO_CHAR); act( "$n begins to chant and calls to $N!", ch, NULL, pet, TO_ROOM ); WAIT_STATE(ch, 2 * PULSE_MOBILE); add_follower( pet, ch ); pet->leader = ch; ch->pet = pet; do_stand(ch,""); SET_BIT(pet->act, ACT_PET); SET_BIT(pet->affected_by, AFF_CHARM); ch->move -= (pet->level / 2); /* physically draining loss of move */ check_improve(ch,gsn_find_dragon,TRUE,6); return; } void do_sever( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; char buf[MAX_INPUT_LENGTH]; CHAR_DATA *victim; OBJ_DATA *obj; int chance; int percent; int skill; one_argument( argument, arg ); if (arg[0] == '\0') { victim = ch->fighting; if (victim == NULL) { send_to_char("But you aren't fighting anyone!\n\r",ch); return; } } else if ((victim = get_char_room(ch,NULL,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if ( is_safe( ch, victim ) ) return; if (!know_skill(ch,"sever")) return; if (IS_NPC(victim) && victim->fighting != NULL && !is_same_group(ch,victim->fighting) && !is_arena(victim)) { send_to_char("Kill stealing is not permitted.\n\r",ch); return; } if ( ( victim = ch->fighting ) == NULL ) { send_to_char( "You must be fighting in order to sever.\n\r", ch ); return; } if(victim == ch) { send_to_char("You reach your neck fine, but cant' get your ankles.\n\r",ch); return; } percent = 10 - (( 100 * victim->hit ) / victim->max_hit); skill = get_skill(ch,gsn_sever)/10; chance = 100 * (skill + percent); if ( number_percent( ) < chance ) { check_killer( ch, victim ); WAIT_STATE( ch, skill_table[gsn_sever].beats ); if ( number_percent( ) < get_skill(ch,gsn_sever) || ( get_skill(ch,gsn_sever) >= 2 && !IS_AWAKE(victim) ) ) { if(!IS_NPC(victim)) act("{W$n picks you up and rips you in half! Oh no!{x",ch,NULL,victim,TO_VICT); act("{W$n picks up $N and rips $S legs off!{x",ch,NULL,victim,TO_NOTVICT); send_to_char("{WYou grab them by the neck and legs and viciously rip them in half!{x\n\r",ch); check_improve(ch,gsn_sever,TRUE,1); one_hit( ch, victim, gsn_sever, TRUE,FALSE ); obj = create_object( get_obj_index(OBJ_VNUM_LEGS ), 0 ); obj->timer = 5; add_sever(ch,victim); if(IS_NPC(victim)) sprintf(buf,"A pair of %s's legs are here, twitching.",victim->short_descr); else sprintf(buf,"A pair of %s's legs are here, twitching.",victim->name); free_string(obj->description); obj->description = str_dup( buf ); if(!IS_NPC(victim)) sprintf(buf,"A pair of %s's legs",victim->short_descr); else sprintf(buf,"A pair of %s's legs",victim->name); free_string(obj->short_descr); obj->short_descr = str_dup( buf ); obj_to_char(obj,ch); } } else { WAIT_STATE( ch, skill_table[gsn_sever].beats ); send_to_char("{WYou didnt manage to rip them in half, best wait till they're more damgaged.{x\n\r", ch); check_improve(ch,gsn_sever,FALSE,1); damage( ch, victim, 0, gsn_sever,DAM_NONE,TRUE,FALSE); } } void spell_venom_lance( int sn, int level, CHAR_DATA *ch,void *vo,int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int attacks; int chance; static const sh_int dam_each[] = { 0, 10, 10, 15, 20, 20, 20, 25, 28, 30, 32, 34, 36, 38, 40, 45, 48, 50, 52, 56, 60, 64, 66, 70, 72, 75, 78, 82, 86, 91, 97, 102, 108, 111, 118, 121, 123, 128, 130, 132, 136, 138, 140, 145, 150, 155, 160, 170, 175, 180, 200 }; int dam; level = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1); level = UMAX(0, level); if ( saves_spell( level, victim,DAM_ENERGY) ) act("{W$n conjures a spear of {Gp{Bu{Gr{Be {Gv{Be{Gn{Bo{Gm{W and launches it at you!{x",ch,NULL,victim,TO_VICT); act("{W$n conjures a spear of {Gp{Bu{Gr{Be {Gv{Be{Gn{Bo{Gm{W and launches it at $N{x",ch,NULL,victim,TO_NOTVICT); act("{WYou conjure a spear of {Gp{Bu{Gr{Be {Gv{Be{Gn{Bo{Gm{W and launch it at $N{x",ch,NULL,victim,TO_CHAR); attacks = 0; chance = number_range(0,12); while ( attacks <= chance) { dam = number_range( dam_each[level] *3, dam_each[level] * 7 ); damage( ch, victim, dam, sn, DAM_POISON ,TRUE,FALSE); attacks ++; } } void spell_thermonuclear( int sn, int level, CHAR_DATA *ch,void *vo,int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; CHAR_DATA *victim_next; int dam; if (IS_SET(ch->in_room->room_flags,ROOM_ARENA) || IS_SET(ch->in_room->room_flags,ROOM_HONCIRC)) { send_to_char("Not in the Arena or in the Honor Circle",ch); return; } dam = number_range( ch->level * 900000, ch->level * 1000000 ); act("{W$n prepares to destroy EVERYTHING in a thermonuclear detonation{x",ch,NULL,victim,TO_ROOM); act("{WYou prepare to destroy EVERYTHING in a thermonuclear detonation{x",ch,NULL,victim,TO_CHAR); for ( victim = ch->in_room->people; victim != NULL; victim = victim_next ) { victim_next = victim->next_in_room; if(is_safe(ch,victim)) continue; if(victim == ch) continue; damage( ch, victim, dam, sn, DAM_NONE ,TRUE,FALSE); } damage( ch, ch, dam, sn, DAM_NONE ,TRUE,FALSE); } void spell_dragonfury( int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim; AFFECT_DATA af; /* character target */ victim = (CHAR_DATA *) vo; if (victim != ch) { send_to_char("You may only cast DragonFury on yourself\n\r",ch); return; } if ( victim->position == POS_FIGHTING || is_affected( victim, sn ) ) { send_to_char("You already have the dragons fury running in your blood\n\r",ch); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level / 7; af.location = APPLY_HITROLL; af.modifier = level / 3; af.bitvector = 0; affect_to_char( victim, &af ); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level / 7; af.location = APPLY_DAMROLL; af.modifier = level / 3; af.bitvector = 0; affect_to_char( victim, &af ); send_to_char( "The rage of all the ancient dragons begins to pound in your veins\n\r", victim ); return; } void spell_mystic_sight( int sn, int level, CHAR_DATA *ch, void *vo,int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if ( IS_AFFECTED2(victim, AFF_MYSTIC_SIGHT) ) { if (victim == ch) send_to_char("You already have mystic sight.\n\r",ch); else act("$N already has mystic sight",ch,NULL,victim,TO_CHAR); return; } af.where = TO_AFFECTS2; af.type = sn; af.level = level; af.duration = level/10; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_MYSTIC_SIGHT; affect_to_char( victim, &af ); send_to_char( "The shadows around you begin to take on new meaning....\n\r", victim ); if ( ch != victim ) send_to_char( "Ok.\n\r", ch ); return; } void spell_elemental_wrath( int sn, int level, CHAR_DATA *ch, void *vo,int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; long dam; int fire_sn; int cold_sn; int lightning_sn; int acid_sn; int negative_sn; int holy_sn; fire_sn = skill_lookup("wrath fire"); cold_sn = skill_lookup("wrath cold"); lightning_sn = skill_lookup("wrath lightning"); acid_sn = skill_lookup("wrath acid"); negative_sn = skill_lookup("wrath negative"); holy_sn = skill_lookup("wrath holy"); act("{W$n's hands move in intricate patterns, as he chants in the language of the elder wyrms{x", ch,NULL,victim,TO_VICT); act("{W$n's hands move in intricate patterns, as he chants in the language of the elder wyrms{x", ch,victim,NULL,TO_NOTVICT); act("{WYou weave patterns of magic and call upong the wrath of the elements!{x", ch,victim,NULL,TO_CHAR); /*Fire*/ dam = (ch->level) * number_range(1,3) + number_range(4,7) * 10; dam *= 2.5; damage( ch, victim, dam, fire_sn, DAM_FIRE ,TRUE,FALSE); /*Cold*/ dam = (ch->level) * number_range(1,3) + number_range(4,7) * 10; dam *= 2.5; damage( ch, victim, dam, cold_sn, DAM_COLD ,TRUE,FALSE); /*Acid*/ dam = (ch->level) * number_range(1,3) + number_range(4,7) * 10; dam *= 2.5; damage( ch, victim, dam, lightning_sn, DAM_LIGHTNING ,TRUE,FALSE); /*Lightning*/ dam = (ch->level) * number_range(1,3) + number_range(4,7) * 10; dam *= 2.5; damage( ch, victim, dam, acid_sn, DAM_ACID ,TRUE,FALSE); /*Negative*/ damage( ch, victim, dam, negative_sn, DAM_NEGATIVE ,TRUE,FALSE); /*Holy*/ damage( ch, victim, dam, holy_sn, DAM_HOLY ,TRUE,FALSE); } void spell_skeleton_dance( int sn, int level, CHAR_DATA *ch, void *vo,int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; long dam; int skeleton_sn; int skeleton1_sn; int skeleton2_sn; int wraith_sn; int chance; skeleton_sn = skill_lookup("skeletal mage"); skeleton1_sn = skill_lookup("skeletal archer"); skeleton2_sn = skill_lookup("skeletal warrior"); wraith_sn = skill_lookup("phantasmal wraith"); act("{D$n summons dark warriors from the depths of hell! {x",ch,NULL,victim,TO_VICT); act("{D$n summons dark warriors from the depths of hell! {x",ch,victim,NULL,TO_NOTVICT); act("{DYou summon dark warriors from the depths of hell! !{x",ch,victim,NULL,TO_CHAR); chance = number_range(1,100); if (chance <= 30) { dam = ((ch->level) * number_range(1, 3)) + dice(40, 120) + number_range(200,400); damage( ch, victim, dam, skeleton_sn, DAM_NEGATIVE ,TRUE, FALSE); if (!IS_SET(victim->affected_by,AFF_WEAKEN)) { af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level / 50; af.location = APPLY_STR; af.modifier = -1 * (level / 4); af.bitvector = AFF_WEAKEN; affect_to_char( victim, &af ); send_to_char( "You feel your muscles deteriorating! \n\r", victim ); } if (!IS_SET(victim->affected_by,AFF_BLIND)) { af.where = TO_AFFECTS; af.type = sn; af.level = level; af.location = APPLY_HITROLL; af.modifier = -50; af.duration = level/50; af.bitvector = AFF_BLIND; affect_to_char( victim, &af ); send_to_char( "Everything suddenly goes dark! \n\r", victim ); } } else if (chance <=60) { dam = ((ch->level) * number_range(1, 3)) + dice(45, 120) + number_range(200,400); damage( ch, victim, dam, skeleton1_sn, DAM_NEGATIVE ,TRUE, FALSE); if (!IS_SET(victim->affected_by,AFF_SLOW)) { af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level/50; af.location = APPLY_DEX; af.modifier = -1 * (level/5); af.bitvector = AFF_SLOW; affect_to_char( victim, &af ); send_to_char( "You feel yourself slowing d o w n...\n\r", victim ); } } else if (chance <= 90) { dam = ((ch->level) * number_range(1, 3)) + dice(50, 120) + number_range(200,400); damage( ch, victim, dam, skeleton2_sn, DAM_NEGATIVE ,TRUE, FALSE); if (!IS_SET(victim->affected_by,AFF_WEAKEN)) { af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level / 50; af.location = APPLY_CON; af.modifier = -1 * (level/4); af.bitvector = AFF_WEAKEN; affect_to_char( victim, &af ); send_to_char( "You feel your defenses dropping! \n\r", victim ); } } else { dam = ((ch->level) * number_range(1, 3)) + dice(55, 120) + number_range(200,400); damage( ch, victim, dam, wraith_sn, DAM_NEGATIVE ,TRUE, FALSE); if (!IS_SET(victim->affected_by,AFF_POISON)) { af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level/50; af.location = APPLY_DAMROLL; af.modifier = -50; af.bitvector = AFF_POISON; affect_join( victim, &af ); send_to_char( "You are seized by a fit of coughing.\n\r", victim ); } if (!IS_SET(victim->affected_by,AFF_FAERIE_FIRE)) { af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level/50; af.location = APPLY_AC; af.modifier = 10 * level; af.bitvector = AFF_FAERIE_FIRE; affect_to_char( victim, &af ); send_to_char( "You are surrounded by a bright pink outline.\n\r", victim ); } } } void spell_exodus( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; int random = number_range(1,4); act("$n clenches $s fist as $s eyes flash a deep crimson.", ch, NULL, NULL, TO_ROOM ); act("You mentally grasp hold of $N's life force and rip it forcefully out of $S body",ch,NULL,victim,TO_CHAR); dam = number_range( ch->level * 15, ch->level * 30 ); damage( ch, victim, dam, sn, DAM_NONE ,TRUE,FALSE); switch (random) { case 1: break; case 2: break; case 3: act("$N's eyes suddenly go dark, as if $S very life has been forcefully ripped from $S body!",ch,NULL,victim,TO_NOTVICT); act("Suddenly a gut wrenching pain flashes through you, and you are left void of mental energies!",ch,NULL,victim,TO_VICT); stc("{WManaburn{x\n\r",ch); victim->mana = 0; break; case 4: act("$N crumples to the ground in a heap, as $n's exodus spell reduces $N to a spasming wretch!",ch,NULL,victim,TO_NOTVICT); act("Suddenly all your muscles go flacid, and you collapse to the ground like a sack of bricks",ch,NULL,victim,TO_VICT); stc("{BMoveburn{x\n\r",ch); victim->move = 0; break; default: break; } return; }