bool Player::SolveResearchProject(uint32 spellId, SpellCastTargets& targets) { uint16 skill_now = GetSkillValue(SKILL_ARCHAEOLOGY); if (!skill_now) return false; ResearchProjectEntry const* entry = NULL; for (std::set<ResearchProjectEntry const*>::const_iterator itr = sResearchProjectSet.begin(); itr != sResearchProjectSet.end(); ++itr) { if ((*itr)->spellId != spellId) continue; entry = (*itr); break; } if (!entry || !HasResearchProject(entry->ID)) return false; ResearchBranchEntry const* branch = NULL; for (uint32 i = 0; i < sResearchBranchStore.GetNumRows(); ++i) { ResearchBranchEntry const* _branch = sResearchBranchStore.LookupEntry(i); if (!_branch) continue; if (_branch->ID != entry->branchId) continue; branch = _branch; break; } if (!branch) return false; uint32 currencyId = branch->currency; int32 currencyAmt = int32(entry->req_currency_amt); ArchaeologyWeights weights = targets.GetWeights(); for (ArchaeologyWeights::iterator itr = weights.begin(); itr != weights.end(); ++itr) { ArchaeologyWeight& w = *itr; if (w.type == WEIGHT_KEYSTONE) { ItemPrototype const* proto = sObjectMgr.GetItemPrototype(w.keystone.itemId); if (!proto) return false; if (proto->GetCurrencySubstitutionId() != currencyId) return false; if (w.keystone.itemCount > entry->Complexity) return false; if (!HasItemCount(w.keystone.itemId, w.keystone.itemCount)) return false; currencyAmt -= int32(proto->CurrencySubstitutionCount * w.keystone.itemCount); } } if (currencyAmt > 0 && !HasCurrencyCount(currencyId, currencyAmt)) return false; ModifyCurrencyCount(currencyId, -currencyAmt); for (ArchaeologyWeights::iterator itr = weights.begin(); itr != weights.end(); ++itr) { ArchaeologyWeight& w = *itr; if (w.type == WEIGHT_KEYSTONE) DestroyItemCount(w.keystone.itemId, w.keystone.itemCount, true); } UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ARCHAEOLOGY_PROJECTS, entry->ID, 1); AddCompletedProject(entry); ResearchProjectSet tempProjects; ResearchProjectSet tempRareProjects; float rare_chance = GetRareArtifactChance(skill_now); for (std::set<ResearchProjectEntry const*>::const_iterator itr = sResearchProjectSet.begin(); itr != sResearchProjectSet.end(); ++itr) { ResearchProjectEntry const* project = *itr; if (project->branchId != entry->branchId) continue; if (project->rare) { if (IsCompletedProject(project->ID, true)) continue; tempRareProjects.insert(project->ID); } else tempProjects.insert(project->ID); } ResearchProjectSet::const_iterator itr; if (tempRareProjects.size() > 0 && roll_chance_f(rare_chance)) { itr = tempRareProjects.begin(); std::advance(itr, urand(0, tempRareProjects.size() - 1)); } else { itr = tempProjects.begin(); std::advance(itr, urand(0, tempProjects.size() - 1)); } ReplaceResearchProject(entry->ID, *itr); _archaeologyChanged = true; WorldPacket data (SMSG_RESEARCH_COMPLETE, 4 * 3); data << uint32(entry->branchId); data << uint32(0); data << uint32(*itr); SendDirectMessage(&data); return true; }