/*************************************************************************** * 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 * ***************************************************************************/ /************************************************************************** *************************************************************************** *************************************************************************** *** *** *** This file is for bard songs, and the music and play skill, *** *** written from scratch by me (Chaos) for the Realm of the lance *** *** MUD, copyright 1998. It may be used as long as this header *** *** file remains intact, and my name is mentioned somewhere in the *** *** help file for music/play. I would also appreciate an e-mail *** *** stating that you are using this and the address of your mud *** *** so I can come check it out! Any comments or suggestions, or *** *** bugs may be e-mailed to chaos@lance.betterbox.net. Enjoy! *** *** *** *************************************************************************** *************************************************************************** **************************************************************************/ #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 "include.h" DECLARE_SONG_FUN( song_of_huma ); DECLARE_SONG_FUN( song_of_soothing ); DECLARE_SONG_FUN( song_of_paralysis ); DECLARE_SONG_FUN( song_of_rage ); const struct song_type bsong_table [MAX_SONG] = { /* { "Song name", "Song list name", level, (void(*)(int, int, CHAR_DATA *))song_fun, min position, min mana, beats } */ { "song of huma", "Song of Huma", 20, (void(*)(int, int, CHAR_DATA *))song_of_huma, POS_RESTING, 40, 25 }, { "song of soothing", "Song of Soothing", 48, (void(*)(int, int, CHAR_DATA *))song_of_soothing, POS_RESTING, 30, 5 }, { "song of paralysis", "Song of Paralysis", 50, (void(*)(int, int, CHAR_DATA *))song_of_paralysis, POS_RESTING, 50, 5 }, { "song of rage", "Song of Rage", 40, (void (*)(int, int, CHAR_DATA *))song_of_rage, POS_RESTING, 50, 5 }, }; void do_songs(CHAR_DATA *ch, char *argument) { char buf[MSL]; int i; sprintf(buf, "{Y[%-18s %5s]{x\n\r", "Song Name", "Level"); send_to_char(buf,ch); for (i = 0; i <= MAX_SONG -1; i++) { sprintf(buf, "{Y[{G%-20s {C%3d{Y]{x\n\r", bsong_table[i].listname, bsong_table[i].level); send_to_char(buf,ch); } return; } int song_lookup( const char *name ) { int songnum; for ( songnum = 0; songnum <= MAX_SKILL -1; songnum++ ) { if ( bsong_table[songnum].name == NULL ) break; if ( LOWER(name[0]) == LOWER(bsong_table[songnum].name[0]) && !str_cmp( name, bsong_table[songnum].name ) ) return songnum; } return -1; } void do_splay( CHAR_DATA *ch, char *argument ) { OBJ_DATA *instrument; int songnum, chance, mana, level; if ((chance = get_skill(ch,skill_lookup("music"))) == 0) { send_to_char("You have no clue how to play music.\n\r", ch); return; } if ((instrument = get_eq_char(ch, WEAR_HOLD)) == NULL) { send_to_char("You aren't carrying an instrument.\n\r", ch); return; } if (instrument->item_type != ITEM_INSTRUMENT) { send_to_char("You aren't carrying an instrument.\n\r", ch); return; } if (argument[0] == '\0') { send_to_char("Play what?\n\r", ch); return; } songnum = song_lookup(argument); if (songnum == -1) { send_to_char("That isn't a song.\n\r", ch); return; } if (ch->level < bsong_table[songnum].level) { send_to_char("You haven't been able to master that song yet.\n\r", ch); return; } if (ch->position < bsong_table[songnum].minimum_position) { send_to_char("You need to be standing up to play that song.\n\r", ch); return; } mana = bsong_table[songnum].min_mana; if (!IS_NPC(ch) && ch->mana < mana) { send_to_char("You don't have enough mana.\n\r", ch); return; } act("$n plays a melody on $s $p.",ch,instrument,NULL,TO_ROOM); act("You play a melody on your $p.",ch,instrument,NULL,TO_CHAR); WAIT_STATE( ch, bsong_table[songnum].beats ); chance = chance - (20 / (1 + ch->level - bsong_table[songnum].level)); /* average of level of player and level of instrument */ level = (ch->level + instrument->level) / 2; if (number_percent() > chance) { ch->mana -= mana / 2; act("$n's fingers slip and the song ends abruptly.",ch,NULL,NULL,TO_ROOM); send_to_char("Your fingers slip and the song ends abruptly.\n\r", ch); check_improve(ch,skill_lookup("music"),FALSE,1); return; } else /* actually start playing the song */ { ch->mana -= mana; if (IS_NPC(ch) || has_spells( ch ) ) (*bsong_table[songnum].song_fun) ( songnum, level, ch ); else (*bsong_table[songnum].song_fun) ( songnum, 3 * level/4, ch ); check_improve(ch,skill_lookup("music"),TRUE,1); } return; } void song_of_huma( int songnum, int level, CHAR_DATA *ch ) { CHAR_DATA *vch; AFFECT_DATA af1, af2; af1.where = TO_AFFECTS; af1.type = skill_lookup("bless"); af1.level = level; af1.duration = level/2; af1.location = APPLY_HITROLL; af1.modifier = level/8; af1.bitvector = 0; af2.where = TO_AFFECTS; af2.type = skill_lookup("armor"); af2.level = level; af2.duration = level/2; af2.location = APPLY_AC; af2.modifier = -20; af2.bitvector = 0; if (!is_affected( ch, af1.type )) { act("$n glows briefly.",ch,NULL,NULL,TO_ROOM); send_to_char("You glow briefly.\n\r", ch); affect_to_char(ch,&af1); } if (!is_affected( ch, af2.type )) { act("$n is suddenly surrounded by a glowing suit of armor.",ch,NULL,NULL,TO_ROOM); send_to_char("You are suddenly surrounded by a glowing suit of armor.\n\r", ch); affect_to_char(ch,&af2); } for ( vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room ) { if (ch == vch) continue; if (!IS_NPC(vch)) { if (number_percent() <= 80 && !is_affected( vch, af1.type )) { act("$N glows briefly.",ch,NULL,vch,TO_ROOM); act("$N glows briefly.",ch,NULL,vch,TO_CHAR); send_to_char("You glow briefly.\n\r", vch); affect_to_char( vch, &af1 ); } if (number_percent() <= 80 && !is_affected( vch, af2.type )) { act("$N is suddenly surrounded by a glowing suit of armor.",ch,NULL,vch,TO_ROOM); act("$N is suddenly surrounded by a glowing suit of armor.",ch,NULL,vch,TO_CHAR); send_to_char("You are suddenly surrounded by a glowing suit of armor.\n\r", vch); affect_to_char( vch, &af2 ); } } } return; } void song_of_soothing( int songnum, int level, CHAR_DATA *ch) { CHAR_DATA *vch; int mlevel = 0; int count = 0; int high_level = 0; int chance; AFFECT_DATA af; int chance1; /* chances you put them to sleep */ chance1 = number_range( 1,100 ); /* get sum of all mobile levels in the room */ for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room) { if (vch->position == POS_FIGHTING) { count++; if (IS_NPC(vch)) mlevel += vch->level; else mlevel += vch->level/2; high_level = UMAX(high_level,vch->level); } } /* compute chance of stopping combat */ chance = 4 * level - high_level + 2 * count; if (IS_IMMORTAL(ch)) /* always works */ mlevel = 0; if (number_range(0, chance) >= mlevel) /* hard to stop large fights */ { for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room) { if (IS_SET(vch->imm_flags,IMM_MAGIC) || IS_SET(vch->act,ACT_UNDEAD)) return; if ( ch == vch ) return; if (IS_AFFECTED(vch,AFF_CALM) || IS_AFFECTED( vch, AFF_SLEEP) ||IS_AFFECTED(vch,AFF_BERSERK) || is_affected(vch,skill_lookup("frenzy"))) return; printf_to_char( ch, "A soothing wave of calm washes over %s\n\r", vch->name ); send_to_char("A soothing wave of calm washes over you.\n\r",vch); act("$n feels a soothing wave of calm wash over $m.",ch,NULL,NULL,TO_ROOM); if (vch->fighting || vch->position == POS_FIGHTING) stop_fighting(vch,FALSE); if ( IS_AWAKE(vch) && chance1 <= 25 ) { send_to_char( "You feel very sleepy ..... zzzzzz.\n\r", vch ); act( "$n goes to sleep.", vch, NULL, NULL, TO_ROOM ); vch->position = POS_SLEEPING; } af.where = TO_AFFECTS; af.type = skill_lookup( "calm" ); af.level = level; af.duration = level/4; af.location = APPLY_HITROLL; if (!IS_NPC(vch)) af.modifier = -5; else af.modifier = -2; af.bitvector = AFF_CALM; affect_to_char(vch,&af); af.type = skill_lookup( "sleep" ); af.location = APPLY_DAMROLL; af.modifier = -5; if ( chance1 <= 25 ) { af.bitvector = AFF_SLEEP; affect_join( vch, &af ); } } } } void song_of_paralysis( int songnum, int level, CHAR_DATA *ch) { CHAR_DATA *vch; for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room) { if (IS_NPC(vch)) { if (vch->fighting || vch->position == POS_FIGHTING) stop_fighting(vch,FALSE); vch->position = POS_STUNNED; WAIT_STATE( vch, 2 * PULSE_VIOLENCE ); act("$n falls into a heap, stunned.", vch, NULL, NULL, TO_ROOM); } } } void song_of_rage( int songnum, int level, CHAR_DATA *ch ) { AFFECT_DATA af1, af2; af1.where = TO_AFFECTS; af1.type = skill_lookup("bless"); af1.level = level; af1.duration = level/2; af1.location = APPLY_HITROLL; af1.modifier = level/8; af1.bitvector = 0; af2.where = TO_AFFECTS; af2.type = skill_lookup("frenzy"); af2.level = level; af2.duration = level/2; af2.location = APPLY_DAMROLL; af2.modifier = ch->level + 10/4; af2.bitvector = 0; if (is_affected(ch, af1.type)) { act("$n glows briefly.",ch,NULL,NULL,TO_ROOM); send_to_char("You glow briefly.\n\r",ch); affect_to_char(ch,&af1); } if (!is_affected(ch,af2.type)) { act("$n is suddenly feels much stronger and battleworthy.",ch,NULL,NULL,TO_ROOM); send_to_char("You feel stronger and more battle worthy.\n\r",ch); affect_to_char(ch,&af2); } return; }