/
rogue24b3/
rogue24b3/data/
/***************************************************************************
 *  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;
}