Function issues

Posted by Meerclar on Wed 25 Dec 2002 05:30 PM — 6 posts, 20,695 views.

USA #0
I am trying to use the function below to recalculate perm_hit for morts based on the values used for training hp presently. The code compiles clean on MSVC and gives a potentially uninitialized warning on hp_mod.


void do_updatehp(char_data *ch, char *argument)
{
 BUFFER *output;
    char_data *victim;
    char arg[MIL];
    char buf[MSL];
    int old_hp, new_hp, level, hp_mod, new_max;
 
 argument = one_argument( argument, arg );
 
 if(arg[0] == '\0' )
 {
        ch->println( "Syntax: updatehp <player>" );
        return;
 }
 
    if ( ( victim = get_char_world( ch, arg ) ) == NULL )
    {
        ch->println( "They aren't here." );
        return;
    }
 
    if (IS_NPC(victim))
    {
        ch->println( "Not on NPCS" );
        return;
    }
/*
Kinda needs to be SB:R config specific
*/
 if(GAMESETTING4(GAMESET4_STORM_HP_CALCULATIONS)){
 
    /* setup a buffer for info to be displayed and initialise our memory variables */
    output = new_buf();
 old_hp = victim->pcdata->perm_hit; // Save old perm_hp
 level = 1;
 new_hp = 20; // Set base hp for new hp calculation
 
    sprintf(buf, "Updating hit points for %s [%d] (%s).",
    victim->name, victim->level, class_table[victim->clss].name);
    log_string(buf);
 
// Idiot checks
    
 if (victim->level>=LEVEL_IMMORTAL)
    {
        log_string("Character is an immortal - aborting");
        if (ch!=victim)
            ch->println( "UpgradeHP isn't relevant to immortals." );
        free_buf(output);
        return;
    }
 
    if (victim->level<2)
    {
        log_string("Character is an level 1 newbie - update not relevant.");
        if (ch!=victim)
            ch->println( "UpgradeHP isn't relevant to level 1 players." );
        free_buf(output);
        return;
    }
 
 //Get hp bonus per level
 if (((ch->perm_stats[STAT_CO] + ch->perm_stats[STAT_SD]) / 2) >= 70)
  hp_mod = 1;
 if (((ch->perm_stats[STAT_CO] + ch->perm_stats[STAT_SD]) / 2) >= 90)
  hp_mod = 2;
 if (((ch->perm_stats[STAT_CO] + ch->perm_stats[STAT_SD]) / 2) >= 100)
  hp_mod = 3;
 
 //loop to deal with calculating revised totals
 while (level <= victim->level ){
  new_hp= (new_hp + number_range(class_table[ch->clss].hp_min, class_table[ch->clss].hp_max));
  new_hp= new_hp + hp_mod;
  new_max = ch->max_hit + new_hp;
  ch->pcdata->perm_hit = UMAX(ch->pcdata->perm_hit, new_max);
  level += 1;}
}
ch->max_hit = ch->pcdata->perm_hit;
}

Australia Forum Administrator #1
You set hp_mod to 1, 2 or 3 depending on certain conditions, but what if those conditions are not met?

I would default it to zero, like this:


int old_hp, new_hp, level, hp_mod = 0, new_max;

USA #2
Thanks for the catch on that one Nick, I hadnt even realized I forgot a default hp_mod value in this routine. I've updated that and made a few other changes as well.... I'll post the current version of the function in a while.
USA #3
Current version, composite fixes included from several sources for several potential problems.

void do_updatehp(char_data *ch, char * argument)
{
	BUFFER *output;
    char_data *victim;
    char arg[MIL];
    char buf[MSL];
    int old_hp;
	int new_hp;
	int cycle;
	int hp_mod;
	int new_max;

	argument = one_argument( argument, arg );

	if(arg[0] == '\0' )
	{
        ch->println( "Syntax: updatehp <player>" );
        return;
	}

    if ( ( victim = get_char_world( ch, arg ) ) == NULL )
    {
        ch->println( "They aren't here." );
        return;
    }

    if (IS_NPC(victim))
    {
        ch->println( "Not on NPCS" );
        return;
    }

	//Kinda needs to be SB:R config specific
	if(GAMESETTING4(GAMESET4_STORM_HP_CALCULATIONS)){

    /* setup a buffer for info to be displayed and initialise our memory variables */
    output = new_buf();
	old_hp = victim->pcdata->perm_hit; //Save old perm_hp
	cycle = 1;
	new_hp = 20; //Set base hp for new hp calculation
	new_max = 20;

    sprintf(buf, "Updating hit points for %s [%d] (%s).",
    victim->name, victim->level, class_table[victim->clss].name);
    log_string(buf);
	ch->println(buf);

	//Idiot checks
    
	if (victim->level>=LEVEL_IMMORTAL)
    {
        log_string("Character is an immortal - aborting");
        if (ch!=victim)
            ch->println( "UpgradeHP isn't relevant to immortals." );
        free_buf(output);
        return;
    }

    if (victim->level<2)
    {
        log_string("Character is an level 1 newbie - update not relevant.");
        if (ch!=victim)
            ch->println( "UpgradeHP isn't relevant to level 1 players." );
        free_buf(output);
        return;
    }
	
	hp_mod = 0;
	//Get hp bonus per level
	if (((ch->perm_stats[STAT_CO] + ch->perm_stats[STAT_SD]) / 2) >= 70)
		hp_mod = 1;
	if (((ch->perm_stats[STAT_CO] + ch->perm_stats[STAT_SD]) / 2) >= 90)
		hp_mod = 2;
	if (((ch->perm_stats[STAT_CO] + ch->perm_stats[STAT_SD]) / 2) >= 100)
		hp_mod = 3;

	//loop to deal with calculating revised totals
	while (cycle <= victim->level ){
		new_hp= (new_max + number_range(class_table[ch->clss].hp_min, class_table[ch->clss].hp_max));
		new_hp= new_hp + hp_mod;
		new_max = new_max + new_hp;
		ch->max_hit = new_max;
		ch->pcdata->perm_hit = UMAX(ch->pcdata->perm_hit, new_max);
		cycle += 1;}
}
}
USA #4
After heavy debugging and reworking, Ive discovered that the loop itself is working fine, the only problem I can't seem to track down is why the updated chars hp arent replaced with the new values where appropriate. Below is the current version with all of the latest corrections and logging code in place.

void do_updatehp(char_data *ch, char * argument)
{
	BUFFER *output;
    char_data *victim;
    char arg[MIL];
    char buf[MSL];
    int old_hp;
	int new_hp;
	int cycle;
	int hp_mod;
	int new_max;

	argument = one_argument( argument, arg );

	if(arg[0] == '\0' )
	{
        ch->println( "Syntax: updatehp <player>" );
        return;
	}

    if ( ( victim = get_char_world( ch, arg ) ) == NULL )
    {
        ch->println( "They aren't here." );
        return;
    }

    if (IS_NPC(victim))
    {
        ch->println( "Not on NPCS" );
        return;
    }

	//Kinda needs to be SB:R config specific
	if(GAMESETTING4(GAMESET4_STORM_HP_CALCULATIONS)){

    /* setup a buffer for info to be displayed and initialise our memory variables */
    output = new_buf();
	old_hp = victim->pcdata->perm_hit; //Save old perm_hp
	cycle = 2;
	new_hp = 20; //Set base hp for new hp calculation, level 1 value
	new_max = 20;

    sprintf(buf, "Updating hit points for %s [%d] (%s).",
    victim->name, victim->level, class_table[victim->clss].name);
    log_string(buf);
	ch->println(buf);

	//Idiot checks
    
	if (victim->level>=LEVEL_IMMORTAL)
    {
        log_string("Character is an immortal - aborting");
        if (ch!=victim)
            ch->println( "UpgradeHP isn't relevant to immortals." );
        free_buf(output);
        return;
    }

    if (victim->level<2)
    {
        log_string("Character is an level 1 newbie - update not relevant.");
        if (ch!=victim)
            ch->println( "UpgradeHP isn't relevant to level 1 players." );
        free_buf(output);
        return;
    }
	
	hp_mod = 0;
	//Get hp bonus per level
	if (((ch->perm_stats[STAT_CO] + ch->perm_stats[STAT_SD]) / 2) >= 70)
		hp_mod = 1;
	if (((ch->perm_stats[STAT_CO] + ch->perm_stats[STAT_SD]) / 2) >= 90)
		hp_mod = 2;
	if (((ch->perm_stats[STAT_CO] + ch->perm_stats[STAT_SD]) / 2) >= 100)
		hp_mod = 3;

	//loop to deal with calculating revised totals
	while (cycle <= victim->level ){
		new_hp = (new_hp + number_range(class_table[ch->clss].hp_min, class_table[ch->clss].hp_max));
		new_hp = new_hp + hp_mod;
		new_max = new_hp;
		ch->max_hit = UMAX(new_max, ch->max_hit);
		ch->pcdata->perm_hit = UMAX(ch->pcdata->perm_hit, new_max);
		sprintf( buf,"Update cycle %d, new_hp = %d, new_max = %d", cycle, new_hp, new_max );
		log_string(buf);
		cycle++;}
}
}
USA #5
K, I finally realized what was wrong with this thing to keep it from updating values where appropriate. I managed to change back to ch->values inatead of victim->values about halfway thru the function. Kinda difficult to update the intended victim when yer evaluating against the imm doing the update.... Only took 2 days to realize what I did wrong.