LPCHARACTER CHARACTER::DistributeExp()
{
int iExpToDistribute = GetExp();
if (iExpToDistribute <= 0)
return NULL;
int iTotalDam = 0;
LPCHARACTER pkChrMostAttacked = NULL;
int iMostDam = 0;
typedef std::vector<TDamageInfo> TDamageInfoTable;
TDamageInfoTable damage_info_table;
std::map<LPPARTY, TDamageInfo> map_party_damage;
damage_info_table.reserve(m_map_kDamage.size());
TDamageMap::iterator it = m_map_kDamage.begin();
while (it != m_map_kDamage.end())
{
const VID &c_VID = it->first;
int iDam = it->second.iTotalDamage;
++it;
LPCHARACTER pAttacker = CHARACTER_MANAGER::instance().Find(c_VID);
if (!pAttacker || pAttacker->IsNPC() || DISTANCE_APPROX(GetX() - pAttacker->GetX(), GetY() - pAttacker->GetY()) > 5000)
continue;
iTotalDam += iDam;
if (!pkChrMostAttacked || iDam > iMostDam)
{
pkChrMostAttacked = pAttacker;
iMostDam = iDam;
}
if (pAttacker->GetParty())
{
auto it = map_party_damage.find(pAttacker->GetParty());
if (it == map_party_damage.end())
{
TDamageInfo di;
di.iDam = iDam;
di.pAttacker = NULL;
di.pParty = pAttacker->GetParty();
map_party_damage.insert(std::make_pair(di.pParty, di));
}
else
{
it->second.iDam += iDam;
}
}
else
{
TDamageInfo di;
di.iDam = iDam;
di.pAttacker = pAttacker;
di.pParty = NULL;
damage_info_table.push_back(di);
}
}
for (auto &it : map_party_damage)
{
damage_info_table.push_back(it.second);
}
SetExp(0);
if (iTotalDam == 0)
return NULL;
sys_log(1, "%s total exp: %d, damage_info_table.size() == %d, TotalDam %d",
GetName(), iExpToDistribute, damage_info_table.size(), iTotalDam);
if (damage_info_table.empty())
return NULL;
DistributeHP(pkChrMostAttacked);
// Yeni EXP Dağıtımı
for (auto &di : damage_info_table)
{
float fPercent = (float)di.iDam / iTotalDam;
if (fPercent > 1.0f)
fPercent = 1.0f;
int iExp = (int)(iExpToDistribute * fPercent);
LPCHARACTER pAttacker = di.pAttacker;
if (!pAttacker)
continue;
LPPARTY pParty = pAttacker->GetParty();
if (!pParty)
{
// Tek başına EXP alıyorsa
pAttacker->PointChange(POINT_EXP, iExp);
}
else
{
int iMemberCount = pParty->GetMemberCount();
if (iMemberCount <= 1)
{
pAttacker->PointChange(POINT_EXP, iExp);
continue;
}
LPCHARACTER leader = pParty->GetLeaderCharacter();
bool isLeader = (pAttacker == leader);
int finalExp = isLeader ? (iExp +iExp * (iMemberCount * 0.50f)) : (iExp + (iExp * (iMemberCount * 0.25f)));
pAttacker->PointChange(POINT_EXP, finalExp);
}
}
return pkChrMostAttacked;
}