asgard/
asgard/.settings/
asgard/area/
asgard/data/clans/
asgard/data/clans/history/
asgard/data/rosters/
asgard/src/notice/
/***************************************************************************
 *  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-1995 Russ Taylor			   *
 *	ROM has been brought to you by the ROM consortium		   *
 *	    Russ Taylor (rtaylor@pacinfo.com)				   *
 *	    Gabrielle Taylor (gtaylor@pacinfo.com)			   *
 *	    Brian Moore (rom@rom.efn.org)				   *
 *	By using this code, you have agreed to follow the terms of the	   *
 *	ROM license, in the file Rom24/doc/rom.license			   *
 ***************************************************************************/

/*************************************************************************** 
 *       ROT 1.4 is copyright 1996-1997 by Russ Walsh                       *
 *       By using this code, you have agreed to follow the terms of the     *
 *       ROT license, in the file doc/rot.license                           *
 ***************************************************************************/

#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#include <sys/time.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include "merc.h"
#include "music.h"
#include "recycle.h"

int channel_songs[MAX_GLOBAL + 1];
struct song_data song_table[MAX_SONGS];

void song_update(void)
{
	OBJ_DATA *obj;
	CHAR_DATA *victim;
	DESCRIPTOR_DATA *d;
	char buf[MAX_STRING_LENGTH];
	char *line;
	int i;

	/* do the global song, if any */
	if (channel_songs[1] >= MAX_SONGS)
		channel_songs[1] = -1;

	if (channel_songs[1] > -1)
	{
		if (channel_songs[0] >= MAX_LINES || channel_songs[0]
				>= song_table[channel_songs[1]].lines)
		{
			channel_songs[0] = -1;

			/* advance songs */
			for (i = 1; i < MAX_GLOBAL; i++)
				channel_songs[i] = channel_songs[i + 1];
			channel_songs[MAX_GLOBAL] = -1;
		}
		else
		{
			if (channel_songs[0] < 0)
			{
				sprintf(buf, "Music: {-%s, %s{x",
						song_table[channel_songs[1]].group,
						song_table[channel_songs[1]].name);
				channel_songs[0] = 0;
			}
			else
			{
				sprintf(buf, "Music: '{-%s{x'",
						song_table[channel_songs[1]].lyrics[channel_songs[0]]);
				channel_songs[0]++;
			}

			for (d = descriptor_list; d != NULL; d = d->next)
			{
				victim = d->original ? d->original : d->character;

				if (d->connected == CON_PLAYING
						&&
						!IS_SET(victim->comm,COMM_NOMUSIC)
						&&
						!IS_SET(victim->comm,COMM_QUIET))
					act_new("$t", d->character, buf, NULL, TO_CHAR,
							POS_SLEEPING);
			}
		}
	}

	for (obj = object_list; obj != NULL; obj = obj->next)
	{
		if (obj->item_type != ITEM_JUKEBOX || obj->value[1] < 0)
			continue;

		if (obj->value[1] >= MAX_SONGS)
		{
			obj->value[1] = -1;
			continue;
		}

		if (obj->value[0] < 0)
		{
			sprintf(buf, "$p starts playing {-%s, %s{x.",
					song_table[obj->value[1]].group,
					song_table[obj->value[1]].name);
			if (obj->in_room->people != NULL)
				act(buf, obj->in_room->people, obj, NULL, TO_ALL);
			obj->value[0] = 0;
			continue;
		}
		else
		{
			if (obj->value[0] >= MAX_LINES || obj->value[0]
					>= song_table[obj->value[1]].lines)
			{

				obj->value[0] = -1;

				/* scroll songs forward */
				obj->value[1] = obj->value[2];
				obj->value[2] = obj->value[3];
				obj->value[3] = obj->value[4];
				obj->value[4] = -1;
				continue;
			}

			line = song_table[obj->value[1]].lyrics[obj->value[0]];
			obj->value[0]++;
		}

		sprintf(buf, "$p bops: '{-%s{x'", line);
		if (obj->in_room->people != NULL)
			act(buf, obj->in_room->people, obj, NULL, TO_ALL);
	}
}

void load_songs(void)
{
	FILE *fp;
	int count = 0, lines, i;
	char letter;

	/* reset global */
	for (i = 0; i <= MAX_GLOBAL; i++)
		channel_songs[i] = -1;

	if ((fp = fopen(MUSIC_FILE, "r")) == NULL)
	{
		printf_debug("Couldn't open music file, no songs available.");
		fclose(fp);
		return;
	}

	for (count = 0; count < MAX_SONGS; count++)
	{
		letter = fread_letter(fp);
		if (letter == '#')
		{
			if (count < MAX_SONGS)
				song_table[count].name = NULL;
			fclose(fp);
			return;
		}
		else
			ungetc(letter, fp);

		song_table[count].group = fread_string(fp);
		song_table[count].name = fread_string(fp);

		/* read lyrics */
		lines = 0;

		for (;;)
		{
			letter = fread_letter(fp);

			if (letter == '~')
			{
				song_table[count].lines = lines;
				break;
			}
			else
				ungetc(letter, fp);

			if (lines >= MAX_LINES)
			{
				printf_debug("Too many lines in a song -- limit is  %d.", MAX_LINES);
				break;
			}

			song_table[count].lyrics[lines] = fread_string_eol(fp);
			lines++;
		}
	}
}

void do_play(CHAR_DATA *ch, char *argument)
{
	OBJ_DATA *juke;
	char *str, arg[MAX_INPUT_LENGTH];
	int song, i;
	bool global = FALSE;

	str = one_argument(argument, arg);

	for (juke = ch->in_room->contents; juke != NULL; juke = juke->next_content)
		if (juke->item_type == ITEM_JUKEBOX && can_see_obj(ch, juke))
			break;

	if (argument[0] == '\0')
	{
		send_to_char("Play what?\n\r", ch);
		return;
	}

	if (juke == NULL)
	{
		send_to_char("You see nothing to play.\n\r", ch);
		return;
	}

	if (!str_cmp(arg, "list"))
	{
		BUFFER *buffer;
		char buf[MAX_STRING_LENGTH];
		int col = 0;
		bool artist = FALSE, match = FALSE;

		buffer = new_buf();
		argument = str;
		argument = one_argument(argument, arg);

		if (!str_cmp(arg, "artist"))
			artist = TRUE;

		if (argument[0] != '\0')
			match = TRUE;

		sprintf(buf, "%s has the following songs available:\n\r",
				juke->short_descr);
		add_buf(buffer, capitalize(buf));

		for (i = 0; i < MAX_SONGS; i++)
		{
			if (song_table[i].name == NULL)
				break;

			if (artist
					&& (!match || !str_prefix(argument, song_table[i].group)))
				sprintf(buf, "%-39s %-39s\n\r", song_table[i].group,
						song_table[i].name);
			else if (!artist && (!match || !str_prefix(argument,
					song_table[i].name)))
				sprintf(buf, "%-35s ", song_table[i].name);
			else
				continue;
			add_buf(buffer, buf);
			if (!artist && ++col % 2 == 0)
				add_buf(buffer, "\n\r");
		}
		if (!artist && col % 2 != 0)
			add_buf(buffer, "\n\r");

		page_to_char(buf_string(buffer), ch);
		free_buf(buffer);
		return;
	}

	if (!str_cmp(arg, "loud"))
	{
		argument = str;
		global = TRUE;
	}

	if (argument[0] == '\0')
	{
		send_to_char("Play what?\n\r", ch);
		return;
	}

	if ((global && channel_songs[MAX_GLOBAL] > -1) || (!global
			&& juke->value[4] > -1))
	{
		send_to_char("The jukebox is full up right now.\n\r", ch);
		return;
	}

	for (song = 0; song < MAX_SONGS; song++)
	{
		if (song_table[song].name == NULL)
		{
			send_to_char("That song isn't available.\n\r", ch);
			return;
		}
		if (!str_prefix(argument, song_table[song].name))
			break;
	}

	if (song >= MAX_SONGS)
	{
		send_to_char("That song isn't available.\n\r", ch);
		return;
	}

	send_to_char("Coming right up.\n\r", ch);

	if (global)
	{
		for (i = 1; i <= MAX_GLOBAL; i++)
			if (channel_songs[i] < 0)
			{
				if (i == 1)
					channel_songs[0] = -1;
				channel_songs[i] = song;
				return;
			}
	}
	else
	{
		for (i = 1; i < 5; i++)
			if (juke->value[i] < 0)
			{
				if (i == 1)
					juke->value[0] = -1;
				juke->value[i] = song;
				return;
			}
	}
}