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.
Australia Forum Administrator
#1
USA
#2
USA
#3
USA
#4
USA
#5
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;
}
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;
I would default it to zero, like this:
int old_hp, new_hp, level, hp_mod = 0, new_max;
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.
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;}
}
}
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++;}
}
}
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.