If I got the code right,
in
LootManager::checkLoot
the line
real_chance = static_cast<int>(static_cast<float>(ec->z) * static_cast<float>(pc->stats.get(Stats::ITEM_FIND) + 100) / 100.f);
truncates the player's 'Item Find Chance' ruthlessly, if the ec->z is small.
I guess this is not intended.
Example:
unique item: ec->z == 1
then:
'Item Find Chance' == 155% -> real_chance == trunc(2.55) == 2
'Item Find Chance' == 100% -> real_chance == trunc(2.0) == 2
where this is later checked against
int chance = Math::randBetween(1,100);
(for items with a higher drop chance, this truncation is less coarse,
but still the resolution of 0.05 for that property is not respected.
)
---
possible fix:
int chance = Math::randBetween(1,100*100);
real_chance = static_cast<int>(static_cast<float>(ec->z) * static_cast<float>(pc->stats.get(Stats::ITEM_FIND) + 100));
// (dropping the division by 100.f )
and in subsequent lines multiply all numbers with 100 etc.
There is a mistake in the above fix proposal.
It must be
int chance = Math::randBetween(1,100*100);
Thanks for the report. What we may do is start using floats across the board for item chance values, including in the game data. As of now, modders are limited to 1% as the smallest drop rate for items, so I'd like to add more flexibility in such cases.
A fix for this using floats is now upstream: https://github.com/flareteam/flare-engine/commit/bbc5f629e4da8a21a8a94a6...
I think there is a new bug in the bugfix:
in src/UtilsMath.h
function randBetweenF
the line
return minVal + (static_cast<float>(rand()) / static_cast<float>(RAND_MAX)) * maxVal;
should be
return minVal + (static_cast<float>(rand()) / static_cast<float>(RAND_MAX)) * (maxVal - minVal);
i.e. (maxVal - minVal) instead of maxVal
Good catch. It had no affect on item drops, since the minVal there is zero. A fix is now upstream.