void GuildAchievementMgr::CompletedAchievement(AchievementEntry const* achievement, Player* player) { if (!(achievement->flags & ACHIEVEMENT_FLAG_GUILD_ACHIEVEMENT)) return; if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER || HasAchieved(achievement->ID)) return; SendAchievementEarned(achievement); CompletedAchievementData& ca = m_completedAchievements[achievement->ID]; ca.date = time(NULL); ca.changed = true; m_achievementPoints += achievement->points; UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT, player); }
void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) { sLog->outDetail("AchievementMgr::CompletedAchievement(%u)", achievement->ID); // disable for gamemasters with GM-mode enabled if (_player->isGameMaster()) return; if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER || HasAchieved(achievement->ID)) return; SendAchievementEarned(achievement); CompletedAchievementData& ca = m_completedAchievements[achievement->ID]; ca.date = time(NULL); ca.changed = true; // don't insert for ACHIEVEMENT_FLAG_REALM_FIRST_KILL since otherwise only the first group member would reach that achievement // TODO: where do set this instead? if (!(achievement->flags & ACHIEVEMENT_FLAG_REALM_FIRST_KILL)) sAchievementMgr->SetRealmCompleted(achievement); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT, _player); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS, _player, achievement->points); m_achievementPoints += achievement->points; // reward items and titles if any AchievementReward const* reward = sAchievementMgr->GetAchievementReward(achievement); // no rewards if (!reward) return; // titles //! Currently there's only one achievement that deals with gender-specific titles. //! Since no common attributes were found, (not even in titleRewardFlags field) //! we explicitly check by ID. Maybe in the future we could move the achievement_reward //! condition fields to the condition system. if (uint32 titleId = reward->titleId[achievement->ID == 1793 ? GetPlayer()->getGender() : (GetPlayer()->GetTeam() == ALLIANCE ? 0 : 1)]) if (CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId)) GetPlayer()->SetTitle(titleEntry); // mail if (reward->sender) { Item* item = reward->itemId ? Item::CreateItem(reward->itemId, 1, GetPlayer ()) : NULL; int loc_idx = GetPlayer()->GetSession()->GetSessionDbLocaleIndex(); // subject and text std::string subject = reward->subject; std::string text = reward->text; if (loc_idx >= 0) { if (AchievementRewardLocale const* loc = sAchievementMgr->GetAchievementRewardLocale(achievement)) { ObjectMgr::GetLocaleString(loc->subject, loc_idx, subject); ObjectMgr::GetLocaleString(loc->text, loc_idx, text); } } MailDraft draft(subject, text); SQLTransaction trans = CharacterDatabase.BeginTransaction(); if (item) { // save new item before send item->SaveToDB(trans); // save for prevent lost at next mail load, if send fail then item will deleted // item draft.AddItem(item); } draft.SendMailTo(trans, GetPlayer(), MailSender(MAIL_CREATURE, reward->sender)); CharacterDatabase.CommitTransaction(trans); } }
/** * called at player login. The player might have fulfilled some achievements when the achievement system wasn't working yet */ void AchievementMgr::CheckAllAchievementCriteria() { // suppress sending packets for (uint32 i=0; i<ACHIEVEMENT_CRITERIA_TYPE_TOTAL; ++i) UpdateAchievementCriteria(AchievementCriteriaTypes(i), _player); }
void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) { sLog.outDetail("AchievementMgr::CompletedAchievement(%u)", achievement->ID); if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER || m_completedAchievements.find(achievement->ID)!=m_completedAchievements.end()) return; SendAchievementEarned(achievement); CompletedAchievementData& ca = m_completedAchievements[achievement->ID]; ca.date = time(NULL); ca.changed = true; // don't insert for ACHIEVEMENT_FLAG_REALM_FIRST_KILL since otherwise only the first group member would reach that achievement // TODO: where do set this instead? if(!(achievement->flags & ACHIEVEMENT_FLAG_REALM_FIRST_KILL)) achievementmgr.SetRealmCompleted(achievement); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT); // reward items and titles if any AchievementReward const* reward = achievementmgr.GetAchievementReward(achievement); // no rewards if(!reward) return; // titles if(uint32 titleId = reward->titleId[GetPlayer()->GetTeam() == HORDE?0:1]) { if(CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId)) GetPlayer()->SetTitle(titleEntry); } // mail if(reward->sender) { Item* item = reward->itemId ? Item::CreateItem(reward->itemId,1,GetPlayer ()) : NULL; MailItemsInfo mi; if(item) { // save new item before send item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted // item mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item); } int loc_idx = GetPlayer()->GetSession()->GetSessionDbLocaleIndex(); // subject and text std::string subject = reward->subject; std::string text = reward->text; if ( loc_idx >= 0 ) { if(AchievementRewardLocale const* loc = achievementmgr.GetAchievementRewardLocale(achievement)) { if (loc->subject.size() > size_t(loc_idx) && !loc->subject[loc_idx].empty()) subject = loc->subject[loc_idx]; if (loc->text.size() > size_t(loc_idx) && !loc->text[loc_idx].empty()) text = loc->text[loc_idx]; } } uint32 itemTextId = objmgr.CreateItemText( text ); WorldSession::SendMailTo(GetPlayer(), MAIL_CREATURE, MAIL_STATIONERY_NORMAL, reward->sender, GetPlayer()->GetGUIDLow(), subject, itemTextId , &mi, 0, 0, MAIL_CHECK_MASK_NONE); } }
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; }
void GuildAchievementMgr::CheckAllAchievementCriteria() { // suppress sending packets for (uint32 i = 0; i < ACHIEVEMENT_CRITERIA_TYPE_TOTAL; ++i) UpdateAchievementCriteria(AchievementCriteriaTypes(i), NULL); // ToDO: Fix this }