FlCodebase3.1/
FlCodebase3.1/bounty/
FlCodebase3.1/challenge/
FlCodebase3.1/clans/
FlCodebase3.1/gods/
FlCodebase3.1/mobprogs/
FlCodebase3.1/player/
FlCodebase3.1/savemud/
/***************************************************************************
 *  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 Envy Diku Mud, you must comply with   *
 *  the original Diku license in 'license.doc', the Merc license in        *
 *  'license.txt', as well as the Envy license in 'license.nvy'.           *
 *  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                     *
 *                                                                         *
 * Code Adapted and Improved by Abandoned Realms Mud                       *
 * and Aabahran: The Forsaken Lands Mud by Virigoth                        *
 *                                                                         *
 * Continued Production of this code is available at www.flcodebase.com    *
 ***************************************************************************/

#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include "merc.h"
#include "magic.h"
#include "song.h"
#include "jail.h"
#include "cabal.h"
#include "interp.h"

const   struct  song_type      song_table     [MAX_SONG]     =
{
    /* Songs for bards */
    {   
        "reserved",
     /* song level,     song rating */
	52, 		10,
     /* song function,  min position,       rafrain,	instrument? duet? */
        0,              POS_STANDING,	    FALSE,	FALSE,	    FALSE,
     /* point to gsn,   spell_type,	mana,   beats */
        NULL,           SPELL_OTHER,	0,      0,
     /* dam message,		mesg_off,	mesg_off2 */
        "",                     "",             ""
    },
    {   
        "Test Song",
	52, 		10,
        song_test,   	POS_FIGHTING,	TRUE,	TRUE,	TRUE,
        NULL,           SPELL_OTHER,	50,      12,
        "", 		"Test ended.", ""
    },
    {   
        "Lullaby",
	10, 		1,
        song_lullaby,   POS_STANDING,	FALSE,	FALSE,   FALSE,
        &gsn_lullaby,   SPELL_OTHER,	30,      12,
        "", 		"The lullaby wears off.", ""
    },
    {   
        "Herald of the Sky",
	13, 		1,
        song_wake,   	POS_STANDING,	FALSE,	FALSE,   TRUE,
        NULL,   SPELL_OTHER,	30,      12,
        "", 		"", ""
    },
    {   
        "Broken Spirit",
	52, 		1,
        song_calm,   	POS_FIGHTING,	FALSE,	TRUE,   TRUE,
        NULL,   SPELL_MENTAL,	65,      12,
        "", 		"You no longer feel as down spirited.", "$n doesn't look as down spirited."
    },
    {   
        "Ode to God",
	52, 		1,
        song_stryth,   	POS_STANDING,	FALSE,	TRUE,   FALSE,
        NULL,   SPELL_OTHER,	50,      12,
        "", 		"", ""
    },
    {   
        "A Soothing Melody",
	52, 		1,
        song_soothing,   POS_FIGHTING,	TRUE,	FALSE,   TRUE,
        NULL,   SPELL_OTHER,	20,      12,
        "", 		"", ""
    },
    {   
        "Rest Thy Feet",
	1, 		1,
        song_refresh,   POS_STANDING,	FALSE,	FALSE,   TRUE,
        NULL,   SPELL_OTHER,	25,      12,
        "", 		"", ""
    },
    {   
        "Travel of Solitary",
	52, 		1,
        song_disband,   POS_STANDING,	FALSE,	TRUE,   TRUE,
        NULL,   SPELL_MENTAL,	60,      24,
        "", 		"You no longer feel so solitary.", ""
    },
    {   
        "Weak of Mind and Body",
	42, 		1,
        song_weaken,   	POS_FIGHTING,	TRUE,	FALSE,   TRUE,
        NULL,   SPELL_MALEDICTIVE,	40,      12,
        "", 		"You don't feel as weak.", "$n looks stronger."
    },
    {   
        "Devils Dance",
	52, 		1,
        song_dance,   	POS_STANDING,	FALSE,	TRUE,   TRUE,
        &gsn_dance_song,   SPELL_MENTAL,	 50,      12,
        "", 		"You finally stop dancing.", "$n stops dancing."
    },
    {   
        "Four Seasons",
	45, 		1,
        song_four_seasons, POS_FIGHTING, TRUE,	TRUE,   TRUE,
        &gsn_seasons,   SPELL_AFFLICTIVE,	65,      12,
        "", 		"The four seasons ends.", ""
    },
    {   
        "Vertigo",
	52, 		1,
        song_disorient,   POS_FIGHTING,	TRUE,	TRUE,   TRUE,
        &gsn_disorient,   SPELL_MENTAL,	 45,      24,
        "", 		"You no longer feel as disoriented.", "$n no longer looks so disoriented."
    },
    {   
        "Paranoia",
	52, 		1,
        song_hysteria,   POS_FIGHTING,	TRUE,	TRUE,   TRUE,
        NULL,   SPELL_MENTAL,	45,      12,
        "", 		"", ""
    },
    {   
        "Water to Wine",
	 1, 		1,
        song_waterwine,   POS_STANDING,	FALSE,	FALSE,   FALSE,
        NULL,   SPELL_OTHER,	15,      12,
        "", 		"", ""
    },
    {   
        "Intoxify My Mind",
	52, 		1,
        song_intoxify,   POS_STANDING,	FALSE,	FALSE,   TRUE,
        NULL,   SPELL_OTHER,	20,      12,
        "", 		"", ""
    },
    {   
        "Clash of Titans",
	30, 		1,
        song_titan,   	POS_FIGHTING,	TRUE,	TRUE,   TRUE,
        NULL,   SPELL_AFFLICTIVE,	35,      12,
        "earthquake", 		"", ""
    },
    {   
        "Twilight of Faeries",
	52, 		1,
        song_faeries,   POS_STANDING,	FALSE,	TRUE,   TRUE,
        NULL,   SPELL_OTHER,	50,      12,
        "", 		"", ""
    },
    {   
        "Flight of the Condor",
	33, 		1,
        song_condor,   	POS_STANDING,	FALSE,	TRUE,   FALSE,
        &gsn_condor,   SPELL_OTHER,	45,      12,
        "", 		"The condors soar away.", "The condors soar away."
    },
    {   
        "Battle Hymn",
	21, 		1,
        song_battle,   	POS_FIGHTING,	FALSE,	TRUE,   FALSE,
        NULL,   SPELL_OTHER,	35,      12,
        "", 		"The battle hymn leaves your mind.", ""
    },
    {   
        "Shield of Words",
	16, 		1,
        song_shield_words,   	POS_STANDING,	FALSE,	FALSE,   FALSE,
        NULL,   SPELL_OTHER,	30,      12,
        "", 		"The verses of the ancients no longer protects you.", ""
    },
    {   
        "Good Tidings",
	4, 		1,
        song_tidings,   POS_STANDING,	FALSE,	FALSE,   FALSE,
        NULL,   SPELL_OTHER,	20,      12,
        "", 		"You don't feel as lucky.", ""
    },
    {   
        "Legend of Hercules",
	19, 		1,
        song_hercules,   POS_STANDING,	FALSE,	FALSE,   FALSE,
        NULL,   SPELL_OTHER,	25,      12,
        "", 		"You no longer feel as strong.", "$n doesn't look as strong."
    },
    {   
        "Weight of Burden",
	52, 		1,
        song_burden,   	POS_STANDING,	FALSE,	FALSE,   TRUE,
        NULL,   SPELL_MALEDICTIVE,	35,      12,
        "", 		"Your load feels lighter.", "$n looks more relieved."
    },
    {   
        "Marriage Song",
	3, 		1,
        song_marriage,   POS_STANDING,	FALSE,	TRUE,   TRUE,
        NULL,   SPELL_OTHER,	100,      12,
        "", 		"", ""
    },
    {   
        "Mourn for the Lost",
	52, 		1,
        song_mourn,   	POS_STANDING,	FALSE,	TRUE,   FALSE,
        NULL,   SPELL_OTHER,	35,      12,
        "", 		"The death of your comrade no longer affects you.", ""
    },
    {   
        "Rest in Peace",
	39, 		1,
        song_rest,   	POS_STANDING,	FALSE,	TRUE,   TRUE,
        NULL,   SPELL_OTHER,	50,      12,
        "", 		"Your are animated once more.", "$n is animated once again."
    },
    {   
        "Birth of the Phoenix",
	52, 		1,
        song_phoenix,   POS_STANDING,	FALSE,	TRUE,   TRUE,
        &gsn_phoenix,   SPELL_OTHER,	200,      24,
        "", 		"", ""
    },
    {   
        "Emancipation",
	52, 		1,
        song_eman,   	POS_STANDING,	FALSE,	TRUE,   TRUE,
        NULL,   SPELL_MENTAL,	55,      12,
        "", 		"", ""
    },
    {   
        "Healing of Laughter",
	52, 		1,
        song_laughter,   POS_STANDING,	FALSE,	FALSE,   TRUE,
        NULL,   SPELL_OTHER,	40,      24,
        "", 		"", ""
    },
    {   
        "Scourge of Black Widow",
	52, 		1,
        song_spider,   	POS_FIGHTING,	FALSE,	TRUE,   TRUE,
        NULL,   SPELL_AFFLICTIVE,	65,      24,
        "", 		"", ""
    },
    {   
        "Mystery of the Unicorn",
	48, 		1,
        song_unicorn,   POS_STANDING,	FALSE,	TRUE,   FALSE,
        NULL,   SPELL_OTHER,	45,      12,
        "", 		"You are no longer protected by the magic of the unicorns.", ""
    },
    {
        "Complete Focus",
	52, 		10,
        song_accuracy,   POS_STANDING,	FALSE,	TRUE,   FALSE,
        &gsn_concen,   SPELL_OTHER,	60,      24,
        "", 		"", ""
    },
    {
        "Sharp Discord",
	52, 		1,
        song_shriek,   	POS_FIGHTING,	TRUE,	FALSE,   TRUE,
        NULL,   SPELL_AFFLICTIVE,	25,      24,
        "shriek", 		"", ""
    },
    {
        "Remembrance",
	36, 		1,
        song_memories,   POS_STANDING,	FALSE,	TRUE,   TRUE,
        NULL,   SPELL_OTHER,	40,      12,
        "", 		"", ""
    },
    {
        "Serenade",
	2, 		1,
        song_serenade,   POS_STANDING,	FALSE,	TRUE,   TRUE,
        NULL,   SPELL_OTHER,	5,      12,
        "", 		"", ""
    },
    {
        "Leviathans Passing",
	7, 		1,
        song_leviathon,  POS_STANDING,	FALSE,	FALSE,   FALSE,
        NULL,   SPELL_OTHER,	15,      12,
        "", 		"", ""
    },
    {
        "Lust Seduction Desire",
	52, 		1,
        song_lust,   	POS_STANDING,	FALSE,	TRUE,   TRUE,
        &gsn_lust,   SPELL_OTHER,	40,      12,
        "", 		"Your hormones level off.", ""
    },
    {
        "A Kings Feast",
	24, 		1,
        song_feast,   	POS_STANDING,	FALSE,	FALSE,   TRUE,
        NULL,   SPELL_OTHER,	30,      12,
        "", 		"", ""
    },
    {
        "Let it be Known",
	27, 		1,
        song_reputation,   POS_STANDING, FALSE,	FALSE,   TRUE,
        &gsn_reputation,   SPELL_OTHER,	20,      12,
        "", 		"Your reputation is no longer as well known.", ""
    },
    {
        "Victory Be Ours",
	52, 		1,
        song_victory,   POS_STANDING,	FALSE,	TRUE,   TRUE,
        NULL,   SPELL_OTHER,	20,      12,
        "", 		"", ""
    },
    {
        "Unforgiven",
	52, 		1,
        song_unforgiven, POS_STANDING, FALSE,	TRUE,   TRUE,
        &gsn_unforgiven,   SPELL_MENTAL,	50,      18,
        "", 		"", ""
    }
};

char * random_garble(int length)
{
    int pos = 0, word = 0, i = 0, j = 0, 
	wlength = number_range(UMAX(2,UMIN(4,length/7)),UMAX(3,UMIN(7,length/4)));
    char buf[MSL], temp;
    for (i = 0;i < wlength;i++)
    {
	word = number_range(UMAX(2,UMIN(4,length/7)),UMAX(4,UMIN(7,length/4)));
	for (j = 0;j < word;j++)
	{
	    if (number_percent() < 50)
		temp = 'A' + number_range (0,25);
	    else
		temp = 'a' + number_range (0,25);
	    buf[pos++] = temp;
	}
	buf[pos++] = ' ';
    }
    buf[pos] = '\0';
    return (str_dup(buf));
}

void song_to_room(CHAR_DATA *ch, char *argument, bool brief, bool sleep, bool duet)
{
    CHAR_DATA *vch;
    if (duet && ch->pcdata->duet)
	ch = ch->pcdata->duet;
    if (ch->in_room == NULL)
	return;
    makedrunk(argument,ch);
    act("You sing '`6$t``'",ch,argument,NULL,TO_CHAR);
    for (vch = ch->in_room->people;vch != NULL; vch = vch->next_in_room)
    {
	if (!sleep && !IS_AWAKE(vch))
	    continue;
	if (brief && IS_SET(vch->comm,COMM_BRIEF))
	    continue;
	if (vch == ch)
	    continue;
	act("$n sings '`6$t``'",ch,argument,vch,TO_VICT);
    }
}

void duet_song_to_room(CHAR_DATA *ch, CHAR_DATA *partner, char *argument, bool brief, bool sleep)
{
    CHAR_DATA *vch;
    char buf[MSL];
    if (ch->in_room == NULL || partner->in_room == NULL)
	return;
    makedrunk(argument,ch);
    makedrunk(argument,partner);
    act("You sing together with $N '`6$t``'",ch,argument,partner,TO_CHAR);
    act("You sing together with $N '`6$t``'",partner,argument,ch,TO_CHAR);
    for (vch = ch->in_room->people;vch != NULL; vch = vch->next_in_room)
    {
	if (!sleep && !IS_AWAKE(vch))
	    continue;
	if (brief && IS_SET(vch->comm,COMM_BRIEF))
	    continue;
	if (vch == ch || vch == partner)
	    continue;
	sprintf(buf,"%s and %s sings together '`6%s``'",PERS(ch,vch),PERS(partner,vch),argument);
	act(buf,vch,NULL,NULL,TO_CHAR);
    }
}

void s_yell( CHAR_DATA *ch, CHAR_DATA *victim, bool force )
{
  char buf[MSL];
  if (ch == NULL || victim == NULL)
    return;
  if (ch->fighting != victim && victim->fighting != ch && (!IS_NPC(ch) || ch->master != NULL)){
    if (!IS_NPC(victim)){
      sprintf(buf,"%s attacked %s at %d", IS_NPC(ch) ? ch->short_descr : ch->name, 
	      victim->name,ch->in_room->vnum);
      log_string(buf);
      wiznet(buf,NULL,NULL,WIZ_FIGHTING,0,0);
      continuum(victim, CONTINUUM_ATTACK);
     
/* MURDER CRIME CHECK */
      if (ch->in_room && is_crime(ch->in_room, CRIME_MURDER, victim)){
	set_crime(ch, victim, ch->in_room->area, CRIME_MURDER);
	
	/* check of simulacra for justices */
	if (is_affected(ch, gsn_doppelganger)){
	  char buf[MIL];
	  sprintf( buf, "Warning! Someone seems to be masquerading as %s!",
		   PERS2(ch));
	  cabal_echo_flag( CABAL_JUSTICE | CABAL_HEARGUARD, buf );
	}
      }
/* ATTACKING JUSTICE IN LAWFUL AREA IS ALWAYS AN OBSTRUCTION */
      else if (victim->pCabal && IS_CABAL(victim->pCabal, CABAL_JUSTICE) && IS_AREA(ch->in_room->area, AREA_LAWFUL)){
	set_crime(ch, victim, ch->in_room->area, CRIME_OBSTRUCT);
      }
      /* CONTINENCY */
      check_contingency(ch, NULL, CONT_ATTACK);
      check_contingency(victim, NULL, CONT_ATTACKED);

    }//END PC CHECK
    else {
      bool fCrime = FALSE;
/* ASSAULT CRIME CHECK */
      if (ch->in_room && is_crime(ch->in_room, CRIME_ASSAULT, victim)){
	set_crime(ch, victim, ch->in_room->area, CRIME_ASSAULT);
	fCrime = TRUE;
      }
/* ATTACKING JUSTICE MOBS IN LAWFUL AREA IS ALWYAS A CRIME */
      else if (victim->pCabal && IS_CABAL(victim->pCabal, CABAL_JUSTICE) && IS_AREA(ch->in_room->area, AREA_LAWFUL)){
	set_crime(ch, victim, ch->in_room->area, CRIME_OBSTRUCT);
	fCrime = TRUE;
      }
/* attackign charmed mobs requiers a yell as well */
      else if (IS_NPC(victim) && IS_AFFECTED(victim, AFF_CHARM))
	fCrime = TRUE;

      if (IS_SET(victim->off_flags,GUILD_GUARD) && victim->pCabal && IS_CABAL(victim->pCabal, CABAL_JUSTICE)){
	sprintf(buf, "%s: Alert! The jail is being attacked!", ch->in_room->area->name);
	cabal_echo_flag( CABAL_JUSTICE, buf );
	sprintf(buf, "Alert! The jail is being attacked by %s!",PERS(ch,victim));
      }
      else if (IS_SET(victim->off_flags,GUILD_GUARD))
	sprintf(buf, "Alert! The guild is being attacked by %s!",PERS(ch,victim));
      else
	sprintf(buf, "Die! %s, you singing fool!",PERS(ch,victim));
      
      if (fCrime){
	REMOVE_BIT(victim->comm,COMM_NOCHANNELS);
	REMOVE_BIT(victim->comm,COMM_NOYELL);
	j_yell(victim,buf);
	SET_BIT(victim->comm,COMM_NOYELL);
	SET_BIT(victim->comm,COMM_NOCHANNELS);
      }
    }//END NPC CHECK
  }
}

int sglevel(CHAR_DATA *ch, int sn)
{
    if IS_NPC(ch)
        return 1000;
    else if (song_table[sn].skill_level != 69)
        return UMIN(52,song_table[sn].skill_level);
    else
	return 1000;
}

int song_lookup( const char *name )
{
    int sn;
    for ( sn = 0; sn < MAX_SONG; sn++ )
    {
        if ( song_table[sn].name == NULL )
            break;
        if ( LOWER(name[0]) == LOWER(song_table[sn].name[0]) && !str_prefix( name, song_table[sn].name ) )
            return sn;
    }
    return -1;
}  

int get_song(CHAR_DATA *ch, int sn)
{
    int skill;
    if (sn == -1)
        skill = ch->level * 5 / 2;
    else if (sn < -1 || sn > MAX_SONG)
    {   
        bug("Bad sn %d in get_song.",sn);
        skill = 0;
    }
    else if (ch->trust == 6969)
        skill = 100;
    else if (is_affected(ch,gsn_ecstacy))
        return 0;
    else if (!IS_NPC(ch))
    {
        if (sglevel(ch,sn) > ch->level)
            skill = 0;
        else
            skill = ch->pcdata->songlearned[sn];
    }
    else
    {
        if (song_table[sn].song_fun != song_null)
            skill = 40 + 2 * ch->level;
	else
	    skill = 0;
    }
    if ( !IS_NPC(ch) && (is_affected(ch,gsn_drunken) || ch->pcdata->condition[COND_DRUNK]  > 10 ))
        skill = 9 * skill / 10;
    if ( is_affected(ch,gsn_hysteria) )
        skill /= 2;
    return URANGE(0,skill,100);
}

int find_song( CHAR_DATA *ch, const char *name )
{
    int sn, found = -1;
    if (IS_NPC(ch))
        return song_lookup(name);
    for ( sn = 0; sn < MAX_SONG; sn++ )
    {
        if (song_table[sn].name == NULL)
            break;
        if (LOWER(name[0]) == LOWER(song_table[sn].name[0])
        && !str_prefix(name,song_table[sn].name))
        {
            if ( found == -1)
                found = sn;
            if (ch->level >= sglevel(ch,sn) && ch->pcdata->songlearned[sn] > 0)
                return sn;
        }
    }
    return found; 
}

void check_improve_song( CHAR_DATA *ch, int sn, bool success, int multiplier )
{
    int chance;
    if (IS_NPC(ch))
        return;
    if (ch->level < sglevel(ch,sn) || song_table[sn].rating == 0
    || ch->pcdata->songlearned[sn] == 0 || ch->pcdata->songlearned[sn] == 100)
        return;
    if (multiplier == -99)
    {
        sendf(ch,"You have become better at %s!\n\r", song_table[sn].name);
        ch->pcdata->songlearned[sn]++;
        gain_exp(ch,song_table[sn].rating);
        return;
    }
    chance = 10 * int_app[get_curr_stat(ch,STAT_INT)].learn;
    chance /= ( multiplier * song_table[sn].rating * 10);
    chance += ch->level / 2;
    chance += get_curr_stat(ch,STAT_WIS) / 2;
    if (!success)
        chance /=2;
    if (number_range(1,1000) > chance)
        return;   
    if (success)
    {
        chance = URANGE(5,100 - ch->pcdata->songlearned[sn], 95);
        if (IS_IMMORTAL(ch) && ch->wimpy == 69)
            chance += 50;
        if (number_percent() < chance)
        {
            sendf(ch,"You have become better at %s!\n\r", song_table[sn].name);
            ch->pcdata->songlearned[sn]++;
            gain_exp(ch,song_table[sn].rating);
        }
    }
    else
    {
        chance = URANGE(5,ch->pcdata->songlearned[sn]/2,30);
        if (number_percent() < chance)
        {
            sendf(ch,"You learn from your mistakes, and your %s song improves.\n\r",song_table[sn].name);
            ch->pcdata->songlearned[sn] += number_range(1,3);
            ch->pcdata->songlearned[sn] = UMIN(ch->pcdata->songlearned[sn],100);
            gain_exp(ch,song_table[sn].rating);
        }
    }   
}

void song_strip( CHAR_DATA *ch, int sn )
{
    AFFECT_DATA *paf, *paf_next;
    for ( paf = ch->affected2; paf != NULL; paf = paf_next )
    {
        paf_next = paf->next;  
        if ( paf->type == sn )
            song_affect_remove( ch, paf);
    }
}

bool check_instrument( CHAR_DATA *ch )
{
    OBJ_DATA *obj;
    if ((obj = get_eq_char(ch,WEAR_WIELD)) != NULL
	&& obj->item_type == ITEM_INSTRUMENT)
      return TRUE;
    if ((obj = get_eq_char(ch,WEAR_HOLD)) != NULL
	&& obj->item_type == ITEM_INSTRUMENT)
      return TRUE;
    return FALSE;
}

void do_sing( CHAR_DATA *ch, char *argument )
{
    CHAR_DATA *vch, *partner = NULL;
    char arg1[MIL];
    int mana, mana2 = 50, sn, concen, concen2 = 0, dchance, sn2 = skill_lookup("duet");
    bool duet = FALSE, found = FALSE, passed = TRUE, sdouble = FALSE;
    if (!IS_IMMORTAL(ch) && ch->class != class_lookup("bard"))
    {
	send_to_char("You think you're a bard?\n\r",ch);
	return;
    }
    if (is_affected(ch, gsn_forget))
    {
        send_to_char("You seem to have forgotten all your songs.\n\r",ch);   
        return;
    }
    if (is_affected(ch, gsn_garble))
    {
        send_to_char("You can't get the right lyrics.\n\r", ch);
        return;
    }
    if (is_affected(ch, gsn_headbutt))
    {
        send_to_char("Your head is still spinning, you can't focus enough.\n\r",ch);
        return;
    }
    if (IS_AFFECTED2(ch, AFF_SILENCE))
    {
	send_to_char("You try to sing, but no words come out of your mouth!\n\r",ch);
	return;
    }
    if (is_affected(ch,gsn_uppercut))
    {
	send_to_char("Your jaws hurt too much to move!\n\r",ch);
	return;
    }
    if (is_affected(ch,gsn_refrain) || is_song_affected(ch,gsn_seasons))
    {
	send_to_char("You mind is not clear enough to sing another song right now.\n\r",ch);
	return;
    }
    argument = one_argument( argument, arg1 );
    if ( arg1[0] == '\0' )
    {
        send_to_char( "Sing which what where?\n\r", ch );
        return;
    }
    if (!str_cmp(arg1,"freeverse"))
    {
	song_to_room(ch,argument,FALSE,FALSE,FALSE);
	return;
    }
    if ((sn = find_song(ch,arg1)) < 1 || song_table[sn].song_fun == song_null  
    || (!IS_NPC(ch) && (ch->level < sglevel(ch,sn) || ch->pcdata->songlearned[sn] == 0)))
    {
        send_to_char( "You don't know any songs of that name.\n\r", ch );
        return;
    }
    if ( ch->position < song_table[sn].minimum_position )
    {
        send_to_char( "You can't concentrate enough.\n\r", ch );    
        return;
    }
    if (song_table[sn].instrument && !check_instrument( ch ) )
    {
	send_to_char("You require an instrument to sing this song.\n\r",ch);
	return;
    }
    if (ch->level + 2 == sglevel(ch,sn))
      mana = 50;
    else
      mana = UMAX( song_table[sn].min_mana, 100 / ( 2 + ch->level - sglevel(ch,sn) ) );
    
    if (song_table[sn].instrument){
      OBJ_DATA* obj = get_eq_char(ch,WEAR_WIELD);
      if (obj){
	act("$n strikes a sweet melody on $p.", ch, obj, NULL, TO_ROOM);
	act("You strike a sweet melody on $p.", ch, obj, NULL, TO_CHAR);
	mana /= 2;
      }
    }

    if ( !IS_NPC(ch) && ch->mana < mana && !IS_IMMORTAL(ch)) 
    {
        send_to_char( "You don't have enough mana.\n\r", ch );
        return; 
    }
    if (!IS_NPC(ch) && (partner = ch->pcdata->duet) != NULL)
    {
	for (vch = ch->in_room->people;vch != NULL;vch = vch->next_in_room)
	{
	    if (!IS_NPC(vch) && partner == vch 
		&& vch->pcdata->duet != NULL && vch->pcdata->duet == ch)
	    {
		found = TRUE;
		break;
	    }
	}
    }
    while (found)
    {
    	act("$n prepares to sing '$t' in a duet.",ch,song_table[sn].name,NULL,TO_ROOM);
    	act("You prepare to sing '$t' in a duet.",ch,song_table[sn].name,NULL,TO_CHAR);
    	if (is_affected(partner, gsn_forget))
    	{
    	    send_to_char("You seem to have forgotten all your songs.\n\r",partner);   
	    act("$N has difficulties singing this song.",ch,NULL,partner,TO_CHAR);
	    passed = FALSE;
	    break;
    	}
    	if (is_affected(partner, gsn_garble))
    	{
    	    send_to_char("You can't get the right lyrics.\n\r", partner);
	    act("$N has difficulties singing this song.",ch,NULL,partner,TO_CHAR);
	    passed = FALSE;
	    break;
    	}
    	if (is_affected(partner, gsn_headbutt))
    	{
    	    send_to_char("Your head is still spinning, you can't focus enough.\n\r",partner);
	    act("$N has difficulties singing this song.",ch,NULL,partner,TO_CHAR);
	    passed = FALSE;
	    break;
    	}
    	if (IS_AFFECTED2(partner, AFF_SILENCE))
    	{
	    send_to_char("You try to sing, but no words come out of your mouth!\n\r",partner);
	    act("$N has difficulties singing this song.",ch,NULL,partner,TO_CHAR);
	    passed = FALSE;
	    break;
    	}
    	if (is_affected(ch,gsn_uppercut))
    	{
	    send_to_char("Your jaws hurt too much to move!\n\r",partner);
	    act("$N has difficulties singing this song.",ch,NULL,partner,TO_CHAR);
	    passed = FALSE;
	    break;
    	}
    	if (is_affected(partner,gsn_refrain))
    	{
	    send_to_char("You mind is not clear enough to sing another song right now.\n\r",partner);
	    act("$N has difficulties singing this song.",ch,NULL,partner,TO_CHAR);
	    passed = FALSE;
	    break;
    	}
        if (partner->level < sglevel(partner,sn) || partner->pcdata->songlearned[sn] == 0)
    	{
            act( "$N doesn't know that song.",ch,NULL,partner,TO_CHAR);
            act( "You don't know that song.",ch,NULL,partner,TO_VICT);
	    passed = FALSE;
	    break;
    	}
    	if ( partner->position < song_table[sn].minimum_position )
    	{
    	    act( "$N can't concentrate enough.", ch,NULL,partner,TO_CHAR );    
    	    act( "You can't concentrate enough.", ch,NULL,partner,TO_VICT );    
	    passed = FALSE;
	    break;
    	}
    	if (song_table[sn].instrument && !check_instrument( partner ) )
    	{
	    act("$N requires an instrument to sing this song.",ch,NULL,partner,TO_CHAR);
	    act("You require an instrument to sing this song.",ch,NULL,partner,TO_VICT);
	    passed = FALSE;
	    break;
    	}
	dchance = number_percent();
	if (get_skill(ch,sn2) < dchance || get_skill(partner,sn2) < dchance)
	{
	    act("You failed to harmonize with $N.",ch,NULL,partner,TO_CHAR);
	    act("You failed to harmonize with $n.",ch,NULL,partner,TO_VICT);
	    passed = FALSE;
	    break;
	}
    	concen2 = get_song(partner,sn);
    	if (concen2 > 0)
    	{
    	    concen2 += get_curr_stat(partner,STAT_LUCK) - 16;
    	    if (is_affected(partner,gsn_prayer))
    	        concen2 += UMIN(5,.3*(100 - concen2));
	    if (is_song_affected(partner,gsn_concen))
	    {
	    	concen2 += concen2 / 3;
	    	song_strip(partner,gsn_concen);
	    }
    	}
        if (partner->level + 2 == sglevel(partner,sn))
            mana2 = 50;
        else
            mana2 = UMAX( song_table[sn].min_mana, 100 / ( 2 + partner->level - sglevel(partner,sn) ) );
    	if ( !IS_NPC(partner) && partner->mana < mana2 && !IS_IMMORTAL(partner)) 
    	{
    	    send_to_char( "You don't have enough mana.\n\r", partner );
	    act("$N doesn't have enough mana to sing with you.",ch,NULL,partner,TO_CHAR);
	    passed = FALSE;
    	    break; 
    	}
	break;
    }
    if (!found)
    {
    	act("$n prepares to sing '$t'.",ch,song_table[sn].name,NULL,TO_ROOM);
    	act("You prepare to sing '$t'.",ch,song_table[sn].name,NULL,TO_CHAR);
    }
    if (!IS_IMMORTAL(ch))
        WAIT_STATE2( ch, song_table[sn].beats );
    concen = get_song(ch,sn);
    if (concen > 0)
    {
        concen += get_curr_stat(ch,STAT_LUCK) - 16;
        if (is_affected(ch,gsn_prayer))
            concen += UMIN(5,.3*(100 - concen));
	if (is_song_affected(ch,gsn_concen))
	{
	    concen += concen/3;
	    song_strip(ch,gsn_concen);
	}
    }
    if ( (IS_NPC(ch) && ch->desc == NULL && !ch->pIndexData->progtypes) || number_percent() > concen )
    {
        send_to_char( "You lost your concentration.\n\r", ch );
	if (found)
	    act("$n lost $s concentration.",ch,NULL,partner,TO_VICT);
        check_improve_song(ch,sn,FALSE,1);
        if (!IS_IMMORTAL(ch))
             ch->mana -= mana / 2;
    }
    else 
    {
	if ( found && passed && number_percent() > concen2 )
    	{
    	    send_to_char( "You lost your concentration.\n\r", partner );
    		act("$N lost $S concentration.",ch,NULL,partner,TO_CHAR);
    	    check_improve_song(partner,sn,FALSE,1);
	    passed = FALSE;
    	    if (!IS_IMMORTAL(partner))
            	partner->mana -= mana2 / 2;
	}
    	if (found)
    	{
	    if (passed)
	    {
		duet = TRUE;
        	check_improve(ch,sn2,TRUE,1);
        	check_improve(partner,sn2,TRUE,1);
		sdouble = song_table[sn].duet;
	    }
	    else
		send_to_char("You'll have to sing this song yourself.\n\r",ch);
	}
	if (duet)
	{
	    if (sdouble)
	    {
                if (!IS_IMMORTAL(ch))
            	    ch->mana -= 2*mana/3;
		if (!IS_IMMORTAL(partner))
            	    partner->mana -= 2*mana2/3;
	    }
	    else
	    {
		if (!IS_IMMORTAL(ch))
            	    ch->mana -= mana/3;
        	if (!IS_IMMORTAL(partner))
            	    partner->mana -= mana2/3;
	    }
	}
	else if (!IS_IMMORTAL(ch))
            ch->mana -= mana;
        (*song_table[sn].song_fun) ( sn, ch->level, ch, duet, TRUE, argument);
	if (duet && sdouble)
	{
            (*song_table[sn].song_fun) ( sn, partner->level, partner, duet, FALSE, argument);	
            check_improve_song(partner,sn,TRUE,1);
	}
        check_improve_song(ch,sn,TRUE,1);
    }
}

bool refrain_sing( CHAR_DATA *ch, int sn )
{
    int mana, concen;
    if (is_affected(ch, gsn_forget))
    {
        send_to_char("You seem to have forgotten all your songs.\n\r",ch);   
        return FALSE;
    }
    if (is_affected(ch, gsn_garble))
    {
        send_to_char("You can't get the right lyrics.\n\r", ch);
        return FALSE;
    }
    if (is_affected(ch, gsn_headbutt))
    {
        send_to_char("Your head is still spinning, you can't focus enough.\n\r",ch);
        return FALSE;
    }
    if (IS_AFFECTED2(ch, AFF_SILENCE))
    {
	send_to_char("You try to sing, but no words come out of your mouth!\n\r",ch);
	return FALSE;
    }
    if (is_affected(ch,gsn_uppercut))
    {
	send_to_char("Your jaws hurt too much to move!\n\r",ch);
	return FALSE;
    }
    if ( ch->position < song_table[sn].minimum_position )
    {
        send_to_char( "You can't concentrate enough.\n\r", ch );    
        return FALSE;
    }
    if (song_table[sn].instrument && !check_instrument( ch ) )
    {
	send_to_char("You require an instrument to sing this song.\n\r",ch);
	return FALSE;
    }
    if (ch->level + 2 == sglevel(ch,sn))
        mana = 50;
    else
        mana = UMAX( song_table[sn].min_mana, 100 / ( 2 + ch->level - sglevel(ch,sn) ) );
    if ( !IS_NPC(ch) && ch->mana < mana && !IS_IMMORTAL(ch)) 
    {
        send_to_char( "You don't have enough mana.\n\r", ch );
        return FALSE; 
    }
    act("$n refrains '$t'.",ch,song_table[sn].name,NULL,TO_ROOM);
    act("You refrain '$t'.",ch,song_table[sn].name,NULL,TO_CHAR);
    concen = get_song(ch,sn);
    if (concen > 0)
    {
        concen += get_curr_stat(ch,STAT_LUCK) - 16;
        if (is_affected(ch,gsn_prayer))
            concen += UMIN(5,.3*(100 - concen));
	if (is_song_affected(ch,gsn_concen))
	{
	    concen += concen/3;
	    song_strip(ch,gsn_concen);
	}
    }
    if ( (IS_NPC(ch) && ch->desc == NULL && !ch->pIndexData->progtypes) || number_percent() > concen )
    {
        send_to_char( "You lost your concentration.\n\r", ch );
        check_improve_song(ch,sn,FALSE,1);
        if (!IS_IMMORTAL(ch))
             ch->mana -= mana / 2;
	return TRUE;
    }
    else
    {
        if (!IS_IMMORTAL(ch))
            ch->mana -= mana;
        (*song_table[sn].song_fun) ( sn, ch->level, ch, FALSE, TRUE, "");
        check_improve_song(ch,sn,TRUE,1);
	return TRUE;
    }
    return TRUE;
}

void do_refrain( CHAR_DATA *ch, char *argument)
{
    char arg[MIL];
    int chance, sn;
    AFFECT_DATA af;
    one_argument(argument,arg);
    if ( IS_NPC(ch) )
	return;
    if ( (chance = get_skill(ch,gsn_refrain) ) == 0 )
    {
	send_to_char("You cannot keep any melodies in your head.\n\r",ch);
	return;
    }
    if (is_affected(ch,gsn_refrain) || is_song_affected(ch,gsn_seasons))
    {
	send_to_char("You cannot refrain another song at the moment.\n\r",ch);
	return;
    }
    if ( arg[0] == '\0' )
    {
        send_to_char( "Sing which what where?\n\r", ch );
        return;
    }
    if ((sn = find_song(ch,arg)) < 1 || song_table[sn].song_fun == song_null  
    || (!IS_NPC(ch) && (ch->level < sglevel(ch,sn) || ch->pcdata->songlearned[sn] == 0)))
    {
        send_to_char( "You don't know any songs of that name.\n\r", ch );
        return;
    }
    if ( ch->position < song_table[sn].minimum_position )
    {
        send_to_char( "You can't concentrate enough.\n\r", ch );    
        return;
    }
    if (!song_table[sn].refrain)
    {
	send_to_char("This song cannot be refrained.\n\r",ch);
	return;
    }
    if (!IS_IMMORTAL(ch))
        WAIT_STATE2( ch, song_table[sn].beats );
    if ( chance < number_percent() || !refrain_sing(ch,sn) )
    {
	send_to_char( "You failed.\n\r",ch);
	check_improve(ch,gsn_refrain,FALSE,1);
	return;
    }
    else
    {
    	af.where     = TO_AFFECTS;
    	af.type      = gsn_refrain;
    	af.level     = ch->level;
    	af.duration  = 0;
    	af.modifier  = sn;  
    	af.location  = APPLY_NONE;
    	af.bitvector = 0;
    	affect_to_char( ch, &af );
	send_to_char("You refrain the song in your head.\n\r",ch);
    }
}

void song_null( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    send_to_char( "That's not a song!\n\r", ch );
}

void song_test( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
//    AFFECT_DATA af;
    char buf[MSL];
//    CHAR_DATA *vch;
    if (sing)
    {
    	sprintf(buf,"This is a test...");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    }
}

void song_lullaby( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    AFFECT_DATA af;
    char buf[MSL];
    CHAR_DATA *vch;
    if (sing)
    {
    	sprintf(buf,"Lay at rest and feel the peace,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"With a song, the pain will cease.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Close thy eyes, the wounds will heal,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Breathe real slow, the cuts will seal.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"This deep sleep, with lullaby,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"You'll awake, with time gone by.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (is_song_affected(vch,sn) || ch == vch)
	    continue;
	if (vch->master == ch || is_same_group(vch, ch))
	{
    	    af.where     = TO_AFFECTS;
    	    af.type      = sn;
    	    af.level     = level;
    	    af.duration  = 8;
    	    af.modifier  = 0;  
    	    af.location  = 0;
    	    af.bitvector = AFF_SLEEP;
    	    song_affect_to_char( vch, &af );
	    if (is_affected(ch,gsn_insomnia))
	      affect_strip(ch,gsn_insomnia);
            if ( IS_AWAKE(vch) ){
	      send_to_char( "Your eyelids feel heavy and you drift into a peaceful slumber.\n\r", vch);
	      do_sleep(vch,"");
	      act("$n is drained and falls asleep.",vch,NULL,NULL,TO_ROOM);
            }
	    else
	      act("$n falls into a deep slumber.",vch,NULL,NULL,TO_ROOM);
	}
    }
}
 
void song_wake( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"No longer rest your weary bones,");
    	song_to_room(ch,buf,TRUE,TRUE,FALSE);
    	sprintf(buf,"Wake now to these warming tones.");
    	song_to_room(ch,buf,TRUE,TRUE,TRUE);
    	sprintf(buf,"From deep sleep your dreams unfurled,");
    	song_to_room(ch,buf,TRUE,TRUE,FALSE);
    	sprintf(buf,"And open your eyes to the world.");
    	song_to_room(ch,buf,TRUE,TRUE,TRUE);
    	sprintf(buf,"So stand hence from where you lie,");
    	song_to_room(ch,buf,FALSE,TRUE,FALSE);
    	sprintf(buf,"Pay heed to the Herald of the Sky.");
    	song_to_room(ch,buf,FALSE,TRUE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (ch == vch)
	    continue;
	if (vch->master == ch || is_same_group(vch, ch))
	{
	  affect_strip(ch,gsn_sleep);
	  affect_strip(ch,gsn_lullaby);
	  affect_strip(ch,gsn_ecstacy);
	  affect_strip(ch,gsn_blackjack);
	  affect_strip(ch,gsn_strangle);
	  affect_strip(ch,gsn_hypnosis);

	  REMOVE_BIT(vch->affected_by,AFF_SLEEP);
	  do_stand(vch,"");
	  if ( IS_AWAKE(vch) )
            {
	      send_to_char( "Your eyes open to a wonderful melody.\n\r", vch);
	      act("$N wakes to $n's melody.",ch,NULL,vch,TO_NOTVICT);
	      act("$N wakes to your melody.",ch,NULL,vch,TO_CHAR);
            }
	}
    }
}

void song_refresh( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"My eyes have traveled far ahead,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"and saw what riches bode!");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"So come my lads, arise and go,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Continue on the Road.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (!IS_AWAKE(vch))
	    continue;
	if (vch->master == ch || is_same_group(vch, ch))
	{
	    vch->move = UMIN( vch->move + level, vch->max_move );
	    if (vch->max_move == vch->move)
	        send_to_char("You feel fully refreshed!\n\r",vch);
	    else
	        send_to_char( "You feel less tired.\n\r", vch );
	}
    }
}

void song_disband( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"Abandoned without a friend,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Stranded until the very end.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"There are none that you can trust,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Solitary is a must.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"With just your shadow by your side.");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Let lonelyness be your ally.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (is_area_safe(ch,vch) || IS_NPC(vch))
	    continue;
	if (!IS_AWAKE(vch))
	    continue;
        s_yell(ch,vch,TRUE);
	if (vch->fighting == NULL)
	    multi_hit(vch,ch,TYPE_UNDEFINED);
	if (saves_spell(level,vch,DAM_OTHER,song_table[sn].spell_type))
	    continue;
	send_to_char("You feel solitary.\n\r",vch);
	stop_follower(vch);
    }
}

void song_weaken( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    char buf[MSL];
    AFFECT_DATA af;
    if (sing)
    {
    	sprintf(buf,"Piercing music drowns your head,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Slowly snapping each logic's thread.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Course of music seeps to the bones,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Slowly adding its weight in stone.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Mind and body fail at each tone,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Sense and strength no longer your own.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (is_area_safe(ch,vch))
	    continue;
	if (!IS_AWAKE(vch))
	    continue;
        s_yell(ch,vch,FALSE);
	if (vch->fighting == NULL)
	    multi_hit(vch,ch,TYPE_UNDEFINED);
	if (is_song_affected(vch,sn))
	    continue;
	if (saves_spell(level,vch,DAM_OTHER,song_table[sn].spell_type)){
	  act("$N resists the song's spell.", ch, NULL, vch, TO_CHAR);
	  continue;
	}

    	af.where     = TO_AFFECTS;
    	af.type      = sn;
    	af.level     = level;
    	af.duration  = level/5;
    	af.modifier  = - level/10;  
    	af.location  = APPLY_STR;
    	af.bitvector = 0;
    	song_affect_to_char( vch, &af );
    	af.location  = APPLY_INT;
    	song_affect_to_char( vch, &af );
	send_to_char("You feel weak...\n\r",vch);
    }
}

void song_dance( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    char buf[MSL];
    AFFECT_DATA af;
    if (sing)
    {
    	sprintf(buf,"We'll dance all night while the moon runs free,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"And dandle the lasses upon our knee,");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"And then you'll ride along with me,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"To dance with the Jack o' Shadows.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (is_area_safe(ch,vch) || IS_NPC(vch))
	    continue;
	if (!IS_AWAKE(vch))
	    continue;
        s_yell(ch,vch,TRUE);
	if (vch->fighting == NULL)
	    multi_hit(vch,ch,TYPE_UNDEFINED);
	if (saves_spell(level-5,vch,DAM_OTHER,song_table[sn].spell_type))
	    continue;
	if (is_song_affected(vch,sn))
	   continue;
    	af.where     = TO_AFFECTS;
    	af.type      = sn;
    	af.level     = level;
    	af.duration  = number_fuzzy(level/8);
    	af.modifier  = 0;  
    	af.location  = APPLY_NONE;
    	af.bitvector = 0;
    	song_affect_to_char( vch, &af );
	send_to_char("You feel dancing!\n\r",vch);
	act("$n starts dancing uncontrollably!",vch,NULL,NULL,TO_ROOM);
    }
}

void song_calm( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    char buf[MSL];
    AFFECT_DATA af;
    if (sing)
    {
    	sprintf(buf,"Here we stand day by day, searching blindly for the way.");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"All you find is another gray, wishing back the days of play.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Here we stand day by day, dwelling in life's long sorrow.");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Walking lost in the barrows, with no hope of a better tomorrow.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Here we stand day by day, life's only truth I have spoken.");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Dark the day before we're awoken, our spirits do be broken.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (!IS_AWAKE(vch))
	    continue;
        if (IS_NPC(vch) && (IS_SET(vch->imm_flags,IMM_MAGIC) || IS_SET(vch->act,ACT_UNDEAD) 
	    || IS_SET(vch->act,ACT_TOO_BIG) || IS_SET(vch->off_flags,GUILD_GUARD) || IS_SET(vch->off_flags,CABAL_GUARD)))
            continue;
        if (IS_AFFECTED(vch,AFF_BERSERK) || is_affected(vch,skill_lookup("frenzy")) || IS_AFFECTED2(vch,AFF_RAGE))
            continue;
	if (!is_same_group(ch,vch) && !(vch->fighting != NULL && is_same_group(ch,vch->fighting)))
	    continue;
	if (!is_same_group(ch,vch) && saves_spell(level-4,vch,DAM_NONE,song_table[sn].spell_type))
	    continue;
        if (vch->fighting || vch->position == POS_FIGHTING)
            stop_fighting(vch,FALSE);
        send_to_char("A wave of calm depression over you.\n\r",vch);
	if (is_song_affected(vch,sn))
	    continue;

    	af.type      = sn;
    	af.level     = level;
    	af.duration  = 2;
    	af.where     = TO_AFFECTS;
	af.bitvector = AFF_CALM;
    	af.modifier  = - level/10;  
    	af.location  = APPLY_HITROLL;
	song_affect_to_char( vch, &af );

    	af.location  = APPLY_DAMROLL;
    	af.bitvector = 0;
    	song_affect_to_char( vch, &af );

	send_to_char("You don't feel like fighting.\n\r",vch);
	act("A depressed look passes over $n's face.",vch,NULL,NULL,TO_ROOM);
    }
}

void song_four_seasons( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    AFFECT_DATA af;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"Ever changing weather marks a cycle of life,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Each passing season will unleash its might.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    af.where     = TO_AFFECTS;
    af.type      = sn;
    af.level     = level;
    af.duration  = 2;
    af.modifier  = 0;  
    af.location  = 0;
    af.bitvector = 0;
    song_affect_to_char( ch, &af );
}

void song_disorient( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    char buf[MSL];
    AFFECT_DATA af;
    if (sing)
    {
    	sprintf(buf,"Downward spiral, eyes at cross,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Lose thy rival, direction loss.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"With no target, who to choose?");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Soon to forget, destined to lose.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Where to run, what to find?");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Eyes wide shut, senses blind.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Order's bane, Shadowspawns's curse,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Made insane, do its worst.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (is_area_safe(ch,vch) || IS_NPC(vch))
	    continue;
	if (!IS_AWAKE(vch))
	    continue;
        s_yell(ch,vch,FALSE);
	if (vch->fighting == NULL)
	    multi_hit(vch,ch,TYPE_UNDEFINED);
	if (saves_spell(level-6,vch,DAM_OTHER,song_table[sn].spell_type))
	    continue;
	if (is_song_affected(vch,sn))
	    continue;
    	af.where     = TO_AFFECTS;
    	af.type      = sn;
    	af.level     = number_range(0,5);
    	af.duration  = 2;
    	af.modifier  = - level/10;
    	af.location  = APPLY_INT;
    	af.bitvector = 0;
    	song_affect_to_char( vch, &af );
    	af.level     = number_range(0,5);
    	af.location  = APPLY_DEX;
    	song_affect_to_char( vch, &af );
	send_to_char("You feel disoriented...\n\r",vch);
	act("$n looks disoriented.",vch,NULL,NULL,TO_ROOM);
    }
}

void song_stryth( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"The Name unmatched throughout the land,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Who turns the world with a flick of the hand.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"From above the clouds he stares down,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"To abolish his foes with but a frown.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"To him who's heart is midnight's cold,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"T'is maybe too late to save your soul.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Thus I wish to beg his blessing,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"So each day may keep on passing.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	act("You kneel on one foot and give thanks to $g.",ch,NULL,NULL,TO_ALL);
    }
}

void song_soothing( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    char buf[MSL];
    int heal = dice(1, 8) + level / 3;
    if (sing)
    {
    	sprintf(buf,"The hidden spring sings to the wind,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Where running nymphs had been.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Let soreness go and wounds subside,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Let life renew within.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (!IS_AWAKE(vch))
	    continue;
	if (vch->master == ch || is_same_group(vch, ch))
	{
            if ( vch->hit < vch->max_hit )
	        act_new("The melody makes you feel a little better.", ch,NULL,vch,TO_CHARVICT,POS_DEAD );
	    vch->hit = UMIN( vch->hit + heal, vch->max_hit );
	    update_pos( vch );
	}
    }
}

void song_intoxify( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"Let us raise our glasses high,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Never let our cups run dry.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Our mouth resides the taste of ale,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"The stench of alchohol inhaled.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"These feelings I cannot leave behind,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Thoughts that shall intoxify my mind.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (IS_NPC(vch))
	    continue;
	if (!IS_AWAKE(vch))
	    continue;
	gain_condition(vch,COND_DRUNK,5);
	send_to_char("Your mind feels lighter.\n\r",vch);	
    }
}

void song_hysteria( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    char buf[MSL];
    AFFECT_DATA af;
    if (sing)
    {
    	sprintf(buf,"The feel of shadows move behind,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Waves of chills runs down your spine.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Ghostly voices echo in your head,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Only to find emptiness instead.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Under the bed at night they hide,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Or maybe it is just in your mind.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);

    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (is_area_safe(ch,vch) || IS_NPC(vch))
	    continue;
	if (!IS_AWAKE(vch))
	    continue;
        s_yell(ch,vch,FALSE);
	if (vch->fighting == NULL)
	    multi_hit(vch,ch,TYPE_UNDEFINED);
	if (is_affected(vch,gsn_hysteria))
	    continue;
	if (saves_spell(level-6,vch,DAM_OTHER,song_table[sn].spell_type))
	    continue;
    	af.where     = TO_AFFECTS;
    	af.type      = gsn_hysteria;
    	af.level     = level;
    	af.duration  = 2;
    	af.modifier  = - level/10;
    	af.location  = APPLY_INT;
    	af.bitvector = 0;
    	affect_to_char( vch, &af );
	send_to_char("You start to panic!\n\r",vch);
	act("$n starts to panic!",vch,NULL,NULL,TO_ROOM);
    }
}

void song_titan( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch, *vch_next;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"From the grounds the titans emerge,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"A tremor through the earth it surge.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"The birds all escape by taking flight,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Up and away from the Titan's might.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"As the Titans soon rumble and clash,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"he mountains start to fall and crash.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
    {
	vch_next = vch->next_in_room;
        if ( !is_area_safe(ch,vch))
        {
            s_yell(ch,vch,FALSE);
            if (IS_AFFECTED(vch,AFF_FLYING) && !is_affected(vch,gsn_thrash))
                damage(ch,vch,0,sn + 5000,DAM_BASH,TRUE);
            else if (is_affected(vch,gsn_burrow))
                damage( ch,vch,2*(level + dice(3, 8)), sn + 5000, DAM_BASH,TRUE);
            else
                damage( ch,vch,level + dice(3, 8), sn + 5000, DAM_BASH,TRUE);
        }
    }
}

void song_faeries( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    char buf[MSL];
    int heal = dice(2, 9) + level /2 ;
    if (sing)
    {
    	sprintf(buf,"Twilight of faeries fly through the skies,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Granting men's dreams of forbidden sights.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Up above our heads they play away,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Sounds of laughter brightens up the day.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Close your eyes with a gentle kneel,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"With fairy dust our wounds will heal.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    }
    act("Hundreds of faeries attracted by the music dance merrily above you.",ch,NULL,NULL,TO_ALL);
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (vch->master == ch || is_same_group(vch, ch))
	{
            if ( vch->hit < vch->max_hit )
	        act_new("The faerie dust lands on you and heals your wounds.", ch,NULL,vch,TO_CHARVICT,POS_DEAD );
	    vch->hit = UMIN( vch->hit + heal, vch->max_hit );
	    update_pos( vch );
	}
    }
}

void song_condor( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    AFFECT_DATA af;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"From high above the clouds I call,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Majestic birds of endless awe.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Accompany us I bid thee respond,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Carry us to unreachable beyonds.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (is_song_affected(vch,sn) || IS_NPC(vch))
	    continue;
	if (vch->master == ch || is_same_group(vch, ch))
	{
    	    af.where     = TO_AFFECTS;
    	    af.type      = sn;
    	    af.level     = level;
    	    af.duration  = 6;
    	    af.modifier  = 0;  
    	    af.location  = 0;
    	    af.bitvector = 0;
    	    song_affect_to_char( vch, &af );
	    act("A large condor arrives and circles over your head, waiting for your bidding.",vch,NULL,NULL,TO_CHAR);
	    act("A large condor arrives and circles over $n's head.",vch,NULL,NULL,TO_ROOM);
	}
    }
}

void song_battle( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    AFFECT_DATA af;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"You stand ready on your feet,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Marching rhythmly to the beat.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"The sounds of battle fill your ears,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Fuels the fire to drown your fears.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Rushing foward to your crusade,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Longing for their blood on your blade.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (is_song_affected(vch,sn) || is_affected(vch,skill_lookup("frenzy")) 
	    || IS_AFFECTED(vch,AFF_BERSERK) || IS_AFFECTED(vch,AFF_CALM))
	    continue;
	if (!IS_AWAKE(vch))
	    continue;
	if (vch->master == ch || is_same_group(vch, ch))
	{
    	    af.where     = TO_AFFECTS;
    	    af.type      = sn;
    	    af.level     = level;
    	    af.duration  = level/4;
    	    af.modifier  = level/7;  
    	    af.bitvector = AFF_BERSERK;
    	    af.location  = APPLY_HITROLL;
    	    song_affect_to_char( vch, &af );
    	    af.location  = APPLY_DAMROLL;
    	    song_affect_to_char( vch, &af );
	    send_to_char("You feel your heart beating faster to the rhythm of battle!\n\r",vch);
	    act("$n looks more ready to do battle.",vch,NULL,NULL,TO_ROOM);
	}
    }
}

void song_shield_words( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    AFFECT_DATA af;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"Words of healing words of pain,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Some words cure and some words maim.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"So as we venture land and sea,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Verses of ancients, protects thee.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (is_song_affected(vch,sn))
	    continue;
	if (vch->master == ch || is_same_group(vch, ch))
	{
    	    af.where     = TO_AFFECTS;
    	    af.type      = sn;
    	    af.level     = level;
    	    af.duration  = level;
    	    af.modifier  = - 20;  
    	    af.location  = APPLY_AC;
    	    af.bitvector = 0;
    	    song_affect_to_char( vch, &af );
	    send_to_char("Verses of the ancients protects you.\n\r",vch);
	    act("$n is surrounded by a shield of words.",vch,NULL,NULL,TO_ROOM);
	}
    }
}

void song_tidings( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    AFFECT_DATA af;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"A rabbit's foot, a shooting star,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Good omens for a brand new start.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"A golden horseshoe, a four leaf clover,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Sounds of good tidings ever so closer.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"The future looking ever so bright,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Lady luck, stay by my side tonight.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (is_song_affected(vch,sn) || IS_NPC(vch))
	    continue;
	if (!IS_AWAKE(vch))
	    continue;
	if (vch->master == ch || is_same_group(vch, ch))
	{
    	    af.where     = TO_AFFECTS;
    	    af.type      = sn;
    	    af.level     = level;
    	    af.duration  = level/2;
    	    af.modifier  = UMAX(1,level/10);  
    	    af.location  = APPLY_LUCK;
    	    af.bitvector = 0;
    	    song_affect_to_char( vch, &af );
	    send_to_char("You feel a little luckier.\n\r",vch);
	}
    }
}

void song_hercules( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    AFFECT_DATA af;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"Born of heaven and endowed with might,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Split the mountain of rushing tides'.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Ten acts of Legend do men recite,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Penance given to set him right.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Now we venture beyond the light,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Let his strength aide our fight.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (is_song_affected(vch,sn))
	    continue;
	if (!IS_AWAKE(vch))
	    continue;
	if (vch->master == ch || is_same_group(vch, ch))
	{
    	    af.where     = TO_AFFECTS;
    	    af.type      = sn;
    	    af.level     = level;
    	    af.duration  = level/2;
    	    af.modifier  = 1 + level/15;  
    	    af.location  = APPLY_STR;
    	    af.bitvector = 0;
    	    song_affect_to_char( vch, &af );
	    send_to_char("Your muscles surge with heightened power!\n\r",vch);
	    act("$n's muscles surge with heightened power.",vch,NULL,NULL,TO_ROOM);
	}
    }
}

void song_burden( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    AFFECT_DATA af;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"A guilt so heavy it sinks the heart,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"A journey so gruelsome to depart,");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"A promise so tough to uphold,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"A silent vow not to be told.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Let the pressures of burden manifest,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Added weight to carry on your chest.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
        if ( is_area_safe(ch,vch) || IS_NPC(vch))
	    continue;
        s_yell(ch,vch,FALSE);
	if (vch->fighting == NULL)
   	    multi_hit(vch,ch,TYPE_UNDEFINED);
	if (is_song_affected(vch,sn))
	    continue;
	if (!IS_AWAKE(vch))
	    continue;
	if (saves_spell(level-5,vch,DAM_OTHER,song_table[sn].spell_type))
	    continue;
    	af.where     = TO_AFFECTS;
    	af.type      = sn;
    	af.level     = level;
    	af.duration  = level/2;
    	af.modifier  = 2*level;  
    	af.location  = APPLY_WEIGHT;
    	af.bitvector = 0;
    	song_affect_to_char( vch, &af );
	send_to_char("You feel more burdened than usual.\n\r",vch);
	act("$n looks more burdened.",vch,NULL,NULL,TO_ROOM);
    }
}

void song_marriage( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"Give your hand to the one you love,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"And sing praises to those above,");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"For giving you someone to hold dear,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"This beautiful day so bright and clear,");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Now at the altar the time is here.");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"You share a bond, a love so true,");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"A spark is felt between the two,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"High on love's wings of joy you flew,");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Witness the souls union at the bell's chime,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
	sprintf(buf,"[`#Bells can be heard ringing in the background``]");
	do_recho(ch,buf);
    	sprintf(buf,"Exchange vowes that lasts the test of time.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
}

void song_mourn( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch, *t_vch;
    OBJ_DATA *obj;
    AFFECT_DATA af;
    char buf[MSL], arg[MIL];
    static char * const his_her [] = { "its", "his", "her" };
    one_argument(argument,arg);
    if ( arg[0]=='\0' )
    {
        send_to_char("What do you want to mourn over?\n\r",ch);
        return;
    }
    obj = get_obj_list( ch, arg, ch->in_room->contents );
    if ( obj == NULL )
    {
        send_to_char( "You can't find it.\n\r", ch );
        return;
    }
    if (obj->item_type != ITEM_CORPSE_PC)
    {
        send_to_char("Why would you mourn over that?.\n\r",ch);
        return;
    }
    for (t_vch = player_list; t_vch != NULL; t_vch = t_vch->next_player)
        if (t_vch->id == obj->owner)
            break;
    if (t_vch == NULL)
    {
	send_to_char("It is too late to mourn over that corpse.\n\r",ch);
	return;
    }
    if (sing)
    {
    	sprintf(buf,"At this place where %s has fell,",PERS2(t_vch));
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Deep in our hearts a place is held,");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"For our companion who fought so well,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Yet bound by the fate of death's bell.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Over %s corpse mourn our farewells,", his_her[URANGE(0,t_vch->sex,2)]);
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Let %s spirit inside us dwell.", his_her[URANGE(0,t_vch->sex,2)]);
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (is_song_affected(vch,sn) || IS_NPC(vch) || vch == t_vch)
	    continue;
	if (!IS_AWAKE(vch))
	    continue;
	if (is_same_group(vch, t_vch))
	{
    	    af.where     = TO_AFFECTS;
    	    af.type      = sn;
    	    af.level     = vch->level;
    	    af.duration  = vch->level*2;
    	    af.modifier  = 3*vch->level/2;  
    	    af.location  = APPLY_HIT;
    	    af.bitvector = 0;
    	    song_affect_to_char( vch, &af );
    	    af.modifier  = - vch->level*2;  
    	    af.location  = APPLY_AC;
    	    song_affect_to_char( vch, &af );
	    vch->hit += 3*vch->level/2;
	    send_to_char("Seeing the fall of your comrade strengthens your will to continue living.\n\r",vch);
	}
	
    }
}

void song_rest( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    AFFECT_DATA af;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"Life so sweet and bitter death,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Both of which you've had a taste.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Rotting flesh of forsaken soul,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Neither of which yours to control.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"The final rest a step away.");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Close your eyes with this breath.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (!IS_SET(vch->act,ACT_UNDEAD) || IS_AFFECTED(vch,AFF_SLEEP))
	    continue;
	if (vch->fighting != NULL)
	    continue;
	if (is_area_safe(ch,vch))
	    continue;
        s_yell(ch,vch,TRUE);
	if (saves_spell(level-5,vch,DAM_OTHER,song_table[sn].spell_type))
	{
	    if (vch->fighting == NULL)
   	    	multi_hit(vch,ch,TYPE_UNDEFINED);
	    continue;
	}
    	af.where     = TO_AFFECTS;
    	af.type      = sn;
    	af.level     = level;
    	af.duration  = number_fuzzy(3);
    	af.modifier  = 0;  
    	af.location  = 0;
    	af.bitvector = AFF_SLEEP;
    	song_affect_to_char( vch, &af );

	if (is_affected(ch,gsn_insomnia))
	    affect_strip(ch,gsn_insomnia);

        if ( IS_AWAKE(vch) ){
	  send_to_char( "Your eyelids feel heavy and you drift into a peaceful slumber.\n\r", vch);
	  do_sleep(vch,"");
	  act("$n is drained and falls asleep.",vch,NULL,NULL,TO_ROOM);
        }
	else
	  act("$n falls into a deep slumber.",vch,NULL,NULL,TO_ROOM);
    }
}

void song_phoenix( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *mob;
    AFFECT_DATA af;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"Sleeping deep within the earth,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Waiting dormant for rebirth.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Rise from your resting chamber,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Let my song wake your slumber.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Out of the ashes of the old,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Manifest your form as foretold.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    if (get_summoned(ch, MOB_VNUM_PHOENIX) > 0)
    {
        send_to_char("Your phoenix is already in existence.\n\r",ch);
        return;
    }
    act ("The ground erupts, giving birth to a baby phoenix!", ch, NULL, NULL, TO_ALL);
    mob = create_mobile( get_mob_index( MOB_VNUM_PHOENIX ) );
    char_to_room(mob,ch->in_room);
    SET_BIT(mob->affected_by, AFF_CHARM);
    mob->comm = COMM_NOTELL|COMM_NOYELL|COMM_NOCHANNELS;
    mob->summoner = ch;
    add_follower(mob,ch);
    mob->leader=ch;
    af.where     = TO_AFFECTS;
    af.type      = sn;
    af.level     = level;
    af.duration  = 100;
    af.modifier  = 0;  
    af.location  = 0;
    af.bitvector = 0;
    song_affect_to_char( mob, &af );
}

void song_eman( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch, *victim;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"Blood and sweat you have laid,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Iron chains once bound your fate.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Standing together we break free,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Never again do another's deed.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (!IS_AFFECTED(vch,AFF_CHARM) || (victim = vch->master) == NULL)
	    continue;
	if (!IS_AWAKE(vch))
	    continue;
	if (is_safe(ch,victim))
	    continue;
        s_yell(ch,victim,TRUE);
	if (saves_spell(level-6,victim,DAM_OTHER,song_table[sn].spell_type))
	{
	    if (victim->fighting == NULL)
   	    	multi_hit(victim,ch,TYPE_UNDEFINED);
	    continue;
	}
	affect_strip(vch,gsn_charm_person);
	REMOVE_BIT(vch->affected_by,AFF_CHARM);
	stop_follower(vch);
	if ((IS_NPC(vch) && IS_SET(vch->act2,ACT_DUPLICATE)) || IS_SET(vch->act,ACT_UNDEAD))
	{
	    act("You are freed from captivity!",vch,NULL,NULL,TO_CHAR);
	    act("$n is freed from captivity!",vch,NULL,NULL,TO_ROOM);
	    if (IS_NPC(vch))
	    {
		char_from_room(vch);
		extract_char(vch,TRUE);
	    }
	}
	else
	{
	    act("$n is freed from captivity and turns against $N!",vch,NULL,victim,TO_NOTVICT);
	    act("You are freed from captivity and turn against $N!",vch,NULL,victim,TO_CHAR);
	    act("$n is freed from captivity and turns against you!",vch,NULL,victim,TO_VICT);
	    multi_hit(vch,victim,TYPE_UNDEFINED);	
	}
    }
}

void song_laughter( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"Forget about your troubles and pains,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Why let your life be bound in chains.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Let your smile lift your spirit,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Laugh out loud for all to hear it.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"With this you'll get the cure you're after,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Because the most effective medicine is laughter.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (!IS_AWAKE(vch))
	    continue;
	if (vch->master == ch || is_same_group(vch, ch))
	{
	    act("The song brings a laughter to your face.",vch,NULL,NULL,TO_CHAR);
	    act("The song brings a laughter to $n's face.",vch,NULL,NULL,TO_ROOM);
	    if (!is_affected(vch,gsn_plague))
	    	continue;
	    if (check_dispel(level-3,vch,gsn_plague))
	    {
	        act_new("Your sores vanish.",vch,NULL,NULL,TO_CHAR,POS_DEAD);
	        act("$n looks relieved as $s sores vanish.",vch,NULL,NULL,TO_ROOM);
	    }
	}
    }
}

void song_spider( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch, *vch_next, *mob, *mob2;
    AFFECT_DATA af;
    char buf[MSL];
    int i = 0;
    if (sing)
    {
    	sprintf(buf,"In the darkest corners they build their nest,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Anticipating an unsuspecting guest.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"With preying eyes upon you they spy,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Venom dripping for the tasty fly.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Descending around you they converge,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Feel the sting of black widow's scourge");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    if (get_summoned(ch, MOB_VNUM_SPIDER) > ch->level/10)
    {
	send_to_char("You've summoned as many as you can!\n\r",ch);
	return;
    }

    mob = create_mobile( get_mob_index(MOB_VNUM_SPIDER) );
    for (i = 0; i < MAX_STATS; i++)
        mob->perm_stat[i] = UMIN(25, (ch->level / 10) + 15);
    mob->max_hit = ch->level;
    mob->hit = mob->max_hit;
    mob->level = ch->level;
    for (i = 0; i < 3; i++)
        mob->armor[i] = interpolate(mob->level/2,100,-100);
    mob->armor[3] = interpolate(mob->level/2,100,0);
    mob->damroll    = (ch->level /10);
    mob->damage[DICE_NUMBER]  = (ch->level /12);
    mob->damage[DICE_TYPE]    = 3;
    mob->sex = number_range(1,2);
    mob->comm = COMM_NOTELL|COMM_NOYELL|COMM_NOCHANNELS;
    mob->summoner = ch;
    af.where     = TO_AFFECTS;
    af.type      = gsn_timer;
    af.level     = level;
    af.duration  = 3;
    af.modifier  = 0;  
    af.location  = APPLY_NONE;
    af.bitvector = 0;
    affect_to_char( mob, &af );

    for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
    {
	int number = number_range(1,2);
	vch_next = vch->next_in_room;
        if (is_area_safe(ch,vch))
	    continue;
	if (IS_NPC(vch) && vch->pIndexData->vnum == MOB_VNUM_SPIDER)
	    continue;
        s_yell(ch,vch,FALSE);
	if (vch->fighting == NULL)
	    multi_hit(vch,ch,TYPE_UNDEFINED);
	for (i = 0;i < number;i++)
	{
	    mob2 = create_mobile(mob->pIndexData);
	    clone_mobile(mob,mob2);
	    mob2->summoner = ch;
	    mob2->master = ch;
	    SET_BIT(mob2->affected_by, AFF_CHARM);
	    char_to_room(mob2,vch->in_room);
	    act("$N drops in from above and starts attacking you!",vch,NULL,mob2,TO_CHAR);
	    act("$N drops in from above and starts attacking $n!",vch,NULL,mob2,TO_ROOM);
	    set_fighting(mob2,vch);
	}
    }
    extract_char(mob,TRUE);
}

void song_unicorn( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    AFFECT_DATA af;
    char buf[MSL];
    int temp = 0;
    if (sing)
    {
    	sprintf(buf,"Travel the distant lands far and wide,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"We search for mystery in great stride.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"A fair steed with wild and fiery mane,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Whose enigma has sparked its fame.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"For those who find this fabled beast,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Its mysteries will be released.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"The secret is abound within its horn,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Alas we have found the great unicorn.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    af.where     = TO_AFFECTS;
    af.type      = sn;
    af.level     = level;
    af.duration  = level/4;
    af.modifier  = - level/3;
    af.bitvector = 0;
    temp = number_range(0,2);
    switch (temp)
    {
	default:
    	    af.location  = APPLY_SAVING_SPELL;
	    break;
	case (0):
    	    af.location  = APPLY_SAVING_AFFL;
	    break;
	case (1):
    	    af.location  = APPLY_SAVING_MALED;
	    break;
	case (2):
    	    af.location  = APPLY_SAVING_MENTAL;
	    break;
    }
    act("A unicorn runs through, filling the air with mystic energy.",ch,NULL,NULL,TO_ALL);
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (is_song_affected(vch,sn) || IS_NPC(vch))
	    continue;
	if (vch->master == ch || is_same_group(vch, ch))
	{
    	    song_affect_to_char( vch, &af );
	    send_to_char("You feel protected by the unicorn's mystic energy.\n\r",vch);
	}
    }
}

void song_accuracy( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    AFFECT_DATA af;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"Accuracy song...");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (is_song_affected(vch,sn) || IS_NPC(vch))
	    continue;
	if (vch->master == ch || is_same_group(vch, ch))
	{
    	    af.where     = TO_AFFECTS;
    	    af.type      = sn;
    	    af.level     = level;
    	    af.duration  = 6;
    	    af.modifier  = 0;  
    	    af.location  = 0;
    	    af.bitvector = 0;
    	    song_affect_to_char( vch, &af );
	    send_to_char("Your mind is in full concentration.\n\r",vch);
	}
    }
}

void song_shriek( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch, *vch_next;
    int dam = 0;
    char buf[MSL];
    sprintf(buf,"%s",random_garble(level));
    if (sing)
    {
    	if (duet && ch->pcdata->duet != NULL)
    	    duet_song_to_room(ch,ch->pcdata->duet,buf,FALSE,FALSE);
    	else
    	    song_to_room(ch,buf,FALSE,FALSE,FALSE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
    {
	vch_next = vch->next_in_room;
        if ( vch->in_room == NULL )
            continue;
        if ( vch->in_room == ch->in_room )
        {
	  if ( !is_area_safe(ch,vch))
            {
                s_yell(ch,vch,FALSE);
		dam = strlen(buf) + UMAX(5,UMIN(15,number_range(level/4,level/2)));

		if (saves_spell(level,vch,DAM_SOUND,song_table[sn].spell_type))
		    dam /= 2;
		//deafen if vuln to sound. (damage or spell)
		if (check_immune(vch,DAM_SOUND, TRUE) == IS_VULNERABLE
		    || check_immune(vch,DAM_SOUND,FALSE) == IS_VULNERABLE)
		  spell_silence(gsn_silence, level + 5, ch, vch, TARGET_CHAR );
		damage(ch,vch,dam,sn + 5000,DAM_SOUND,TRUE);
		act("Your eardrums rupture from $n's shriek.",ch,NULL,vch,TO_VICT);
             }
        }
    }
}

void song_memories( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"A distant memory locked away,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Seems like a dream from yesterday.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"A thought in fragments you almost grasped,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Perhaps a clue that reveals your past.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Heed my song and the nightmare will end,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Let your memory surface once again.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (vch->master == ch || is_same_group(vch, ch))
	{
	    if (!IS_AWAKE(vch))
	    	continue;
	    if (check_dispel(level-2,vch,gsn_forget))
	    {
	    	act("The song brings back your memories.",vch,NULL,NULL,TO_CHAR);
	    	act("The song brings a familiar look to $n's face.",vch,NULL,NULL,TO_ROOM);
	    }
	    if (check_dispel(level-2,vch,gsn_hysteria))
	    {
	    	act("The song brings back your senses.",vch,NULL,NULL,TO_CHAR);
	    	act("The song brings a relaxed look to $n's face.",vch,NULL,NULL,TO_ROOM);
	    }
	}
    }
}

void song_leviathon( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    OBJ_DATA *spring = create_object( get_obj_index( OBJ_VNUM_SPRING ), 0);
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"Ancient creature that lives beneath,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Who nurtures the life we receive.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Here we stand dried of mouth,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Without a river north or south.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Bring the gift of infinite worth,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"The sweet essence of all birth.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    spring->timer = 1;
    obj_to_room( spring, ch->in_room );
    act("You summon the Leviathon, leaving springs flowing from the ground in its path.",ch,NULL,NULL,TO_CHAR);
    act("$n summons the Leviathon, leaving springs flowing from the ground in its path.",ch,NULL,NULL,TO_ROOM);
}

void song_serenade( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"My heart aches when you are not here,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"There is nothing else I hold dear.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"My mind has never been so clear,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"I always want you to stay near.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"When with me you'll never have to fear,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"I will never let you shed a tear.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"On my knees to show that I'm sincere,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"A love that hold trues throughout the years.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
}

void song_lust( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    AFFECT_DATA af;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"Lust, Seduction, and Desire,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Your heart beats faster, your loin's on fire.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Unlock the urge that sleeps within,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Fall to the temptations of mortal sin.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Enjoy a feeling so refresh,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Indulge in the pleasures of the flesh.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);

    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (is_song_affected(vch,sn))
	    continue;
	if (!IS_AWAKE(vch))
	    continue;
	if (IS_IMMORTAL(vch))
	    continue;
	if (saves_spell(vch->level-3,vch,DAM_OTHER,song_table[sn].spell_type))
	    continue;
    	af.where     = TO_AFFECTS;
    	af.type      = sn;
    	af.level     = level;
    	af.duration  = 6;
    	af.modifier  = 0;  
    	af.location  = 0;
    	af.bitvector = 0;
    	song_affect_to_char( vch, &af );
    }
}

void song_feast( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    OBJ_DATA *obj;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"Here I stand to prepare a feast,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"A sight so grand to say the least.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Ingredients I use of the old,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Enhancing flavor to a taste so bold,");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"ealing in the freshness of spring,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"A meal truly fitting for a king.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    }
    for (obj = ch->carrying; obj != NULL; obj = obj->next_content)
    {
    	if (obj->item_type != ITEM_FOOD)
	    continue;
    	if (obj->wear_loc != -1)
	    continue;
	if (obj->value[1] > 40 || obj->timer > 99)
	    continue;
	act("$p looks fit for a king!",ch,obj,NULL,TO_CHAR);
	obj->value[1] = 48;
	obj->timer = 100;
    }
}

void song_reputation( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    AFFECT_DATA af;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"Let it be known throughout the land,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"For I am the greatest, the most grand.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Let it be known and all take heed,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Young and old know my heroic deeds.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    	sprintf(buf,"Let it be known with all my glory,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Ages to come will tell my story.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Let it be known my ample fame,");
    	song_to_room(ch,buf,TRUE,FALSE,FALSE);
    	sprintf(buf,"Man and beast do speak my name.");
    	song_to_room(ch,buf,TRUE,FALSE,TRUE);
    }
    af.where     = TO_AFFECTS;
    af.type      = sn;
    af.level     = level;
    af.duration  = 24;
    af.modifier  = 0;  
    af.location  = 0;
    af.bitvector = 0;
    song_affect_to_char( ch, &af );
    send_to_char("Your reputation is well known throughout the lands.\n\r",ch);
}

void song_victory( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
  //    CHAR_DATA *vch;
//    AFFECT_DATA af;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"Oh great beauty, oh lovely sky,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"On watch duty, sitting up high.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Victory Goddess, grant us fate,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"This I promise, homage of great.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Give us a boon, from the stars,");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"With this tune, Victory be ours.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }

}

void song_unforgiven( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    AFFECT_DATA af;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"Unforgiven the gods turn away.");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Unforgiven the deaths you lay.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Unforgiven the game you play.");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Unforgiven those you betray.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Unforgiven the sin this day.");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Unforgiven the curse shall stay.");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
	if (IS_NPC(vch) || !is_area_safe(ch,vch) || !is_affected(vch,gsn_curse))
	    continue;
	if (!IS_AWAKE(vch))
	    continue;
	s_yell(ch,vch,FALSE);
	if (vch->fighting == NULL)
	    multi_hit(vch,ch,TYPE_UNDEFINED);
	if (is_song_affected(vch,sn))
	    continue;
	if (saves_spell(level-5,vch,DAM_OTHER,song_table[sn].spell_type))
	    continue;
    	af.where     = TO_AFFECTS;
    	af.type      = sn;
    	af.level     = level;
    	af.duration  = 6;
    	af.modifier  = 0;  
    	af.location  = 0;
    	af.bitvector = 0;
    	song_affect_to_char( vch, &af );
	send_to_char("Your curse is unforgivable!.\n\r",vch);
    }
}

void song_waterwine( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    OBJ_DATA *obj;
    int liquid = 0;
    char buf[MSL], arg[MIL];
    one_argument(argument,arg);
    if ( arg[0]=='\0' )
    {
        send_to_char("Syntax: sing 'water to wine' <drink container>\n\r",ch);
        return;
    }
    obj = get_obj_list( ch, arg, ch->carrying );
    if ( obj == NULL )
    {
        send_to_char( "You can't find it.\n\r", ch );
        return;
    }
    if ( obj->wear_loc != WEAR_NONE )
    {
	send_to_char( "It must be in your inventory.\n\r",ch);
	return;
    }
    if (obj->item_type != ITEM_DRINK_CON)
    {
        send_to_char("That isn't a drink container.\n\r",ch);
        return;
    }
    if ( obj->value[1] <= 0 )
    {
        send_to_char( "It is already empty.\n\r", ch );
        return;
    }
    liquid = obj->value[2];
    if ( liquid != 0 )
    {
        send_to_char("You can only turn pure water into wine.\n\r",ch);
        return;
    }
    if (sing)
    {
    	sprintf(buf,"From a liquid so clear and pure");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"Add in the ages to mature");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    	sprintf(buf,"Sprinkle a dash of morning dew");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    	sprintf(buf,"A concoction of the finest brew");
    	song_to_room(ch,buf,FALSE,FALSE,TRUE);
    }
    switch (number_range(0,4))
    {
	case (0):
	    obj->value[2] = 3;
	    break;
	case (1):
	    obj->value[2] = 18;
	    break;
	case (2):
	    obj->value[2] = 23;
	    break;
	case (3):
	    obj->value[2] = 31;
	    break;
	case (4):
	    obj->value[2] = 35;
	    break;
    }		
    obj->value[3] = 0;
    act("The water in $p slowly changes color.",ch,obj,NULL,TO_ALL);
}

/*
void song_format( int sn, int level, CHAR_DATA *ch, bool duet, bool sing, char *argument)
{
    CHAR_DATA *vch;
    char buf[MSL];
    if (sing)
    {
    	sprintf(buf,"Lyrics...");
    	song_to_room(ch,buf,FALSE,FALSE,FALSE);
    }
    for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
    {
    }
}
*/