OK, so I did some more checking and experimenting...
It turns out that while the original code appears to handle scaled HP incorrectly, it does handle Mana and Endurance correctly. I had made changes to the code to try and get HP to work, and that's when the Mana and Endurance started showing discrepancies. I'm not sure why this is the case, but it appears that HP is handled differently than Mana and Endurance in terms of the actual data values used. I can't figure that one out, but I'm not too worried about it.
When I changed the code to try and fix the HP issue, I used implicit type conversion, and this caused the issue with Mana and Endurance to show up. Apparently there was some data loss and it was setting the return values for scaled Mana and Endurance to be 0, so the server was using values as though there was no bonus Mana or Endurance, while the client was showing the correct values for what should have been there. I changed it again to use explicit type conversion and now all three seem to work correctly, at least on my client and server combination (server is slightly modified from 01/23/2014 git, client is RoF).
If anyone is interested, all I changed was the CalcRecommendedLevelBonus function in bonuses.cpp to use float values instead of int values. I didn't honestly expect that to work, I just wanted the code to make more sense to me personally, but it seems to have solved the issue. Following is my modified function...
Code:
int Client::CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat)
{
if( (reclevel > 0) && (level < reclevel) )
{
// DrakePhoenix: original function...
/*int32 statmod = (level * 10000 / reclevel) * basestat;
if( statmod < 0 )
{
statmod -= 5000;
return (statmod/10000);
}
else
{
statmod += 5000;
return (statmod/10000);
}*/
// DrakePhoenix: my function... designed to use full float values, then use standard rounding
// values between 0.0 and 1.0 will always be 1.0
// negative values will not be scaled
int32 statmod = 0;
float statmodf = (float(level) / float(reclevel)) * float(basestat);
statmodf = statmodf + 0.5; // used for rounding, necessary for float-to-int truncation
// standard rounding would normally require a -0.5 for negative values, but since negative values are not scaled, no need
// if scaled stat bonus is greater than 0.0 but less than 1.0, use value of 1.0
if((statmodf > 0.0) && (statmodf < 1.0))
{
statmodf = 1.0;
}
statmod = int32(statmodf); // convert float value to int value so we can return int.
// if basestat is a negative value, do not scale, but use full amount
if(basestat < 0)
{
statmod = basestat;
}
return statmod;
}
return 0;
}
Using my modified function as above the client and server both now seem to agree on max and actual stats for HP, Mana, and Endurance when using level-scaled bonuses.
Take care,
Drake Phoenix