[Complete] ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA and ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA

Hi all ^^

I created this patch (based on rev https://github.com/TrinityCore/TrinityCore/commit/8f573f416a7deb56e7dd2c795cb53c8b5dcaddde) to fix these two Achievement Criteria Types:

  • ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA

  • ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA

With this patch, all satistics regarding Arena Matches are fixed as well as this achievement http://www.wowhead.com/achievement=699.


diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp

index d8c9a3b..e656c76 100755

--- a/src/server/game/Achievements/AchievementMgr.cpp

+++ b/src/server/game/Achievements/AchievementMgr.cpp

@@ -87,6 +87,8 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)

         case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:          // only hardcoded list

         case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL:

         case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA:

+        case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA:

+        case ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA:

         case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:

         case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL:

         case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL:

@@ -263,7 +265,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)

         case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM:

             if (equipped_item.item_quality >= MAX_ITEM_QUALITY)

             {

-                sLog->outErrorDb("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.",

+                sLog->outErrorDb("Table `achievement_criteria_data` (Entry: %u Type: %u) for requirement ACHIEVEMENT_CRITERIA_REQUIRE_S_EQUIPED_ITEM (%u) has unknown quality state in value1 (%u), ignored.",

                     criteria->ID, criteria->requiredType, dataType, equipped_item.item_quality);

                 return false;

             }

@@ -271,11 +273,21 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)

         case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID:

             if (!sMapStore.LookupEntry(map_id.mapId))

             {

-                sLog->outErrorDb("Table `achievement_criteria_requirement` (Entry: %u Type: %u) for requirement ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID (%u) has unknown map id in value1 (%u), ignored.",

+                sLog->outErrorDb("Table `achievement_criteria_data` (Entry: %u Type: %u) for requirement ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID (%u) has unknown map id in value1 (%u), ignored.",

                     criteria->ID, criteria->requiredType, dataType, map_id.mapId);

                 return false;

             }

             return true;

+        case ACHIEVEMENT_CRITERIA_DATA_TYPE_ARENA_TYPE:

+            if (arena_type.arenaType != ARENA_TEAM_2v2 && 

+                arena_type.arenaType != ARENA_TEAM_3v3 && 

+                arena_type.arenaType != ARENA_TEAM_5v5)

+            {

+                sLog->outErrorDb("Table `achievement_criteria_data` (Entry: %u Type: %u) for requirement ACHIEVEMENT_CRITERIA_DATA_TYPE_ARENA_TYPE (%u) has unknown arena type in value1 (%u), ignored.",

+                    criteria->ID, criteria->requiredType, dataType, arena_type.arenaType);

+                return false;

+            }

+            return true;

         default:

             sLog->outErrorDb("Table `achievement_criteria_data` (Entry: %u Type: %u) has data for non-supported data type (%u), ignored.", criteria->ID, criteria->requiredType, dataType);

             return false;

@@ -381,6 +393,10 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un

         }

         case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID:

             return source->GetMapId() == map_id.mapId;

+        case ACHIEVEMENT_CRITERIA_DATA_TYPE_ARENA_TYPE:

+            if (!miscvalue1)            

+                return false;

+            return miscvalue1 == arena_type.arenaType;

         default:

             break;

     }

@@ -1161,6 +1177,38 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui


                 SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);

                 break;

+            case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA:

+                {

+                    // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case

+                    // miscValue1 = increment

+                    // miscValue2 = arena type

+                    if (!miscValue1 || !miscValue2)

+                        continue;

+                    if (GetPlayer()->GetMapId() != achievementCriteria->win_arena.mapID)

+                        continue;

+                    // arena type requirements couldn't be found in the dbc

+                    AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);

+                    if (!data || !data->Meets(GetPlayer(), unit, miscValue2))

+                        continue;

+                    SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_ACCUMULATE);

+                    break;

+                }

+            case ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA:

+                {

+                    // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case

+                    // miscValue1 = increment

+                    // miscValue2 = arena type

+                    if (!miscValue1 || !miscValue2)

+                        continue;

+                    if (GetPlayer()->GetMapId() != achievementCriteria->play_arena.mapID)

+                        continue;

+                    // arena type requirements couldn't be found in the dbc

+                    AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);

+                    if (!data || !data->Meets(GetPlayer(), unit, miscValue2))

+                        continue;

+                    SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_ACCUMULATE);

+                    break;

+                }

             case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM:

                 // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case

                 if (!miscValue1)

@@ -1568,8 +1616,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui

                 break;

             // FIXME: not triggered in code as result, need to implement

             case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID:

-            case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA:

-            case ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA:

             case ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK:

             case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE:

             case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE:

@@ -2011,7 +2057,7 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement, b

         return;


     SendAchievementEarned(achievement);

-    CompletedAchievementData& ca =  m_completedAchievements[achievement->ID];

+    CompletedAchievementData& ca = m_completedAchievements[achievement->ID];

     ca.date = time(NULL);

     ca.changed = true;


diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h

index 3456e31..86ae0ea 100755

--- a/src/server/game/Achievements/AchievementMgr.h

+++ b/src/server/game/Achievements/AchievementMgr.h

@@ -63,9 +63,10 @@ enum AchievementCriteriaDataType

     ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT          = 18, // 0              0             maker instance script call for check current criteria requirements fit

     ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM      = 19, // item_level     item_quality  for equipped item in slot to check item level and quality

     ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID              = 20, // map_id         0             player must be on map with id in map_id

+    ACHIEVEMENT_CRITERIA_DATA_TYPE_ARENA_TYPE          = 21, // arena_type     0             player must be in the arena bracket specified by arena_type

 };


-#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE               21 // maximum value in AchievementCriteriaDataType enum

+#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE               22 // maximum value in AchievementCriteriaDataType enum


 class Player;

 class Unit;

@@ -168,6 +169,11 @@ struct AchievementCriteriaData

         {

             uint32 mapId;

         } map_id;

+        // ACHIEVEMENT_CRITERIA_DATA_TYPE_ARENA_TYPE        = 21

+        struct

+        {

+            uint32 arenaType;

+        } arena_type;

         // ...

         struct

         {

diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp

index 3b96b84..57ccaab 100755

--- a/src/server/game/Battlegrounds/Battleground.cpp

+++ b/src/server/game/Battlegrounds/Battleground.cpp

@@ -775,17 +775,26 @@ void Battleground::EndBattleground(uint32 winner)

             {

                 // update achievement BEFORE personal rating update

                 ArenaTeamMember* member = winner_arena_team->GetMember(plr->GetGUID());

-                if (member)

+                if (member) 

+                {

                     plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, member->PersonalRating);

+                    plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA, 1, winner_arena_team->GetType());

+                    plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA, 1, winner_arena_team->GetType());

+                }


                 winner_arena_team->MemberWon(plr, loser_matchmaker_rating, winner_change);

             }

             else

             {

                 loser_arena_team->MemberLost(plr, winner_matchmaker_rating, loser_change);

-

-                // Arena lost => reset the win_rated_arena having the "no_lose" condition

-                plr->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE);

+                

+                ArenaTeamMember* member = loser_arena_team->GetMember(plr->GetGUID());

+                if (member)

+                {

+                    // Arena lost => reset the win_rated_arena having the "no_lose" condition

+                    plr->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE);

+                    plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA, 1, loser_arena_team->GetType());

+                }

             }

         }

This sql is also needed:

– Criteria Type 32: ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA
DELETE FROM disables WHERE entry IN (5735,5736,5734,8599,8602,5726,8601,8600,5727,8607,8610,8609,8608,8615,5728,8616,8617,8618,609,608,610,5810,5809,8590,5739,8587,8589,8588,5737,5738) AND sourceType=4;
DELETE FROM achievement_criteria_data WHERE criteria_id IN (5735,5736,5734,8599,8602,5726,8601,8600,5727,8607,8610,8609,8608,8615,5728,8616,8617,8618,609,608,610,5810,5809,8590,5739,8587,8589,8588,5737,5738);
INSERT INTO achievement_criteria_data (criteria_id, type, value1, value2, ScriptName) VALUES
(5735,0,0,0,‘’),
(5736,0,0,0,‘’),
(5734,0,0,0,‘’),
(8599,21,5,0,‘’),
(8602,21,5,0,‘’),
(5726,21,5,0,‘’),
(8601,21,5,0,‘’),
(8600,21,5,0,‘’),
(5727,21,3,0,‘’),
(8607,21,3,0,‘’),
(8610,21,3,0,‘’),
(8609,21,3,0,‘’),
(8608,21,3,0,‘’),
(8615,21,2,0,‘’),
(5728,21,2,0,‘’),
(8616,21,2,0,‘’),
(8617,21,2,0,‘’),
(8618,21,2,0,‘’),
(609,0,0,0,‘’), – World Wide Winner
(608,0,0,0,‘’), – World Wide Winner
(610,0,0,0,‘’), – World Wide Winner
(5810,0,0,0,‘’), – World Wide Winner
(5809,0,0,0,‘’), – World Wide Winner
(8590,0,0,0,‘’),
(5739,0,0,0,‘’),
(8587,0,0,0,‘’),
(8589,0,0,0,‘’),
(8588,0,0,0,‘’),
(5737,0,0,0,‘’),
(5738,0,0,0,‘’);

– Criteria Type 33: ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA
DELETE FROM disables WHERE entry IN (5732,5730,5729,5723,8596,8595,8598,8597,8605,8604,8603,5724,8606,8611,8612,8613,8614,5725,8593,8592,8591,5740,8594,5731,5733) AND sourceType=4;
DELETE FROM achievement_criteria_data WHERE criteria_id IN (5732,5730,5729,5723,8596,8595,8598,8597,8605,8604,8603,5724,8606,8611,8612,8613,8614,5725,8593,8592,8591,5740,8594,5731,5733);
INSERT INTO achievement_criteria_data (criteria_id, type, value1, value2, ScriptName) VALUES
(5732,0,0,0,‘’),
(5730,0,0,0,‘’),
(5729,0,0,0,‘’),
(5723,21,5,0,‘’),
(8596,21,5,0,‘’),
(8595,21,5,0,‘’),
(8598,21,5,0,‘’),
(8597,21,5,0,‘’),
(8605,21,3,0,‘’),
(8604,21,3,0,‘’),
(8603,21,3,0,‘’),
(5724,21,3,0,‘’),
(8606,21,3,0,‘’),
(8611,21,2,0,‘’),
(8612,21,2,0,‘’),
(8613,21,2,0,‘’),
(8614,21,2,0,‘’),
(5725,21,2,0,‘’),
(8593,0,0,0,‘’),
(8592,0,0,0,‘’),
(8591,0,0,0,‘’),
(5740,0,0,0,‘’),
(8594,0,0,0,‘’),
(5731,0,0,0,‘’),
(5733,0,0,0,‘’);

Feel free to change my code if needed. I also fixed a couple of typos. I tested this patch on my server and everything seems to work as intended. Hope this helps /emoticons/default_smile.png

achievement.patch