/*************************************************************************** * 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! *** *** *** *************************************************************************** *************************************************************************** **************************************************************************/ #include "merc.h" #include "magic.h" #include "tables.h" #include "recycle.h" #include "songs.h" /* * Table for the songs of the MUD * add a new set of brackets for each new song you add, and dont forget * to increment MAX_SONGS in merc.h */ const struct song_type song_table [MAX_SONGS] = { /* { "Song name", "Song list name", level, song_fun, min position, min mana, beats } */ { "song of huma", "Song of Huma", 20, song_of_huma, POS_RESTING, 40, 25 }, { "tale of champions", "Tale of Champions", 1, tale_of_champions, POS_RESTING, 10, 10 }, { "hymn of thunder", "Hymn of Thunder", 5, hymn_of_thunder, POS_FIGHTING, 15, 25 }, { "legend of aegis", "Legend of Aegis", 40, aegis_legend, POS_RESTING, 200, 40 }, { "charm", "Charm", 44, song_charm, POS_STANDING, 20, 12 } }; ACMD(do_songs) { BUFFER *buffer; char arg[MAX_INPUT_LENGTH]; char song_list[LVL_HERO + 1][MAX_STRING_LENGTH]; int sn, level, min_lev = 1, max_lev = LVL_HERO; bool fAll = FALSE, found = FALSE; char buf[MAX_STRING_LENGTH], buf1[MSL]; if (IS_NPC(ch)) return; if (argument[0] != '\0') { fAll = TRUE; if (str_prefix(argument,"all")) { argument = one_argument(argument,arg); if (!is_number(arg)) { send_to_char("Arguments must be numerical or all.\n\r",ch); return; } max_lev = atoi(arg); if (max_lev < 1 || max_lev > LVL_HERO) { sprintf(buf,"Levels must be between 1 and %d.\n\r",LVL_HERO); send_to_char(buf,ch); return; } if (argument[0] != '\0') { argument = one_argument(argument,arg); if (!is_number(arg)) { send_to_char("Arguments must be numerical or all.\n\r",ch); return; } min_lev = max_lev; max_lev = atoi(arg); if (max_lev < 1 || max_lev > LVL_HERO) { sprintf(buf, "Levels must be between 1 and %d.\n\r",LVL_HERO); send_to_char(buf,ch); return; } if (min_lev > max_lev) { send_to_char("That would be silly.\n\r",ch); return; } } } } /* initialize data */ for (level = 0; level < LVL_HERO + 1; level++) { song_list[level][0] = '\0'; } for (sn = 0; sn < MAX_SONGS; sn++) { if (song_table[sn].name == NULL ) break; if ((level = song_table[sn].level) < LVL_HERO + 1 && (fAll || level <= ch->level) && level >= min_lev && level <= max_lev) { found = TRUE; level = song_table[sn].level; sprintf(buf,"%-20s %3d\n\r",song_table[sn].listname,song_table[sn].level); strcat(song_list[level],buf); } } /* return results */ if (!found) { send_to_char("No songs found.\n\r",ch); return; } buffer = new_buf(); sprintf(buf1, "%-18s %5s\n\r", "Song Name", "Level"); send_to_char(buf1,ch); send_to_char("`m------------------------`n\n\r",ch); for (level = 0; level < LVL_HERO + 1; level++) if (song_list[level][0] != '\0') add_buf(buffer,song_list[level]); page_to_char(buf_string(buffer),ch); free_buf(buffer); } /* looks up a song */ int song_lookup( const char *name ) { int songnum; for ( songnum = 0; songnum < MAX_SONGS; songnum++ ) { if ( song_table[songnum].name == NULL ) break; if ( LOWER(name[0]) == LOWER(song_table[songnum].name[0]) && !str_prefix( name, song_table[songnum].name ) ) return songnum; } return -1; } /* actually starts the playing process */ ACMD(do_play) { OBJ_DATA *instrument; char arg[MSL], buf[MSL]; int songnum, chance, mana, level, worth; one_argument(argument, arg); if ((chance = get_skill(ch,gsn_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 (arg[0] == '\0') { send_to_char("Play what?\n\r", ch); return; } songnum = song_lookup(arg); if (songnum == -1) { send_to_char("That isn't a song.\n\r", ch); return; } if (ch->level < song_table[songnum].level) { send_to_char("You haven't been able to master that song yet.\n\r",ch); return; } if (ch->position < song_table[songnum].minimum_position) { ch->Send("You can't do that while %s.", position_table[ch->position].name); return; } mana = UMAX(song_table[songnum].min_mana, 100 / (2+ch->level - song_table[songnum].level)); if (!IS_NPC(ch) && ch->mana < mana) { send_to_char("You don't have enough mana.\n\r", ch); return; } sprintf(buf, "You start playing '%s' on $p.",song_table[songnum].listname); act(buf,ch,instrument,NULL,TO_CHAR); sprintf(buf, "$n starts playing '%s' on $p.",song_table[songnum].listname); act(buf,ch,instrument,NULL,TO_ROOM); if (!IS_STAFF(ch)) WAIT_STATE( ch, song_table[songnum].beats ); chance = chance - (20 / (1 + ch->level - song_table[songnum].level)); /* average of level of player and level of instrument */ level = (ch->level + instrument->level) / 2; worth = instrument->cost; 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,gsn_music,FALSE,1); return; } else /* actually start playing the song */ { ch->mana -= mana; if (IS_NPC(ch) || class_table[ch->Class].fMana) (*song_table[songnum].song_fun) ( songnum, level, worth, ch,instrument); else (*song_table[songnum].song_fun) ( songnum, 3 * level/4, worth, ch, instrument); check_improve(ch,gsn_music,TRUE,1); } return; } /* SAMPLE SONG! This song casts armor and bless on the player, and theres an 80% chance for each spell for each person in the room that they will receive the effect also */ void song_of_huma( int songnum, int level, int worth, CHAR_DATA *ch, OBJ_DATA *inst) { 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_CHAR); act("You glow briefly.",ch,NULL,vch,TO_VICT); act("$N glows briefly.",ch,NULL,vch,TO_NOTVICT); 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_CHAR); act("You are suddenly surrounded by a glowing suit of armor.",ch,NULL,vch,TO_VICT); act("$N is suddenly surrounded by a glowing suit of armor.",ch,NULL,vch,TO_NOTVICT); affect_to_char( vch, &af2 ); } } } return; }