There is a very old bug, most known on servers where players can deal absurd amount of damage or there is a world boss and many players can join the fight.
So the issue is that mobs can drop items without ownership, and if there is a lot of players the drop just instantly disappears cause everyone is spamming the pick up key.
How is it possible?
The main issue is in CHARACTER::Reward (check comments):
std::priority_queue<std::pair<int, LPCHARACTER> > pq;
int total_dam = 0;
for (TDamageMap::iterator it = m_map_kDamage.begin(); it != m_map_kDamage.end(); ++it)
{
int iDamage = it->second.iTotalDamage;
if (iDamage > 0)
{
LPCHARACTER ch = CHARACTER_MANAGER::instance().Find(it->first);
if (ch)
{
pq.push(std::make_pair(iDamage, ch));
// first issue here
total_dam += iDamage;
}
}
}
std::vector<LPCHARACTER> v;
// second one here
while (!pq.empty() && pq.top().first * 10 >= total_dam)
{
v.emplace_back(pq.top().second);
pq.pop();
}
so when the total damage (int total_dam) of all players exceeds INT_MAX, guess what happens? It overflows to values below 0.
Another risk is that pq.top().first * 10 will exceed the INT_MAX if the fight is long enough and the player has really good DPS.
How do we fix it? It's trivial easy:
@@ -812,7 +812,7 @@ void CHARACTER::Reward(bool bItemDrop)
std::priority_queue<std::pair<int, LPCHARACTER> > pq;
- int total_dam = 0;
+ long long total_dam = 0;
for (TDamageMap::iterator it = m_map_kDamage.begin(); it != m_map_kDamage.end(); ++it)
{
@@ -830,8 +830,7 @@ void CHARACTER::Reward(bool bItemDrop)
}
std::vector<LPCHARACTER> v;
-
- while (!pq.empty() && pq.top().first * 10 >= total_dam)
+ while (!pq.empty() && static_cast<long long>(pq.top().first) * 10 >= total_dam)
{
v.emplace_back(pq.top().second);
pq.pop();
--
The topic covers the case which can occur on base Metin2. There is nearly 0% chance to reach INT_MAX in total damage per Mob as a normal player.
However, 30 players fighting with world boss are able to exceed the INT limit.
If you assume that a player himself is able to exceed INT_MAX in total damage per mob you should consider changing the type of iTotalDamage in TBattleInfo struct.
This of course comes with more editions, wherever the damage map is changed or read.