mud++0.26/etc/
mud++0.26/etc/guilds/
mud++0.26/log/
mud++0.26/mudC/
mud++0.26/player/
mud++0.26/src/unix/
/*
....[@@@..[@@@..............[@.................. 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@hom.net 
MUD++ development mailing list    mudpp-list@mailhost.net
------------------------------------------------------------------------------
help.cc
*/

#include "io.h"
#include "string.h"
#include "llist.h"
#include "hash.h"
#include "help.h"
#include "global.h"
#include "pc.h"
#include "bit.h"


const bitType help_bit_list[] =
{
	{0,				0				},
	{"all",			ALL_CAN_READ	},
	{"no-title", 	NO_TITLE		},
	{0,				0				}
};

/*
 *	Helps are registered in both LList and HashTable.
 *  LList is used for keeping them for later saving
 *	and HashTable is used for quick lookups
 *  One help has one entru in LList, but may have many in HashTables
 *  (one for every keyword)
 */

void Help::add( Help * help )
{
	char buf[BUF];
	const char * name;

	// add it to hashtable under each of the names
	// maybe we will add later '' delimited strings, not only words

	// Temp copy - strtok do not use const pointers
	strcpy( buf, help->getName().chars() );
	name = strtok( buf, " " );
	helps_ht.add( String(name), help );

	while ( ( name = strtok( NULL, " "	) ) != NULL )
		helps_ht.add( String(name), help );
	
	// Add also to normal LList
	helps_ll.add(help);
}

void Help::remove( Help * help )
{
	// remove from LList
	helps_ll.remove(help);

	// and from hashTable
	helps_ht.removeAllInstancesOf(help);

}

void loadHelps()
{
	char filename[BUF];
	char buf[BUF];
	Help * help;

	sprintf( filename, "%s/%s", HELP_DIR, HELP_FILE );

	InFile in( filename );
 
	if( !in )
	{
		Cout<<"loadHelps : can't open help file "<<filename<<endl;
		return;
	}

	int i = 0;

	while( in && ( in.get( *buf ) != '#' ) )
	{
		in.putback();
		help = new Help();
		help->readFrom(in);
		Help::add(help);
		i++;
	}
 
	Cout<<"Help index loaded with "<<i<<" keywords.\n"; 
}

void saveHelps()
{
	char filename[BUF];
	Help * help;
	sprintf( filename, "%s/%s", HELP_DIR, HELP_FILE );

	OutFile out( filename );
 
	if( !out )
	{
		Cout<< "saveHelps : can't open help file "<<filename<<endl;
		return;
	}

	for_each( helps_ll, help )
	{
		help->writeTo(out);
	}
	out << "#";
	out.close(); 
}

int Help::readFrom( InFile &in )
{
	if( !in )
		return -1;

	char buf[ BUF ];
	setName( in.getstring( buf ) );
	level = in.getnum();
	filename = in.getword( buf );
	in.getbitfield( priv_needed );
	in.getbitfield( help_bits );
	return 0;
}

int Help::writeTo( OutFile &out ) const
{
	if( !out ) 
		return -1;

	out << name << "~\t" << level << "\t" << filename << " ";
	out.putbitfield( priv_needed, MAX_PRIV_BIT_FIELDS );
	out << " ";
	out.putbitfield( help_bits, MAX_HELP_BIT_FIELDS );
	out << endl;
	return 0;
}

bool Help::isAllowed( PC * pc )
{
	if ( pc->getLevel() < level )
		return false;

	if ( IS_SET( help_bits, ALL_CAN_READ ) )
		return true;
	
	int i;
	for ( i =1; i < MAX_PRIV_BITS; i++ )
	{
		if ( IS_SET(priv_needed, i ) && pc->authorized(i) )
	return true;
	}


	return false;
}