/***************************************************************************
* 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[LEVEL_HERO + 1][MAX_STRING_LENGTH];
int sn, level, min_lev = 1, max_lev = LEVEL_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 > LEVEL_HERO)
{
sprintf(buf,"Levels must be between 1 and %d.\n\r",LEVEL_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 > LEVEL_HERO)
{
sprintf(buf,
"Levels must be between 1 and %d.\n\r",LEVEL_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 < LEVEL_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) < LEVEL_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 < LEVEL_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;
}