Exemple #1
0
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;
}