From 43fcc558e4f118e8114783072b0b0941912cbda5 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Wed, 6 May 2020 17:52:14 -0400 Subject: [PATCH] Core/Achievements: Optimized resetting achievement criteria by condition and changed the functionality to properly reset all possible criteria with given condition Port From (https://github.com/TrinityCore/TrinityCore/commit/6f7ff9a3efd10cd4f776a67540109e7bb774f1c5) --- .../Framework/Constants/AchievementConst.cs | 10 +++-- .../Game/Achievements/AchievementManager.cs | 39 ++++++++++--------- Source/Game/Achievements/CriteriaHandler.cs | 11 ++++++ Source/Game/Arenas/Arena.cs | 2 +- Source/Game/BattleGrounds/BattleGround.cs | 16 +++----- .../Entities/Player/Player.Achievement.cs | 6 +-- Source/Game/Entities/Player/Player.cs | 6 +-- .../Quest/QuestObjectiveCriteriaManager.cs | 9 ++--- 8 files changed, 53 insertions(+), 46 deletions(-) diff --git a/Source/Framework/Constants/AchievementConst.cs b/Source/Framework/Constants/AchievementConst.cs index 956a386cd..2f9efd350 100644 --- a/Source/Framework/Constants/AchievementConst.cs +++ b/Source/Framework/Constants/AchievementConst.cs @@ -91,11 +91,15 @@ namespace Framework.Constants Unk2 = 2, BgMap = 3, NoLose = 4, - Unk5 = 5, - Unk8 = 8, + RemoveAura = 5, + CastSpell = 8, NoSpellHit = 9, NotInGroup = 10, - Unk13 = 13 + LostPetBattle = 11, + Unk13 = 13, + Event = 14, + + Max } public enum CriteriaAdditionalCondition diff --git a/Source/Game/Achievements/AchievementManager.cs b/Source/Game/Achievements/AchievementManager.cs index e5a98889a..a7f964ab9 100644 --- a/Source/Game/Achievements/AchievementManager.cs +++ b/Source/Game/Achievements/AchievementManager.cs @@ -355,36 +355,37 @@ namespace Game.Achievements } } - public void ResetCriteria(CriteriaTypes type, ulong miscValue1, ulong miscValue2, bool evenIfCriteriaComplete) + public void ResetCriteria(CriteriaCondition condition, uint failAsset, bool evenIfCriteriaComplete) { - Log.outDebug(LogFilter.Achievement, "ResetAchievementCriteria({0}, {1}, {2})", type, miscValue1, miscValue2); + Log.outDebug(LogFilter.Achievement, $"ResetAchievementCriteria({condition}, {failAsset}, {evenIfCriteriaComplete})"); // disable for gamemasters with GM-mode enabled if (_owner.IsGameMaster()) return; - var achievementCriteriaList = GetCriteriaByType(type); - foreach (Criteria achievementCriteria in achievementCriteriaList) + var achievementCriteriaList = Global.CriteriaMgr.GetCriteriaByFailEvent(condition, (int)failAsset); + if (!achievementCriteriaList.Empty()) { - if (achievementCriteria.Entry.FailEvent != miscValue1 || (achievementCriteria.Entry.FailAsset != 0 && achievementCriteria.Entry.FailAsset != miscValue2)) - continue; - - var trees = Global.CriteriaMgr.GetCriteriaTreesByCriteria(achievementCriteria.Id); - bool allComplete = true; - foreach (CriteriaTree tree in trees) + foreach (Criteria achievementCriteria in achievementCriteriaList) { - // don't update already completed criteria if not forced or achievement already complete - if (!(IsCompletedCriteriaTree(tree) && !evenIfCriteriaComplete) || !HasAchieved(tree.Achievement.Id)) + + var trees = Global.CriteriaMgr.GetCriteriaTreesByCriteria(achievementCriteria.Id); + bool allComplete = true; + foreach (CriteriaTree tree in trees) { - allComplete = false; - break; + // don't update already completed criteria if not forced or achievement already complete + if (!(IsCompletedCriteriaTree(tree) && !evenIfCriteriaComplete) || !HasAchieved(tree.Achievement.Id)) + { + allComplete = false; + break; + } } + + if (allComplete) + continue; + + RemoveCriteriaProgress(achievementCriteria); } - - if (allComplete) - continue; - - RemoveCriteriaProgress(achievementCriteria); } } diff --git a/Source/Game/Achievements/CriteriaHandler.cs b/Source/Game/Achievements/CriteriaHandler.cs index 90c4a40fc..f0325c72d 100644 --- a/Source/Game/Achievements/CriteriaHandler.cs +++ b/Source/Game/Achievements/CriteriaHandler.cs @@ -2620,6 +2620,8 @@ namespace Game.Achievements { Cypher.Assert(criteriaEntry.Type < CriteriaTypes.TotalTypes, $"CRITERIA_TYPE_TOTAL must be greater than or equal to {criteriaEntry.Type + 1} but is currently equal to {CriteriaTypes.TotalTypes}"); + Cypher.Assert(criteriaEntry.StartEvent < CriteriaTimedTypes.Max, $"CRITERIA_TYPE_TOTAL must be greater than or equal to {criteriaEntry.StartEvent + 1} but is currently equal to {CriteriaTimedTypes.Max}"); + Cypher.Assert(criteriaEntry.FailEvent < (byte)CriteriaCondition.Max, $"CRITERIA_CONDITION_MAX must be greater than or equal to {criteriaEntry.FailEvent + 1} but is currently equal to {CriteriaCondition.Max}"); var treeList = _criteriaTreeByCriteria.LookupByKey(criteriaEntry.Id); if (treeList.Empty()) @@ -2678,6 +2680,9 @@ namespace Game.Achievements if (criteriaEntry.StartTimer != 0) _criteriasByTimedType.Add(criteriaEntry.StartEvent, criteria); + + if (criteriaEntry.FailEvent != 0) + _criteriasByFailEvent[criteriaEntry.FailEvent].Add((int)criteriaEntry.FailAsset, criteria); } foreach (var p in _criteriaTrees) @@ -2789,6 +2794,11 @@ namespace Game.Achievements return _criteriasByTimedType.LookupByKey(type); } + public List GetCriteriaByFailEvent(CriteriaCondition condition, int asset) + { + return _criteriasByFailEvent[(int)condition].LookupByKey(asset); + } + public CriteriaDataSet GetCriteriaDataSet(Criteria criteria) { return _criteriaDataMap.LookupByKey(criteria.Id); @@ -2835,6 +2845,7 @@ namespace Game.Achievements MultiMap _questObjectiveCriteriasByType = new MultiMap(); MultiMap _criteriasByTimedType = new MultiMap(); + MultiMap[] _criteriasByFailEvent = new MultiMap[(int)CriteriaCondition.Max]; } public class ModifierTreeNode diff --git a/Source/Game/Arenas/Arena.cs b/Source/Game/Arenas/Arena.cs index 23ba7d380..6c466c9f5 100644 --- a/Source/Game/Arenas/Arena.cs +++ b/Source/Game/Arenas/Arena.cs @@ -282,7 +282,7 @@ namespace Game.Arenas loserArenaTeam.MemberLost(player, winnerMatchmakerRating, loserMatchmakerChange); // Arena lost => reset the win_rated_arena having the "no_lose" condition - player.ResetCriteria(CriteriaTypes.WinRatedArena, (uint)CriteriaCondition.NoLose); + player.ResetCriteria(CriteriaCondition.NoLose, 0); } } diff --git a/Source/Game/BattleGrounds/BattleGround.cs b/Source/Game/BattleGrounds/BattleGround.cs index 1511ed56d..643d165aa 100644 --- a/Source/Game/BattleGrounds/BattleGround.cs +++ b/Source/Game/BattleGrounds/BattleGround.cs @@ -914,6 +914,9 @@ namespace Game.BattleGrounds // reset destination bg team player.SetBGTeam(0); + // remove all criterias on bg leave + player.ResetCriteria(CriteriaCondition.BgMap, GetMapId(), true); + if (Transport) player.TeleportToBGEntryPoint(); @@ -1036,17 +1039,8 @@ namespace Game.BattleGrounds } } - player.ResetCriteria(CriteriaTypes.KillCreature, (int)CriteriaCondition.BgMap, GetMapId(), true); - player.ResetCriteria(CriteriaTypes.WinBg, (int)CriteriaCondition.BgMap, GetMapId(), true); - player.ResetCriteria(CriteriaTypes.DamageDone, (int)CriteriaCondition.BgMap, GetMapId(), true); - player.ResetCriteria(CriteriaTypes.BeSpellTarget, (int)CriteriaCondition.BgMap, GetMapId(), true); - player.ResetCriteria(CriteriaTypes.CastSpell, (int)CriteriaCondition.BgMap, GetMapId(), true); - player.ResetCriteria(CriteriaTypes.BgObjectiveCapture, (int)CriteriaCondition.BgMap, GetMapId(), true); - player.ResetCriteria(CriteriaTypes.HonorableKillAtArea, (int)CriteriaCondition.BgMap, GetMapId(), true); - player.ResetCriteria(CriteriaTypes.HonorableKill, (int)CriteriaCondition.BgMap, GetMapId(), true); - player.ResetCriteria(CriteriaTypes.HealingDone, (int)CriteriaCondition.BgMap, GetMapId(), true); - player.ResetCriteria(CriteriaTypes.GetKillingBlows, (int)CriteriaCondition.BgMap, GetMapId(), true); - player.ResetCriteria(CriteriaTypes.SpecialPvpKill, (int)CriteriaCondition.BgMap, GetMapId(), true); + // reset all map criterias on map enter + player.ResetCriteria(CriteriaCondition.BgMap, GetMapId(), true); // setup BG group membership PlayerAddedToBGCheckIfBGIsRunning(player); diff --git a/Source/Game/Entities/Player/Player.Achievement.cs b/Source/Game/Entities/Player/Player.Achievement.cs index 3e535504a..558b9d191 100644 --- a/Source/Game/Entities/Player/Player.Achievement.cs +++ b/Source/Game/Entities/Player/Player.Achievement.cs @@ -53,10 +53,10 @@ namespace Game.Entities m_achievementSys.RemoveCriteriaTimer(type, entry); } - public void ResetCriteria(CriteriaTypes type, ulong miscValue1 = 0, ulong miscValue2 = 0, bool evenIfCriteriaComplete = false) + public void ResetCriteria(CriteriaCondition condition, uint failAsset, bool evenIfCriteriaComplete = false) { - m_achievementSys.ResetCriteria(type, miscValue1, miscValue2, evenIfCriteriaComplete); - m_questObjectiveCriteriaMgr.ResetCriteria(type, miscValue1, miscValue2, evenIfCriteriaComplete); + m_achievementSys.ResetCriteria(condition, failAsset, evenIfCriteriaComplete); + m_questObjectiveCriteriaMgr.ResetCriteria(condition, failAsset, evenIfCriteriaComplete); } public void UpdateCriteria(CriteriaTypes type, ulong miscValue1 = 0, ulong miscValue2 = 0, ulong miscValue3 = 0, Unit unit = null) diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index 47b140fec..a7e8b4e1b 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -774,9 +774,9 @@ namespace Game.Entities UpdateCriteria(CriteriaTypes.DeathAtMap, 1); UpdateCriteria(CriteriaTypes.Death, 1); UpdateCriteria(CriteriaTypes.DeathInDungeon, 1); - ResetCriteria(CriteriaTypes.BgObjectiveCapture, (uint)CriteriaCondition.NoDeath); - ResetCriteria(CriteriaTypes.HonorableKill, (uint)CriteriaCondition.NoDeath); - ResetCriteria(CriteriaTypes.GetKillingBlows, (uint)CriteriaCondition.NoDeath); + + // reset all death criterias + ResetCriteria(CriteriaCondition.NoDeath, 0); } base.SetDeathState(s); diff --git a/Source/Game/Quest/QuestObjectiveCriteriaManager.cs b/Source/Game/Quest/QuestObjectiveCriteriaManager.cs index 25c68699d..9fd382852 100644 --- a/Source/Game/Quest/QuestObjectiveCriteriaManager.cs +++ b/Source/Game/Quest/QuestObjectiveCriteriaManager.cs @@ -163,20 +163,17 @@ namespace Game } } - public void ResetCriteria(CriteriaTypes type, ulong miscValue1, ulong miscValue2, bool evenIfCriteriaComplete) + public void ResetCriteria(CriteriaCondition condition, uint failAsset, bool evenIfCriteriaComplete) { - Log.outDebug(LogFilter.Player, "QuestObjectiveCriteriaMgr.ResetCriteria({type}, {miscValue1}, {miscValue2})"); + Log.outDebug(LogFilter.Player, $"QuestObjectiveCriteriaMgr.ResetCriteria({condition}, {failAsset}, {evenIfCriteriaComplete})"); // disable for gamemasters with GM-mode enabled if (_owner.IsGameMaster()) return; - var playerCriteriaList = GetCriteriaByType(type); + var playerCriteriaList = Global.CriteriaMgr.GetCriteriaByFailEvent(condition, (int)failAsset); foreach (Criteria playerCriteria in playerCriteriaList) { - if (playerCriteria.Entry.FailEvent != miscValue1 || (playerCriteria.Entry.FailAsset != 0 && playerCriteria.Entry.FailAsset != miscValue2)) - continue; - var trees = Global.CriteriaMgr.GetCriteriaTreesByCriteria(playerCriteria.Id); bool allComplete = true; foreach (CriteriaTree tree in trees)