void Player::UpdateDodgePercentage()
{
    const float dodge_cap[MAX_CLASSES] =
    {
        88.129021f,     // Warrior
        88.129021f,     // Paladin
        145.560408f,    // Hunter
        145.560408f,    // Rogue
        150.375940f,    // Priest
        88.129021f,     // DK
        145.560408f,    // Shaman
        150.375940f,    // Mage
        150.375940f,    // Warlock
        0.0f,           // ??
        116.890707f     // Druid
    };

    float diminishing = 0.0f, nondiminishing = 0.0f;
    GetDodgeFromAgility(diminishing, nondiminishing);
    // Modify value from defense skill (only bonus from defense rating diminishes)
    nondiminishing += (GetSkillValue(SKILL_DEFENSE) - GetMaxSkillValueForLevel()) * 0.04f;
    diminishing += (int32(GetRatingBonusValue(CR_DEFENSE_SKILL))) * 0.04f;
    // Dodge from SPELL_AURA_MOD_DODGE_PERCENT aura
    nondiminishing += GetTotalAuraModifier(SPELL_AURA_MOD_DODGE_PERCENT);
    // Dodge from rating
    diminishing += GetRatingBonusValue(CR_DODGE);
    // apply diminishing formula to diminishing dodge chance
    uint32 pclass = getClass()-1;
    float value = nondiminishing + (diminishing * dodge_cap[pclass] / (diminishing + dodge_cap[pclass] * m_diminishing_k[pclass]));

    value = value < 0.0f ? 0.0f : value;
    SetStatFloatValue(PLAYER_DODGE_PERCENTAGE, value);
}
float Player::GetMissPercentageFromDefence() const
{
    float const miss_cap[MAX_CLASSES] =
    {
        16.00f,     // Warrior //correct
        16.00f,     // Paladin //correct
        16.00f,     // Hunter  //?
        16.00f,     // Rogue   //?
        16.00f,     // Priest  //?
        16.00f,     // DK      //correct
        16.00f,     // Shaman  //?
        16.00f,     // Mage    //?
        16.00f,     // Warlock //?
        0.0f,       // ??
        16.00f      // Druid   //?
    };

    float diminishing = 0.0f, nondiminishing = 0.0f;
    // Modify value from defense skill (only bonus from defense rating diminishes)
    nondiminishing += (GetSkillValue(SKILL_DEFENSE) - GetMaxSkillValueForLevel()) * 0.04f;
    diminishing += (int32(GetRatingBonusValue(CR_DEFENSE_SKILL))) * 0.04f;

    // apply diminishing formula to diminishing miss chance
    uint32 pclass = getClass()-1;
    return nondiminishing + (diminishing * miss_cap[pclass] / (diminishing + miss_cap[pclass] * m_diminishing_k[pclass]));
}
Beispiel #3
0
bool Player::CanResearchWithLevel(uint32 site_id)
{
    if (!GetSkillValue(SKILL_ARCHAEOLOGY))
        return false;

    ResearchSiteDataMap::const_iterator itr = sResearchSiteDataMap.find(site_id);
    if (itr != sResearchSiteDataMap.end())
        return getLevel() + 19 >= itr->second.level;

    return true;
}
Beispiel #4
0
void Player::GenerateResearchProjects()
{
    if (sResearchProjectSet.empty())
        return;

    uint16 skill_now = GetSkillValue(SKILL_ARCHAEOLOGY);
    if (!skill_now)
        return;

    for (uint32 i = 0; i < MAX_RESEARCH_PROJECTS / 2; ++i)
        SetUInt32Value(PLAYER_FIELD_RESEARCHING_1 + i, 0);

    typedef std::map<uint32, ResearchProjectSet> ProjectsByBranch;
    ProjectsByBranch tempProjects;
    ProjectsByBranch tempRareProjects;
    float rare_chance = GetRareArtifactChance(skill_now);

    for (std::set<ResearchProjectEntry const*>::const_iterator itr = sResearchProjectSet.begin(); itr != sResearchProjectSet.end(); ++itr)
    {
        ResearchProjectEntry const* entry = (*itr);

        if (entry->rare)
        {
            if (IsCompletedProject(entry->ID, true))
                continue;

            tempRareProjects[entry->branchId].insert(entry->ID);
        }
        else
            tempProjects[entry->branchId].insert(entry->ID);
    }

    for (ProjectsByBranch::const_iterator itr = tempProjects.begin(); itr != tempProjects.end(); ++itr)
    {
        ResearchProjectSet::iterator itr2;

        if (tempRareProjects[itr->first].size() > 0 && roll_chance_f(rare_chance))
        {
            itr2 = tempRareProjects[itr->first].begin();
            std::advance(itr2, urand(0, tempRareProjects[itr->first].size() - 1));
        }
        else
        {
            itr2 = itr->second.begin();
            std::advance(itr2, urand(0, itr->second.size() - 1));
        }

        ReplaceResearchProject(0, *itr2);
    }

    _archaeologyChanged = true;
}
Beispiel #5
0
void Player::_SaveArchaeology()
{
    if (!sWorld.getConfig(CONFIG_BOOL_ARCHAEOLOGY_ENABLED))
        return;

    if (!GetSkillValue(SKILL_ARCHAEOLOGY))
        return;

    if (!_archaeologyChanged)
        return;

    CharacterDatabase.PExecute("DELETE FROM character_archaeology WHERE guid = '%u'", GetGUIDLow());

    std::ostringstream ss;

    ss << "INSERT INTO character_archaeology (guid, sites, counts, projects) VALUES (";

    ss << GetGUIDLow() << ", '";

    for (ResearchSiteSet::const_iterator itr = _researchSites.begin(); itr != _researchSites.end(); ++itr)
        ss << (*itr) << " ";

    ss << "', '";

    for (uint8 j = 0; j < MAX_RESEARCH_SITES; ++j)
        ss << uint32(_digSites[j].count) << " ";

    ss << "', '";

    for (uint32 i = 0; i < MAX_RESEARCH_PROJECTS; ++i)
        if (uint16 val = GetUInt16Value(PLAYER_FIELD_RESEARCHING_1 + i / 2, i % 2))
            ss << val << " ";

    ss << "')"; 

    CharacterDatabase.Execute(ss.str().c_str());

    for (CompletedProjectList::iterator itr = _completedProjects.begin(); itr != _completedProjects.end(); ++itr)
    {
        CharacterDatabase.PExecute("REPLACE INTO character_archaeology_finds (guid, id, count, date) VALUES (%u, %u, %u, FROM_UNIXTIME(%u))",
            GetGUIDLow(), itr->entry->ID, itr->count, itr->date);
    }

    _archaeologyChanged = false;
}
Beispiel #6
0
void Player::ShowResearchSites()
{
    if (!GetSkillValue(SKILL_ARCHAEOLOGY))
        return;

    uint8 count = 0;

    for (ResearchSiteSet::const_iterator itr = _researchSites.begin(); itr != _researchSites.end(); ++itr)
    {
        uint32 id = (*itr);
        ResearchSiteEntry const* rs = GetResearchSiteEntryById(id);

        if (!rs || CanResearchWithSkillLevel(rs->ID) == 2)
            id = 0;

        SetUInt16Value(PLAYER_FIELD_RESERACH_SITE_1 + count / 2, count % 2, id);
        ++count;
    }
}
Beispiel #7
0
uint8 Player::CanResearchWithSkillLevel(uint32 site_id)
{
    uint16 skill_now = GetSkillValue(SKILL_ARCHAEOLOGY);
    if (!skill_now)
        return 0;

    ResearchSiteDataMap::const_iterator itr = sResearchSiteDataMap.find(site_id);
    if (itr != sResearchSiteDataMap.end())
    {
        ResearchSiteData const& entry = itr->second;

        uint16 skill_cap = 0;
        switch (entry.entry->mapId)
        {
            case 0:
                if (entry.zone == 4922) // Twilight Hightlands
                    skill_cap = 450;
                break;
            case 1:
                if (entry.zone == 616) // Hyjal
                    skill_cap = 450;
                else if (entry.zone == 5034) // Uldum
                    skill_cap = 450;
                break;
            case 530:
                skill_cap = 300; // Outland
                break;
            case 571:
                skill_cap = 375; // Northrend
                break;
        }

        if (skill_now >= skill_cap)
            return 1;

        if (entry.entry->mapId == 530 || entry.entry->mapId == 571)
            return 2;
    }

    return 0;
}
Beispiel #8
0
void Player::UpdateParryPercentage()
{ 
    const float parry_cap[MAX_CLASSES] =
    {
        47.003525f,     // Warrior
        47.003525f,     // Paladin
        145.560408f,    // Hunter
        145.560408f,    // Rogue
        0.0f,           // Priest
        47.003525f,     // DK
        145.560408f,    // Shaman
        0.0f,           // Mage
        0.0f,           // Warlock
        0.0f,           // ??
        0.0f            // Druid
    };

    // No parry
    float value = 0.0f;
	m_realParry = 0.0f;
    uint32 pclass = getClass()-1;
    if (CanParry() && parry_cap[pclass] > 0.0f)
    {
        float nondiminishing  = 5.0f;
        // Parry from rating
        float diminishing = GetRatingBonusValue(CR_PARRY);
        // Modify value from defense skill (only bonus from defense rating diminishes)
        nondiminishing += (GetSkillValue(SKILL_DEFENSE) - GetMaxSkillValueForLevel()) * 0.04f;
        diminishing += (int32(GetRatingBonusValue(CR_DEFENSE_SKILL))) * 0.04f;
        // Parry from SPELL_AURA_MOD_PARRY_PERCENT aura
        nondiminishing += GetTotalAuraModifier(SPELL_AURA_MOD_PARRY_PERCENT);
        // apply diminishing formula to diminishing parry chance
        m_realParry = nondiminishing + diminishing * parry_cap[pclass] / (diminishing + parry_cap[pclass] * m_diminishing_k[pclass]);
        m_realParry = m_realParry < 0.0f ? 0.0f : m_realParry;

		value = std::max(diminishing + nondiminishing, 0.0f);
    }

    SetStatFloatValue(PLAYER_PARRY_PERCENTAGE, value);
}
Beispiel #9
0
bool Player::OnSurvey(uint32& entry, float& x, float& y, float& z, float &orientation)
{
    entry = 0;

    uint16 skill_now = GetSkillValue(SKILL_ARCHAEOLOGY);
    if (!skill_now)
        return false;

    uint16 site_id = GetResearchSiteID();
    if (!site_id)
        return false;

    uint8 i = 0;
    for(; i < MAX_RESEARCH_SITES; ++i)
        if (GetUInt16Value(PLAYER_FIELD_RESERACH_SITE_1 + i / 2, i % 2) == site_id)
            break;

    MANGOS_ASSERT(i < MAX_RESEARCH_SITES);

    DigSite &site = _digSites[i];
    if (site.site_id != site_id)
    {
        if (!GenerateDigSiteLoot(site_id, site))
            return false;

        site.site_id = site_id;
    }

    orientation = GetAngle(site.loot_x, site.loot_y);
    float dist_now = GetDistance2d(site.loot_x, site.loot_y);

    if (dist_now >= ARCHAEOLOGY_DIG_SITE_FAR_DIST)
    {
        entry = GO_FAR_SURVEYBOT;
        return false;
    }
    if (dist_now >= ARCHAEOLOGY_DIG_SITE_MED_DIST)
    {
        entry = GO_MEDIUM_SURVEYBOT;
        return false;
    }
    if (dist_now >= ARCHAEOLOGY_DIG_SITE_FIND_DIST)
    {
        entry = GO_CLOSE_SURVEYBOT;
        return false;
    }

    if (skill_now < 50)
        UpdateSkill(SKILL_ARCHAEOLOGY, 1);

    entry = site.find_id;
    x = site.loot_x;
    y = site.loot_y;
    z = GetMap()->GetTerrain()->GetHeightStatic(x, y, GetPositionZ(), true, 5);

    if (site.count < 2)
    {
        ++site.count;
        if (!GenerateDigSiteLoot(site_id, site))
            return true;
    }
    else
    {
        site.clear();
        UseResearchSite(site_id);
    }

    _archaeologyChanged = true;

    return true;
}
Beispiel #10
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;
}