dawn/notes/
dawn/src/
dawn/src/docs/
/**************************************************************************/
// roles.cpp - character stat roller, Kal
/***************************************************************************
 * The Dawn of Time v1.69r (c)1997-2004 Michael Garratt                    *
 * >> A number of people have contributed to the Dawn codebase, with the   *
 *    majority of code written by Michael Garratt - www.dawnoftime.org     *
 * >> To use this source code, you must fully comply with the dawn license *
 *    in licenses.txt... In particular, you may not remove this copyright  *
 *    notice.                                                              *
 **************************************************************************/
/***************************************************************************
 *  FILE: roles.cpp - stat roling system - based heavily of the            *
 *                    rolemaster stat system.                              *
 ***************************************************************************/
#include "include.h"
#include "roles.h"

const struct role_type role_table[39] = {
//  low,high, 25, 39, 59, 74, 84, 89, 94, 97, 99,100
	{-2, -2, {25, 39, 59, 74, 84, 89, 94, 97, 99,100}},
    {1 , 10, {25, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, 
    {11, 20, {30, -1, -1, -1, -1, -1, -1, -1, -1, -1}}, 
    {21, 30, {35, 39, -1, -1, -1, -1, -1, -1, -1, -1}}, 
    {31, 35, {38, 42, 59, -1, -1, -1, -1, -1, -1, -1}}, 
    {36, 40, {40, 45, 62, -1, -1, -1, -1, -1, -1, -1}}, 
    {41, 45, {42, 47, 64, -1, -1, -1, -1, -1, -1, -1}}, 
    {46, 49, {44, 49, 66, -1, -1, -1, -1, -1, -1, -1}}, 
    {50, 51, {46, 51, 68, -1, -1, -1, -1, -1, -1, -1}}, 
    {52, 53, {48, 53, 70, -1, -1, -1, -1, -1, -1, -1}}, 
    {54, 55, {50, 55, 71, -1, -1, -1, -1, -1, -1, -1}}, 
    {56, 57, {52, 57, 72, 74, 84, -1, -1, -1, -1, -1}}, 
    {58, 59, {54, 59, 73, 75, 85, -1, -1, -1, -1, -1}}, 
    {60, 61, {56, 61, 74, 76, 86, -1, -1, -1, -1, -1}}, 
    {62, 63, {58, 63, 75, 77, 87, -1, -1, -1, -1, -1}}, 
    {64, 65, {60, 65, 76, 78, 88, -1, -1, -1, -1, -1}}, 
    {66, 67, {62, 67, 77, 79, 88, 89, -1, -1, -1, -1}}, 
    {68, 69, {64, 69, 78, 80, 89, 89, -1, -1, -1, -1}}, 
    {70, 71, {66, 71, 79, 81, 89, 90, -1, -1, -1, -1}}, 
    {72, 73, {68, 73, 80, 82, 90, 90, -1, -1, -1, -1}}, 
    {74, 75, {70, 75, 81, 83, 90, 91, -1, -1, -1, -1}}, 
    {76, 77, {72, 77, 82, 84, 91, 91, -1, -1, -1, -1}}, 
    {78, 79, {74, 79, 83, 85, 91, 92, -1, -1, -1, -1}}, 
    {80, 81, {76, 81, 84, 86, 92, 92, -1, -1, -1, -1}}, 
    {82, 83, {78, 83, 85, 87, 92, 93, -1, -1, -1, -1}}, 
    {84, 85, {80, 85, 86, 88, 93, 93, 94, -1, -1, -1}}, 
    {86, 87, {82, 86, 87, 89, 93, 94, 94, -1, -1, -1}}, 
    {88, 89, {84, 87, 88, 90, 94, 94, 95, -1, -1, -1}}, 
    {90, 90, {86, 88, 89, 91, 94, 95, 95, 97, -1, -1}}, 
    {91, 91, {88, 89, 90, 92, 95, 95, 96, 97, -1, -1}}, 
    {92, 92, {90, 90, 91, 93, 95, 96, 96, 97, -1, -1}}, 
    {93, 93, {91, 91, 92, 94, 96, 96, 97, 98, -1, -1}}, 
    {94, 94, {92, 92, 93, 95, 96, 97, 97, 98, 99, -1}}, 
    {95, 95, {93, 93, 94, 96, 97, 97, 98, 98, 99, -1}}, 
    {96, 96, {94, 94, 95, 97, 97, 98, 98, 99, 99, -1}}, 
    {97, 97, {95, 95, 96, 97, 98, 98, 99, 99, 99, -1}}, 
    {98, 98, {96, 96, 97, 98, 98, 99, 99, 99,100, -1}}, 
    {99, 99, {97, 97, 98, 98, 99, 99,100,100,100, -1}}, 
    {100,100,{98, 98, 99, 99, 99,100,100,100,100,101}}
};

/**************************************************************************/
int role_table_lookup(int first_role){
	int second_roll;
	int vert_index, horizontal_index;

	// find where first_role fits horizontally in the table 
	for(horizontal_index=0;horizontal_index<10;horizontal_index++){
		if (first_role<= role_table[0].table[horizontal_index]){
			break;
		}
	}
	
	second_roll = number_range(1,100);
	// find where the second roll fits vertically in the table
	for(vert_index=1;vert_index<39;vert_index++){
		if (second_roll<= role_table[vert_index].high){
			break;
		}
	}

#ifdef STATS_SYSTEM_DEBUG
	logf("rtl> f=%2d, s=%2d, r=%2d",first_role, second_roll,
		UMAX(role_table[vert_index].table[horizontal_index],first_role));
#endif
	return (UMAX(role_table[vert_index].table[horizontal_index], first_role));
}


/**************************************************************************/
// modifies the rolled_stats pointer to a rolled set of stats
// using the rolemaster stat generation system
void gen_rolemaster_stats(attributes_set *rolled_stats, int bias_against){
	int rolling_stat, roll_out_of, total, loop, i;
	int highstats;

#ifdef STATS_SYSTEM_DEBUG
	logf("gen_rolemaster_stats() test - bias = %d ", 
		bias_against);
#endif

	loop=0;
    do{
		loop++;
		for (rolling_stat=0; rolling_stat<10; rolling_stat++){
			// generate the first part of the stat
			do{
				if(GAMESETTING(GAMESET_ROLE_ROLEMASTER_STATS)){
					roll_out_of=100;
				}else{					
					roll_out_of=number_range(UMIN(game_settings->roll_min_total/5, 100),
											UMIN(game_settings->roll_max_total/10, 100));
					roll_out_of=number_range(URANGE(10,game_settings->roll_min_total/7, 70),	
												roll_out_of);
				}

				if(!GAMESETTING(GAMESET_NO_BIAS_AGAINST_REROLLING)){
					if(bias_against>5){
						roll_out_of-=(bias_against*3);
						roll_out_of=UMAX(roll_out_of,60);
					}
				}

				rolled_stats->perm[rolling_stat]=number_range(1,roll_out_of);			
			}while (rolled_stats->perm[rolling_stat]<20);

			rolled_stats->potential[rolling_stat]=
				role_table_lookup(rolled_stats->perm[rolling_stat]);	
		}
        total=0; 
		highstats=0;
        for(i=0; i<MAX_STATS; i++)
        {
            total+=rolled_stats->potential[i];
            if(rolled_stats->potential[i]>80)
            {
                total+=10;
            }
            if(rolled_stats->potential[i]>90)
            {
				highstats++;
                total+=5;
            }
        }
		total+=highstats*highstats*4;
    }while( (   total<game_settings->roll_min_total
		     || total> game_settings->roll_max_total)
			&& loop<100);


	if (loop>99)
	{
		logf("gen_rolemaster_stats(): Reroll looped %d times! bias_against = %d", 
			loop, bias_against);

		char buf[MSL];
		sprintf(buf,"Rolling char - warning, if we get lots of these, "
			"there might be a bug in stat rolling - unverified stats were allowed thru!");
		autonote(NOTE_SNOTE, "p_anote()","Reroll looped =100 times!", 
			"admin", buf, true);
	}


}
/**************************************************************************/