bool CHARACTER::GiveItemFromSpecialItemGroupNew(DWORD dwGroupNum, WORD& loopCount) { const CSpecialItemGroup* pGroup = ITEM_MANAGER::instance().GetSpecialItemGroup(dwGroupNum); if (!pGroup) { sys_err("cannot find special item group %d", dwGroupNum); return false; } std::map vecItemCounts; std::map vecUpdateItems; const WORD constCount = loopCount; WORD workCount = loopCount; int returnCount = 5; for (DWORD j = 0; j < constCount; ++j) { if (returnCount <= 0 || workCount <= 0) break; std::vector idxes; const int n = pGroup->GetMultiIndex(idxes); bool isOkey = false; for (int i = 0; i < n; i++) { if (returnCount <= 0 || (workCount <= 0 && !isOkey)) break; const int idx = idxes[i]; const DWORD dwVnum = pGroup->GetVnum(idx); const DWORD dwEarnCount = pGroup->GetCount(idx); DWORD dwCount = pGroup->GetCount(idx); switch (dwVnum) { case CSpecialItemGroup::GOLD: PointChange(POINT_GOLD, dwCount); if(isOkey == false) { isOkey = true; workCount -= 1; } break; case CSpecialItemGroup::POISON: AttackedByPoison(NULL); if(isOkey == false) { isOkey = true; workCount -= 1; } break; case CSpecialItemGroup::EXP: PointChange(POINT_EXP, dwCount); if(isOkey == false) { isOkey = true; workCount -= 1; } break; case CSpecialItemGroup::MOB: { LPCHARACTER ch = CHARACTER_MANAGER::instance().SpawnMob(dwCount, GetMapIndex(), GetX() + number(-500, 500), GetY() + number(-500, 500), 0, true, -1); if (ch) ch->SetAggressive(); if(isOkey == false) { isOkey = true; workCount -= 1; } } break; case CSpecialItemGroup::MOB_GROUP: CHARACTER_MANAGER::instance().SpawnGroup(dwCount, GetMapIndex(), GetX() - number(300, 500), GetY() - number(300, 500), GetX() + number(300, 500), GetY() + number(300, 500), NULL, true); if(isOkey == false) { isOkey = true; workCount -= 1; } break; case CSpecialItemGroup::SLOW: AddAffect(AFFECT_SLOW, POINT_MOV_SPEED, -(int)dwCount, AFF_SLOW, 300, 0, true); if(isOkey == false) { isOkey = true; workCount -= 1; } break; case CSpecialItemGroup::DRAIN_HP: { int iDropHP = GetMaxHP() * dwCount / 100; iDropHP = MIN(iDropHP, GetHP() - 1); PointChange(POINT_HP, -iDropHP); if(isOkey == false) { isOkey = true; workCount -= 1; } } break; default: { LPITEM item = ITEM_MANAGER::Instance().CreateItem(dwVnum, dwCount); if (item) { if (AutoGiveItemChest(item, dwCount, vecUpdateItems)) { if(isOkey == false) { isOkey = true; workCount -= 1; } auto itCount = vecItemCounts.find(dwVnum); if (itCount != vecItemCounts.end()) itCount->second += dwEarnCount; else vecItemCounts.emplace(dwVnum, dwEarnCount); if (dwCount == 0) { M2_DESTROY_ITEM(item); continue; } } else { M2_DESTROY_ITEM(item); returnCount -= 1; } } } } } } for (auto it = vecUpdateItems.begin(); it != vecUpdateItems.end(); ++it) { LPITEM item = it->first; item->SetUpdateStatus(false); if (item->GetCount() != it->second) item->UpdatePacket(); if (item->GetType() == ITEM_QUEST || item->GetType() == ITEM_MATERIAL) quest::CQuestManager::instance().PickupItem (GetPlayerID(), item); } for (auto it = vecItemCounts.begin(); it != vecItemCounts.end(); ++it) ChatPacket(CHAT_TYPE_INFO, "165 I%d %d", it->first, it->second); loopCount = workCount; return (workCount != constCount); }