/*
....[@@@..[@@@..............[@.................. MUD++ is a written from
....[@..[@..[@..[@..[@..[@@@@@....[@......[@.... scratch multi-user swords and
....[@..[@..[@..[@..[@..[@..[@..[@@@@@..[@@@@@.. sorcery game written in C++.
....[@......[@..[@..[@..[@..[@....[@......[@.... This server is an ongoing
....[@......[@..[@@@@@..[@@@@@.................. development project.  All 
................................................ contributions are welcome. 
....Copyright(C).1995.Melvin.Smith.............. Enjoy. 
------------------------------------------------------------------------------
Melvin Smith (aka Fusion)         msmith@falcon.mercer.peachnet.edu 
MUD++ development mailing list    mudpp-list@spice.com
------------------------------------------------------------------------------
utils.cc
*/

#include "string.h"
#include "llist.h"
#include "indexable.h"
#include "room.h"
#include "object.h"
#include "npc.h"
#include "pc.h"

#include "global.h"

void outAllChar( const String & str )
{
	PC *ch;
	LList<PC> tlist = pcs;
	tlist.reset();

	while( ( ch = tlist.peek() ) )
	{
		tlist.next();

		if( !ch->isPlaying() )
			continue;

		ch->out( str );
	}
}

void outAllCharExcept( const String & str, Char * ch1, Char * ch2 )
{
	PC *ch;
	LList<PC> tlist = pcs;
	tlist.reset();

	while( ( ch = tlist.peek() ) )
	{
		tlist.next();

		if( !ch->isPlaying() )
			continue;
		else
		if( ch == ch1 || ch == ch2 )
			continue;

		ch->out( str );
	}
}


PC *getPCWorld( const String & name )
{
	PC *ch;
	LList<PC> tlist = pcs;
	tlist.reset();

	while( ( ch = tlist.peek() ) )
	{
		if( !ch->isPlaying() )
			continue;

		if( ch->isName( name ) )
			break;

		tlist.next();
	}

	return ch;
}


NPC *getNPCWorld( const String & name )
{
	NPC *ch;
	LList<NPC> tlist = npcs;
	tlist.reset();

	while( ( ch = tlist.peek() ) )
	{
		if( ch->isName( name ) )
			break;

		tlist.next();
	}

	return ch;
}



int bitNum( int bit )
{
	// Order( log2 N )- most compilers employ binary search to
	// implement switch statement
	// Anyone want to be nice enough to run a profile on them?

	switch( bit )
	{
		default:       return 0;  // messy - this is a multiple bit case
		case BIT( 0 ):   return 0; case BIT( 1 ):   return 1;
		case BIT( 2 ):   return 2; case BIT( 3 ):   return 3;
		case BIT( 4 ):   return 4; case BIT( 5 ):   return 5;
		case BIT( 6 ):   return 6; case BIT( 7 ):   return 7;
		case BIT( 8 ):   return 8; case BIT( 9 ):   return 9;
		case BIT( 10 ):  return 10; case BIT( 11 ):  return 11;
		case BIT( 12 ):  return 12; case BIT( 13 ):  return 13;
		case BIT( 14 ):  return 14; case BIT( 15 ):  return 15;
		case BIT( 16 ):  return 16; case BIT( 17 ):  return 17;
		case BIT( 18 ):  return 18; case BIT( 19 ):  return 19;
		case BIT( 20 ):  return 20; case BIT( 21 ):  return 21;
		case BIT( 22 ):  return 22; case BIT( 23 ):  return 23;
		case BIT( 24 ):  return 24; case BIT( 25 ):  return 25;
		case BIT( 26 ):  return 26; case BIT( 27 ):  return 27;
		case BIT( 28 ):  return 28; case BIT( 29 ):  return 29;
		case BIT( 30 ):  return 30; case BIT( 31 ):  return 31;
	}
}


// Direction functions

const char *getDirName( int dir )
{
	static const char *dir_name[] =
	{
		"north",
		"east",
		"south",
		"west",
		"up",
		"down"
	};


	if( dir < 0 || dir >= MAX_DIR )
		return "undefined";

	return dir_name[ dir ];
}


int getDir( char ch )
{
	switch( tolower(ch) )
	{
		default : return DIR_UNDEFINED;
		case 'n': return DIR_NORTH;
		case 'e': return DIR_EAST;
		case 's': return DIR_SOUTH;
		case 'w': return DIR_WEST;
		case 'u': return DIR_UP;
		case 'd': return DIR_DOWN;
	}
}


int getDir( const char * str )
{
	switch( tolower(*str) )
	{
		default : return DIR_UNDEFINED;
		case 'n': if( !str_cmp( "north", str ) ) return DIR_NORTH; return DIR_UNDEFINED;
		case 'e': if( !str_cmp( "east", str ) ) return DIR_EAST; return DIR_UNDEFINED;
		case 's': if( !str_cmp( "south", str ) ) return DIR_SOUTH; return DIR_UNDEFINED;
		case 'w': if( !str_cmp( "west", str ) ) return DIR_WEST; return DIR_UNDEFINED;
		case 'u': if( !str_cmp( "up", str ) ) return DIR_UP; return DIR_UNDEFINED;
		case 'd': if( !str_cmp( "down", str ) ) return DIR_DOWN; return DIR_UNDEFINED;
	}
}


void error( char *buf )
{
	printf( "%s\nFatal error.\n", buf );
	exit( 0 );
}