aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp38
-rw-r--r--src/server/game/Achievements/AchievementMgr.h11
-rw-r--r--src/server/game/Battlegrounds/Arena.cpp2
-rw-r--r--src/server/game/Battlegrounds/Battleground.cpp16
-rw-r--r--src/server/game/DataStores/DBCEnums.h4
-rw-r--r--src/server/game/Entities/Player/Player.cpp10
-rw-r--r--src/server/game/Entities/Player/Player.h2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp2
8 files changed, 50 insertions, 35 deletions
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 34955846886..6fd2037cf51 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -474,19 +474,21 @@ void AchievementMgr::Reset()
CheckAllAchievementCriteria();
}
-void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1, uint32 miscvalue2, bool evenIfCriteriaComplete)
+void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaCondition condition, uint32 value, bool evenIfCriteriaComplete)
{
- TC_LOG_DEBUG("achievement", "AchievementMgr::ResetAchievementCriteria(%u, %u, %u)", type, miscvalue1, miscvalue2);
+ TC_LOG_DEBUG("achievement", "AchievementMgr::ResetAchievementCriteria(%u, %u, %u)", condition, value, evenIfCriteriaComplete);
// disable for gamemasters with GM-mode enabled
if (m_player->IsGameMaster())
return;
- AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type, 0/*get all*/);
- for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i)
- {
- AchievementCriteriaEntry const* achievementCriteria = (*i);
+ AchievementCriteriaEntryList const* achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByCondition(condition, value);
+ if (!achievementCriteriaList)
+ return;
+ for (auto itr = achievementCriteriaList->begin(); itr != achievementCriteriaList->end(); ++itr)
+ {
+ AchievementCriteriaEntry const* achievementCriteria = *itr;
AchievementEntry const* achievement = sAchievementMgr->GetAchievement(achievementCriteria->ReferredAchievement);
if (!achievement)
continue;
@@ -495,14 +497,7 @@ void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uin
if ((IsCompletedCriteria(achievementCriteria, achievement) && !evenIfCriteriaComplete) || HasAchieved(achievement->ID))
continue;
- for (uint8 j = 0; j < MAX_CRITERIA_REQUIREMENTS; ++j)
- if (achievementCriteria->AdditionalRequirements[j].Type == miscvalue1 &&
- (!achievementCriteria->AdditionalRequirements[j].Asset ||
- achievementCriteria->AdditionalRequirements[j].Asset == miscvalue2))
- {
- RemoveCriteriaProgress(achievementCriteria);
- break;
- }
+ RemoveCriteriaProgress(achievementCriteria);
}
}
@@ -2297,6 +2292,21 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList()
}
}
+ for (uint32 i = 0; i < MAX_CRITERIA_REQUIREMENTS; ++i)
+ {
+ if (criteria->AdditionalRequirements[i].Type != ACHIEVEMENT_CRITERIA_CONDITION_NONE)
+ {
+ ASSERT(criteria->AdditionalRequirements[i].Type < ACHIEVEMENT_CRITERIA_CONDITION_MAX,
+ "ACHIEVEMENT_CRITERIA_CONDITION_MAX must be greater than or equal to %u but is currently equal to %u",
+ criteria->AdditionalRequirements[i].Type + 1, ACHIEVEMENT_CRITERIA_CONDITION_MAX);
+
+ if (i == 0
+ || criteria->AdditionalRequirements[i].Type != criteria->AdditionalRequirements[i - 1].Type
+ || criteria->AdditionalRequirements[i].Asset != criteria->AdditionalRequirements[i - 1].Asset)
+ m_AchievementCriteriasByCondition[criteria->AdditionalRequirements[i].Type][criteria->AdditionalRequirements[i].Asset].push_back(criteria);
+ }
+ }
+
if (criteria->StartTimer)
{
ASSERT(criteria->StartEvent < ACHIEVEMENT_TIMED_TYPE_MAX, "ACHIEVEMENT_TIMED_TYPE_MAX must be greater than or equal to %u but is currently equal to %u",
diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h
index e39c8e03b73..64d852d9011 100644
--- a/src/server/game/Achievements/AchievementMgr.h
+++ b/src/server/game/Achievements/AchievementMgr.h
@@ -37,6 +37,7 @@ typedef std::vector<AchievementEntry const*> AchievementEntryList;
typedef std::unordered_map<uint32, AchievementCriteriaEntryList> AchievementCriteriaListByAchievement;
typedef std::unordered_map<uint32, AchievementCriteriaEntryList> AchievementCriteriaListByMiscValue;
+typedef std::unordered_map<uint32, AchievementCriteriaEntryList> AchievementCriteriaListByCondition;
typedef std::unordered_map<uint32, AchievementEntryList> AchievementListByReferencedId;
struct CriteriaProgress
@@ -280,7 +281,7 @@ class TC_GAME_API AchievementMgr
static void DeleteFromDB(ObjectGuid lowguid);
void LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult);
void SaveToDB(SQLTransaction& trans);
- void ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, bool evenIfCriteriaComplete = false);
+ void ResetAchievementCriteria(AchievementCriteriaCondition condition, uint32 value, bool evenIfCriteriaComplete);
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = NULL);
void CompletedAchievement(AchievementEntry const* entry);
void CheckAllAchievementCriteria();
@@ -332,6 +333,12 @@ class TC_GAME_API AchievementGlobalMgr
return m_AchievementCriteriasByTimedType[type];
}
+ AchievementCriteriaEntryList const* GetAchievementCriteriaByCondition(AchievementCriteriaCondition condition, uint32 val)
+ {
+ AchievementCriteriaListByCondition::const_iterator itr = m_AchievementCriteriasByCondition[condition].find(val);
+ return itr != m_AchievementCriteriasByCondition[condition].end() ? &itr->second : nullptr;
+ }
+
AchievementCriteriaEntryList const* GetAchievementCriteriaByAchievement(uint32 id) const
{
AchievementCriteriaListByAchievement::const_iterator itr = m_AchievementCriteriaListByAchievement.find(id);
@@ -404,6 +411,8 @@ class TC_GAME_API AchievementGlobalMgr
AchievementCriteriaEntryList m_AchievementCriteriasByTimedType[ACHIEVEMENT_TIMED_TYPE_MAX];
+ AchievementCriteriaListByCondition m_AchievementCriteriasByCondition[ACHIEVEMENT_CRITERIA_CONDITION_MAX];
+
// store achievement criterias by achievement to speed up lookup
AchievementCriteriaListByAchievement m_AchievementCriteriaListByAchievement;
diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp
index 498a8d42ac0..fb4f6b965ca 100644
--- a/src/server/game/Battlegrounds/Arena.cpp
+++ b/src/server/game/Battlegrounds/Arena.cpp
@@ -245,7 +245,7 @@ void Arena::EndBattleground(uint32 winner)
loserArenaTeam->MemberLost(player, winnerMatchmakerRating, loserMatchmakerChange);
// Arena lost => reset the win_rated_arena having the "no_lose" condition
- player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE);
+ player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE, 0);
}
}
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index af4f177d5fb..84a539bfaaa 100644
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -963,6 +963,9 @@ void Battleground::RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool Sen
// reset destination bg team
player->SetBGTeam(0);
+ // remove all criterias on bg leave
+ player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true);
+
if (Transport)
player->TeleportToBGEntryPoint();
@@ -1062,17 +1065,8 @@ void Battleground::AddPlayer(Player* player)
player->CastSpell(player, SPELL_PREPARATION, true); // reduces all mana cost of spells.
}
- player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true);
- player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true);
- player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true);
- player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true);
- player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true);
- player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true);
- player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true);
- player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true);
- player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true);
- player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true);
- player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true);
+ // reset all map criterias on map enter
+ player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true);
// setup BG group membership
PlayerAddedToBGCheckIfBGIsRunning(player);
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index 3f4a2190857..08f015dcaf2 100644
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -100,7 +100,9 @@ enum AchievementCriteriaCondition
ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE = 4, // only used in "Win 10 arenas without losing"
ACHIEVEMENT_CRITERIA_CONDITION_NO_SPELL_HIT = 9, // requires the player not to be hit by specific spell
ACHIEVEMENT_CRITERIA_CONDITION_NOT_IN_GROUP = 10, // requires the player not to be in group
- ACHIEVEMENT_CRITERIA_CONDITION_UNK13 = 13 // unk
+ ACHIEVEMENT_CRITERIA_CONDITION_UNK13 = 13, // unk
+
+ ACHIEVEMENT_CRITERIA_CONDITION_MAX
};
enum AchievementCriteriaFlags
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 73a20ff0310..a7735b9de19 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -1605,9 +1605,9 @@ void Player::setDeathState(DeathState s)
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP, 1);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH, 1);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON, 1);
- ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH);
- ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH);
- ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH);
+
+ // reset all death criterias
+ ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH, 0);
}
Unit::setDeathState(s);
@@ -24894,9 +24894,9 @@ void Player::RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 e
m_achievementMgr->RemoveTimedAchievement(type, entry);
}
-void Player::ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, bool evenIfCriteriaComplete /* = false*/)
+void Player::ResetAchievementCriteria(AchievementCriteriaCondition condition, uint32 value, bool evenIfCriteriaComplete /* = false*/)
{
- m_achievementMgr->ResetAchievementCriteria(type, miscValue1, miscValue2, evenIfCriteriaComplete);
+ m_achievementMgr->ResetAchievementCriteria(condition, value, evenIfCriteriaComplete);
}
void Player::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit* unit /*= NULL*/)
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 9fbac96b4e6..09f546841a7 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -2243,7 +2243,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void SendRespondInspectAchievements(Player* player) const;
bool HasAchieved(uint32 achievementId) const;
void ResetAchievements();
- void ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, bool evenIfCriteriaComplete = false);
+ void ResetAchievementCriteria(AchievementCriteriaCondition condition, uint32 value, bool evenIfCriteriaComplete = false);
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = NULL);
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost = 0);
void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry);
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
index 3f9f81b5158..d12b1cd5cf2 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
@@ -1351,7 +1351,7 @@ class spell_algalon_supermassive_fail : public SpellScriptLoader
if (!GetHitPlayer())
return;
- GetHitPlayer()->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_CONDITION_NO_SPELL_HIT, GetSpellInfo()->Id, true);
+ GetHitPlayer()->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_CONDITION_NO_SPELL_HIT, GetSpellInfo()->Id, true);
}
void Register() override