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])); }
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; }
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; }
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; }
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; } }
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; }
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); }
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; }
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; }