smaug1.8/area/imc/
smaug1.8/boards/
smaug1.8/councils/
smaug1.8/deity/
smaug1.8/doc/mudprogs/
smaug1.8/gods/
smaug1.8/houses/
smaug1.8/log/
smaug1.8/vault/
/****************************************************************************
 * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame      |   \\._.//   *
 * -----------------------------------------------------------|   (0...0)   *
 * SMAUG 1.4 (C) 1994, 1995, 1996, 1998  by Derek Snider      |    ).:.(    *
 * -----------------------------------------------------------|    {o o}    *
 * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus,      |   / ' ' \   *
 * Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek,      |~'~.VxvxV.~'~*
 * Tricops, Fireblade, Edmond, Conran                         |             *
 * ------------------------------------------------------------------------ *
 * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael        *
 * Chastain, Michael Quan, and Mitchell Tse.                                *
 * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,          *
 * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.     *
 * ------------------------------------------------------------------------ *
 *                 Online Hints module by Zedd of Slips in Time             *
 ****************************************************************************/
 
#if defined(macintosh)
#include <types.h>
#include <time.h>
#else
#include <sys/types.h>
#include <sys/time.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include "mud.h"
#include "imc-mercbase.h"




HINT_DATA *           first_hint;
HINT_DATA *           last_hint;


HINT_DATA *read_hint args( ( char *filename, FILE *fp));
void do_hintedit args ((CHAR_DATA *ch, char *argument));

void SwapHint args (( HINT_DATA *pHint1, HINT_DATA *pHint2));

void write_rank args (( void ));

void SwapHint(HINT_DATA *pHint1, HINT_DATA *pHint2)
{
        if (pHint1->prev)
        {
                pHint1->prev->next = pHint2;
        }
        else  
        {
                first_hint = pHint2;
        }
          
        pHint2->prev = pHint1->prev;
         
        pHint1->next = pHint2->next;
                 
        if (pHint1->next)
        {
                pHint1->next->prev = pHint1;
        }
                                
        pHint2->next = pHint1;   
        pHint1->prev = pHint2;
}

char *get_hint(int level)
{
   HINT_DATA *hintData;
   bool found=FALSE;
   char buf[MAX_STRING_LENGTH];
   int count,which;

   count = 0;
   if (level < 0)
   {
	sprintf(buf,"HintLevel error, Level was %d",level);
	 return str_dup(buf);
   }
   else
   {
	found = FALSE;
	hintData = first_hint;
	for (hintData = first_hint;hintData;hintData = hintData->next)
	{
	    if (level >= hintData->low && level <= hintData->high)
		count++;
	}
	if (count > 1)
 	{
	    which = number_range(1,count);
	    count = 0;
	    for (hintData = first_hint;hintData;hintData = hintData->next)
	    {
		if (level >= hintData->low && level <= hintData->high)
		    count++;
		if (count == which)
		    return str_dup(hintData->text);
	    }
	}		
	else if (count == 1)
	{
	    for (hintData = first_hint;hintData;hintData = hintData->next)
	    {
		if (level >= hintData->low && level <= hintData->high)
		    return str_dup(hintData->text);
	    }
	}
	else return str_dup(" ");	    
    }
    return str_dup(" ");
}


void write_hint( void)
{
    HINT_DATA *hintData;
    FILE *fp;
    char filename[256];

    sprintf(filename,"%s",HINT_FILE);
    fclose(fpReserve);
    if (( fp = fopen(filename,"w")) == NULL)
    {
	bug("Save hint: fopen",0);
	perror(filename);
	return;
    }
    else
    {
    	for (hintData = first_hint;hintData;hintData=hintData->next)
    	{
		fprintf(fp,"Text     %s~\n",hintData->text);
	       	fprintf(fp,"Low        %d\n",hintData->low);
		fprintf(fp,"High       %d\n",hintData->high);
		fprintf(fp,"End\n");
	}
	fclose(fp);
	fpReserve = fopen(NULL_FILE,"r");
	return;
    }
}
void do_hintedit(CHAR_DATA *ch, char *argument)
{
    char arg[MAX_STRING_LENGTH];
    char arg2[MAX_STRING_LENGTH];
    char arg3[MAX_STRING_LENGTH];
    int  i;
    HINT_DATA *hintData;
    int no=0;
    int ano=0;
    bool found=FALSE;


    if (IS_NPC(ch))
	return;

    if (!IS_IMMORTAL(ch))
	return;
/*
    else 
    if (argument[0] == '\0' && IS_IMMORTAL(ch))
    {
	send_to_char_color("&CHint what ?\n\r",ch);
	return;
    }
*/

    set_char_color( AT_LBLUE, ch );
    argument = one_argument(argument,arg);
    argument = one_argument(argument,arg2);
    argument = one_argument(argument,arg3);
    if (!str_cmp(arg,"help") || arg[0]=='\0')
    {
	do_help( ch, "imm_hints" );
     	return;
    }
/*
    if (!str_cmp(arg,"sort"))
    {
	HINT_DATA *pCurrentHint;
	
        pCurrentHint = first_hint;  
 
        while (pCurrentHint->next)
        {
                if (pCurrentHint->next->low < pCurrentHint->low)
                {
                        while (pCurrentHint->next->low < pCurrentHint->low)
                        {
                                SwapHint(pCurrentHint, pCurrentHint->next);
 
                                if(pCurrentHint->prev->prev)
                                {
                                        pCurrentHint = pCurrentHint->prev->prev;
                                }
                                else
                                {
                                        pCurrentHint = first_hint;
                                }
                        }
                }
                else
                {
                        pCurrentHint = pCurrentHint->next;
                }
        }
	send_to_char_color("Hints have been sorted.\n\r",ch);
	return;
    }
*/
    if(!str_cmp(arg,"list"))
    {
        if (first_hint)
        {
    	    pager_printf(ch,"No | Low | High |            Text             \n\r");
    	    pager_printf(ch,"---|-----|------|--------------------------------------------------\n\r");
    	    i=0;
    	    for (hintData=first_hint;hintData;hintData = hintData->next)
    	    {
    	    	i++;
    	    	pager_printf(ch,"%2d | %3d | %4d | %-30s\n\r",i,hintData->low,hintData->high,hintData->text);
     	    }
 	    pager_printf(ch,"\n\r%d hints in file.\n\r",i);
 	}
 	else
 	   ch_printf(ch,"No hints in file.\n\r");
 	return;
    }

    else if (!str_cmp(arg,"remove"))
    {
	no = 0;
	if (!is_number(arg2))
	{
	    send_to_char_color("Remove which hint?\n\r",ch);
	    return;
	}
	ano = atoi(arg2);
	found = FALSE;
	for (hintData=first_hint;hintData;hintData=hintData->next)
	{
	    no++;
	    if (no==ano)
	    {
		    ch_printf_color(ch,"&CHint Number %d removed\n\r",ano);
		    UNLINK(hintData,first_hint,last_hint,next,prev);
	   	    if (hintData->text) STRFREE(hintData->text);
		    DISPOSE(hintData);
		    found = TRUE;
		    break;
	    }
	}
	if (!found)
	{
	    send_to_char("Hint not found\n\r",ch);
	    return;
	}
	return;
    }
    else if (!str_cmp(arg,"add"))
    {
	if (arg2=='\0')
	{
	    send_to_char("What is the minimum level for this hint?\n\r",ch);
	    return;
	}
	if (arg3=='\0')	
	{
	    send_to_char("What is the maximum level for this hint?\n\r",ch);
	    return;
	}
	if (atoi(arg2) > atoi(arg3))
 	{
	    ch_printf(ch,"Aborting:  max less than min!\n\r");
	    return;
	}
	CREATE(hintData, HINT_DATA,1);
	hintData->low = atoi(arg2);
	hintData->high = atoi(arg3);
	hintData->text = STRALLOC(argument);
	LINK(hintData,first_hint,last_hint,next,prev);
	send_to_char("Ok.  Hint created\n\r",ch);
	return;
    }
    else if (!str_cmp(arg,"force"))
    {
	ch_printf_color( ch,"&p( &wHINT&p ):  &P%s\n\r", get_hint(50));
	return;
    }
    else if (!str_cmp(arg,"edit"))
    {
    	int no=0;
    	int i=0;
    	
    	if (arg2[0]== '\0')
    	{
    	    ch_printf(ch,"Edit which hint number?\n\r");
    	    return;
    	}
    	else no = atoi(arg2);
    	if (arg3[0]=='\0')
    	{
    	    ch_printf(ch,"Edit which field of hint %d (low/high/text)?\n\r",no);
    	    return;
    	}
    	if (argument[0]=='\0')
    	{
    	    ch_printf(ch,"Change hint %d's field %s to what ?\n\r",no,arg3);
    	    return;
    	}
    	for (hintData=first_hint;hintData;hintData = hintData->next)
    	{
    	    i++;
    	    if (i==no)
    	    {
    	    	found = TRUE;
    	    	break;
    	    }
    	}
    	if (!found)
    	{
    	    ch_printf(ch,"Hint %d not found.\n\r",no);
    	    return;
    	}
    	else
    	{
    	    if (!str_cmp(arg3,"text"))
    	    {
    	    	if (hintData->text) STRFREE(hintData->text);
    	    	hintData->text = STRALLOC(argument);
    	    	ch_printf(ch,"Hint text changed!\n\r");
    	    	return;
    	    }
    	    else if (!str_cmp(arg3,"low"))
    	    {
		if (atoi(argument) > hintData->high)
		{
		    ch_printf(ch,"Aborting:  min higher than max.\n\r");
		    return;
		}
		hintData->low = atoi(argument);
    	    	ch_printf(ch,"Minimum level for hint changed.\n\r");
    	    	return;
    	    }
	    else if (!str_cmp(arg3,"high"))
	    {
		if (atoi(argument) < hintData->low)
		{
		    ch_printf(ch,"Aborting:  max lower than min.\n\r");
		    return;
		}
		hintData->high = atoi(argument);
		ch_printf(ch,"Maximum level for hint changed.\n\r");
		return;
	    }
    	    else
    	    {
    	    	ch_printf(ch,"Valid fields are:  low/high/text\n\r",ch);
    	    	return;
    	    }
    	}
    }
    else if (!str_cmp(arg,"save"))
    {
    	write_hint();	    
	ch_printf(ch,"Saved.\n\r");
    }
    else
    {
	send_to_char("Syntax:  hint (list/add/remove/edit/save/force)\n\r",ch);
	return;
    }	
}


void load_hint( void )
{
   char filename[MAX_INPUT_LENGTH];
   FILE *fp;
   HINT_DATA *hintData;

   first_hint = NULL;
   last_hint = NULL;
   sprintf( filename, "%s",HINT_FILE );
   if( ( fp = fopen( filename, "r" ) ) == NULL )
      return;

   while( ( hintData = read_hint( filename, fp ) ) != NULL )
      LINK( hintData, first_hint, last_hint, next, prev );

   return;
}
HINT_DATA *read_hint( char *filename, FILE *fp )
{
   HINT_DATA *hintData;
   char *word;
   char buf[MAX_STRING_LENGTH];
   bool fMatch;
   char letter;

   do
   {
      letter = getc( fp );
      if( feof(fp) )
      {
         fclose( fp );
         return NULL;
      }
   }
   while( isspace(letter) );
   ungetc( letter, fp );

   CREATE( hintData, HINT_DATA, 1);
#ifdef KEY
#undef KEY
#endif
#define KEY( literal, field, value )                                    \
                                if ( !str_cmp( word, literal ) )        \
                                {                                       \
                                    field  = value;                     \
                                    fMatch = TRUE;                      \
                                    break;                              \
                                }
   hintData->next       = NULL;
   hintData->prev       = NULL;
   hintData->text	   = STRALLOC("");
   hintData->low	   = 0;
   hintData->high       = 0;
    for ( ; ; )
    {
        word   = feof( fp ) ? "End" : fread_word( fp );
        fMatch = FALSE;

        switch ( UPPER(word[0]) )
        {
        case 'T':
                if (!str_cmp(word, "Text") )
                        STRFREE(hintData->text);
                KEY("Text",           hintData->text,         fread_string( fp ));
                break;
        case 'E':
            if ( !str_cmp( word, "End" ) )
            {
              if ( !hintData->text )
                hintData->text = STRALLOC("");
              return hintData;
            }
                break;
        case 'H':
                KEY("High",           hintData->high, fread_number(fp));
                break;
        case 'L':
                KEY("Low",           hintData->low, fread_number(fp));
                break;
        }
        if ( !fMatch )
        {
            sprintf( buf, "read_hint: no match: %s", word );
            bug( buf, 0 );
        }
    }
  if ( hintData->text)
        STRFREE( hintData->text);
  DISPOSE( hintData);
  return hintData;
}