Ace notified me of a weird, random crash in my implementation.
It took me some time, but I found two bugs:
1. When the current exp gets close to the max exp, the percentage will round to 100%
I guessed this would only have visual effects, but i was taught other xD.
Having a percentage of 100 will cause this line
Code:
int barnum = floor(exp_percentage / 10.0);
to return 10 as the highest bar-index to be filled, but there are only 0-9 bars available causing this line:
Code:
gauges[barnum]->background_value = exp_remain;
gauges[barnum]->foreground_value = exp_remain;
to crash the application.
Luckily, there is a simple
fix for this:
Code:
// Calculate EXP as percentage value
double exp_percentage = g_CICPlayer->exp_current * 100.0 / data->Exp_C;
if (exp_percentage > 99.99)
exp_percentage = 99.99;
2. GetLevelData sometimes returns nullptr
I actually noticed that during testing, but considered it being a bug of my own. When i fixed several offset-issues regarding
g_CICPlayer->level, it did not occur again so i considered it fixed.
It still seems to appear, so ... wtf?
Definitely needs more research, but there is a quick fix that will solve it for now.
Code:
// Retrieve LevelData for current Level
// (this is one line of Media\server_dep\silkroad\textdata\leveldata.txt)
CLevelData* data = g_CGlobalDataManager->GetLevelData(g_CICPlayer->level);
if (data == 0)
return;
Edit: Many months later, I seem to have finally figured out whats wrong. The level of the player is stored as a byte, while I am interpreting it as an int (4 byte). While the other 3 bytes are null, there is no problem. If the other bytes are not null, they are interpreted as the level, too, resulting in levels greater than 1000 or even a couple of million. As a result, GetLevelData(1 Million) will return crap, causing my code to do crap and eventually crash.
Long story short: Make level a char instead of int. Problem solved
Thanks to $Wegs for debugging this out with me and supplying helpful crashdumps.