Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
AchievementMgr.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "AchievementMgr.h"
8#include "ArenaTeam.h"
9#include "ArenaTeamMgr.h"
10#include "BattlePet.h"
11#include "BattlePetMgr.h"
12#include "Battleground.h"
13#include "CellImpl.h"
14#include "Chat.h"
15#include "Common.h"
16#include "DatabaseEnv.h"
17#include "DB2Stores.h"
18#include "DBCEnums.h"
19#include "DBCStructure.h"
20#include "DisableMgr.h"
21#include "GameEventMgr.h"
22#include "GridNotifiersImpl.h"
23#include "Group.h"
24#include "Guild.h"
25#include "GuildMgr.h"
26#include "InstanceScript.h"
27#include "Language.h"
28#include "Map.h"
29#include "MapManager.h"
30#include "ObjectMgr.h"
31#include "Player.h"
32#include "ReputationMgr.h"
33#include "ScriptMgr.h"
34#include "SpellMgr.h"
35#include "World.h"
36#include "WorldPacket.h"
37
38namespace Skyfire
39{
41 {
42 public:
43 AchievementChatBuilder(Player const& player, ChatMsg msgtype, int32 textId, uint32 ach_id)
44 : i_player(player), i_msgtype(msgtype), i_textId(textId), i_achievementId(ach_id) { }
45
47 {
48 std::string text = sObjectMgr->GetSkyFireString(i_textId, loc_idx);
50 }
51
52 private:
57 };
58} // namespace Skyfire
59
60
62{
64 {
65 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` for criteria (Entry: %u) has wrong data type (%u), ignored.", criteria->ID, dataType);
66 return false;
67 }
68
69 switch (criteria->type)
70 {
75 case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: // only hardcoded list
90 case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST: // only Children's Week achievements
91 case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: // only Children's Week achievements
94 break;
95 default:
97 {
98 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` has data for non-supported criteria type (Entry: %u Type: %u), ignored.", criteria->ID, criteria->type);
99 return false;
100 }
101 break;
102 }
103
104 switch (dataType)
105 {
108 return true;
110 if (!creature.id || !sObjectMgr->GetCreatureTemplate(creature.id))
111 {
112 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE (%u) has non-existing creature id in value1 (%u), ignored.",
113 criteria->ID, criteria->type, dataType, creature.id);
114 return false;
115 }
116 return true;
118 if (!classRace.class_id && !classRace.race_id)
119 {
120 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE (%u) must not have 0 in either value field, ignored.",
121 criteria->ID, criteria->type, dataType);
122 return false;
123 }
124 if (classRace.class_id && ((1 << (classRace.class_id - 1)) & CLASSMASK_ALL_PLAYABLE) == 0)
125 {
126 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE (%u) has non-existing class in value1 (%u), ignored.",
127 criteria->ID, criteria->type, dataType, classRace.class_id);
128 return false;
129 }
130 if (classRace.race_id && ((1 << (classRace.race_id - 1)) & RACEMASK_ALL_PLAYABLE) == 0)
131 {
132 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE (%u) has non-existing race in value2 (%u), ignored.",
133 criteria->ID, criteria->type, dataType, classRace.race_id);
134 return false;
135 }
136 return true;
138 if (health.percent < 1 || health.percent > 100)
139 {
140 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH (%u) has wrong percent value in value1 (%u), ignored.",
141 criteria->ID, criteria->type, dataType, health.percent);
142 return false;
143 }
144 return true;
147 {
148 SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(aura.spell_id);
149 if (!spellEntry)
150 {
151 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) has wrong spell id in value1 (%u), ignored.",
152 criteria->ID, criteria->type, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA ? "ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA" : "ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.spell_id);
153 return false;
154 }
155 if (aura.effect_idx >= 3)
156 {
157 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) has wrong spell effect index in value2 (%u), ignored.",
158 criteria->ID, criteria->type, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA ? "ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA" : "ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.effect_idx);
159 return false;
160 }
161 if (!spellEntry->Effects[aura.effect_idx].ApplyAuraName)
162 {
163 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) has non-aura spell effect (ID: %u Effect: %u), ignores.",
164 criteria->ID, criteria->type, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA ? "ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA" : "ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.spell_id, aura.effect_idx);
165 return false;
166 }
167 return true;
168 }
170 if (!GetAreaEntryByAreaID(area.id))
171 {
172 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA (%u) has wrong area id in value1 (%u), ignored.",
173 criteria->ID, criteria->type, dataType, area.id);
174 return false;
175 }
176 return true;
178 if (value.compType >= COMP_TYPE_MAX)
179 {
180 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE (%u) has wrong ComparisionType in value2 (%u), ignored.",
181 criteria->ID, criteria->type, dataType, value.compType);
182 return false;
183 }
184 return true;
186 if (level.minlevel > STRONG_MAX_LEVEL)
187 {
188 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL (%u) has wrong minlevel in value1 (%u), ignored.",
189 criteria->ID, criteria->type, dataType, level.minlevel);
190 return false;
191 }
192 return true;
194 if (gender.gender > GENDER_NONE)
195 {
196 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_GENDER (%u) has wrong gender in value1 (%u), ignored.",
197 criteria->ID, criteria->type, dataType, gender.gender);
198 return false;
199 }
200 return true;
202 if (!ScriptId)
203 {
204 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT (%u) does not have ScriptName set, ignored.",
205 criteria->ID, criteria->type, dataType);
206 return false;
207 }
208 return true;
210 if (map_players.maxcount <= 0)
211 {
212 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT (%u) has wrong max players count in value1 (%u), ignored.",
213 criteria->ID, criteria->type, dataType, map_players.maxcount);
214 return false;
215 }
216 return true;
218 if (team.team != ALLIANCE && team.team != HORDE)
219 {
220 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM (%u) has unknown team in value1 (%u), ignored.",
221 criteria->ID, criteria->type, dataType, team.team);
222 return false;
223 }
224 return true;
226 if (drunk.state >= MAX_DRUNKEN)
227 {
228 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK (%u) has unknown drunken state in value1 (%u), ignored.",
229 criteria->ID, criteria->type, dataType, drunk.state);
230 return false;
231 }
232 return true;
234 if (!sHolidaysStore.LookupEntry(holiday.id))
236 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY (%u) has unknown holiday in value1 (%u), ignored.",
237 criteria->ID, criteria->type, dataType, holiday.id);
238 return false;
239 }
240 return true;
242 return true; // not check correctness node indexes
244 if (equipped_item.item_quality >= MAX_ITEM_QUALITY)
245 {
246 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_requirement` (Entry: %u Type: %u) for requirement ACHIEVEMENT_CRITERIA_REQUIRE_S_EQUIPED_ITEM (%u) has unknown quality state in value1 (%u), ignored.",
247 criteria->ID, criteria->type, dataType, equipped_item.item_quality);
248 return false;
249 }
250 return true;
252 if (!classRace.class_id && !classRace.race_id)
253 {
254 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE (%u) must not have 0 in either value field, ignored.",
255 criteria->ID, criteria->type, dataType);
256 return false;
257 }
258 if (classRace.class_id && ((1 << (classRace.class_id - 1)) & CLASSMASK_ALL_PLAYABLE) == 0)
260 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE (%u) has non-existing class in value1 (%u), ignored.",
261 criteria->ID, criteria->type, dataType, classRace.class_id);
262 return false;
264 if (classRace.race_id && ((1 << (classRace.race_id - 1)) & RACEMASK_ALL_PLAYABLE) == 0)
266 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE (%u) has non-existing race in value2 (%u), ignored.",
267 criteria->ID, criteria->type, dataType, classRace.race_id);
268 return false;
270 return true;
271 default:
272 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) has data for non-supported data type (%u), ignored.", criteria->ID, criteria->type, dataType);
273 return false;
274 }
275}
276
277bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Unit const* target, uint32 miscValue1 /*= 0*/) const
278{
279 switch (dataType)
280 {
282 return true;
284 if (!target || target->GetTypeId() != TypeID::TYPEID_UNIT)
285 return false;
286 return target->GetEntry() == creature.id;
288 if (!target || target->GetTypeId() != TypeID::TYPEID_PLAYER)
289 return false;
290 if (classRace.class_id && classRace.class_id != target->ToPlayer()->getClass())
291 return false;
292 if (classRace.race_id && classRace.race_id != target->ToPlayer()->getRace())
293 return false;
294 return true;
296 if (!source || source->GetTypeId() != TypeID::TYPEID_PLAYER)
297 return false;
298 if (classRace.class_id && classRace.class_id != source->ToPlayer()->getClass())
299 return false;
300 if (classRace.race_id && classRace.race_id != source->ToPlayer()->getRace())
301 return false;
302 return true;
304 if (!target || target->GetTypeId() != TypeID::TYPEID_PLAYER)
305 return false;
306 return !target->HealthAbovePct(health.percent);
308 return source->HasAuraEffect(aura.spell_id, aura.effect_idx);
310 {
311 uint32 zoneId, areaId;
312 source->GetZoneAndAreaId(zoneId, areaId);
313 return area.id == zoneId || area.id == areaId;
314 }
316 return target && target->HasAuraEffect(aura.spell_id, aura.effect_idx);
318 return CompareValues(ComparisionType(value.compType), miscValue1, value.value);
320 if (!target)
321 return false;
322 return target->getLevel() >= level.minlevel;
324 if (!target)
325 return false;
326 return target->getGender() == gender.gender;
328 return sScriptMgr->OnCriteriaCheck(ScriptId, const_cast<Player*>(source), const_cast<Unit*>(target));
330 return source->GetMap()->GetPlayersCountExceptGMs() <= map_players.maxcount;
332 if (!target || target->GetTypeId() != TypeID::TYPEID_PLAYER)
333 return false;
334 return target->ToPlayer()->GetTeam() == team.team;
340 {
341 Battleground* bg = source->GetBattleground();
342 if (!bg)
343 return false;
344
346 return score >= bg_loss_team_score.min_score && score <= bg_loss_team_score.max_score;
347 }
349 {
350 if (!source->IsInWorld())
351 return false;
352 Map* map = source->GetMap();
353 if (!map->IsInstance())
354 {
355 SF_LOG_ERROR("achievement", "Achievement system call ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT (%u) for achievement criteria %u for non-dungeon/non-raid map %u",
357 return false;
358 }
359 InstanceScript* instance = ((InstanceMap*)map)->GetInstanceScript();
360 if (!instance)
361 {
362 SF_LOG_ERROR("achievement", "Achievement system call ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT (%u) for achievement criteria %u for map %u but map does not have a instance script",
364 return false;
365 }
366 return instance->CheckAchievementCriteriaMeet(criteria_id, source, target, miscValue1);
367 }
369 {
370 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(miscValue1);
371 if (!pProto)
372 return false;
373 return pProto->ItemLevel >= equipped_item.item_level && pProto->Quality >= equipped_item.item_quality;
374 }
375 default:
376 break;
377 }
378 return false;
379}
380
381bool AchievementCriteriaDataSet::Meets(Player const* source, Unit const* target, uint32 miscValue /*= 0*/) const
382{
383 for (Storage::const_iterator itr = storage.begin(); itr != storage.end(); ++itr)
384 if (!itr->Meets(criteria_id, source, target, miscValue))
385 return false;
386
387 return true;
388}
389
390template<class T>
392
393template<class T>
395
396template<class T>
398
399template<>
401{
402 GetOwner()->BroadcastPacket(data);
403}
404
405template<>
407{
408 GetOwner()->GetSession()->SendPacket(data);
409}
410
411template<class T>
413{
414 if (!entry)
415 return;
416
417 CriteriaProgressMap::iterator criteriaProgress = m_criteriaProgress.find(entry->ID);
418 if (criteriaProgress == m_criteriaProgress.end())
419 return;
420
422 data << uint32(entry->ID);
423 SendPacket(&data);
424
425 m_criteriaProgress.erase(criteriaProgress);
426}
427
428template<>
430{
431 if (!entry)
432 return;
433
434 CriteriaProgressMap::iterator criteriaProgress = m_criteriaProgress.find(entry->ID);
435 if (criteriaProgress == m_criteriaProgress.end())
436 return;
437
438 ObjectGuid guid = GetOwner()->GetGUID();
439
441 data.WriteGuidMask(guid, 2, 4, 0, 3, 6, 7, 5, 1);
442 data.WriteGuidBytes(guid, 6, 1, 2, 3, 4, 5, 7, 0);
443
444 data << uint32(entry->ID);
445
446 SendPacket(&data);
447
448 m_criteriaProgress.erase(criteriaProgress);
449}
450
451template<class T>
452void AchievementMgr<T>::ResetAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1, uint64 miscValue2, bool evenIfCriteriaComplete)
453{
454 SF_LOG_DEBUG("achievement", "ResetAchievementCriteria(%u, " UI64FMTD ", " UI64FMTD ")", type, miscValue1, miscValue2);
455
456 // disable for gamemasters with GM-mode enabled
457 if (GetOwner()->IsGameMaster())
458 return;
459
460 AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type);
461 for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i)
462 {
463 CriteriaEntry const* achievementCriteria = (*i);
464
465 if (achievementCriteria->failEvent != miscValue1)
466 continue;
467
468 if (achievementCriteria->failAsset && achievementCriteria->failAsset != miscValue2)
469 continue;
470
471 // Keep reset criteria in sync with persistence without emitting criteria delete packets.
472 if (evenIfCriteriaComplete || !IsCompletedCriteria(achievementCriteria))
473 SetCriteriaProgress(achievementCriteria, 0, GetOwner(), PROGRESS_SET);
474 }
475}
476
477template<>
478void AchievementMgr<Guild>::ResetAchievementCriteria(AchievementCriteriaTypes /*type*/, uint64 /*miscValue1*/, uint64 /*miscValue2*/, bool /*evenIfCriteriaComplete*/)
479{
480 // Not needed
481}
482
483template<class T>
485{
486}
487
488template<>
490{
491 SQLTransaction trans = CharacterDatabase.BeginTransaction();
492
494 stmt->setUInt32(0, lowguid);
495 trans->Append(stmt);
496
497 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS);
498 stmt->setUInt32(0, lowguid);
499 trans->Append(stmt);
500
501 CharacterDatabase.CommitTransaction(trans);
502}
503
504template<>
506{
507 SQLTransaction trans = CharacterDatabase.BeginTransaction();
508
510 stmt->setUInt32(0, lowguid);
511 trans->Append(stmt);
512
514 stmt->setUInt32(0, lowguid);
515 trans->Append(stmt);
516
517 CharacterDatabase.CommitTransaction(trans);
518}
519
520template<class T>
524
525template<>
527{
528 if (!m_completedAchievements.empty())
529 {
530 for (CompletedAchievementMap::iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter)
531 {
532 if (!iter->second.changed)
533 continue;
534
536 stmt->setUInt16(0, iter->first);
537 stmt->setUInt32(1, GetOwner()->GetGUID());
538 trans->Append(stmt);
539
540 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_ACHIEVEMENT);
541 stmt->setUInt32(0, GetOwner()->GetGUID());
542 stmt->setUInt16(1, iter->first);
543 stmt->setUInt32(2, uint32(iter->second.date));
544 trans->Append(stmt);
545
546 iter->second.changed = false;
547 }
548 }
549
550 if (!m_criteriaProgress.empty())
551 {
552 for (CriteriaProgressMap::iterator iter = m_criteriaProgress.begin(); iter != m_criteriaProgress.end(); ++iter)
553 {
554 if (!iter->second.changed)
555 continue;
556
558 stmt->setUInt32(0, GetOwner()->GetGUID());
559 stmt->setUInt16(1, iter->first);
560 trans->Append(stmt);
561
562 if (iter->second.counter)
563 {
564 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_ACHIEVEMENT_PROGRESS);
565 stmt->setUInt32(0, GetOwner()->GetGUID());
566 stmt->setUInt16(1, iter->first);
567 stmt->setUInt32(2, iter->second.counter);
568 stmt->setUInt32(3, uint32(iter->second.date));
569 trans->Append(stmt);
570 }
571
572 iter->second.changed = false;
573 }
574 }
575}
576
577template<>
579{
580 PreparedStatement* stmt;
581 std::ostringstream guidstr;
582 for (CompletedAchievementMap::const_iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr)
583 {
584 if (!itr->second.changed)
585 continue;
586
587 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_ACHIEVEMENT);
588 stmt->setUInt32(0, GetOwner()->GetId());
589 stmt->setUInt16(1, itr->first);
590 trans->Append(stmt);
591
592 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_ACHIEVEMENT);
593 stmt->setUInt32(0, GetOwner()->GetId());
594 stmt->setUInt16(1, itr->first);
595 stmt->setUInt32(2, itr->second.date);
596 for (std::set<uint64>::const_iterator gItr = itr->second.guids.begin(); gItr != itr->second.guids.end(); ++gItr)
597 guidstr << GUID_LOPART(*gItr) << ',';
598
599 stmt->setString(3, guidstr.str());
600 trans->Append(stmt);
601
602 guidstr.str("");
603 }
604
605 for (CriteriaProgressMap::const_iterator itr = m_criteriaProgress.begin(); itr != m_criteriaProgress.end(); ++itr)
606 {
607 if (!itr->second.changed)
608 continue;
609
610 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_ACHIEVEMENT_CRITERIA);
611 stmt->setUInt32(0, GetOwner()->GetId());
612 stmt->setUInt16(1, itr->first);
613 trans->Append(stmt);
614
615 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_ACHIEVEMENT_CRITERIA);
616 stmt->setUInt32(0, GetOwner()->GetId());
617 stmt->setUInt16(1, itr->first);
618 stmt->setUInt64(2, itr->second.counter);
619 stmt->setUInt32(3, itr->second.date);
620 stmt->setUInt32(4, GUID_LOPART(itr->second.CompletedGUID));
621 trans->Append(stmt);
622 }
623}
624
625template<class T>
627{
628}
629
630template<>
632{
633 if (achievementResult)
634 {
635 do
636 {
637 Field* fields = achievementResult->Fetch();
638 uint32 achievementid = fields[0].GetUInt16();
639
640 // must not happen: cleanup at server startup in sAchievementMgr->LoadCompletedAchievements()
641 AchievementEntry const* achievement = sAchievementMgr->GetAchievement(achievementid);
642 if (!achievement)
643 continue;
644
646 ca.date = time_t(fields[1].GetUInt32());
647 ca.changed = false;
648
649 _achievementPoints += achievement->points;
650
651 // title achievement rewards are retroactive
652 if (AchievementReward const* reward = sAchievementMgr->GetAchievementReward(achievement))
653 {
654 if (uint32 titleId = reward->titleId[Player::TeamForRace(GetOwner()->getRace()) == ALLIANCE ? 0 : 1])
655 if (CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId))
656 GetOwner()->SetTitle(titleEntry);
657
658 if (reward->spellId < 0)
659 {
660 // Because spells are not loaded yet
661 uint32 spellId = uint32(-reward->spellId);
662 Player* player = GetOwner();
663 if (!player->HasSpell(spellId))
664 player->addSpell(spellId, true, true, false, false, true);
665 }
666 }
667 } while (achievementResult->NextRow());
668 }
669
670 if (criteriaResult)
671 {
672 time_t now = time(NULL);
673 do
674 {
675 Field* fields = criteriaResult->Fetch();
676 uint32 id = fields[0].GetUInt16();
677 uint64 counter = fields[1].GetUInt64();
678 time_t date = time_t(fields[2].GetUInt32());
679
680 CriteriaEntry const* criteria = sAchievementMgr->GetAchievementCriteria(id);
681 if (!criteria)
682 {
683 // we will remove not existed criteria for all characters
684 SF_LOG_ERROR("achievement", "Non-existing achievement criteria %u data removed from table `character_achievement_progress`.", id);
685
687 stmt->setUInt16(0, uint16(id));
688 CharacterDatabase.Execute(stmt);
689
690 continue;
691 }
692
693 if (criteria->timeLimit && time_t(date + criteria->timeLimit) < now)
694 continue;
695
696 CriteriaProgress& progress = m_criteriaProgress[id];
697 progress.counter = counter;
698 progress.date = date;
699 progress.changed = false;
700 } while (criteriaResult->NextRow());
701 }
702}
703
704template<>
706{
707 if (achievementResult)
708 {
709 do
710 {
711 Field* fields = achievementResult->Fetch();
712 uint32 achievementid = fields[0].GetUInt16();
713
714 // must not happen: cleanup at server startup in sAchievementMgr->LoadCompletedAchievements()
715 AchievementEntry const* achievement = sAchievementMgr->GetAchievement(achievementid);
716 if (!achievement)
717 continue;
718
720 ca.date = time_t(fields[1].GetUInt32());
721 Tokenizer guids(fields[2].GetString(), ' ');
722 for (uint32 i = 0; i < guids.size(); ++i)
723 ca.guids.insert(MAKE_NEW_GUID(atol(guids[i]), 0, HIGHGUID_PLAYER));
724
725 ca.changed = false;
726
727 _achievementPoints += achievement->points;
728 } while (achievementResult->NextRow());
729 }
730
731 if (criteriaResult)
732 {
733 time_t now = time(NULL);
734 do
735 {
736 Field* fields = criteriaResult->Fetch();
737 uint32 id = fields[0].GetUInt16();
738 uint32 counter = fields[1].GetUInt32();
739 time_t date = time_t(fields[2].GetUInt32());
740 uint64 guid = fields[3].GetUInt32();
741
742 CriteriaEntry const* criteria = sAchievementMgr->GetAchievementCriteria(id);
743 if (!criteria)
744 {
745 // we will remove not existed criteria for all guilds
746 SF_LOG_ERROR("achievement", "Non-existing achievement criteria %u data removed from table `guild_achievement_progress`.", id);
747
749 stmt->setUInt16(0, uint16(id));
750 CharacterDatabase.Execute(stmt);
751 continue;
752 }
753
754 if (criteria->timeLimit && time_t(date + criteria->timeLimit) < now)
755 continue;
756
757 CriteriaProgress& progress = m_criteriaProgress[id];
758 progress.counter = counter;
759 progress.date = date;
760 progress.CompletedGUID = MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER);
761 progress.changed = false;
762 } while (criteriaResult->NextRow());
763 }
764}
765
766template<class T>
770
771template<>
773{
774 for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter)
775 {
777 data << uint32(iter->first);
778 data << uint32(0); // Unk
779 SendPacket(&data);
780 }
781
782 for (CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter != m_criteriaProgress.end(); ++iter)
783 {
785 data << uint32(iter->first);
786 SendPacket(&data);
787 }
788
791 m_criteriaProgress.clear();
792 DeleteFromDB(GetOwner()->GetGUIDLow());
793
794 // re-fill data
796}
797
798template<>
800{
801 ObjectGuid guid = GetOwner()->GetGUID();
802 for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter)
803 {
805 data.WriteBit(guid[4]);
806 data.WriteBit(guid[1]);
807 data.WriteBit(guid[2]);
808 data.WriteBit(guid[3]);
809 data.WriteBit(guid[0]);
810 data.WriteBit(guid[7]);
811 data.WriteBit(guid[5]);
812 data.WriteBit(guid[6]);
813 data << uint32(iter->first);
814 data.WriteByteSeq(guid[5]);
815 data.WriteByteSeq(guid[1]);
816 data.WriteByteSeq(guid[3]);
817 data.WriteByteSeq(guid[6]);
818 data.WriteByteSeq(guid[0]);
819 data.WriteByteSeq(guid[7]);
820 data.AppendPackedTime(iter->second.date);
821 data.WriteByteSeq(guid[4]);
822 data.WriteByteSeq(guid[2]);
823 SendPacket(&data);
824 }
825
826 while (!m_criteriaProgress.empty())
827 if (CriteriaEntry const* criteria = sAchievementMgr->GetAchievementCriteria(m_criteriaProgress.begin()->first))
828 RemoveCriteriaProgress(criteria);
829
832 DeleteFromDB(GetOwner()->GetId());
833}
834
835template<class T>
837{
838 bool GuildAchievement = false;
839
840 // Don't send for achievements with ACHIEVEMENT_FLAG_HIDDEN
841 if (achievement->flags & ACHIEVEMENT_FLAG_HIDDEN)
842 return;
843
844 SF_LOG_DEBUG("achievement", "AchievementMgr::SendAchievementEarned(%u)", achievement->ID);
845
846 if (Guild* guild = sGuildMgr->GetGuildById(GetOwner()->GetGuildId()))
847 {
850 guild->BroadcastWorker(say_do);
851 }
852
854 {
855 // broadcast realm first reached
856 WorldPacket data(SMSG_SERVER_FIRST_ACHIEVEMENT, GetOwner()->GetName().size() + 1 + 8 + 4 + 4);
857 data.WriteGuidMask(GetOwner()->GetObjectGUID(), 5, 6, 3, 7, 0, 4);
858 data.WriteBits(GetOwner()->GetName().size(), 7);
859 data.WriteGuidMask(GetOwner()->GetObjectGUID(), 2, 1);
860 data.WriteBit(GuildAchievement); // GuildAchievement
861 data.FlushBits();
862 data.WriteGuidBytes(GetOwner()->GetObjectGUID(), 1);
863 data.WriteString(GetOwner()->GetName());
864 data.WriteGuidBytes(GetOwner()->GetObjectGUID(), 0, 2);
865 data << uint32(achievement->ID); //29
866 data.WriteGuidBytes(GetOwner()->GetObjectGUID(), 6, 3, 4, 5, 7);
867 sWorld->SendGlobalMessage(&data);
868 }
869
870 // if player is in world he can tell his friends about new achievement
871 else if (GetOwner()->IsInWorld())
872 {
874
875 CellCoord p = Skyfire::ComputeCellCoord(GetOwner()->GetPositionX(), GetOwner()->GetPositionY());
876
877 Cell cell(p);
878 cell.SetNoCreate();
879
883 cell.Visit(p, message, *GetOwner()->GetMap(), *GetOwner(), sWorld->GetFloatConfig(WorldFloatConfigs::CONFIG_LISTEN_RANGE_SAY));
884 }
885
886 ObjectGuid guid = GetOwner()->GetGUID();
887 ObjectGuid guid2 = GetOwner()->GetGUID();
888
889 WorldPacket data(SMSG_ACHIEVEMENT_EARNED, 8 + 4 + 8);
890 data.WriteGuidMask(guid2, 6, 2);
891 data.WriteGuidMask(guid, 4, 5, 0, 3);
892 data.WriteBit(0); // does not notify player ingame
893 data.WriteGuidMask(guid2, 2);
894 data.WriteGuidMask(guid, 7, 1);
895 data.WriteGuidMask(guid2, 3, 0, 4);
896 data.WriteGuidMask(guid, 6);
897 data.WriteGuidMask(guid2, 1);
898 data.WriteGuidMask(guid, 2);
899 data.WriteGuidMask(guid2, 5);
900
901 data.WriteGuidBytes(guid2, 5);
902 data.WriteGuidBytes(guid, 3);
903 data.WriteGuidBytes(guid2, 6);
904 data.WriteGuidBytes(guid, 6);
905 data.AppendPackedTime(time(NULL));
906 data.WriteGuidBytes(guid2, 1);
907 data.WriteGuidBytes(guid, 2, 0, 7);
908 data.WriteGuidBytes(guid2, 3);
909 data.WriteGuidBytes(guid, 4);
910 data.WriteGuidBytes(guid2, 7);
911 data << uint32(achievement->ID);
912 data.WriteGuidBytes(guid2, 4);
913 data.WriteGuidBytes(guid, 1);
914 data.WriteGuidBytes(guid2, 0);
915 data.WriteGuidBytes(guid, 5);
916 data << uint32(realmID);
917 data.WriteGuidBytes(guid, 5);
918 data << uint32(realmID);
919 data.WriteGuidBytes(guid2, 2);
920 GetOwner()->SendMessageToSetInRange(&data, sWorld->GetFloatConfig(WorldFloatConfigs::CONFIG_LISTEN_RANGE_SAY), true);
921}
922
923template<>
925{
926 ObjectGuid GuildGUID = GetOwner()->GetGUID();
927 bool GuildAchievement = true;
929 {
930 // broadcast realm first reached
931 WorldPacket data(SMSG_SERVER_FIRST_ACHIEVEMENT, GetOwner()->GetName().size() + 1 + 8 + 4 + 4);
932 data.WriteGuidMask(GuildGUID, 5, 6, 3, 7, 0, 4);
933 data.WriteBits(GetOwner()->GetName().size(), 7);
934 data.WriteGuidMask(GuildGUID, 2, 1);
935 data.WriteBit(GuildAchievement); // GuildAchievement
936 data.FlushBits();
937 data.WriteGuidBytes(GuildGUID, 1);
938 data.WriteString(GetOwner()->GetName());
939 data.WriteGuidBytes(GuildGUID, 0, 2);
940 data << uint32(achievement->ID); //29
941 data.WriteGuidBytes(GuildGUID, 6, 3, 4, 5, 7);
942 sWorld->SendGlobalMessage(&data);
943 }
944
946 data.WriteGuidMask(GuildGUID, 5, 7, 1, 4, 2, 0, 3, 6);
947 data.WriteGuidBytes(GuildGUID, 7);
948 data.AppendPackedTime(time(NULL));
949 data << uint32(achievement->ID);
950 data.WriteGuidBytes(GuildGUID, 0, 5, 3, 2, 4, 1, 6);
951 SendPacket(&data);
952}
953
954template<class T>
955void AchievementMgr<T>::SendCriteriaUpdate(CriteriaEntry const* /*entry*/, CriteriaProgress const* /*progress*/, uint32 /*timeElapsed*/, bool /*timedCompleted*/) const
956{
957}
958
959template<>
960void AchievementMgr<Player>::SendCriteriaUpdate(CriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted) const
961{
962 ObjectGuid guid = GetOwner()->GetGUID();
963
964 WorldPacket data(SMSG_CRITERIA_UPDATE, 8 + 4 + 8);
965 data.WriteBit(guid[4]);
966 data.WriteBit(guid[6]);
967 data.WriteBit(guid[2]);
968 data.WriteBit(guid[3]);
969 data.WriteBit(guid[7]);
970 data.WriteBit(guid[1]);
971 data.WriteBit(guid[5]);
972 data.WriteBit(guid[0]);
973
974 data.WriteByteSeq(guid[3]);
975 data.WriteByteSeq(guid[6]);
976 data.WriteByteSeq(guid[2]);
977
978 data << uint32(entry->ID);
979
980 if (!entry->timeLimit)
981 data << uint32(0);
982 else
983 data << uint32(timedCompleted ? 0 : 1);
984
985 data.WriteByteSeq(guid[5]);
986 data.WriteByteSeq(guid[1]);
987
988 data.AppendPackedTime(progress->date);
989 data.WriteByteSeq(guid[4]);
990
991 data << uint32(timeElapsed);
992 data << uint32(0);
993
994 data.WriteByteSeq(guid[7]);
995 data.WriteByteSeq(guid[0]);
996
997 data << uint64(progress->counter);
998 SendPacket(&data);
999}
1000
1001template<>
1002void AchievementMgr<Guild>::SendCriteriaUpdate(CriteriaEntry const* entry, CriteriaProgress const* progress, uint32 /*timeElapsed*/, bool /*timedCompleted*/) const
1003{
1004 //will send response to criteria progress request
1005 WorldPacket data(SMSG_GUILD_CRITERIA_DATA, 3 + 1 + 1 + 8 + 8 + 4 + 4 + 4 + 4 + 4);
1006
1007 ObjectGuid counter = progress->counter; // for accessing every byte individually
1008 ObjectGuid guid = progress->CompletedGUID;
1009
1010 data.WriteBits(1, 21);
1011 data.WriteBit(counter[4]);
1012 data.WriteBit(counter[1]);
1013 data.WriteBit(guid[2]);
1014 data.WriteBit(counter[3]);
1015 data.WriteBit(guid[1]);
1016 data.WriteBit(counter[5]);
1017 data.WriteBit(counter[0]);
1018 data.WriteBit(guid[3]);
1019 data.WriteBit(counter[2]);
1020 data.WriteBit(guid[7]);
1021 data.WriteBit(guid[5]);
1022 data.WriteBit(guid[0]);
1023 data.WriteBit(counter[6]);
1024 data.WriteBit(guid[6]);
1025 data.WriteBit(counter[7]);
1026 data.WriteBit(guid[4]);
1027
1028 data.FlushBits();
1029
1030 data.WriteByteSeq(guid[5]);
1031 data << uint32(progress->date); // unknown date
1032 data.WriteByteSeq(counter[3]);
1033 data.WriteByteSeq(counter[7]);
1034 data << uint32(progress->date); // unknown date
1035 data.WriteByteSeq(counter[6]);
1036 data.WriteByteSeq(guid[4]);
1037 data.WriteByteSeq(guid[1]);
1038 data.WriteByteSeq(counter[4]);
1039 data.WriteByteSeq(guid[3]);
1040 data.WriteByteSeq(counter[0]);
1041 data.WriteByteSeq(guid[2]);
1042 data.WriteByteSeq(counter[1]);
1043 data.WriteByteSeq(guid[6]);
1044 data << uint32(progress->date); // last update time (not packed!)
1045 data << uint32(entry->ID);
1046 data.WriteByteSeq(counter[5]);
1047 data << uint32(0);
1048 data.WriteByteSeq(guid[7]);
1049 data.WriteByteSeq(counter[2]);
1050 data.WriteByteSeq(guid[0]);
1051
1052 SendPacket(&data);
1053}
1054
1058template<class T>
1060{
1061 // suppress sending packets
1062 for (uint32 i = 0; i < ACHIEVEMENT_CRITERIA_TYPE_TOTAL; ++i)
1063 UpdateAchievementCriteria(AchievementCriteriaTypes(i), 0, 0, 0, NULL, referencePlayer);
1064}
1065
1066static const uint32 achievIdByArenaSlot[MAX_ARENA_SLOT] = { 1057, 1107, 1108 };
1067static const uint32 achievIdForDungeon[][4] =
1068{
1069 // ach_cr_id, is_dungeon, is_raid, is_heroic_dungeon
1070 { 321, true, true, true },
1071 { 916, false, true, false },
1072 { 917, false, true, false },
1073 { 918, true, false, false },
1074 { 2219, false, false, true },
1075 { 0, false, false, false }
1076};
1077
1078// Helper function to avoid having to specialize template for a 800 line long function
1079template <typename T> static bool IsGuild() { return false; }
1080template<> bool IsGuild<Guild>() { return true; }
1081
1083{
1084 return categoryId == 15118 || categoryId == 15119 || categoryId == 15120;
1085}
1086
1088{
1089 return categoryId == 15117 || IsPetBattleAchievementCategory(categoryId);
1090}
1091
1095template<class T>
1096void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1 /*= 0*/, uint64 miscValue2 /*= 0*/, uint64 miscValue3 /*= 0*/, Unit const* unit /*= NULL*/, Player* referencePlayer /*= NULL*/)
1097{
1099 {
1100 SF_LOG_DEBUG("achievement", "UpdateAchievementCriteria: Wrong criteria type %u", type);
1101 return;
1102 }
1103
1104 if (!referencePlayer)
1105 {
1106 SF_LOG_DEBUG("achievement", "UpdateAchievementCriteria: Player is NULL! Cant update criteria");
1107 return;
1108 }
1109
1110 // disable for gamemasters with GM-mode enabled
1111 if (referencePlayer->IsGameMaster())
1112 {
1113 SF_LOG_DEBUG("achievement", "UpdateAchievementCriteria: [Player %s GM mode on] %s, %s (%u), " UI64FMTD ", " UI64FMTD ", " UI64FMTD,
1114 referencePlayer->GetName().c_str(), GetLogNameForGuid(GetOwner()->GetGUID()), AchievementGlobalMgr::GetCriteriaTypeString(type), type, miscValue1, miscValue2, miscValue3);
1115 return;
1116 }
1117
1118 SF_LOG_DEBUG("achievement", "UpdateAchievementCriteria: %s, %s (%u), " UI64FMTD ", " UI64FMTD ", " UI64FMTD,
1119 GetLogNameForGuid(GetOwner()->GetGUID()), AchievementGlobalMgr::GetCriteriaTypeString(type), type, miscValue1, miscValue2, miscValue3);
1120
1121 // Lua_GetGuildLevelEnabled() is checked in achievement UI to display guild tab
1123 return;
1124
1125 AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type);
1126 for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i)
1127 {
1128 CriteriaEntry const* achievementCriteria = (*i);
1129
1130 if (!CanUpdateCriteria(achievementCriteria, NULL, miscValue1, miscValue2, miscValue3, unit, referencePlayer))
1131 continue;
1132
1133 // requirements not found in the dbc
1134 if (AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria))
1135 if (!data->Meets(referencePlayer, unit, miscValue1))
1136 continue;
1137
1138 switch (type)
1139 {
1140 // std. case: increment at 1
1144 case ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS: /* FIXME: for online player only currently */
1178 case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA: // This also behaves like ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA
1183 SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
1184 break;
1185 // std case: increment at miscValue1
1193 case ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS:/* FIXME: for online player only currently */
1201 SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_ACCUMULATE);
1202 break;
1209 SetCriteriaProgress(achievementCriteria, miscValue2, referencePlayer, PROGRESS_ACCUMULATE);
1210 break;
1211 // std case: high value at miscValue1
1213 case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD: /* FIXME: for online player only currently */
1219 SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_HIGHEST);
1220 break;
1222 SetCriteriaProgress(achievementCriteria, referencePlayer->getLevel(), referencePlayer);
1223 break;
1225 if (uint32 skillvalue = referencePlayer->GetBaseSkillValue(achievementCriteria->reach_skill_level.skillID))
1226 SetCriteriaProgress(achievementCriteria, skillvalue, referencePlayer);
1227 break;
1229 if (uint32 maxSkillvalue = referencePlayer->GetPureMaxSkillValue(achievementCriteria->learn_skill_level.skillID))
1230 SetCriteriaProgress(achievementCriteria, maxSkillvalue, referencePlayer);
1231 break;
1233 SetCriteriaProgress(achievementCriteria, referencePlayer->GetRewardedQuestCount(), referencePlayer);
1234 break;
1236 {
1237 time_t nextDailyResetTime = sWorld->GetNextDailyQuestsResetTime();
1238 CriteriaProgress* progress = GetCriteriaProgress(achievementCriteria);
1239
1240 if (!miscValue1) // Login case.
1241 {
1242 // reset if player missed one day.
1243 if (progress && progress->date < (nextDailyResetTime - 2 * DAY))
1244 SetCriteriaProgress(achievementCriteria, 0, referencePlayer, PROGRESS_SET);
1245 continue;
1246 }
1247
1248 ProgressType progressType;
1249 if (!progress)
1250 // 1st time. Start count.
1251 progressType = PROGRESS_SET;
1252 else if (progress->date < (nextDailyResetTime - 2 * DAY))
1253 // last progress is older than 2 days. Player missed 1 day => Restart count.
1254 progressType = PROGRESS_SET;
1255 else if (progress->date < (nextDailyResetTime - DAY))
1256 // last progress is between 1 and 2 days. => 1st time of the day.
1257 progressType = PROGRESS_ACCUMULATE;
1258 else
1259 // last progress is within the day before the reset => Already counted today.
1260 continue;
1261
1262 SetCriteriaProgress(achievementCriteria, 1, referencePlayer, progressType);
1263 break;
1264 }
1266 {
1267 uint32 counter = 0;
1268
1269 const RewardedQuestSet& rewQuests = referencePlayer->getRewardedQuests();
1270 for (RewardedQuestSet::const_iterator itr = rewQuests.begin(); itr != rewQuests.end(); ++itr)
1271 {
1272 Quest const* quest = sObjectMgr->GetQuestTemplate(*itr);
1273 if (quest && quest->GetZoneOrSort() >= 0 && uint32(quest->GetZoneOrSort()) == achievementCriteria->complete_quests_in_zone.zoneID)
1274 ++counter;
1275 }
1276 SetCriteriaProgress(achievementCriteria, counter, referencePlayer);
1277 break;
1278 }
1280 // miscValue1 is the ingame fallheight*100 as stored in dbc
1281 SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer);
1282 break;
1292 SetCriteriaProgress(achievementCriteria, 1, referencePlayer);
1293 break;
1295 SetCriteriaProgress(achievementCriteria, referencePlayer->GetBankBagSlotCount(), referencePlayer);
1296 break;
1298 {
1299 int32 reputation = referencePlayer->GetReputationMgr().GetReputation(achievementCriteria->gain_reputation.factionID);
1300 if (reputation > 0)
1301 SetCriteriaProgress(achievementCriteria, reputation, referencePlayer);
1302 break;
1303 }
1305 SetCriteriaProgress(achievementCriteria, referencePlayer->GetReputationMgr().GetExaltedFactionCount(), referencePlayer);
1306 break;
1308 {
1309 uint32 spellCount = 0;
1310 for (PlayerSpellMap::const_iterator spellIter = referencePlayer->GetSpellMap().begin();
1311 spellIter != referencePlayer->GetSpellMap().end();
1312 ++spellIter)
1313 {
1314 SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spellIter->first);
1315 for (SkillLineAbilityMap::const_iterator skillIter = bounds.first; skillIter != bounds.second; ++skillIter)
1316 {
1317 if (skillIter->second->skillId == achievementCriteria->learn_skillline_spell.skillLine)
1318 spellCount++;
1319 }
1320 }
1321 SetCriteriaProgress(achievementCriteria, spellCount, referencePlayer);
1322 break;
1323 }
1325 SetCriteriaProgress(achievementCriteria, referencePlayer->GetReputationMgr().GetReveredFactionCount(), referencePlayer);
1326 break;
1328 SetCriteriaProgress(achievementCriteria, referencePlayer->GetReputationMgr().GetHonoredFactionCount(), referencePlayer);
1329 break;
1331 SetCriteriaProgress(achievementCriteria, referencePlayer->GetReputationMgr().GetVisibleFactionCount(), referencePlayer);
1332 break;
1334 {
1335 uint32 spellCount = 0;
1336 for (PlayerSpellMap::const_iterator spellIter = referencePlayer->GetSpellMap().begin();
1337 spellIter != referencePlayer->GetSpellMap().end();
1338 ++spellIter)
1339 {
1340 SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spellIter->first);
1341 for (SkillLineAbilityMap::const_iterator skillIter = bounds.first; skillIter != bounds.second; ++skillIter)
1342 if (skillIter->second->skillId == achievementCriteria->learn_skill_line.skillLine)
1343 spellCount++;
1344 }
1345 SetCriteriaProgress(achievementCriteria, spellCount, referencePlayer);
1346 break;
1347 }
1349 SetCriteriaProgress(achievementCriteria, referencePlayer->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS), referencePlayer);
1350 break;
1352 SetCriteriaProgress(achievementCriteria, referencePlayer->GetMoney(), referencePlayer, PROGRESS_HIGHEST);
1353 break;
1355 if (!miscValue1)
1356 SetCriteriaProgress(achievementCriteria, _achievementPoints, referencePlayer, PROGRESS_SET);
1357 else
1358 SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_ACCUMULATE);
1359 break;
1361 {
1362 uint32 points = 0;
1363 for (CompletedAchievementMap::const_iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr)
1364 {
1365 AchievementEntry const* achievement = sAchievementMgr->GetAchievement(itr->first);
1366 if (achievement && IsPetBattleAchievementCategory(achievement->categoryId))
1367 points += achievement->points;
1368 }
1369
1370 SetCriteriaProgress(achievementCriteria, points, referencePlayer, PROGRESS_SET);
1371 break;
1372 }
1373 /*
1374 case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING:
1375 {
1376 uint32 reqTeamType = achievementCriteria->highest_team_rating.teamtype;
1377
1378 if (miscValue1)
1379 {
1380 if (miscValue2 != reqTeamType)
1381 continue;
1382
1383 SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_HIGHEST);
1384 }
1385 else // login case
1386 {
1387 for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot)
1388 {
1389 uint32 teamId = referencePlayer->GetArenaTeamId(arena_slot);
1390 if (!teamId)
1391 continue;
1392
1393 ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(teamId);
1394 if (!team || team->GetType() != reqTeamType)
1395 continue;
1396
1397 SetCriteriaProgress(achievementCriteria, team->GetStats().Rating, referencePlayer, PROGRESS_HIGHEST);
1398 break;
1399 }
1400 }
1401
1402 break;
1403 }
1404 case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_PERSONAL_RATING:
1405 {
1406 uint32 reqTeamType = achievementCriteria->highest_personal_rating.teamtype;
1407
1408 if (miscValue1)
1409 {
1410 if (miscValue2 != reqTeamType)
1411 continue;
1412
1413 SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_HIGHEST);
1414 }
1415 else // login case
1416 {
1417 for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot)
1418 {
1419 uint32 teamId = referencePlayer->GetArenaTeamId(arena_slot);
1420 if (!teamId)
1421 continue;
1422
1423 ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(teamId);
1424 if (!team || team->GetType() != reqTeamType)
1425 continue;
1426
1427 if (ArenaTeamMember const* member = team->GetMember(referencePlayer->GetGUID()))
1428 {
1429 SetCriteriaProgress(achievementCriteria, member->PersonalRating, referencePlayer, PROGRESS_HIGHEST);
1430 break;
1431 }
1432 }
1433 }
1434 break;
1435 }*/
1437 SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer);
1438 break;
1439 // FIXME: not triggered in code as result, need to implement
1458 break; // Not implemented yet :(
1459 }
1460
1461 AchievementCriteriaTreeList achievementCriteriaTreeList = sAchievementMgr->GetAchievementCriteriaTreeList(achievementCriteria);
1462 for (AchievementCriteriaTreeList::const_iterator iter = achievementCriteriaTreeList.begin(); iter != achievementCriteriaTreeList.end(); ++iter)
1463 {
1464 AchievementEntry const* achievement = sAchievementMgr->GetAchievementEntryByCriteriaTree(*iter);
1465
1466 if (!achievement)
1467 continue;
1468
1469 if (IsCompletedCriteriaForAchievement(achievementCriteria, achievement))
1470 CompletedCriteriaFor(achievement, referencePlayer);
1471
1472 // check again the completeness for SUMM and REQ COUNT achievements,
1473 // as they don't depend on the completed criteria but on the sum of the progress of each individual criteria
1474 if (achievement->flags & ACHIEVEMENT_FLAG_SUMM)
1475 if (IsCompletedAchievement(achievement))
1476 CompletedAchievement(achievement, referencePlayer);
1477
1478 if (AchievementEntryList const* achRefList = sAchievementMgr->GetAchievementByReferencedId(achievement->ID))
1479 for (AchievementEntryList::const_iterator itr = achRefList->begin(); itr != achRefList->end(); ++itr)
1480 if (IsCompletedAchievement(*itr))
1481 CompletedAchievement(*itr, referencePlayer);
1482 }
1483 }
1484}
1485
1486template<class T>
1488{
1489 AchievementCriteriaTreeList const& criteriaTreeList = sAchievementMgr->GetAchievementCriteriaTreeList(criteria);
1490 for (AchievementCriteriaTreeList::const_iterator iter = criteriaTreeList.begin(); iter != criteriaTreeList.end(); ++iter)
1491 {
1492 CriteriaTreeEntry const* criteriaTree = *iter;
1493 AchievementEntry const* achievement = sAchievementMgr->GetAchievementEntryByCriteriaTree(criteriaTree);
1494
1495 if (!achievement)
1496 return false;
1497
1498 if (CriteriaEntry const* criteria = sCriteriaStore.LookupEntry(criteriaTree->criteriaID))
1499 if (!IsCompletedCriteriaForAchievement(criteria, achievement))
1500 return false;
1501 }
1502
1503 return true;
1504}
1505
1506template<class T>
1508{
1509 if (!criteria || !achievement)
1510 return false;
1511
1512 CriteriaTreeEntry const* criteriaTree = NULL;
1513 AchievementCriteriaTreeList const* treeList = sAchievementMgr->GetSubCriteriaTreeById(achievement->criteriaTreeID);
1514
1515 if (treeList)
1516 {
1517 for (AchievementCriteriaTreeList::const_iterator iter = treeList->begin(); iter != treeList->end(); ++iter)
1518 {
1519 if ((*iter)->criteriaID == criteria->ID)
1520 {
1521 criteriaTree = *iter;
1522 break;
1523 }
1524 }
1525 }
1526 if (!criteriaTree)
1527 return false;
1528
1529 // counter can never complete
1530 if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
1531 return false;
1532
1534 {
1535 // someone on this realm has already completed that achievement
1536 if (sAchievementMgr->IsRealmCompleted(achievement))
1537 return false;
1538 }
1539
1540 CriteriaProgress const* progress = GetCriteriaProgress(criteria);
1541 if (!progress)
1542 return false;
1543
1544 switch (AchievementCriteriaTypes(criteria->type))
1545 {
1602 return progress->counter >= criteriaTree->criteriaCount;
1607 return progress->counter >= 1;
1609 return progress->counter >= (criteriaTree->criteriaCount * 75);
1611 return progress->counter >= 9000;
1613 return criteriaTree->criteriaCount && progress->counter >= criteriaTree->criteriaCount;
1614 // handle all statistic-only criteria here
1646 default:
1647 return false;
1648 }
1649}
1650
1651template<class T>
1652void AchievementMgr<T>::CompletedCriteriaFor(AchievementEntry const* achievement, Player* referencePlayer)
1653{
1654 // counter can never complete
1655 if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
1656 return;
1657
1658 // already completed and stored
1659 if (HasAchieved(achievement->ID))
1660 return;
1661
1662 if (IsCompletedAchievement(achievement))
1663 CompletedAchievement(achievement, referencePlayer);
1664}
1665
1666template<class T>
1668{
1669 // counter can never complete
1670 if (entry->flags & ACHIEVEMENT_FLAG_COUNTER)
1671 return false;
1672
1673 // for achievement with referenced achievement criterias get from referenced and counter from self
1674 uint32 achievementForTestCount = entry->count;
1675
1676 if (CriteriaTreeEntry const* criteriaTree = sCriteriaTreeStore.LookupEntry(entry->criteriaTreeID))
1677 achievementForTestCount = criteriaTree->criteriaCount;
1678
1680 AchievementCriteriaTreeList const* list = sAchievementMgr->GetSubCriteriaTreeById(entry->criteriaTreeID);
1681 for (AchievementCriteriaTreeList::const_iterator iter = list->begin(); iter != list->end(); ++iter)
1682 {
1683 CriteriaTreeEntry const* criteriaTree = *iter;
1684 if (CriteriaEntry const* criteria = sCriteriaStore.LookupEntry(criteriaTree->criteriaID))
1685 cList.push_back(criteria);
1686 }
1687
1688 if (!cList.size())
1689 return false;
1690
1691 uint64 count = 0;
1692
1693 // For SUMM achievements, we have to count the progress of each criteria of the achievement.
1694 // Oddly, the target count is NOT contained in the achievement, but in each individual criteria
1695 if (entry->flags & ACHIEVEMENT_FLAG_SUMM)
1696 {
1697 for (AchievementCriteriaEntryList::const_iterator itr = cList.begin(); itr != cList.end(); ++itr)
1698 {
1699 CriteriaEntry const* criteria = *itr;
1700
1701 CriteriaProgress const* progress = GetCriteriaProgress(criteria);
1702 if (!progress)
1703 continue;
1704
1705 count += progress->counter;
1706
1707 // for counters, field4 contains the main count requirement
1708 if (count >= sCriteriaTreeStore.LookupEntry(entry->criteriaTreeID)->criteriaCount)
1709 return true;
1710 }
1711 return false;
1712 }
1713
1714 // Default case - need complete all or
1715 bool completed_all = true;
1716 for (AchievementCriteriaEntryList::const_iterator itr = cList.begin(); itr != cList.end(); ++itr)
1717 {
1718 CriteriaEntry const* criteria = *itr;
1719
1720 bool completed = IsCompletedCriteriaForAchievement(criteria, entry);
1721
1722 // found an uncompleted criteria, but DONT return false yet - there might be a completed criteria with ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL
1723 if (completed)
1724 ++count;
1725 else
1726 completed_all = false;
1727
1728 // completed as have req. count of completed criterias
1729 if (achievementForTestCount > 0 && achievementForTestCount <= count)
1730 return true;
1731 }
1732
1733 // all criterias completed requirement
1734 if (completed_all && achievementForTestCount == 0)
1735 return true;
1736
1737 return false;
1738}
1739
1740template<class T>
1742{
1743 CriteriaProgressMap::iterator iter = m_criteriaProgress.find(entry->ID);
1744
1745 if (iter == m_criteriaProgress.end())
1746 return NULL;
1747
1748 return &(iter->second);
1749}
1750
1751template<class T>
1752void AchievementMgr<T>::SetCriteriaProgress(CriteriaEntry const* entry, uint64 changeValue, Player* referencePlayer, ProgressType ptype)
1753{
1754 // Don't allow to cheat - doing timed achievements without timer active
1755 TimedAchievementMap::iterator timedIter = m_timedAchievements.find(entry->ID);
1756 if (entry->timeLimit && timedIter == m_timedAchievements.end())
1757 return;
1758
1759 SF_LOG_DEBUG("achievement", "SetCriteriaProgress(%u, " UI64FMTD ") for (%s GUID: %u)",
1760 entry->ID, changeValue, GetLogNameForGuid(GetOwner()->GetGUID()), GUID_LOPART(GetOwner()->GetGUID()));
1761
1762 CriteriaProgress* progress = GetCriteriaProgress(entry);
1763 if (!progress)
1764 {
1765 // not create record for 0 counter but allow it for timed achievements
1766 // we will need to send 0 progress to client to start the timer
1767 if (changeValue == 0 && !entry->timeLimit)
1768 return;
1769
1770 progress = &m_criteriaProgress[entry->ID];
1771 progress->counter = changeValue;
1772 }
1773 else
1774 {
1775 uint64 newValue = 0;
1776 switch (ptype)
1777 {
1778 case PROGRESS_SET:
1779 newValue = changeValue;
1780 break;
1782 {
1783 // avoid overflow
1784 uint64 max_value = std::numeric_limits<uint64>::max();
1785 newValue = max_value - progress->counter > changeValue ? progress->counter + changeValue : max_value;
1786 break;
1787 }
1788 case PROGRESS_HIGHEST:
1789 newValue = progress->counter < changeValue ? changeValue : progress->counter;
1790 break;
1791 }
1792
1793 // not update (not mark as changed) if counter will have same value
1794 if (progress->counter == newValue && !entry->timeLimit)
1795 return;
1796
1797 progress->counter = newValue;
1798 }
1799
1800 progress->changed = true;
1801 progress->date = time(NULL); // set the date to the latest update.
1802 uint32 timeElapsed = 0; // @todo : Fix me
1803
1804 bool hasLinkedAchievement = false;
1805 bool hasLiveEligibleAchievement = false;
1806
1807 AchievementCriteriaTreeList criteriaList = sAchievementMgr->GetAchievementCriteriaTreeList(entry);
1808 for (AchievementCriteriaTreeList::const_iterator iter = criteriaList.begin(); iter != criteriaList.end(); ++iter)
1809 {
1810 AchievementEntry const* achievement = sAchievementMgr->GetAchievementEntryByCriteriaTree(*iter);
1811
1812 if (!achievement)
1813 continue;
1814
1815 hasLinkedAchievement = true;
1816 hasLiveEligibleAchievement = hasLiveEligibleAchievement
1819
1820 bool criteriaComplete = IsCompletedCriteriaForAchievement(entry, achievement);
1821
1822 if (entry->timeLimit)
1823 {
1824 // Client expects this in packet
1825 timeElapsed = entry->timeLimit - (timedIter->second / IN_MILLISECONDS);
1826
1827 // Remove the timer, we wont need it anymore
1828 if (criteriaComplete)
1829 m_timedAchievements.erase(timedIter);
1830 }
1831
1832 if (criteriaComplete && achievement->flags & ACHIEVEMENT_FLAG_SHOW_CRITERIA_MEMBERS && !progress->CompletedGUID)
1833 progress->CompletedGUID = referencePlayer->GetGUID();
1834 }
1835
1836 if (Skyfire::Achievements::ShouldSendLiveCriteriaProgress(hasLinkedAchievement, hasLiveEligibleAchievement))
1837 SendCriteriaUpdate(entry, progress, timeElapsed, false);
1838}
1839
1840template<class T>
1842{
1843 if (!m_timedAchievements.empty())
1844 {
1845 for (TimedAchievementMap::iterator itr = m_timedAchievements.begin(); itr != m_timedAchievements.end();)
1846 {
1847 // Time is up, remove timer and reset progress
1848 if (itr->second <= timeDiff)
1849 {
1850 CriteriaEntry const* entry = sAchievementMgr->GetAchievementCriteria(itr->first);
1852 m_timedAchievements.erase(itr++);
1853 }
1854 else
1855 {
1856 itr->second -= timeDiff;
1857 ++itr;
1858 }
1859 }
1860 }
1861}
1862
1863template<class T>
1865{
1866}
1867
1868template<>
1870{
1871 AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetTimedAchievementCriteriaByType(type);
1872 for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i)
1873 {
1874 if ((*i)->timedCriteriaMiscId != entry)
1875 continue;
1876
1877 AchievementEntry const* achievement = sAchievementMgr->GetAchievement(entry);
1878 if (m_timedAchievements.find((*i)->ID) == m_timedAchievements.end() && !IsCompletedCriteriaForAchievement(*i, achievement))
1879 {
1880 // Start the timer
1881 if ((*i)->timeLimit * IN_MILLISECONDS > timeLost)
1882 {
1883 m_timedAchievements[(*i)->ID] = (*i)->timeLimit * IN_MILLISECONDS - timeLost;
1884
1885 // and at client too
1887 }
1888 }
1889 }
1890}
1891
1892template<class T>
1894{
1895 AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetTimedAchievementCriteriaByType(type);
1896 for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i)
1897 {
1898 if ((*i)->timedCriteriaMiscId != entry)
1899 continue;
1900
1901 TimedAchievementMap::iterator timedIter = m_timedAchievements.find((*i)->ID);
1902 // We don't have timer for this achievement
1903 if (timedIter == m_timedAchievements.end())
1904 continue;
1905
1906 // remove progress
1908
1909 // Remove the timer
1910 m_timedAchievements.erase(timedIter);
1911 }
1912}
1913
1914template<>
1916{
1917 // disable for gamemasters with GM-mode enabled
1918 if (GetOwner()->IsGameMaster())
1919 return;
1920
1921 if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER || HasAchieved(achievement->ID))
1922 return;
1923
1924 if (achievement->flags & ACHIEVEMENT_FLAG_SHOW_IN_GUILD_NEWS)
1925 if (Guild* guild = referencePlayer->GetGuild())
1926 guild->AddGuildNews(GUILD_NEWS_PLAYER_ACHIEVEMENT, referencePlayer->GetGUID(), achievement->flags & ACHIEVEMENT_FLAG_SHOW_IN_GUILD_HEADER, achievement->ID);
1927
1928 if (!GetOwner()->GetSession()->PlayerLoading())
1929 SendAchievementEarned(achievement);
1930
1931 SF_LOG_INFO("achievement", "AchievementMgr::CompletedAchievement(%u). Player: %s (%u)",
1932 achievement->ID, GetOwner()->GetName().c_str(), GetOwner()->GetGUIDLow());
1933
1935 ca.date = time(NULL);
1936 ca.changed = true;
1937
1938 // don't insert for ACHIEVEMENT_FLAG_REALM_FIRST_KILL since otherwise only the first group member would reach that achievement
1940 if (!(achievement->flags & ACHIEVEMENT_FLAG_REALM_FIRST_KILL))
1941 sAchievementMgr->SetRealmCompleted(achievement);
1942
1943 _achievementPoints += achievement->points;
1944
1949
1950 if (BattlePetMgr* battlePetMgr = referencePlayer->GetBattlePetMgr())
1951 battlePetMgr->OnAchievementEarned(achievement->ID);
1952
1953 // reward items and titles if any
1954 AchievementReward const* reward = sAchievementMgr->GetAchievementReward(achievement);
1955
1956 // no rewards
1957 if (!reward)
1958 return;
1959
1960 // titles
1965 if (uint32 titleId = reward->titleId[achievement->ID == 1793 ? GetOwner()->getGender() : (GetOwner()->GetTeam() == ALLIANCE ? 0 : 1)])
1966 if (CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId))
1967 GetOwner()->SetTitle(titleEntry);
1968
1969 if (reward->spellId > 0)
1970 referencePlayer->CastSpell(referencePlayer, reward->spellId);
1971 else if (reward->spellId < 0)
1972 referencePlayer->learnSpell(uint32(-reward->spellId), false);
1973
1974 // mail
1975 if (reward->sender)
1976 {
1977 Item* item = reward->itemId ? Item::CreateItem(reward->itemId, 1, GetOwner()) : NULL;
1978
1979 int loc_idx = GetOwner()->GetSession()->GetSessionDbLocaleIndex();
1980
1981 // subject and text
1982 std::string subject = reward->subject;
1983 std::string text = reward->text;
1984 if (loc_idx >= 0)
1985 {
1986 if (AchievementRewardLocale const* loc = sAchievementMgr->GetAchievementRewardLocale(achievement))
1987 {
1988 ObjectMgr::GetLocaleString(loc->subject, loc_idx, subject);
1989 ObjectMgr::GetLocaleString(loc->text, loc_idx, text);
1990 }
1991 }
1992
1993 MailDraft draft(subject, text);
1994
1995 SQLTransaction trans = CharacterDatabase.BeginTransaction();
1996 if (item)
1997 {
1998 // save new item before send
1999 item->SaveToDB(trans); // save for prevent lost at next mail load, if send fail then item will deleted
2000
2001 // item
2002 draft.AddItem(item);
2003 }
2004
2005 draft.SendMailTo(trans, GetOwner(), MailSender(MAIL_CREATURE, reward->sender));
2006 CharacterDatabase.CommitTransaction(trans);
2007 }
2008}
2009
2010template<>
2012{
2013 SF_LOG_DEBUG("achievement", "AchievementMgr<Guild>::CompletedAchievement(%u)", achievement->ID);
2014
2015 if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER || HasAchieved(achievement->ID))
2016 return;
2017
2018 if (achievement->flags & ACHIEVEMENT_FLAG_SHOW_IN_GUILD_NEWS)
2019 if (Guild* guild = referencePlayer->GetGuild())
2020 guild->AddGuildNews(GUILD_NEWS_GUILD_ACHIEVEMENT, 0, achievement->flags & ACHIEVEMENT_FLAG_SHOW_IN_GUILD_HEADER, achievement->ID);
2021
2022 SendAchievementEarned(achievement);
2024 ca.date = time(NULL);
2025 ca.changed = true;
2026
2027 if (achievement->flags & ACHIEVEMENT_FLAG_SHOW_GUILD_MEMBERS)
2028 {
2029 if (referencePlayer->GetGuildId() == GetOwner()->GetId())
2030 ca.guids.insert(referencePlayer->GetGUID());
2031
2032 if (Group const* group = referencePlayer->GetGroup())
2033 for (GroupReference const* ref = group->GetFirstMember(); ref != NULL; ref = ref->next())
2034 if (Player const* groupMember = ref->GetSource())
2035 if (groupMember->GetGuildId() == GetOwner()->GetId())
2036 ca.guids.insert(groupMember->GetGUID());
2037 }
2038
2039 sAchievementMgr->SetRealmCompleted(achievement);
2040
2041 _achievementPoints += achievement->points;
2042
2045}
2046
2048{
2049 bool operator()(CompletedAchievementMap::value_type const& val)
2050 {
2051 AchievementEntry const* achievement = sAchievementMgr->GetAchievement(val.first);
2052 return achievement && !(achievement->flags & ACHIEVEMENT_FLAG_HIDDEN);
2053 }
2054};
2055
2056template<class T>
2058{
2059 /*
2060 * Temporary fix for displaying achievements! Still uses old system.
2061 * More core and database changes required for cross character achievements
2062 */
2063
2064 VisibleAchievementPred isVisible;
2065 size_t numCriteria = m_criteriaProgress.size();
2066 size_t numAchievements = std::count_if(m_completedAchievements.begin(), m_completedAchievements.end(), isVisible);
2067 ByteBuffer criteriaData(numCriteria * (4 + 4 + 4 + 4 + 8 + 8));
2068 ByteBuffer completedData(numAchievements * (4 + 4 + 4 + 4 + 8));
2069 ObjectGuid guid = GetOwner()->GetGUID();
2070 ObjectGuid counter;
2071
2072 WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA, 5 + numAchievements * (1 + 4 + 4 + 4 + 4 + 8) + numCriteria * (1 + 4 + 4 + 4 + 4 + 8 + 8));
2073 data.WriteBits(numCriteria, 19);
2074
2075 for (CriteriaProgressMap::const_iterator itr = m_criteriaProgress.begin(); itr != m_criteriaProgress.end(); ++itr)
2076 {
2077 counter = itr->second.counter;
2078
2079 data.WriteBit(counter[3]);
2080 data.WriteBit(guid[3]);
2081 data.WriteBit(guid[6]);
2082 data.WriteBit(counter[0]);
2083 data.WriteBit(guid[7]);
2084 data.WriteBit(counter[1]);
2085 data.WriteBit(counter[5]);
2086 data.WriteBit(guid[2]);
2087 data.WriteBit(guid[1]);
2088 data.WriteBit(counter[7]);
2089 data.WriteBit(guid[4]);
2090 data.WriteBit(guid[0]);
2091 data.WriteBit(counter[2]);
2092 data.WriteBit(guid[5]);
2093 data.WriteBit(counter[4]);
2094 data.WriteBits(0, 4);
2095 data.WriteBit(counter[6]);
2096
2097 criteriaData.WriteByteSeq(counter[7]);
2098 criteriaData << uint32(0); // timer 1
2099 criteriaData.WriteByteSeq(counter[6]);
2100 criteriaData.WriteByteSeq(guid[1]);
2101 criteriaData << uint32(itr->first); // criteria id
2102 criteriaData.WriteByteSeq(counter[4]);
2103 criteriaData.WriteByteSeq(guid[0]);
2104 criteriaData.WriteByteSeq(guid[4]);
2105 criteriaData.WriteByteSeq(guid[6]);
2106 criteriaData.WriteByteSeq(counter[1]);
2107 criteriaData.WriteByteSeq(counter[5]);
2108 criteriaData.WriteByteSeq(guid[7]);
2109 criteriaData.WriteByteSeq(guid[2]);
2110 criteriaData.WriteByteSeq(counter[2]);
2111 criteriaData.WriteByteSeq(counter[0]);
2112 criteriaData.WriteByteSeq(guid[3]);
2113 criteriaData.WriteByteSeq(counter[3]);
2114 criteriaData << uint32(0); // timer 2
2115 criteriaData.WriteByteSeq(guid[5]);
2116 criteriaData.AppendPackedTime(itr->second.date); // criteria date
2117 }
2118
2119 data.WriteBits(numAchievements, 20);
2120 for (CompletedAchievementMap::const_iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr)
2121 {
2122 if (!isVisible(*itr))
2123 continue;
2124
2125 data.WriteBit(guid[0]);
2126 data.WriteBit(guid[7]);
2127 data.WriteBit(guid[1]);
2128 data.WriteBit(guid[5]);
2129 data.WriteBit(guid[2]);
2130 data.WriteBit(guid[4]);
2131 data.WriteBit(guid[6]);
2132 data.WriteBit(guid[3]);
2133
2134 completedData << uint32(itr->first); // achievement Id
2135 completedData << uint32(realmID);
2136 completedData.WriteByteSeq(guid[5]);
2137 completedData.WriteByteSeq(guid[7]);
2138 completedData << uint32(realmID);
2139 completedData.AppendPackedTime(itr->second.date); // achievement date
2140 completedData.WriteByteSeq(guid[0]);
2141 completedData.WriteByteSeq(guid[4]);
2142 completedData.WriteByteSeq(guid[1]);
2143 completedData.WriteByteSeq(guid[6]);
2144 completedData.WriteByteSeq(guid[2]);
2145 completedData.WriteByteSeq(guid[3]);
2146 }
2147
2148 data.FlushBits();
2149 data.append(completedData);
2150 data.append(criteriaData);
2151
2152 SendPacket(&data);
2153}
2154
2155template<>
2157{
2158 VisibleAchievementPred isVisible;
2160 data.WriteBits(std::count_if(m_completedAchievements.begin(), m_completedAchievements.end(), isVisible), 23);
2161 for (CompletedAchievementMap::const_iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr)
2162 {
2163 if (!isVisible(*itr))
2164 continue;
2165
2166 data.AppendPackedTime(itr->second.date);
2167 data << uint32(itr->first);
2168 }
2169
2170 receiver->GetSession()->SendPacket(&data);
2171}
2172
2173template<>
2174void AchievementMgr<Player>::SendAchievementInfo(Player* receiver, uint32 /*achievementId = 0 */) const
2175{
2176 ObjectGuid guid = GetOwner()->GetGUID();
2177 ObjectGuid counter;
2178
2179 VisibleAchievementPred isVisible;
2180 size_t numCriteria = m_criteriaProgress.size();
2181 size_t numAchievements = std::count_if(m_completedAchievements.begin(), m_completedAchievements.end(), isVisible);
2182 ByteBuffer criteriaData(numCriteria * 32);
2183 ByteBuffer achievementsData(numAchievements * 24);
2184
2185 WorldPacket data(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, 1 + 8 + 3 + 3 + numAchievements * (4 + 4) + numCriteria * (0));
2186
2187 data.WriteBit(guid[3]);
2188 data.WriteBit(guid[6]);
2189 data.WriteBit(guid[0]);
2190 data.WriteBit(guid[2]);
2191 data.WriteBits(numAchievements, 20);
2192 data.WriteBits(numCriteria, 19);
2193
2194 for (CriteriaProgressMap::const_iterator itr = m_criteriaProgress.begin(); itr != m_criteriaProgress.end(); ++itr)
2195 {
2196 counter = itr->second.counter;
2197 ObjectGuid guid2 = itr->second.CompletedGUID;
2198
2199 data.WriteBit(guid2[1]);
2200 data.WriteBit(guid2[4]);
2201 data.WriteBit(guid2[5]);
2202 data.WriteBit(counter[7]);
2203 data.WriteBit(counter[4]);
2204 data.WriteBit(counter[3]);
2205 data.WriteBit(guid2[7]);
2206 data.WriteBit(guid2[0]);
2207 data.WriteBit(guid2[6]);
2208 data.WriteBits(0, 4); // criteria progress flags
2209 data.WriteBit(guid2[2]);
2210 data.WriteBit(counter[5]);
2211 data.WriteBit(counter[6]);
2212 data.WriteBit(counter[0]);
2213 data.WriteBit(counter[2]);
2214 data.WriteBit(counter[1]);
2215 data.WriteBit(guid2[3]);
2216
2217 criteriaData.WriteByteSeq(counter[4]);
2218 criteriaData << uint32(0); // timer 1
2219 criteriaData.WriteByteSeq(counter[1]);
2220 criteriaData.WriteByteSeq(guid2[1]);
2221 criteriaData.WriteByteSeq(counter[7]);
2222 criteriaData << uint32(itr->first);
2223 criteriaData.WriteByteSeq(guid2[3]);
2224 criteriaData.WriteByteSeq(counter[3]);
2225 criteriaData.WriteByteSeq(counter[5]);
2226 criteriaData.WriteByteSeq(counter[2]);
2227 criteriaData.WriteByteSeq(guid2[4]);
2228 criteriaData.WriteByteSeq(counter[0]);
2229 criteriaData.WriteByteSeq(guid2[0]);
2230 criteriaData << uint32(0); // timer 2
2231 criteriaData.WriteByteSeq(guid2[7]);
2232 criteriaData.AppendPackedTime(itr->second.date);
2233 criteriaData.WriteByteSeq(counter[6]);
2234 criteriaData.WriteByteSeq(guid2[2]);
2235 criteriaData.WriteByteSeq(guid2[6]);
2236 criteriaData.WriteByteSeq(guid2[5]);
2237 }
2238
2239 data.WriteBit(guid[5]);
2240
2241 for (CompletedAchievementMap::const_iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr)
2242 {
2243 ObjectGuid guid3 = *(itr->second.guids.begin());
2244
2245 data.WriteBit(guid3[0]);
2246 data.WriteBit(guid3[2]);
2247 data.WriteBit(guid3[5]);
2248 data.WriteBit(guid3[4]);
2249 data.WriteBit(guid3[3]);
2250 data.WriteBit(guid3[6]);
2251 data.WriteBit(guid3[1]);
2252 data.WriteBit(guid3[7]);
2253
2254 achievementsData.WriteByteSeq(guid3[1]);
2255 achievementsData.WriteByteSeq(guid3[0]);
2256 achievementsData.AppendPackedTime(itr->second.date);
2257 achievementsData << uint32(0); //RealmID
2258 achievementsData << uint32(itr->first);
2259 achievementsData.WriteByteSeq(guid3[7]);
2260 achievementsData.WriteByteSeq(guid3[4]);
2261 achievementsData.WriteByteSeq(guid3[6]);
2262 achievementsData.WriteByteSeq(guid3[2]);
2263 achievementsData.WriteByteSeq(guid3[3]);
2264 achievementsData.WriteByteSeq(guid3[5]);
2265 achievementsData << uint32(0); //RealmID
2266 }
2267
2268 data.WriteBit(guid[4]);
2269 data.WriteBit(guid[7]);
2270 data.WriteBit(guid[1]);
2271
2272 data.FlushBits();
2273 data.WriteByteSeq(guid[5]);
2274
2275 data.append(achievementsData);
2276 data.append(criteriaData);
2277
2278 data.WriteByteSeq(guid[0]);
2279 data.WriteByteSeq(guid[3]);
2280 data.WriteByteSeq(guid[6]);
2281 data.WriteByteSeq(guid[2]);
2282 data.WriteByteSeq(guid[7]);
2283 data.WriteByteSeq(guid[4]);
2284 data.WriteByteSeq(guid[1]);
2285
2286 receiver->GetSession()->SendPacket(&data);
2287}
2288
2289template<>
2290void AchievementMgr<Guild>::SendAchievementInfo(Player* receiver, uint32 achievementId /*= 0*/) const
2291{
2292 /*AchievementEntry const* achievement = sAchievementStore.LookupEntry(achievementId);
2293
2294 if (!achievement)
2295 {
2296 // send empty packet
2297 WorldPacket data(SMSG_GUILD_CRITERIA_DATA, 3);
2298 data.WriteBits(0, 21);
2299 receiver->GetSession()->SendPacket(&data);
2300 return;
2301 }
2302
2303 CriteriaTreeEntry const* criteriaTree = sCriteriaTreeStore.LookupEntry(achievement->criteriaTreeID);
2304
2305 if (!criteriaTree)
2306 {
2307 // send empty packet
2308 WorldPacket data(SMSG_GUILD_CRITERIA_DATA, 3);
2309 data.WriteBits(0, 21);
2310 receiver->GetSession()->SendPacket(&data);
2311 return;
2312 }
2313
2314 //will send response to criteria progress request
2315 AchievementCriteriaEntryList const* criteria = criteriaTreeList
2316 if (!criteria)
2317 {
2318 // send empty packet
2319 WorldPacket data(SMSG_GUILD_CRITERIA_DATA, 3);
2320 data.WriteBits(0, 21);
2321 receiver->GetSession()->SendPacket(&data);
2322 return;
2323 }
2324
2325 ObjectGuid counter;
2326 ObjectGuid guid;
2327 uint32 numCriteria = 0;
2328 ByteBuffer criteriaData(criteria->size() * (8 + 8 + 4 + 4 + 4));
2329 ByteBuffer criteriaBits(criteria->size() * (8 + 8) / 8);
2330 for (AchievementCriteriaEntryList::const_iterator itr = criteria->begin(); itr != criteria->end(); ++itr)
2331 {
2332 uint32 criteriaId = (*itr)->ID;
2333 CriteriaProgressMap::const_iterator progress = m_criteriaProgress.find(criteriaId);
2334 if (progress == m_criteriaProgress.end())
2335 continue;
2336
2337 ++numCriteria;
2338 }
2339
2340 criteriaBits.WriteBits(numCriteria, 21);
2341
2342 for (AchievementCriteriaEntryList::const_iterator itr = criteria->begin(); itr != criteria->end(); ++itr)
2343 {
2344 uint32 criteriaId = (*itr)->ID;
2345 CriteriaProgressMap::const_iterator progress = m_criteriaProgress.find(criteriaId);
2346 if (progress == m_criteriaProgress.end())
2347 continue;
2348
2349 counter = progress->second.counter;
2350 guid = progress->second.CompletedGUID;
2351
2352 criteriaBits.WriteBit(counter[4]);
2353 criteriaBits.WriteBit(counter[1]);
2354 criteriaBits.WriteBit(guid[2]);
2355 criteriaBits.WriteBit(counter[3]);
2356 criteriaBits.WriteBit(guid[1]);
2357 criteriaBits.WriteBit(counter[5]);
2358 criteriaBits.WriteBit(counter[0]);
2359 criteriaBits.WriteBit(guid[3]);
2360 criteriaBits.WriteBit(counter[2]);
2361 criteriaBits.WriteBit(guid[7]);
2362 criteriaBits.WriteBit(guid[5]);
2363 criteriaBits.WriteBit(guid[0]);
2364 criteriaBits.WriteBit(counter[6]);
2365 criteriaBits.WriteBit(guid[6]);
2366 criteriaBits.WriteBit(counter[7]);
2367 criteriaBits.WriteBit(guid[4]);
2368
2369 criteriaData.WriteByteSeq(guid[5]);
2370 criteriaData << uint32(progress->second.date); // unknown date
2371 criteriaData.WriteByteSeq(counter[3]);
2372 criteriaData.WriteByteSeq(counter[7]);
2373 criteriaData << uint32(progress->second.date); // unknown date
2374 criteriaData.WriteByteSeq(counter[6]);
2375 criteriaData.WriteByteSeq(guid[4]);
2376 criteriaData.WriteByteSeq(guid[1]);
2377 criteriaData.WriteByteSeq(counter[4]);
2378 criteriaData.WriteByteSeq(guid[3]);
2379 criteriaData.WriteByteSeq(counter[0]);
2380 criteriaData.WriteByteSeq(guid[2]);
2381 criteriaData.WriteByteSeq(counter[1]);
2382 criteriaData.WriteByteSeq(guid[6]);
2383 criteriaData << uint32(progress->second.date); // last update time (not packed!)
2384 criteriaData << uint32(criteriaId);
2385 criteriaData.WriteByteSeq(counter[5]);
2386 criteriaData << uint32(0);
2387 criteriaData.WriteByteSeq(guid[7]);
2388 criteriaData.WriteByteSeq(counter[2]);
2389 criteriaData.WriteByteSeq(guid[0]);
2390 }
2391
2392 WorldPacket data(SMSG_GUILD_CRITERIA_DATA, criteriaBits.size() + criteriaData.size());
2393 data.append(criteriaBits);
2394 if (numCriteria)
2395 data.append(criteriaData);
2396
2397 receiver->GetSession()->SendPacket(&data);*/
2398}
2399
2400template<class T>
2402{
2403 return m_completedAchievements.find(achievementId) != m_completedAchievements.end();
2404}
2405
2406template<class T>
2407bool AchievementMgr<T>::CanUpdateCriteria(CriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit const* unit, Player* referencePlayer)
2408{
2410 {
2411 SF_LOG_TRACE("achievement", "CanUpdateCriteria: (Id: %u Type %s) Disabled",
2413 return false;
2414 }
2415
2416 if (achievement && achievement->mapID != -1 && referencePlayer->GetMapId() != uint32(achievement->mapID))
2417 {
2418 SF_LOG_TRACE("achievement", "CanUpdateCriteria: (Id: %u Type %s) Wrong map",
2420 return false;
2421 }
2422
2423 if (achievement && ((achievement->requiredFaction == ACHIEVEMENT_FACTION_HORDE && referencePlayer->GetTeam() != HORDE) ||
2424 (achievement->requiredFaction == ACHIEVEMENT_FACTION_ALLIANCE && referencePlayer->GetTeam() != ALLIANCE)))
2425 {
2426 SF_LOG_TRACE("achievement", "CanUpdateCriteria: (Id: %u Type %s) Wrong faction",
2428 return false;
2429 }
2430
2431 if (IsCompletedCriteria(criteria))
2432 {
2433 SF_LOG_TRACE("achievement", "CanUpdateCriteria: (Id: %u Type %s) Is Completed",
2435 return false;
2436 }
2437
2438
2439 if (!RequirementsSatisfied(criteria, miscValue1, miscValue2, miscValue3, unit, referencePlayer))
2440 {
2441 SF_LOG_TRACE("achievement", "CanUpdateCriteria: (Id: %u Type %s) Requirements not satisfied",
2443 return false;
2444 }
2445
2446 if (!AdditionalRequirementsSatisfied(criteria, miscValue1, miscValue2, miscValue3, unit, referencePlayer))
2447 {
2448 SF_LOG_TRACE("achievement", "CanUpdateCriteria: (Id: %u Type %s) Additional requirements not satisfied",
2450 return false;
2451 }
2452
2453 if (!ConditionsSatisfied(criteria, referencePlayer))
2454 {
2455 SF_LOG_TRACE("achievement", "CanUpdateCriteria: (Id: %u Type %s) Conditions not satisfied",
2457 return false;
2458 }
2459
2460 return true;
2461}
2462
2463template<class T>
2464bool AchievementMgr<T>::ConditionsSatisfied(CriteriaEntry const* criteria, Player* referencePlayer) const
2465{
2466 /* for (uint32 i = 0; i < MAX_CRITERIA_REQUIREMENTS; ++i)
2467 {
2468 if (!criteria->additionalRequirements[i].additionalRequirement_type)
2469 continue;
2470
2471 switch (criteria->additionalRequirements[i].additionalRequirement_type)
2472 {
2473 case ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP:
2474 if (referencePlayer->GetMapId() != criteria->additionalRequirements[i].additionalRequirement_value)
2475 return false;
2476 break;
2477 case ACHIEVEMENT_CRITERIA_CONDITION_NOT_IN_GROUP:
2478 if (referencePlayer->GetGroup())
2479 return false;
2480 break;
2481 default:
2482 break;
2483 }
2484 }
2485 */
2486 return true;
2487}
2488
2489
2490template<class T>
2491bool AchievementMgr<T>::RequirementsSatisfied(CriteriaEntry const* achievementCriteria, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit const* unit, Player* referencePlayer) const
2492{
2493 switch (AchievementCriteriaTypes(achievementCriteria->type))
2494 {
2530 if (!miscValue1)
2531 return false;
2532 break;
2548 break;
2551 return false;
2552 break;
2554 if (!miscValue1 || (achievementCriteria->collect_battle_pet.creatureID && miscValue1 != achievementCriteria->collect_battle_pet.creatureID))
2555 return false;
2556 break;
2558 if (!miscValue1 || (achievementCriteria->collect_battle_pet_species.speciesID && miscValue1 != achievementCriteria->collect_battle_pet_species.speciesID))
2559 return false;
2560 break;
2562 if (!miscValue1 || (achievementCriteria->reach_battle_pet_level.level && miscValue1 < achievementCriteria->reach_battle_pet_level.level))
2563 return false;
2564 break;
2568 break;
2570 if (!miscValue1 || achievementCriteria->win_bg.bgMapID != referencePlayer->GetMapId())
2571 return false;
2572 break;
2574 if (!miscValue1 || achievementCriteria->kill_creature.creatureID != miscValue1)
2575 return false;
2576 break;
2578 // update at loading or specific skill update
2579 if (miscValue1 && miscValue1 != achievementCriteria->reach_skill_level.skillID)
2580 return false;
2581 break;
2583 // update at loading or specific skill update
2584 if (miscValue1 && miscValue1 != achievementCriteria->learn_skill_level.skillID)
2585 return false;
2586 break;
2588 if (miscValue1 && miscValue1 != achievementCriteria->complete_quests_in_zone.zoneID)
2589 return false;
2590 break;
2592 if (!miscValue1 || referencePlayer->GetMapId() != achievementCriteria->complete_battleground.mapID)
2593 return false;
2594 break;
2596 if (!miscValue1 || referencePlayer->GetMapId() != achievementCriteria->death_at_map.mapID)
2597 return false;
2598 break;
2600 {
2601 if (!miscValue1)
2602 return false;
2603 // skip wrong arena achievements, if not achievIdByArenaSlot then normal total death counter
2604 /*bool notfit = false;
2605 for (int j = 0; j < MAX_ARENA_SLOT; ++j)
2606 {
2607 if (achievIdByArenaSlot[j] == achievementCriteria->achievement)
2608 {
2609 Battleground* bg = referencePlayer->GetBattleground();
2610 if (!bg || !bg->isArena() || ArenaTeam::GetSlotByType(bg->GetArenaType()) != j)
2611 notfit = true;
2612 break;
2613 }
2614 }
2615 if (notfit)
2616 return false;*/
2617 break;
2618 }
2620 {
2621 if (!miscValue1)
2622 return false;
2623 /*
2624 Map const* map = referencePlayer->IsInWorld() ? referencePlayer->GetMap() : sMapMgr->FindMap(referencePlayer->GetMapId(), referencePlayer->GetInstanceId());
2625 if (!map || !map->IsDungeon())
2626 return false;
2627
2628 // search case
2629 bool found = false;
2630 for (int j = 0; achievIdForDungeon[j][0]; ++j)
2631 {
2632 if (achievIdForDungeon[j][0] == achievementCriteria->achievement)
2633 {
2634 if (map->IsRaid())
2635 {
2636 // if raid accepted (ignore difficulty)
2637 if (!achievIdForDungeon[j][2])
2638 break; // for
2639 }
2640 else if (referencePlayer->GetDungeonDifficulty() == DUNGEON_DIFFICULTY_NORMAL)
2641 {
2642 // dungeon in normal mode accepted
2643 if (!achievIdForDungeon[j][1])
2644 break; // for
2645 }
2646 else
2647 {
2648 // dungeon in heroic mode accepted
2649 if (!achievIdForDungeon[j][3])
2650 break; // for
2651 }
2652
2653 found = true;
2654 break; // for
2655 }
2656 }
2657 if (!found)
2658 return false;
2659
2660 //FIXME: work only for instances where max == min for players
2661 if (((InstanceMap*)map)->GetMaxPlayers() != achievementCriteria->death_in_dungeon.manLimit)
2662 return false;
2663 */
2664 return false;
2665 }
2667 if (!miscValue1 || miscValue1 != achievementCriteria->killed_by_creature.creatureEntry)
2668 return false;
2669 break;
2671 if (!miscValue1 || !unit || unit->GetTypeId() != TypeID::TYPEID_PLAYER)
2672 return false;
2673 break;
2675 if (!miscValue1 || miscValue2 != achievementCriteria->death_from.type)
2676 return false;
2677 break;
2679 {
2680 // if miscValues != 0, it contains the questID.
2681 if (miscValue1)
2682 {
2683 if (miscValue1 != achievementCriteria->complete_quest.questID)
2684 return false;
2685 }
2686 else
2687 {
2688 // login case.
2689 if (!referencePlayer->GetQuestRewardStatus(achievementCriteria->complete_quest.questID))
2690 return false;
2691 }
2692
2693 if (AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria))
2694 if (!data->Meets(referencePlayer, unit))
2695 return false;
2696 break;
2697 }
2700 if (!miscValue1 || miscValue1 != achievementCriteria->be_spell_target.spellID)
2701 return false;
2702 break;
2705 if (!miscValue1 || miscValue1 != achievementCriteria->cast_spell.spellID)
2706 return false;
2707 break;
2709 if (miscValue1 && miscValue1 != achievementCriteria->learn_spell.spellID)
2710 return false;
2711
2712 if (!referencePlayer->HasSpell(achievementCriteria->learn_spell.spellID))
2713 return false;
2714 break;
2716 // miscValue1 = itemId - miscValue2 = count of item loot
2717 // miscValue3 = loot_type (note: 0 = LOOT_CORPSE and then it ignored)
2718 if (!miscValue1 || !miscValue2 || !miscValue3 || miscValue3 != achievementCriteria->loot_type.lootType)
2719 return false;
2720 break;
2722 if (miscValue1 && achievementCriteria->own_item.itemID != miscValue1)
2723 return false;
2724 break;
2726 if (!miscValue1 || achievementCriteria->use_item.itemID != miscValue1)
2727 return false;
2728 break;
2730 if (!miscValue1 || miscValue1 != achievementCriteria->own_item.itemID)
2731 return false;
2732 break;
2734 {
2735 WorldMapOverlayEntry const* worldOverlayEntry = sWorldMapOverlayStore.LookupEntry(achievementCriteria->explore_area.areaReference);
2736 if (!worldOverlayEntry)
2737 break;
2738
2739 bool matchFound = false;
2740 for (int j = 0; j < MAX_WORLD_MAP_OVERLAY_AREA_IDX; ++j)
2741 {
2742 uint32 area_id = worldOverlayEntry->areatableID[j];
2743 if (!area_id) // array have 0 only in empty tail
2744 break;
2745
2746 int32 exploreFlag = GetAreaFlagByAreaID(area_id);
2747 if (exploreFlag < 0)
2748 continue;
2749
2750 uint32 playerIndexOffset = uint32(exploreFlag) / 32;
2751 uint32 mask = 1 << (uint32(exploreFlag) % 32);
2752
2753 if (referencePlayer->GetUInt32Value(PLAYER_FIELD_EXPLORED_ZONES + playerIndexOffset) & mask)
2754 {
2755 matchFound = true;
2756 break;
2757 }
2758 }
2759
2760 if (!matchFound)
2761 return false;
2762 break;
2763 }
2765 if (miscValue1 && miscValue1 != achievementCriteria->gain_reputation.factionID)
2766 return false;
2767 break;
2769 // miscValue1 = itemid miscValue2 = itemSlot
2770 if (!miscValue1 || miscValue2 != achievementCriteria->equip_epic_item.itemSlot)
2771 return false;
2772 break;
2775 {
2776 // miscValue1 = itemid miscValue2 = diced value
2777 if (!miscValue1 || miscValue2 != achievementCriteria->roll_greed_on_loot.rollValue)
2778 return false;
2779
2780 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(uint32(miscValue1));
2781 if (!proto)
2782 return false;
2783 break;
2784 }
2786 if (!miscValue1 || miscValue1 != achievementCriteria->do_emote.emoteID)
2787 return false;
2788 break;
2791 if (!miscValue1)
2792 return false;
2793 // map specific case (BG in fact) expected player targeted damage/heal
2794 if (!unit || unit->GetTypeId() != TypeID::TYPEID_PLAYER)
2795 return false;
2796 break;
2798 // miscValue1 = item_id
2799 if (!miscValue1 || miscValue1 != achievementCriteria->equip_item.itemID)
2800 return false;
2801 break;
2803 if (!miscValue1 || miscValue1 != achievementCriteria->use_gameobject.goEntry)
2804 return false;
2805 break;
2807 if (!miscValue1 || miscValue1 != achievementCriteria->fish_in_gameobject.goEntry)
2808 return false;
2809 break;
2811 if (miscValue1 && miscValue1 != achievementCriteria->learn_skillline_spell.skillLine)
2812 return false;
2813 break;
2816 {
2817 if (!miscValue1)
2818 return false;
2819 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(uint32(miscValue1));
2820 if (!proto || proto->Quality < ITEM_QUALITY_EPIC)
2821 return false;
2822 break;
2823 }
2825 if (miscValue1 && miscValue1 != achievementCriteria->learn_skill_line.skillLine)
2826 return false;
2827 break;
2829 if (!miscValue1 || miscValue1 != achievementCriteria->hk_class.classID)
2830 return false;
2831 break;
2833 if (!miscValue1 || miscValue1 != achievementCriteria->hk_race.raceID)
2834 return false;
2835 break;
2837 if (!miscValue1 || miscValue1 != achievementCriteria->bg_objective.objectiveId)
2838 return false;
2839 break;
2841 if (!miscValue1 || miscValue1 != achievementCriteria->honorable_kill_at_area.areaID)
2842 return false;
2843 break;
2845 if (!miscValue1 || !miscValue2 || int64(miscValue2) < 0
2846 || miscValue1 != achievementCriteria->currencyGain.currency)
2847 return false;
2848 break;
2850 if (miscValue1 != achievementCriteria->win_arena.mapID)
2851 return false;
2852 break;
2853 default:
2854 break;
2855 }
2856 return true;
2857}
2858
2859template<class T>
2860bool AchievementMgr<T>::AdditionalRequirementsSatisfied(CriteriaEntry const* criteria, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit const* unit, Player* referencePlayer) const
2861{
2862 ModifierTreeEntry const* condition = sModifierTreeStore.LookupEntry(criteria->modifierTreeId);
2863
2864 if (!condition)
2865 return true;
2866
2867 ModifierTreeEntryList const* list = sAchievementMgr->GetModifierTreeByModifierId(condition->ID);
2868
2869 if (!list)
2870 return true;
2871
2872 for (ModifierTreeEntryList::const_iterator iter = list->begin(); iter != list->end(); ++iter)
2873 {
2874 ModifierTreeEntry const* tree = (*iter);
2875 uint32 reqType = tree->conditionType;
2876 uint32 reqValue = tree->conditionValue[0];
2877 uint32 battlePetPayload = uint32(miscValue3);
2878
2880 {
2882 if (!unit || unit->GetEntry() != reqValue)
2883 return false;
2884 break;
2886 if (!unit || unit->GetTypeId() != TypeID::TYPEID_PLAYER)
2887 return false;
2888 break;
2890 if (!unit || unit->IsAlive())
2891 return false;
2892 break;
2894 if (!unit || !referencePlayer->IsHostileTo(unit))
2895 return false;
2896 break;
2898 if (!referencePlayer->HasAura(reqValue))
2899 return false;
2900 break;
2902 if (!unit || !unit->HasAura(reqValue))
2903 return false;
2904 break;
2906 if (!unit || !unit->HasAuraType(AuraType(reqValue)))
2907 return false;
2908 break;
2910 {
2911 // miscValue1 is itemid
2912 ItemTemplate const* const item = sObjectMgr->GetItemTemplate(uint32(miscValue1));
2913 if (!item || item->Quality < reqValue)
2914 return false;
2915 break;
2916 }
2918 {
2919 // miscValue1 is itemid
2920 ItemTemplate const* const item = sObjectMgr->GetItemTemplate(uint32(miscValue1));
2921 if (!item || item->Quality != reqValue)
2922 return false;
2923 break;
2924 }
2926 {
2927 uint32 zoneId, areaId;
2928 referencePlayer->GetZoneAndAreaId(zoneId, areaId);
2929 if (zoneId != reqValue && areaId != reqValue)
2930 return false;
2931 break;
2932 }
2934 {
2935 if (!unit)
2936 return false;
2937 uint32 zoneId, areaId;
2938 unit->GetZoneAndAreaId(zoneId, areaId);
2939 if (zoneId != reqValue && areaId != reqValue)
2940 return false;
2941 break;
2942 }
2944 if (uint32(referencePlayer->GetMap()->GetDifficulty()) != reqValue)
2945 return false;
2946 break;
2948 if (referencePlayer->getRace() != reqValue)
2949 return false;
2950 break;
2952 if (referencePlayer->getClass() != reqValue)
2953 return false;
2954 break;
2956 if (!unit || unit->GetTypeId() != TypeID::TYPEID_PLAYER || unit->getRace() != reqValue)
2957 return false;
2958 break;
2960 if (!unit || unit->GetTypeId() != TypeID::TYPEID_PLAYER || unit->getClass() != reqValue)
2961 return false;
2962 break;
2964 if (referencePlayer->GetGroup() && referencePlayer->GetGroup()->GetMembersCount() >= reqValue)
2965 return false;
2966 break;
2968 {
2969 if (!unit)
2970 return false;
2971 Creature const* const creature = unit->ToCreature();
2972 if (!creature || creature->GetCreatureType() != reqValue)
2973 return false;
2974 break;
2975 }
2977 if (referencePlayer->GetMapId() != reqValue)
2978 return false;
2979 break;
2981 // miscValue1 is title's bit index
2982 if (miscValue1 != reqValue)
2983 return false;
2984 break;
2986 if (referencePlayer->getLevel() != reqValue)
2987 return false;
2988 break;
2990 if (!unit || unit->getLevel() != reqValue)
2991 return false;
2992 break;
2994 if (!unit || unit->GetZoneId() != reqValue)
2995 return false;
2996 break;
2998 if (!unit || unit->GetHealthPct() >= reqValue)
2999 return false;
3000 break;
3002 if (reqValue >= 32 || !(uint32(miscValue2) & (uint32(1) << reqValue)))
3003 return false;
3004 break;
3006 if (!BattlePetAchievementCriteriaHealthPercent(battlePetPayload) || BattlePetAchievementCriteriaHealthPercent(battlePetPayload) >= reqValue)
3007 return false;
3008 break;
3010 return false;
3012 {
3013 uint32 quality = reqValue;
3014 if (BattlePetBreedQualityEntry const* qualityEntry = sBattlePetBreedQualityStore.LookupEntry(reqValue))
3015 quality = qualityEntry->Quality;
3016
3017 if (BattlePetAchievementCriteriaQuality(battlePetPayload) != quality)
3018 return false;
3019 break;
3020 }
3022 if (BattlePetAchievementCriteriaIsPvp(battlePetPayload) != (reqValue != 0))
3023 return false;
3024 break;
3026 if (miscValue1 != reqValue)
3027 return false;
3028 break;
3029 default:
3030 break;
3031 }
3032 }
3033 return true;
3034}
3035
3040
3042{
3043 switch (type)
3044 {
3046 return "KILL_CREATURE";
3048 return "TYPE_WIN_BG";
3050 return "COMPLETE_RESEARCH";
3052 return "REACH_LEVEL";
3054 return "REACH_SKILL_LEVEL";
3056 return "COMPLETE_ACHIEVEMENT";
3058 return "COMPLETE_QUEST_COUNT";
3060 return "COMPLETE_DAILY_QUEST_DAILY";
3062 return "COMPLETE_QUESTS_IN_ZONE";
3064 return "CURRENCY";
3066 return "DAMAGE_DONE";
3068 return "COMPLETE_DAILY_QUEST";
3070 return "COMPLETE_BATTLEGROUND";
3072 return "DEATH_AT_MAP";
3074 return "DEATH";
3076 return "DEATH_IN_DUNGEON";
3078 return "COMPLETE_RAID";
3080 return "KILLED_BY_CREATURE";
3082 return "KILLED_BY_PLAYER";
3084 return "FALL_WITHOUT_DYING";
3086 return "DEATHS_FROM";
3088 return "COMPLETE_QUEST";
3090 return "BE_SPELL_TARGET";
3092 return "CAST_SPELL";
3094 return "BG_OBJECTIVE_CAPTURE";
3096 return "HONORABLE_KILL_AT_AREA";
3098 return "WIN_ARENA";
3100 return "PLAY_ARENA";
3102 return "LEARN_SPELL";
3104 return "HONORABLE_KILL";
3106 return "OWN_ITEM";
3108 return "WIN_RATED_ARENA";
3110 return "HIGHEST_TEAM_RATING";
3112 return "HIGHEST_PERSONAL_RATING";
3114 return "LEARN_SKILL_LEVEL";
3116 return "USE_ITEM";
3118 return "LOOT_ITEM";
3120 return "EXPLORE_AREA";
3122 return "OWN_RANK";
3124 return "BUY_BANK_SLOT";
3126 return "GAIN_REPUTATION";
3128 return "GAIN_EXALTED_REPUTATION";
3130 return "VISIT_BARBER_SHOP";
3132 return "EQUIP_EPIC_ITEM";
3134 return "ROLL_NEED_ON_LOOT";
3136 return "GREED_ON_LOOT";
3138 return "HK_CLASS";
3140 return "HK_RACE";
3142 return "DO_EMOTE";
3144 return "HEALING_DONE";
3146 return "GET_KILLING_BLOWS";
3148 return "EQUIP_ITEM";
3150 return "MONEY_FROM_VENDORS";
3152 return "GOLD_SPENT_FOR_TALENTS";
3154 return "NUMBER_OF_TALENT_RESETS";
3156 return "MONEY_FROM_QUEST_REWARD";
3158 return "GOLD_SPENT_FOR_TRAVELLING";
3160 return "GOLD_SPENT_AT_BARBER";
3162 return "GOLD_SPENT_FOR_MAIL";
3164 return "LOOT_MONEY";
3166 return "USE_GAMEOBJECT";
3168 return "BE_SPELL_TARGET2";
3170 return "SPECIAL_PVP_KILL";
3172 return "FISH_IN_GAMEOBJECT";
3174 return "EARNED_PVP_TITLE";
3176 return "LEARN_SKILLLINE_SPELLS";
3178 return "WIN_DUEL";
3180 return "LOSE_DUEL";
3182 return "KILL_CREATURE_TYPE";
3184 return "GOLD_EARNED_BY_AUCTIONS";
3186 return "CREATE_AUCTION";
3188 return "HIGHEST_AUCTION_BID";
3190 return "WON_AUCTIONS";
3192 return "HIGHEST_AUCTION_SOLD";
3194 return "HIGHEST_GOLD_VALUE_OWNED";
3196 return "GAIN_REVERED_REPUTATION";
3198 return "GAIN_HONORED_REPUTATION";
3200 return "KNOWN_FACTIONS";
3202 return "LOOT_EPIC_ITEM";
3204 return "RECEIVE_EPIC_ITEM";
3206 return "ROLL_NEED";
3208 return "ROLL_GREED";
3210 return "HIT_DEALT";
3212 return "HIT_RECEIVED";
3214 return "TOTAL_DAMAGE_RECEIVED";
3216 return "HIGHEST_HEAL_CASTED";
3218 return "TOTAL_HEALING_RECEIVED";
3220 return "HIGHEST_HEALING_RECEIVED";
3222 return "QUEST_ABANDONED";
3224 return "FLIGHT_PATHS_TAKEN";
3226 return "LOOT_TYPE";
3228 return "CAST_SPELL2";
3230 return "LEARN_SKILL_LINE";
3232 return "EARN_HONORABLE_KILL";
3234 return "ACCEPTED_SUMMONINGS";
3236 return "EARN_ACHIEVEMENT_POINTS";
3238 return "PET_BATTLE_ACHIEVEMENT_POINTS";
3240 return "COLLECT_BATTLE_PET";
3242 return "COLLECT_BATTLE_PET_SPECIES";
3244 return "OWN_BATTLE_PET_COUNT";
3246 return "CAPTURE_BATTLE_PET";
3248 return "WIN_PET_BATTLE";
3250 return "REACH_BATTLE_PET_LEVEL";
3252 return "CAPTURE_BATTLE_PET2";
3254 return "USE_LFD_TO_GROUP_WITH_PLAYERS";
3256 return "SPENT_GOLD_GUILD_REPAIRS";
3258 return "REACH_GUILD_LEVEL";
3260 return "CRAFT_ITEMS_GUILD";
3262 return "CATCH_FROM_POOL";
3264 return "BUY_GUILD_BANK_SLOTS";
3266 return "EARN_GUILD_ACHIEVEMENT_POINTS";
3268 return "WIN_RATED_BATTLEGROUND";
3270 return "REACH_BG_RATING";
3272 return "BUY_GUILD_TABARD";
3274 return "COMPLETE_QUESTS_GUILD";
3276 return "HONORABLE_KILLS_GUILD";
3278 return "KILL_CREATURE_TYPE_GUILD";
3280 return "GUILD_CHALLENGE_TYPE";
3282 return "GUILD_CHALLENGE";
3283 }
3284 return "MISSING_TYPE";
3285}
3286
3287template class AchievementMgr<Guild>;
3288template class AchievementMgr<Player>;
3289
3290//==========================================================
3292{
3293 uint32 oldMSTime = getMSTime();
3294
3295 if (sCriteriaStore.GetNumRows() == 0)
3296 {
3297 SF_LOG_ERROR("server.loading", ">> Loaded 0 achievement criteria.");
3298 return;
3299 }
3300
3301 for (uint32 entryId = 0; entryId < sCriteriaTreeStore.GetNumRows(); entryId++)
3302 {
3303 CriteriaTreeEntry const* criteriaTree = sCriteriaTreeStore.LookupEntry(entryId);
3304
3305 if (!criteriaTree)
3306 continue;
3307
3308 if (CriteriaTreeEntry const* parent = sCriteriaTreeStore.LookupEntry(criteriaTree->parentID))
3309 m_SubCriteriaTreeListById[parent->ID].push_back(criteriaTree);
3310
3312 CriteriaEntry const* criteriaEntry = sCriteriaStore.LookupEntry(criteriaTree->criteriaID);
3313
3314 if (!criteriaEntry)
3315 continue;
3316
3317 m_AchievementCriteriaTreeByCriteriaId[criteriaEntry->ID].push_back(criteriaTree);
3318 }
3319
3320 for (uint32 entryId = 0; entryId < sModifierTreeStore.GetNumRows(); entryId++)
3321 {
3322 ModifierTreeEntry const* modifier = sModifierTreeStore.LookupEntry(entryId);
3323
3324 if (!modifier)
3325 continue;
3326
3327 if (modifier->parent)
3328 m_ModifierTreeEntryByTreeId[modifier->parent].push_back(modifier);
3329 }
3330
3331 uint32 criterias = 0;
3332 for (uint32 entryId = 0; entryId < sCriteriaStore.GetNumRows(); entryId++)
3333 {
3334 CriteriaEntry const* criteria = sAchievementMgr->GetAchievementCriteria(entryId);
3335
3336 if (!criteria)
3337 continue;
3338
3339 m_AchievementCriteriasByType[criteria->type].push_back(criteria);
3340
3341 if (criteria->timeLimit)
3342 m_AchievementCriteriasByTimedType[criteria->timedCriteriaStartType].push_back(criteria);
3343 }
3344
3345 SF_LOG_INFO("server.loading", ">> Loaded %u achievement criteria in %u ms", ++criterias, GetMSTimeDiffToNow(oldMSTime));
3346}
3347
3349{
3350 uint32 oldMSTime = getMSTime();
3351
3352 if (sAchievementStore.GetNumRows() == 0)
3353 {
3354 SF_LOG_INFO("server.loading", ">> Loaded 0 achievement references.");
3355 return;
3356 }
3357
3358 uint32 count = 0;
3359
3360 for (uint32 entryId = 0; entryId < sAchievementStore.GetNumRows(); ++entryId)
3361 {
3362 AchievementEntry const* achievement = sAchievementMgr->GetAchievement(entryId);
3363 if (!achievement)
3364 continue;
3365
3366 m_AchievementEntryByCriteriaTree[achievement->criteriaTreeID] = achievement;
3367
3368 if (!achievement->refAchievement)
3369 continue;
3370
3371 m_AchievementListByReferencedId[achievement->refAchievement].push_back(achievement);
3372 ++count;
3373 }
3374
3375 // Once Bitten, Twice Shy (10 player) - Icecrown Citadel
3376 if (AchievementEntry const* achievement = sAchievementMgr->GetAchievement(4539))
3377 const_cast<AchievementEntry*>(achievement)->mapID = 631; // Correct map requirement (currently has Ulduar)
3378
3379 SF_LOG_INFO("server.loading", ">> Loaded %u achievement references in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
3380}
3381
3383{
3384 uint32 oldMSTime = getMSTime();
3385
3386 m_criteriaDataMap.clear(); // need for reload case
3387
3388 QueryResult result = WorldDatabase.Query("SELECT criteria_id, type, value1, value2, ScriptName FROM achievement_criteria_data");
3389
3390 if (!result)
3391 {
3392 SF_LOG_INFO("server.loading", ">> Loaded 0 additional achievement criteria data. DB table `achievement_criteria_data` is empty.");
3393 return;
3394 }
3395
3396 uint32 count = 0;
3397
3398 do
3399 {
3400 Field* fields = result->Fetch();
3401 uint32 criteria_id = fields[0].GetUInt32();
3402
3403 CriteriaEntry const* criteria = sAchievementMgr->GetAchievementCriteria(criteria_id);
3404
3405 if (!criteria)
3406 {
3407 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` has data for non-existing criteria (Entry: %u), ignore.", criteria_id);
3408 continue;
3409 }
3410
3411 uint32 dataType = fields[1].GetUInt8();
3412 std::string scriptName = fields[4].GetString();
3413 uint32 scriptId = 0;
3414 if (scriptName.length()) // not empty
3415 {
3417 SF_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` has ScriptName set for non-scripted data type (Entry: %u, type %u), useless data.", criteria_id, dataType);
3418 else
3419 scriptId = sObjectMgr->GetScriptId(scriptName.c_str());
3420 }
3421
3422 AchievementCriteriaData data(dataType, fields[2].GetUInt32(), fields[3].GetUInt32(), scriptId);
3423
3424 if (!data.IsValid(criteria))
3425 continue;
3426
3427 // this will allocate empty data set storage
3428 AchievementCriteriaDataSet& dataSet = m_criteriaDataMap[criteria_id];
3429 dataSet.SetCriteriaId(criteria_id);
3430
3431 // add real data only for not NONE data types
3433 dataSet.Add(data);
3434
3435 // counting data by and data types
3436 ++count;
3437 } while (result->NextRow());
3438
3439 SF_LOG_INFO("server.loading", ">> Loaded %u additional achievement criteria data in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
3440}
3441
3443{
3444 uint32 oldMSTime = getMSTime();
3445
3446 QueryResult result = CharacterDatabase.Query("SELECT achievement FROM character_achievement GROUP BY achievement");
3447
3448 if (!result)
3449 {
3450 SF_LOG_INFO("server.loading", ">> Loaded 0 realm first completed achievements. DB table `character_achievement` is empty.");
3451 return;
3452 }
3453
3454 do
3455 {
3456 Field* fields = result->Fetch();
3457
3458 uint16 achievementId = fields[0].GetUInt16();
3459 const AchievementEntry* achievement = sAchievementMgr->GetAchievement(achievementId);
3460 if (!achievement)
3461 {
3462 // Remove non existent achievements from all characters
3463 SF_LOG_ERROR("achievement", "Non-existing achievement %u data removed from table `character_achievement`.", achievementId);
3464
3466 stmt->setUInt16(0, uint16(achievementId));
3467 CharacterDatabase.Execute(stmt);
3468
3469 continue;
3470 }
3472 m_allCompletedAchievements.insert(achievementId);
3473 } while (result->NextRow());
3474
3475 SF_LOG_INFO("server.loading", ">> Loaded %lu realm first completed achievements in %u ms", (unsigned long)m_allCompletedAchievements.size(), GetMSTimeDiffToNow(oldMSTime));
3476}
3477
3479{
3480 uint32 oldMSTime = getMSTime();
3481
3482 m_achievementRewards.clear(); // need for reload case
3483
3484 // 0 1 2 3 4 5 6 7
3485 QueryResult result = WorldDatabase.Query("SELECT entry, title_A, title_H, item, spell, sender, subject, text FROM achievement_reward");
3486
3487 if (!result)
3488 {
3489 SF_LOG_ERROR("server.loading", ">> Loaded 0 achievement rewards. DB table `achievement_reward` is empty.");
3490 return;
3491 }
3492
3493 uint32 count = 0;
3494
3495 do
3496 {
3497 Field* fields = result->Fetch();
3498 uint32 entry = fields[0].GetUInt32();
3499 const AchievementEntry* pAchievement = GetAchievement(entry);
3500 if (!pAchievement)
3501 {
3502 SF_LOG_ERROR("sql.sql", "Table `achievement_reward` has wrong achievement (Entry: %u), ignored.", entry);
3503 continue;
3504 }
3505
3506 AchievementReward reward;
3507 reward.titleId[0] = fields[1].GetUInt32();
3508 reward.titleId[1] = fields[2].GetUInt32();
3509 reward.itemId = fields[3].GetUInt32();
3510 reward.spellId = fields[4].GetInt32();
3511 reward.sender = fields[5].GetUInt32();
3512 reward.subject = fields[6].GetString();
3513 reward.text = fields[7].GetString();
3514
3515 // must be title or mail at least
3516 if (!reward.titleId[0] && !reward.titleId[1] && !reward.sender && !reward.spellId)
3517 {
3518 SF_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) does not have title or item reward data, ignored.", entry);
3519 continue;
3520 }
3521
3522 if (pAchievement->requiredFaction == ACHIEVEMENT_FACTION_ANY && ((reward.titleId[0] == 0) != (reward.titleId[1] == 0)))
3523 SF_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) has title (A: %u H: %u) for only one team.", entry, reward.titleId[0], reward.titleId[1]);
3524
3525 if (reward.titleId[0])
3526 {
3527 CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(reward.titleId[0]);
3528 if (!titleEntry)
3529 {
3530 SF_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) has invalid title id (%u) in `title_A`, set to 0", entry, reward.titleId[0]);
3531 reward.titleId[0] = 0;
3532 }
3533 }
3534
3535 if (reward.titleId[1])
3536 {
3537 CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(reward.titleId[1]);
3538 if (!titleEntry)
3539 {
3540 SF_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) has invalid title id (%u) in `title_H`, set to 0", entry, reward.titleId[1]);
3541 reward.titleId[1] = 0;
3542 }
3543 }
3544
3545 //check mail data before item for report including wrong item case
3546 if (reward.sender)
3547 {
3548 if (!sObjectMgr->GetCreatureTemplate(reward.sender))
3549 {
3550 SF_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) has invalid creature entry %u as sender, mail reward skipped.", entry, reward.sender);
3551 reward.sender = 0;
3552 }
3553 }
3554 else
3555 {
3556 if (reward.itemId)
3557 SF_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) does not have sender data but has item reward, item will not be rewarded.", entry);
3558
3559 if (!reward.subject.empty())
3560 SF_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) does not have sender data but has mail subject.", entry);
3561
3562 if (!reward.text.empty())
3563 SF_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) does not have sender data but has mail text.", entry);
3564 }
3565
3566 if (reward.itemId)
3567 {
3568 if (!sObjectMgr->GetItemTemplate(reward.itemId))
3569 {
3570 SF_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) has invalid item id %u, reward mail will not contain item.", entry, reward.itemId);
3571 reward.itemId = 0;
3572 }
3573 }
3574
3575 if (reward.spellId)
3576 {
3577 if (!sSpellMgr->GetSpellInfo(std::abs(reward.spellId)))
3578 {
3579 SF_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) has invalid spell id %u, skipped.", entry, reward.spellId);
3580 reward.spellId = 0;
3581 }
3582 }
3583
3584 m_achievementRewards[entry] = reward;
3585 ++count;
3586 } while (result->NextRow());
3587
3588 SF_LOG_INFO("server.loading", ">> Loaded %u achievement rewards in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
3589}
3590
3592{
3593 uint32 oldMSTime = getMSTime();
3594
3595 m_achievementRewardLocales.clear(); // need for reload case
3596
3597 QueryResult result = WorldDatabase.Query("SELECT entry, subject_loc1, text_loc1, subject_loc2, text_loc2, subject_loc3, text_loc3, subject_loc4, text_loc4, "
3598 "subject_loc5, text_loc5, subject_loc6, text_loc6, subject_loc7, text_loc7, subject_loc8, text_loc8, "
3599 "subject_loc9, text_loc9, subject_loc10, text_loc10, subject_loc11, text_loc11 "
3600 " FROM locales_achievement_reward");
3601
3602 if (!result)
3603 {
3604 SF_LOG_INFO("server.loading", ">> Loaded 0 achievement reward locale strings. DB table `locales_achievement_reward` is empty");
3605 return;
3606 }
3607
3608 do
3609 {
3610 Field* fields = result->Fetch();
3611
3612 uint32 entry = fields[0].GetUInt32();
3613
3614 if (m_achievementRewards.find(entry) == m_achievementRewards.end())
3615 {
3616 SF_LOG_ERROR("sql.sql", "Table `locales_achievement_reward` (Entry: %u) has locale strings for non-existing achievement reward.", entry);
3617 continue;
3618 }
3619
3621
3622 for (int i = 1; i < TOTAL_LOCALES; ++i)
3623 {
3624 LocaleConstant locale = (LocaleConstant)i;
3625 ObjectMgr::AddLocaleString(fields[1 + 2 * (i - 1)].GetString(), locale, data.subject);
3626 ObjectMgr::AddLocaleString(fields[1 + 2 * (i - 1) + 1].GetString(), locale, data.text);
3627 }
3628 } while (result->NextRow());
3629
3630 SF_LOG_INFO("server.loading", ">> Loaded %lu achievement reward locale strings in %u ms", (unsigned long)m_achievementRewardLocales.size(), GetMSTimeDiffToNow(oldMSTime));
3631}
3632
3634{
3635 return sAchievementStore.LookupEntry(achievementId);
3636}
3637
3639{
3640 return sCriteriaStore.LookupEntry(criteriaId);
3641}
bool IsGuild< Guild >()
static const uint32 achievIdByArenaSlot[MAX_ARENA_SLOT]
static bool UpdatesPetBattleAchievementPoints(uint32 categoryId)
static bool IsPetBattleAchievementCategory(uint32 categoryId)
static const uint32 achievIdForDungeon[][4]
static bool IsGuild()
ProgressType
@ PROGRESS_SET
@ PROGRESS_ACCUMULATE
@ PROGRESS_HIGHEST
std::vector< CriteriaTreeEntry const * > AchievementCriteriaTreeList
std::vector< CriteriaEntry const * > AchievementCriteriaEntryList
@ ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT
@ ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT
@ ACHIEVEMENT_CRITERIA_DATA_TYPE_T_GENDER
@ ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA
@ ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE
@ ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE
@ ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT
@ ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK
@ ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA
@ ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY
@ ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA
@ ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM
@ ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE
@ ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE
@ ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL
@ ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE
@ ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH
@ ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM
@ ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE
#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE
std::vector< ModifierTreeEntry const * > ModifierTreeEntryList
UNORDERED_MAP< uint32, ModifierTreeEntryList > ModifierTreeEntryByTreeId
#define sAchievementMgr
std::vector< AchievementEntry const * > AchievementEntryList
#define MAX_ARENA_SLOT
Definition ArenaTeam.h:96
uint8 BattlePetAchievementCriteriaHealthPercent(uint32 payload)
Definition BattlePet.h:83
uint8 BattlePetAchievementCriteriaQuality(uint32 payload)
Definition BattlePet.h:63
bool BattlePetAchievementCriteriaIsPvp(uint32 payload)
Definition BattlePet.h:73
@ CHAR_INS_GUILD_ACHIEVEMENT_CRITERIA
@ CHAR_DEL_ALL_GUILD_ACHIEVEMENTS
@ CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS_BY_CRITERIA
@ CHAR_INS_CHAR_ACHIEVEMENT_PROGRESS
@ CHAR_INS_CHAR_ACHIEVEMENT
@ CHAR_DEL_CHAR_ACHIEVEMENT_BY_ACHIEVEMENT
@ CHAR_DEL_INVALID_ACHIEVMENT
@ CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS
@ CHAR_INS_GUILD_ACHIEVEMENT
@ CHAR_DEL_GUILD_ACHIEVEMENT
@ CHAR_DEL_GUILD_ACHIEVEMENT_CRITERIA
@ CHAR_DEL_ALL_GUILD_ACHIEVEMENT_CRITERIA
@ CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA
@ CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA_GUILD
@ CHAR_DEL_CHAR_ACHIEVEMENT
const uint8 TOTAL_LOCALES
Definition Common.h:153
LocaleConstant
Definition Common.h:138
@ IN_MILLISECONDS
Definition Common.h:125
@ DAY
Definition Common.h:121
DB2Storage< BattlePetBreedQualityEntry > sBattlePetBreedQualityStore(BattlePetBreedQualityfmt)
@ ACHIEVEMENT_FACTION_HORDE
Definition DBCEnums.h:46
@ ACHIEVEMENT_FACTION_ALLIANCE
Definition DBCEnums.h:47
@ ACHIEVEMENT_FACTION_ANY
Definition DBCEnums.h:48
AchievementCriteriaAdditionalCondition
Definition DBCEnums.h:94
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_TYPE
Definition DBCEnums.h:118
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_PLAYER
Definition DBCEnums.h:99
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL
Definition DBCEnums.h:125
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TITLE_BIT_INDEX
Definition DBCEnums.h:124
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_BATTLE_PET_HEALTH_PCT
Definition DBCEnums.h:139
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_AREA_OR_ZONE
Definition DBCEnums.h:108
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_AREA_OR_ZONE
Definition DBCEnums.h:109
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAX_GROUP_MEMBERS
Definition DBCEnums.h:117
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_CLASS
Definition DBCEnums.h:114
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_BATTLE_PET_QUALITY
Definition DBCEnums.h:141
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_MIN
Definition DBCEnums.h:105
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_DEAD
Definition DBCEnums.h:100
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_MAP
Definition DBCEnums.h:119
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_ENEMY
Definition DBCEnums.h:101
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_RACE
Definition DBCEnums.h:113
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_PET_BATTLE_AGAINST_TAMER
Definition DBCEnums.h:140
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CLASS
Definition DBCEnums.h:116
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_HAS_AURA
Definition DBCEnums.h:102
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HAS_AURA_TYPE
Definition DBCEnums.h:104
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_RACE
Definition DBCEnums.h:115
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_ENTRY
Definition DBCEnums.h:98
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_BATTLE_PET_SPECIES
Definition DBCEnums.h:143
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAP_DIFFICULTY
Definition DBCEnums.h:110
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_ZONE
Definition DBCEnums.h:127
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PERCENT_BELOW
Definition DBCEnums.h:128
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_LEVEL
Definition DBCEnums.h:126
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_BATTLE_PET_FAMILY
Definition DBCEnums.h:138
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_EQUALS
Definition DBCEnums.h:106
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HAS_AURA
Definition DBCEnums.h:103
@ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_PET_BATTLE_PVP
Definition DBCEnums.h:142
@ STRONG_MAX_LEVEL
Definition DBCEnums.h:24
AchievementCriteriaTimedTypes
Definition DBCEnums.h:157
@ ACHIEVEMENT_FLAG_COUNTER
Definition DBCEnums.h:53
@ ACHIEVEMENT_FLAG_SHOW_GUILD_MEMBERS
Definition DBCEnums.h:68
@ ACHIEVEMENT_FLAG_HIDDEN
Definition DBCEnums.h:54
@ ACHIEVEMENT_FLAG_REALM_FIRST_REACH
Definition DBCEnums.h:61
@ ACHIEVEMENT_FLAG_REALM_FIRST_KILL
Definition DBCEnums.h:62
@ ACHIEVEMENT_FLAG_SHOW_IN_GUILD_HEADER
Definition DBCEnums.h:66
@ ACHIEVEMENT_FLAG_SHOW_IN_GUILD_NEWS
Definition DBCEnums.h:65
@ ACHIEVEMENT_FLAG_SUMM
Definition DBCEnums.h:56
@ ACHIEVEMENT_FLAG_SHOW_CRITERIA_MEMBERS
Definition DBCEnums.h:69
AchievementCriteriaTypes
Definition DBCEnums.h:170
@ ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION
Definition DBCEnums.h:243
@ ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE
Definition DBCEnums.h:264
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2
Definition DBCEnums.h:232
@ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ARCHAEOLOGY_PROJECTS
Definition DBCEnums.h:173
@ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE
Definition DBCEnums.h:179
@ ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM
Definition DBCEnums.h:206
@ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY
Definition DBCEnums.h:178
@ ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN
Definition DBCEnums.h:263
@ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED
Definition DBCEnums.h:247
@ ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL
Definition DBCEnums.h:175
@ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL
Definition DBCEnums.h:229
@ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT
Definition DBCEnums.h:177
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET
Definition DBCEnums.h:193
@ ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM
Definition DBCEnums.h:222
@ ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA
Definition DBCEnums.h:198
@ ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT
Definition DBCEnums.h:234
@ ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING
Definition DBCEnums.h:190
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL
Definition DBCEnums.h:194
@ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED
Definition DBCEnums.h:257
@ ACHIEVEMENT_CRITERIA_TYPE_REACH_BATTLE_PET_LEVEL
Definition DBCEnums.h:289
@ ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM
Definition DBCEnums.h:207
@ ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP
Definition DBCEnums.h:213
@ ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILLS_GUILD
Definition DBCEnums.h:281
@ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST
Definition DBCEnums.h:182
@ ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS
Definition DBCEnums.h:241
@ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND
Definition DBCEnums.h:183
@ ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK
Definition DBCEnums.h:209
@ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID
Definition DBCEnums.h:187
@ ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT
Definition DBCEnums.h:216
@ ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_TABARD
Definition DBCEnums.h:279
@ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER
Definition DBCEnums.h:228
@ ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT
Definition DBCEnums.h:231
@ ACHIEVEMENT_CRITERIA_TYPE_REACH_BG_RATING
Definition DBCEnums.h:278
@ ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE
Definition DBCEnums.h:219
@ ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS
Definition DBCEnums.h:245
@ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED
Definition DBCEnums.h:261
@ ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM
Definition DBCEnums.h:201
@ ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION
Definition DBCEnums.h:212
@ ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS
Definition DBCEnums.h:270
@ ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED
Definition DBCEnums.h:262
@ ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP
Definition DBCEnums.h:184
@ ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL
Definition DBCEnums.h:199
@ ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT
Definition DBCEnums.h:210
@ ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS
Definition DBCEnums.h:237
@ ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED
Definition DBCEnums.h:254
@ ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL
Definition DBCEnums.h:174
@ ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL
Definition DBCEnums.h:267
@ ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE
Definition DBCEnums.h:220
@ ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE_GUILD
Definition DBCEnums.h:282
@ ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE
Definition DBCEnums.h:240
@ ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM
Definition DBCEnums.h:191
@ ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION
Definition DBCEnums.h:248
@ ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD
Definition DBCEnums.h:226
@ ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED
Definition DBCEnums.h:260
@ ACHIEVEMENT_CRITERIA_TYPE_CATCH_FROM_POOL
Definition DBCEnums.h:274
@ ACHIEVEMENT_CRITERIA_TYPE_CURRENCY
Definition DBCEnums.h:180
@ ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER
Definition DBCEnums.h:189
@ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING
Definition DBCEnums.h:227
@ ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM
Definition DBCEnums.h:251
@ ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL
Definition DBCEnums.h:272
@ ACHIEVEMENT_CRITERIA_TYPE_CRAFT_ITEMS_GUILD
Definition DBCEnums.h:273
@ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT
Definition DBCEnums.h:176
@ ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL
Definition DBCEnums.h:200
@ ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION
Definition DBCEnums.h:211
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2
Definition DBCEnums.h:265
@ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED
Definition DBCEnums.h:259
@ ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE
Definition DBCEnums.h:266
@ ACHIEVEMENT_CRITERIA_TYPE_EARN_GUILD_ACHIEVEMENT_POINTS
Definition DBCEnums.h:276
@ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS
Definition DBCEnums.h:224
@ ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_BANK_SLOTS
Definition DBCEnums.h:275
@ ACHIEVEMENT_CRITERIA_TYPE_SPENT_GOLD_GUILD_REPAIRS
Definition DBCEnums.h:271
@ ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE
Definition DBCEnums.h:181
@ ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED
Definition DBCEnums.h:258
@ ACHIEVEMENT_CRITERIA_TYPE_OWN_BATTLE_PET_COUNT
Definition DBCEnums.h:286
@ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST
Definition DBCEnums.h:192
@ ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA
Definition DBCEnums.h:202
@ ACHIEVEMENT_CRITERIA_TYPE_HK_RACE
Definition DBCEnums.h:218
@ ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS
Definition DBCEnums.h:250
@ ACHIEVEMENT_CRITERIA_TYPE_DEATH
Definition DBCEnums.h:185
@ ACHIEVEMENT_CRITERIA_TYPE_PET_BATTLE_ACHIEVEMENT_POINTS
Definition DBCEnums.h:242
@ ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA
Definition DBCEnums.h:208
@ ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS
Definition DBCEnums.h:223
@ ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS
Definition DBCEnums.h:269
@ ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL
Definition DBCEnums.h:205
@ ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE
Definition DBCEnums.h:188
@ ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM
Definition DBCEnums.h:214
@ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID
Definition DBCEnums.h:244
@ ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE
Definition DBCEnums.h:171
@ ACHIEVEMENT_CRITERIA_TYPE_COLLECT_BATTLE_PET_SPECIES
Definition DBCEnums.h:285
@ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD
Definition DBCEnums.h:246
@ ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON
Definition DBCEnums.h:186
@ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_GUILD_CHALLENGE_TYPE
Definition DBCEnums.h:283
@ ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL
Definition DBCEnums.h:238
@ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_GUILD_CHALLENGE
Definition DBCEnums.h:284
@ ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS
Definition DBCEnums.h:268
@ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT
Definition DBCEnums.h:256
@ ACHIEVEMENT_CRITERIA_TYPE_CAPTURE_BATTLE_PET
Definition DBCEnums.h:287
@ ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA
Definition DBCEnums.h:196
@ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING
Definition DBCEnums.h:203
@ ACHIEVEMENT_CRITERIA_TYPE_WIN_BG
Definition DBCEnums.h:172
@ ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION
Definition DBCEnums.h:249
@ ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL
Definition DBCEnums.h:233
@ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_GUILD
Definition DBCEnums.h:280
@ ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE
Definition DBCEnums.h:195
@ ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS
Definition DBCEnums.h:221
@ ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY
Definition DBCEnums.h:230
@ ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA
Definition DBCEnums.h:197
@ ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS
Definition DBCEnums.h:225
@ ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT
Definition DBCEnums.h:215
@ ACHIEVEMENT_CRITERIA_TYPE_CAPTURE_BATTLE_PET2
Definition DBCEnums.h:290
@ ACHIEVEMENT_CRITERIA_TYPE_COLLECT_BATTLE_PET
Definition DBCEnums.h:255
@ ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE
Definition DBCEnums.h:236
@ ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM
Definition DBCEnums.h:252
@ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_PERSONAL_RATING
Definition DBCEnums.h:204
@ ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS
Definition DBCEnums.h:217
@ ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED
Definition DBCEnums.h:253
@ ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_BATTLEGROUND
Definition DBCEnums.h:277
@ ACHIEVEMENT_CRITERIA_TYPE_WIN_PET_BATTLE
Definition DBCEnums.h:288
@ ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL
Definition DBCEnums.h:239
#define ACHIEVEMENT_CRITERIA_TYPE_TOTAL
Definition DBCEnums.h:293
DBCStorage< CharTitlesEntry > sCharTitlesStore(CharTitlesEntryfmt)
DBCStorage< CriteriaTreeEntry > sCriteriaTreeStore(CriteriaTreefmt)
int32 GetAreaFlagByAreaID(uint32 area_id)
DBCStorage< ModifierTreeEntry > sModifierTreeStore(ModifierTreefmt)
DBCStorage< HolidaysEntry > sHolidaysStore(Holidaysfmt)
DBCStorage< AchievementEntry > sAchievementStore(Achievementfmt)
DBCStorage< WorldMapOverlayEntry > sWorldMapOverlayStore(WorldMapOverlayEntryfmt)
AreaTableEntry const * GetAreaEntryByAreaID(uint32 area_id)
DBCStorage< CriteriaEntry > sCriteriaStore(Criteriafmt)
#define MAX_WORLD_MAP_OVERLAY_AREA_IDX
std::int32_t int32
Definition Define.h:73
#define UI64FMTD
Definition Define.h:64
std::uint32_t uint32
Definition Define.h:77
std::uint64_t uint64
Definition Define.h:76
std::int64_t int64
Definition Define.h:72
std::uint16_t uint16
Definition Define.h:78
@ DISABLE_TYPE_ACHIEVEMENT_CRITERIA
Definition DisableMgr.h:19
bool IsHolidayActive(HolidayIds id)
TypeMapContainer< AllWorldObjectTypes > WorldTypeMapContainer
Definition GridDefines.h:72
CoordPair< TOTAL_NUMBER_OF_CELLS_PER_MAP > CellCoord
@ GUILD_NEWS_GUILD_ACHIEVEMENT
Definition Guild.h:240
@ GUILD_NEWS_PLAYER_ACHIEVEMENT
Definition Guild.h:241
#define sGuildMgr
Definition GuildMgr.h:53
@ LANG_ACHIEVEMENT_EARNED
Definition Language.h:755
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
#define SF_LOG_TRACE(filterType__,...)
Definition Log.h:131
#define SF_LOG_INFO(filterType__,...)
Definition Log.h:137
@ MAIL_CREATURE
Definition Mail.h:26
@ TYPEID_PLAYER
Definition Object.h:55
@ TYPEID_UNIT
Definition Object.h:54
uint32 GUID_LOPART(uint64 x)
char const * GetLogNameForGuid(uint64 guid)
@ HIGHGUID_PLAYER
uint64 MAKE_NEW_GUID(uint32 l, uint32 e, uint32 h)
#define sObjectMgr
Definition ObjectMgr.h:1617
std::set< uint32 > RewardedQuestSet
Definition Player.h:629
Skyfire::AutoPtr< PreparedResultSet, Skyfire::Mutex > PreparedQueryResult
Definition QueryResult.h:94
Skyfire::AutoPtr< ResultSet, Skyfire::Mutex > QueryResult
Definition QueryResult.h:48
#define sScriptMgr
Definition ScriptMgr.h:764
ChatMsg
@ CHAT_MSG_ACHIEVEMENT
@ CHAT_MSG_GUILD_ACHIEVEMENT
@ GENDER_NONE
@ ITEM_QUALITY_EPIC
@ TEAM_ALLIANCE
@ TEAM_HORDE
#define MAX_ITEM_QUALITY
@ ALLIANCE
@ HORDE
#define MAX_DRUNKEN
#define CLASSMASK_ALL_PLAYABLE
HolidayIds
#define RACEMASK_ALL_PLAYABLE
DrunkenState
#define sSpellMgr
Definition SpellMgr.h:744
std::pair< SkillLineAbilityMap::const_iterator, SkillLineAbilityMap::const_iterator > SkillLineAbilityMapBounds
Definition SpellMgr.h:544
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:22
uint32 getMSTime()
Definition Timer.h:12
Skyfire::AutoPtr< Transaction, Skyfire::Mutex > SQLTransaction
Definition Transaction.h:42
@ PLAYER_FIELD_EXPLORED_ZONES
@ PLAYER_FIELD_LIFETIME_HONORABLE_KILLS
bool CompareValues(ComparisionType type, T val1, T val2)
Definition Util.h:698
ComparisionType
Definition Util.h:688
@ COMP_TYPE_MAX
Definition Util.h:694
AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL]
ModifierTreeEntryByTreeId m_ModifierTreeEntryByTreeId
AchievementEntryByCriteriaTree m_AchievementEntryByCriteriaTree
SubCriteriaTreeListById m_SubCriteriaTreeListById
AchievementRewards m_achievementRewards
AchievementListByReferencedId m_AchievementListByReferencedId
static char const * GetCriteriaTypeString(AchievementCriteriaTypes type)
AchievementRewardLocales m_achievementRewardLocales
AchievementCriteriaTreeByCriteriaId m_AchievementCriteriaTreeByCriteriaId
AllCompletedAchievements m_allCompletedAchievements
AchievementCriteriaDataMap m_criteriaDataMap
AchievementEntry const * GetAchievement(uint32 achievementId) const
AchievementCriteriaEntryList m_AchievementCriteriasByTimedType[ACHIEVEMENT_TIMED_TYPE_MAX]
CriteriaEntry const * GetAchievementCriteria(uint32 achievementId) const
CriteriaProgressMap m_criteriaProgress
void SendPacket(WorldPacket *data) const
void SendPacket(WorldPacket *data) const
bool HasAchieved(uint32 achievementId) const
CompletedAchievementMap m_completedAchievements
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
void SendCriteriaUpdate(CriteriaEntry const *entry, CriteriaProgress const *progress, uint32 timeElapsed, bool timedCompleted) const
bool IsCompletedCriteriaForAchievement(CriteriaEntry const *criteria, AchievementEntry const *achievementEntry)
bool IsCompletedCriteria(CriteriaEntry const *criteria)
void SetCriteriaProgress(CriteriaEntry const *entry, uint64 changeValue, Player *referencePlayer, ProgressType ptype=PROGRESS_SET)
void CompletedAchievement(AchievementEntry const *entry, Player *referencePlayer)
void CompletedCriteriaFor(AchievementEntry const *achievement, Player *referencePlayer)
void RemoveCriteriaProgress(CriteriaEntry const *entry)
void UpdateTimedAchievements(uint32 timeDiff)
uint32 _achievementPoints
void SendAllAchievementData(Player *receiver) const
void SendAchievementEarned(AchievementEntry const *achievement) const
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1=0, uint64 miscValue2=0, uint64 miscValue3=0, Unit const *unit=NULL, Player *referencePlayer=NULL)
bool RequirementsSatisfied(CriteriaEntry const *criteria, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit const *unit, Player *referencePlayer) const
void CheckAllAchievementCriteria(Player *referencePlayer)
static void DeleteFromDB(uint32 lowguid)
void SendAchievementInfo(Player *receiver, uint32 achievementId=0) const
void DeleteFromDB(uint32 lowguid)
void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry)
TimedAchievementMap m_timedAchievements
void SaveToDB(SQLTransaction &trans)
void ResetAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1=0, uint64 miscValue2=0, bool evenIfCriteriaComplete=false)
bool CanUpdateCriteria(CriteriaEntry const *criteria, AchievementEntry const *achievement, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit const *unit, Player *referencePlayer)
void RemoveCriteriaProgress(CriteriaEntry const *entry)
bool ConditionsSatisfied(CriteriaEntry const *criteria, Player *referencePlayer) const
void SendAchievementEarned(AchievementEntry const *achievement) const
CriteriaProgress * GetCriteriaProgress(CriteriaEntry const *entry)
bool IsCompletedAchievement(AchievementEntry const *entry)
void LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult)
bool AdditionalRequirementsSatisfied(CriteriaEntry const *criteria, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit const *unit, Player *referencePlayer) const
AchievementMgr(T *owner)
uint32 GetTeamScore(uint32 TeamID) const
void WriteGuidBytes(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:264
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:248
void WriteString(std::string const &str)
Definition ByteBuffer.h:578
void append(T value)
Definition ByteBuffer.h:147
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
void AppendPackedTime(time_t time)
Definition ByteBuffer.h:700
void WriteByteSeq(uint8 b)
Definition ByteBuffer.h:227
void FlushBits()
Definition ByteBuffer.h:154
static size_t BuildChatPacket(WorldPacket &data, ChatMsg chatType, Language language, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string const &message, uint8 chatTag, std::string const &senderName="", std::string const &receiverName="", uint32 achievementId=0, bool gmMessage=false, std::string const &channelName="", std::string const &addonPrefix="")
Definition Chat.cpp:580
Definition Field.h:16
uint8 GetUInt8() const
Definition Field.h:26
std::string GetString() const
Definition Field.h:228
uint64 GetUInt64() const
Definition Field.h:141
uint16 GetUInt16() const
Definition Field.h:69
uint32 GetUInt32() const
Definition Field.h:105
int32 GetInt32() const
Definition Field.h:123
Definition Group.h:147
uint32 GetMembersCount() const
Definition Group.h:227
GroupReference * next()
Definition Guild.h:324
virtual bool CheckAchievementCriteriaMeet(uint32, Player const *, Unit const *=NULL, uint32=0)
Definition Item.h:202
virtual void SaveToDB(SQLTransaction &trans)
Definition Item.cpp:305
static Item * CreateItem(uint32 itemEntry, uint32 count, Player const *player=NULL)
Definition Item.cpp:1012
void SendMailTo(SQLTransaction &trans, MailReceiver const &receiver, MailSender const &sender, MailCheckMask checked=MAIL_CHECK_MASK_NONE, uint32 deliver_delay=0)
Definition Mail.cpp:162
MailDraft & AddItem(Item *item)
Definition Mail.cpp:70
Definition Map.h:238
DifficultyID GetDifficulty() const
Definition Map.h:363
uint32 GetPlayersCountExceptGMs() const
Definition Map.cpp:2516
uint32 GetId(void) const
Definition Map.h:300
bool IsInstance() const
Definition Map.h:368
uint64 GetGUID() const
Definition Object.h:119
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:325
Player * ToPlayer()
Definition Object.h:204
bool IsInWorld() const
Definition Object.h:114
TypeID GetTypeId() const
Definition Object.h:131
uint32 GetEntry() const
Definition Object.h:125
Creature * ToCreature()
Definition Object.h:207
static void AddLocaleString(std::string const &s, LocaleConstant locale, StringVector &data)
static void GetLocaleString(const StringVector &data, int loc_idx, std::string &value)
Definition ObjectMgr.h:1353
uint32 GetTeam() const
Definition Player.h:2527
uint32 GetGuildId() const
Definition Player.h:2291
RewardedQuestSet const & getRewardedQuests() const
Definition Player.h:1957
uint8 GetDrunkValue() const
Definition Player.h:2594
bool GetQuestRewardStatus(uint32 quest_id) const
BattlePetMgr * GetBattlePetMgr()
Definition Player.h:2573
uint8 GetBankBagSlotCount() const
Definition Player.h:1552
bool addSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading=false)
Definition Player.cpp:3634
Guild * GetGuild()
Definition Player.cpp:22662
WorldSession * GetSession() const
Definition Player.h:2417
static uint32 TeamForRace(uint8 race)
Definition Player.cpp:7072
uint16 GetBaseSkillValue(uint32 skill) const
Definition Player.cpp:6614
TeamId GetTeamId() const
Definition Player.h:2531
PlayerSpellMap const & GetSpellMap() const
Definition Player.h:2141
uint16 GetPureMaxSkillValue(uint32 skill) const
Definition Player.cpp:6599
Battleground * GetBattleground() const
Definition Player.cpp:19212
Group * GetGroup()
Definition Player.h:2972
bool IsGameMaster() const
Definition Player.h:1369
void learnSpell(uint32 spell_id, bool dependent)
Definition Player.cpp:4021
uint64 GetMoney() const
Definition Player.h:1945
bool HasSpell(uint32 spell) const override
Definition Player.cpp:4674
size_t GetRewardedQuestCount() const
Definition Player.h:1966
ReputationMgr & GetReputationMgr()
Definition Player.h:2555
static DrunkenState GetDrunkenstateByValue(uint8 value)
Definition Player.cpp:1346
void setString(const uint8 index, const std::string &value)
void setUInt16(const uint8 index, const uint16 value)
void setUInt64(const uint8 index, const uint64 value)
void setUInt32(const uint8 index, const uint32 value)
int32 GetZoneOrSort() const
Definition QuestDef.h:272
uint8 GetHonoredFactionCount() const
uint8 GetReveredFactionCount() const
int32 GetReputation(uint32 faction_id) const
uint8 GetExaltedFactionCount() const
uint8 GetVisibleFactionCount() const
AchievementChatBuilder(Player const &player, ChatMsg msgtype, int32 textId, uint32 ach_id)
void operator()(WorldPacket &data, LocaleConstant loc_idx)
uint32 ApplyAuraName
Definition SpellInfo.h:90
SpellEffectInfo Effects[MAX_SPELL_EFFECTS]
Definition SpellInfo.h:255
size_type size() const
Definition Util.h:46
Definition Unit.h:1367
bool HealthAbovePct(int32 pct) const
Definition Unit.h:1621
float GetHealthPct() const
Definition Unit.h:1629
uint8 getGender() const
Definition Unit.h:1551
bool HasAuraEffect(uint32 spellId, uint8 effIndex, uint64 caster=0) const
void CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
uint8 getClass() const
Definition Unit.h:1543
bool IsAlive() const
Definition Unit.h:2032
bool HasAura(uint32 spellId, uint64 casterGUID=0, uint64 itemCasterGUID=0, uint32 reqEffMask=0) const
uint32 GetCreatureType() const
Definition Unit.cpp:4910
bool HasAuraType(AuraType auraType) const
uint8 getLevel() const
Definition Unit.h:1528
bool IsHostileTo(Unit const *unit) const
Definition Unit.cpp:2278
uint8 getRace() const
Definition Unit.h:1535
uint32 GetMapId() const
Definition Object.h:546
Map * GetMap() const
Definition Object.h:740
std::string const & GetName() const
Definition Object.h:664
uint32 GetZoneId() const
Definition Object.cpp:1597
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition Object.cpp:1607
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition Main.cpp:41
WorldDatabaseWorkerPool WorldDatabase
Accessor to the world database.
Definition Main.cpp:40
@ SMSG_ACHIEVEMENT_EARNED
Definition Opcodes.h:507
@ SMSG_SERVER_FIRST_ACHIEVEMENT
Definition Opcodes.h:948
@ SMSG_GUILD_ACHIEVEMENT_EARNED
Definition Opcodes.h:681
@ SMSG_RESPOND_INSPECT_ACHIEVEMENTS
Definition Opcodes.h:941
@ SMSG_CRITERIA_DELETED
Definition Opcodes.h:629
@ SMSG_GUILD_CRITERIA_DELETED
Definition Opcodes.h:689
@ SMSG_GUILD_CRITERIA_DATA
Definition Opcodes.h:688
@ SMSG_GUILD_ACHIEVEMENT_DELETED
Definition Opcodes.h:680
@ SMSG_GUILD_ACHIEVEMENT_DATA
Definition Opcodes.h:679
@ SMSG_ALL_ACHIEVEMENT_DATA
Definition Opcodes.h:513
@ SMSG_CRITERIA_UPDATE
Definition Opcodes.h:630
@ SMSG_ACHIEVEMENT_DELETED
Definition Opcodes.h:506
#define sWorld
Definition World.h:910
uint32 realmID
Id of the realm.
Definition Main.cpp:73
@ CONFIG_GUILD_LEVELING_ENABLED
Definition World.h:161
@ CONFIG_LISTEN_RANGE_SAY
Definition World.h:183
bool IsDisabledFor(DisableType type, uint32 entry, Unit const *unit, uint8 flags)
bool IsLiveCriteriaTypeEligible(uint32 criteriaType)
bool IsLiveCriteriaProgressEligible(uint32 achievementFlags)
bool ShouldSendLiveCriteriaProgress(bool hasLinkedAchievement, bool hasLiveEligibleAchievement)
CellCoord ComputeCellCoord(float x, float y)
struct AchievementCriteriaData::@106234210224313230010274346235221313360252063263::@024174374254033004277026301075062165130262072115 bg_loss_team_score
struct AchievementCriteriaData::@106234210224313230010274346235221313360252063263::@242275372266152233237245200135230111133067133327 drunk
struct AchievementCriteriaData::@106234210224313230010274346235221313360252063263::@057072032343071104215271130142020325273334150275 level
struct AchievementCriteriaData::@106234210224313230010274346235221313360252063263::@216021007006316026312235077267015221071344272202 aura
bool Meets(uint32 criteria_id, Player const *source, Unit const *target, uint32 miscValue1=0) const
struct AchievementCriteriaData::@106234210224313230010274346235221313360252063263::@336320011221331007167071255301216365172157057155 creature
struct AchievementCriteriaData::@106234210224313230010274346235221313360252063263::@320377026037266164246202240071302363266115322001 area
AchievementCriteriaDataType dataType
struct AchievementCriteriaData::@106234210224313230010274346235221313360252063263::@056275250256040003142024016221011315062167165214 health
struct AchievementCriteriaData::@106234210224313230010274346235221313360252063263::@244322361360134003272016350324260205076224125117 holiday
struct AchievementCriteriaData::@106234210224313230010274346235221313360252063263::@172302147354037330143253231262341126300056164132 classRace
struct AchievementCriteriaData::@106234210224313230010274346235221313360252063263::@107316206207337342166046010026175222131076365132 map_players
bool IsValid(CriteriaEntry const *criteria)
struct AchievementCriteriaData::@106234210224313230010274346235221313360252063263::@127266277105012275312221217150103304016252214022 equipped_item
void Add(AchievementCriteriaData const &data)
bool Meets(Player const *source, Unit const *target, uint32 miscValue=0) const
uint32 categoryId
uint32 flags
int32 requiredFaction
uint32 ID
uint32 refAchievement
uint32 count
int32 mapID
uint32 points
uint32 criteriaTreeID
std::vector< std::string > text
std::vector< std::string > subject
Definition Cell.h:37
void SetNoCreate()
Definition Cell.h:66
void Visit(CellCoord const &, TypeContainerVisitor< T, CONTAINER > &visitor, Map &, WorldObject const &, float) const
Definition CellImpl.h:109
std::set< uint64 > guids
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@155054343104315247226070332164215206302033027366 bg_objective
uint32 lootType
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@363072277046354060141332027202235316302276212336 gain_reputation
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@170213076040032203356242316360022040077201163357 reach_skill_level
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@315274205240162012350307044336136237232251153207 collect_battle_pet_species
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@365330015044177022354332336123067002370060350076 do_emote
uint32 bgMapID
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@377337335252316161360312250372213142222074313246 own_item
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@046316241355326241376163066335143213363124144336 hk_race
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@345234236313026077117152255011006124312363305150 learn_spell
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@174144145255077235152273004223233200017324167264 currencyGain
uint32 areaReference
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@021203240056244120276046036233301230266254012265 complete_quest
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@272036164363073024020074101121067213256041074141 complete_battleground
uint32 zoneID
uint32 ID
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@303224370273354123156275070201154037203323021040 learn_skill_line
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@252141276047360231264041005143012263253252060321 equip_epic_item
uint32 emoteID
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@155224045270122077025256231335026265046243154254 cast_spell
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@200263160026040337222023353106312212300036340373 learn_skillline_spell
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@137206212146252026123010125054215361112224112331 win_arena
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@202032204316306143021314120023223157357053237132 roll_greed_on_loot
uint32 speciesID
uint32 timedCriteriaStartType
uint32 questID
uint32 type
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@124155230370177343123035335307267321042041343165 complete_quests_in_zone
uint32 raceID
uint32 modifierTreeId
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@145020032061045307244276146151306076241166343074 kill_creature
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@040126152076004320345151123073342161374077106175 win_bg
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@377251333175221103040333313262154062016061002177 use_gameobject
uint32 timeLimit
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@344224337173133016032174023000100210306163234367 honorable_kill_at_area
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@226166206351331214306246166272022103053025012230 reach_battle_pet_level
uint32 skillID
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@177214247114106113217220330146125332371234032103 hk_class
uint32 itemID
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@043245350336207244022374376310206337252016003124 learn_skill_level
uint32 level
uint32 creatureEntry
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@156371326021026040167240312273017356056170321234 be_spell_target
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@257014116243264075112106007135041333265226315121 explore_area
uint32 linkedAchievement
uint32 goEntry
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@234250345245021161254340245153131216233003346165 killed_by_creature
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@345223042050174377263075217177002173065115333020 use_item
uint32 objectiveId
uint32 spellID
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@166000337046172330023301127054026235073161252152 complete_achievement
uint32 skillLine
uint32 failEvent
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@070241247357031051035113042322125241115042267040 collect_battle_pet
uint32 itemSlot
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@017210121314152347012226254260077214375242224331 death_from
uint32 mapID
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@203206252056004136317074254276154324014203311247 death_at_map
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@212237251022357172040173021300062006341106034137 loot_type
uint32 creatureID
uint32 failAsset
uint32 areaID
uint32 classID
uint32 factionID
uint32 rollValue
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@200167322244331233113111044210152015217015334006 fish_in_gameobject
uint32 currency
struct CriteriaEntry::@350132267162301254113063251105274111176100346071::@033317225107033255210024347312044247305221351170 equip_item
uint32 parentID
uint32 criteriaCount
uint32 criteriaID
uint32 ID
uint32 conditionValue[2]
uint32 conditionType
uint32 parent
bool operator()(CompletedAchievementMap::value_type const &val)
uint32 areatableID[MAX_WORLD_MAP_OVERLAY_AREA_IDX]