eldhamud/boards/
eldhamud/clans/
eldhamud/classes/
eldhamud/councils/
eldhamud/deity/
eldhamud/doc/
eldhamud/doc/DIKU/
eldhamud/doc/MERC/
eldhamud/doc/mudprogs/
eldhamud/houses/
#include "mud.h"
#if defined(KEY)
#undef KEY
#endif

#define KEY( literal, field, value )					\
				if ( !str_cmp( word, literal ) )	\
				{					\
				    field  = value;			\
				    fMatch = TRUE;			\
				    break;				\
				}

/*
 * Load a single stock and put it into the linked list
 */
void fread_stock( FILE *fp)
{
    char buf[MAX_STRING_LENGTH];
    char *word;
    bool fMatch;
	STOCK_DATA *stock;

    CREATE( stock, STOCK_DATA, 1 );
    
    for ( ; ; )
    {
		word   = feof( fp ) ? "End" : fread_word( fp );
		fMatch = FALSE;

		switch ( UPPER(word[0]) )
		{
			case '*':
	   			fMatch = TRUE;
	    		fread_to_eol( fp );
	    	break;
			case 'N':
				KEY( "Name", stock->name, fread_string_nohash( fp ) );
				break;
			case 'V':
				KEY( "Vnum", stock->vnum, fread_number( fp ) );
				break;
			case 'C':
				KEY( "Constant", stock->resource_constant, fread_number( fp ) );
				break;
			case 'S':
				KEY( "Supply", stock->resource_supply, fread_number( fp ) );
				break;
			case 'E':
				if( !str_cmp( word, "End" ) )
				{
					LINK( stock, first_stock, last_stock, next, prev );
					return;
				}
				break;
		}
		
		if ( !fMatch )
		{
            sprintf( buf, "Fread_stock: no match: %s", word );
	    	bug( buf, 0 );
		}
    }
}

/**
 * Builds the Resource linked-list
 */
void load_stocks()
{
    FILE *fp;

    if ( ( fp = fopen( STOCKS_FILE, "r" ) ) != NULL )
    {
		for ( ;; )
		{
	    	char letter;
		    char *word;

	    	letter = fread_letter( fp );
		
		    if ( letter == '*' )
		    {
				fread_to_eol( fp );
				continue;
		    }
	
		    if ( letter != '#' )
	    	{
            	bug( "Load_stocks: # not found.", 0 );
				break;
		    }

	    	word = fread_word( fp );
			
	        if ( !str_cmp( word, "STOCK"      ) )
		    {
				fread_stock( fp );
				continue;
		    }
	    	else
		    if ( !str_cmp( word, "END"	) )
		        break;
	    	else
		    {
    	        bug( "Load_skill_table: bad section.", 0 );
				continue;
	    	}
		}
	fclose( fp );
    }
    else
    {
		perror( STOCKS_FILE );
		bug( "Cannot open stocks.dat", 0 );
 		exit(0);
    }
}

/*
 * Write skill data to a file
 */
void fwrite_stock( FILE *fpout, STOCK_DATA *stock )
{
	fprintf( fpout, "Name		%s~\n",	stock->name	             );
	fprintf( fpout, "Vnum		%d\n",  stock->vnum              );
	fprintf( fpout, "Constant	%d\n",  stock->resource_constant );
	fprintf( fpout, "Supply		%d\n",  stock->resource_supply   );
    fprintf( fpout, "End\n\n"                                    );
	return;
}

/*
 * Save the stocks to stocks.dat
 */
void save_stocks()
{
    FILE *fpout;
	STOCK_DATA *temp;

    if ( (fpout=fopen( STOCKS_FILE, "w" )) == NULL )
    {
		perror( STOCKS_FILE );
		bug( "Cannot open stocks.dat for writting", 0 );
		return;
    }

    for( temp = first_stock; temp; temp = temp->next )
    {
		if ( !temp->name || temp->name[0] == '\0' )
	   		break;
		fprintf( fpout, "#STOCK\n" );
		fwrite_stock( fpout, temp );
    }
	
    fprintf( fpout, "#END\n" );
    fclose( fpout );
}

/*
 * Returns pointer to stock structure based on vnum
 */
STOCK_DATA *get_stock( int vnum )
{
	STOCK_DATA *temp;
	for( temp = first_stock; temp; temp = temp->next )
		if( temp->vnum == vnum )
			return temp;
	return NULL;
}

/*
 * (Randomly) update the PPU value of each stock
 */
void update_stocks()
{
	int action, gain, loss;
	
	STOCK_DATA *temp;
	for( temp = first_stock; temp; temp = temp->next )
	{		
		action = number_percent();
		
		/* Normal -3% <-> +3% */
		if( action > 5 )
		{
			temp->resource_constant += number_range( -(temp->resource_constant * .03),(temp->resource_constant * .03) ); 
		}
		/* Extraordinary Gains +3% <-> +12% */
		else if( action > 1 )
		{
			gain = number_range( (temp->resource_constant * .03),(temp->resource_constant * .12) );
			temp->resource_constant += gain;
			/* Display a (good) message to the stock channel */			
		}
		/* Crash! -20% <-> -12% */
		else
		{			
			loss = number_range( -(temp->resource_constant * .2),(temp->resource_constant * .2) );
			temp->resource_constant += loss;
			/* display loss to stock channel */
		}
	}
	save_stocks();
	return;
}

/*
 * Administrative stocks command
 */
 
void do_stocks( CHAR_DATA *ch, char * argument )
{
	STOCK_DATA *temp;
	char arg1[MAX_INPUT_LENGTH];
	
	if( argument[0] == '\0' || !argument )
	{
		/* stock option... clever eh? --Jesse */
		send_to_char( "Syntax:\n\rstock <option> [option...]\n\r", ch );
		return;
	}
	
	if( !str_cmp( argument, "report" ) ) 
	{
		send_to_char( "------------------------------------------------------------------------\n\r", ch );
		send_to_char( "                               Stock Report\n\r",                              ch );
		send_to_char( "------------------------------------------------------------------------\n\r", ch );
		send_to_char( " vnum  | name            | price per unit | supply \n\r",  ch );
		for( temp = first_stock; temp; temp = temp->next ) 
		{
			ch_printf( ch, " %-5d | %-15s | %14d | %d\n\r", 
				temp->vnum, temp->name, temp->resource_constant, temp->resource_supply );
		}
		return;
	}
	
	argument = one_argument( argument, arg1 );
	
	/* Set values of a stock based on vnum */
	if( !str_cmp( arg1, "set" ) ) 
	{
		/*
		 * options:
		 *  -- NAME of the stock
		 *  -- PPU of the stock
		 *  -- SUPPLY of the stock
		 */
		char arg2[MAX_INPUT_LENGTH], arg3[MAX_INPUT_LENGTH];
		
		argument = one_argument( argument, arg2 );
		argument = one_argument( argument, arg3 );
		
		/* See if the vnum exists as a stock item */
		if( ( temp = get_stock( atoi( arg2 ) ) ) != NULL )
		{
			/* figure out which field to manipulate */
			if( !str_cmp( arg3, "name" ) )
			{
				/* Attempt to set the name */
				if( temp->name )
					DISPOSE( temp->name );
				temp->name = str_dup( argument );
				ch_printf( ch, "Stock #%d name changed to %s.\n\r", temp->vnum, temp->name );
				save_stocks();
				return;
			}
			else if( !str_cmp( arg3, "ppu" ) )
			{
				/* Attempt to set the price per unit */
				temp->resource_constant = atoi( argument );
				ch_printf( ch, "Stock %s(#%d) price per unit changed to %d\n\r", temp->name, temp->vnum, temp->resource_constant );
				save_stocks();
				return;
			}
			else if( !str_cmp( arg3, "supply" ) )
			{
				/* Attempt to set the supply */
				temp->resource_supply = atoi( argument );
				ch_printf( ch, "Stock %s(#%d) supply changed to %d\n\r", temp->name, temp->vnum, temp->resource_supply );
				save_stocks();
				return;
			}
			else
			{
				send_to_char( "&RInvalid field! valid fields are: name, ppu, and supply.\n\r", ch );
				return;
			}
		}
		send_to_char( "&RYou must supply a valid vnum!\n\r", ch );
		
		return;
	}
	
	/* Create a new stock */
	if( !str_cmp( arg1, "create" ) )
	{
		if( is_number( argument ) )
		{
			STOCK_DATA *stock;
			CREATE( stock, STOCK_DATA, 1 );
			stock->vnum = atoi( argument );
			LINK( stock, first_stock, last_stock, next, prev );
			ch_printf( ch, "Vnum #%d added as a stock item.\n\r", stock->vnum );
			return;
		}
		else
		{	
			send_to_char( "&RSyntax: stock create <vnum>\n\r", ch );
			return;
		}
	}
	
	/* Delete a stock */
	if( !str_cmp( arg1, "delete" ) )
	{
		STOCK_DATA *d_stock;
		if( ( d_stock = get_stock( atoi( argument ) ) ) != NULL )
		{
			ch_printf( ch, "Deleting %s(#%d )as a stock item\n\r", d_stock->name, d_stock->vnum );
			UNLINK( d_stock, first_stock, last_stock, next, prev );
			DISPOSE( d_stock->name );
			DISPOSE( d_stock );
			
		}
		else
		{
			send_to_char( "&RInvalid Vnum to delete!\n\r", ch );
			return;
		}
	}
	
	return;
}