Premium mihnea 38 Posted September 17, 2023 Premium Share Posted September 17, 2023 I can't find any answers on this. How does bonus drop and bonus yang work when you are in the party? I don't think it stacks. And who takes the kill when more people are attacking the same mob? Is it worth for your party members e.g. shamans to also stack bonus drop on their armor? Link to comment Share on other sites More sharing options...
Active+ Member m2Ciaran 389 Posted September 17, 2023 Active+ Member Share Posted September 17, 2023 Yes it does not work in party. Only killer is counted Link to comment Share on other sites More sharing options...
Premium mihnea 38 Posted September 17, 2023 Author Premium Share Posted September 17, 2023 and how is the killer decided? Link to comment Share on other sites More sharing options...
Active+ Member Solution m2Ciaran 389 Posted September 17, 2023 Active+ Member Solution Share Posted September 17, 2023 (edited) 27 minutes ago, mihnea said: and how is the killer decided? Last hit is the killer, but the item drop is divided by damage dealt You can see it in char_battle.cpp Reward function int iItemIdx = s_vec_item.size() - 1; 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)); total_dam += iDamage; } } } std::vector<LPCHARACTER> v; while (!pq.empty() && pq.top().first * 10 >= total_dam) { v.push_back(pq.top().second); pq.pop(); } if (v.empty()) { // 데미지를 특별히 많이 준 사람이 없으니 소유권 없음 while (iItemIdx >= 0) { item = s_vec_item[iItemIdx--]; if (!item) { sys_err("item null in vector idx %d", iItemIdx + 1); continue; } item->AddToGround(GetMapIndex(), pos); // 10% 이하 데미지 준 사람끼리는 소유권없음 //item->SetOwnership(pkAttacker); item->StartDestroyEvent(); pos.x = number(-7, 7) * 20; pos.y = number(-7, 7) * 20; pos.x += GetX(); pos.y += GetY(); sys_log(0, "DROP_ITEM: %s %d %d by %s", item->GetName(), pos.x, pos.y, GetName()); } } else { // 데미지 많이 준 사람들 끼리만 소유권 나눠가짐 std::vector<LPCHARACTER>::iterator it = v.begin(); while (iItemIdx >= 0) { item = s_vec_item[iItemIdx--]; if (!item) { sys_err("item null in vector idx %d", iItemIdx + 1); continue; } item->AddToGround(GetMapIndex(), pos); LPCHARACTER ch = *it; if (ch->GetParty()) ch = ch->GetParty()->GetNextOwnership(ch, GetX(), GetY()); ++it; if (it == v.end()) it = v.begin(); if (CBattleArena::instance().IsBattleArenaMap(ch->GetMapIndex()) == false) { item->SetOwnership(ch); } item->StartDestroyEvent(); pos.x = number(-7, 7) * 20; pos.y = number(-7, 7) * 20; pos.x += GetX(); pos.y += GetY(); sys_log(0, "DROP_ITEM: %s %d %d by %s", item->GetName(), pos.x, pos.y, GetName()); } As you can see in this function SetOwnership is used when dealt at least 10% damage but this does not apply to gold reward the gold is reward for the killer. Worth to note that the chance for item drop is calculated for killer only: if (ITEM_MANAGER::Instance().CreateDropItem(this, pkAttacker, s_vec_item)) This means that only killer thief gloves are counted Im not sure this is the official clean code because I took it from random github but looks like. Have a nice day Edited September 17, 2023 by m2Ciaran 1 Link to comment Share on other sites More sharing options...
caanmasu 312 Posted September 17, 2023 Share Posted September 17, 2023 (edited) 10 hours ago, mihnea said: I don't think it stacks Fix: char_item.cpp Find: else if (!IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_GIVE | ITEM_ANTIFLAG_DROP) && GetParty()) { NPartyPickupDistribute::FFindOwnership funcFindOwnership(item); GetParty()->ForEachOnlineMember(funcFindOwnership); LPCHARACTER owner = funcFindOwnership.owner; // @fixme115 if (!owner) return false; int iEmptyCell; Add below: if (owner) { if (item->IsStackable() && !IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_STACK)) { uint16_t wCount = item->GetCount(); for (int i = 0; i < INVENTORY_MAX_NUM; ++i) { LPITEM item2 = owner->GetInventoryItem(i); if (!item2) continue; if (item2->GetVnum() == item->GetVnum()) { int j; for (j = 0; j < ITEM_SOCKET_MAX_NUM; ++j) { if (item2->GetSocket(j) != item->GetSocket(j)) break; } if (j != ITEM_SOCKET_MAX_NUM) continue; const uint16_t wCount2 = MIN(g_wItemCountLimit - item2->GetCount(), wCount); wCount -= wCount2; item2->SetCount(item2->GetCount() + wCount2); if (wCount == 0) { owner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템 획득: %s 님으로부터 %s"), GetName(), item->GetName()); ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템 전달: %s 님에게 %s"), owner->GetName(), item->GetName()); M2_DESTROY_ITEM(item); if (item2->GetType() == ITEM_QUEST) quest::CQuestManager::Instance().PickupItem(owner->GetPlayerID(), item2); return true; } } } item->SetCount(wCount); } } Note: check count datatypes. In my server is wCount2 with uint16_t but in your server likely is bCount2 BYTE Edited September 17, 2023 by caanmasu 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now