diff options
author | megamage <none@none> | 2009-07-31 11:36:02 +0800 |
---|---|---|
committer | megamage <none@none> | 2009-07-31 11:36:02 +0800 |
commit | 70e31cce3fc41cc5ebfbc9f0a69a1757ea4ec42a (patch) | |
tree | a35de670296d3fa287bfa88d457d6eed237c1e73 /src | |
parent | d96642c92fbeab49ae613a78c3fb578934288d2f (diff) |
[8276] Implement achievment ACHIEVEMENT_CRITERIA_TYPE_WIN_BG Author: VladimirMangos
* including new achievement createria data type ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE
Note: Some achivement creteria for success need data in `achievement_criteria_data`
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/game/AchievementMgr.cpp | 66 | ||||
-rw-r--r-- | src/game/AchievementMgr.h | 13 | ||||
-rw-r--r-- | src/game/BattleGround.cpp | 8 | ||||
-rw-r--r-- | src/game/BattleGround.h | 8 | ||||
-rw-r--r-- | src/game/BattleGroundAB.cpp | 42 | ||||
-rw-r--r-- | src/game/BattleGroundAB.h | 7 | ||||
-rw-r--r-- | src/game/BattleGroundEY.cpp | 11 | ||||
-rw-r--r-- | src/game/BattleGroundEY.h | 2 | ||||
-rw-r--r-- | src/game/BattleGroundWS.h | 1 | ||||
-rw-r--r-- | src/game/DBCStructure.h | 5 | ||||
-rw-r--r-- | src/game/Makefile.am | 8 |
11 files changed, 143 insertions, 28 deletions
diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index fdaa5dd82a8..482be8d069a 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -36,6 +36,8 @@ #include "SpellMgr.h" #include "MapManager.h" +#include "BattleGround.h" +#include "BattleGroundAB.h" INSTANTIATE_SINGLETON_1(AchievementGlobalMgr); @@ -81,6 +83,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) switch(criteria->requiredType) { + case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: // only hardcoded list case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING: @@ -233,6 +236,8 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) return false; } return true; + case ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE: + return true; // not check correctness node indexes default: sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) have data for not supported data type (%u), ignore.", criteria->ID, criteria->requiredType,dataType); return false; @@ -301,6 +306,13 @@ bool AchievementCriteriaData::Meets(Player const* source, Unit const* target, ui return Player::GetDrunkenstateByValue(source->GetDrunkValue()) >= drunk.state; case ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY: return IsHolidayActive(HolidayIds(holiday.id)); + case ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE: + { + BattleGround* bg = source->GetBattleGround(); + if(!bg) + return false; + return bg->IsTeamScoreInRange(source->GetTeam()==ALLIANCE ? HORDE : ALLIANCE,bg_loss_team_score.min_score,bg_loss_team_score.max_score); + } } return false; } @@ -720,6 +732,54 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui // specialized cases + case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: + { + // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case + if (!miscvalue1) + continue; + if (achievementCriteria->win_bg.bgMapID != GetPlayer()->GetMapId()) + continue; + + if (achievementCriteria->win_bg.additionalRequirement1_type) + { + // those requirements couldn't be found in the dbc + AchievementCriteriaDataSet const* data = achievementmgr.GetCriteriaDataSet(achievementCriteria); + if (!data || !data->Meets(GetPlayer(),unit)) + continue; + } + // some hardcoded requirements + else + { + BattleGround* bg = GetPlayer()->GetBattleGround(); + if (!bg) + continue; + + switch(achievementCriteria->referredAchievement) + { + case 161: // AB, Overcome a 500 resource disadvantage + { + if (bg->GetTypeID() != BATTLEGROUND_AB) + continue; + if(!((BattleGroundAB*)bg)->IsTeamScores500disadvantage(GetPlayer()->GetTeam())) + continue; + break; + } + case 156: // AB, win while controlling all 5 flags (all nodes) + case 784: // EY, win while holding 4 bases (all nodes) + { + if(!bg->IsAllNodesConrolledByTeam(GetPlayer()->GetTeam())) + continue; + break; + } + case 1762: // SA, win without losing any siege vehicles + case 2192: // SA, win without losing any siege vehicles + continue; // not implemented + } + } + + SetCriteriaProgress(achievementCriteria, miscvalue1, PROGRESS_ACCUMULATE); + break; + } case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: { // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case @@ -1347,6 +1407,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve switch(achievementCriteria->requiredType) { + case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: + return progress->counter >= achievementCriteria->win_bg.winCount; case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: return progress->counter >= achievementCriteria->kill_creature.creatureCount; case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL: @@ -1853,6 +1915,10 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData() switch(criteria->requiredType) { + case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: + if(!criteria->win_bg.additionalRequirement1_type) + continue; + break; case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: break; // any cases case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: diff --git a/src/game/AchievementMgr.h b/src/game/AchievementMgr.h index b790716b77a..6f30dbfa446 100644 --- a/src/game/AchievementMgr.h +++ b/src/game/AchievementMgr.h @@ -59,9 +59,10 @@ enum AchievementCriteriaDataType ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM = 14,// team HORDE(67), ALLIANCE(469) ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK = 15,// drunken_state 0 (enum DrunkenState) of player ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY = 16,// holiday_id 0 event in holiday time + ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE = 17,// min_score max_score player's team win bg and opposition team have team score in range }; -#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 17 // maximum value in AchievementCriteriaDataType enum +#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 18 // maximum value in AchievementCriteriaDataType enum class Player; class Unit; @@ -141,11 +142,17 @@ struct AchievementCriteriaData { uint32 state; } drunk; - // ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY + // ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY = 16 struct { - uint16 id; + uint32 id; } holiday; + // ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE= 17 + struct + { + uint32 min_score; + uint32 max_score; + } bg_loss_team_score; // ... struct { diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index c0af8af0e16..14778e9b471 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -476,7 +476,7 @@ void BattleGround::Update(uint32 diff) void BattleGround::SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, float O) { - uint8 idx = GetTeamIndexByTeamId(TeamID); + BattleGroundTeamId idx = GetTeamIndexByTeamId(TeamID); m_TeamStartLocX[idx] = X; m_TeamStartLocY[idx] = Y; m_TeamStartLocZ[idx] = Z; @@ -1878,3 +1878,9 @@ WorldSafeLocsEntry const* BattleGround::GetClosestGraveYard( Player* player ) { return objmgr.GetClosestGraveYard( player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), player->GetTeam() ); } + +bool BattleGround::IsTeamScoreInRange(uint32 team, uint32 minScore, uint32 maxScore) const +{ + BattleGroundTeamId team_idx = GetTeamIndexByTeamId(team); + return m_TeamScores[team_idx] >= minScore && m_TeamScores[team_idx] <= maxScore; +} diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h index 2d7419e8798..ab1a3d4b13c 100644 --- a/src/game/BattleGround.h +++ b/src/game/BattleGround.h @@ -298,6 +298,10 @@ class BattleGround virtual void StartingEventCloseDoors() {} virtual void StartingEventOpenDoors() {} + /* achievement req. */ + virtual bool IsAllNodesConrolledByTeam(uint32 /*team*/) const { return false; } + bool IsTeamScoreInRange(uint32 team, uint32 minScore, uint32 maxScore) const; + /* Battleground */ // Get methods: char const* GetName() const { return m_Name; } @@ -397,7 +401,7 @@ class BattleGround void SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, float O); void GetTeamStartLoc(uint32 TeamID, float &X, float &Y, float &Z, float &O) const { - uint8 idx = GetTeamIndexByTeamId(TeamID); + BattleGroundTeamId idx = GetTeamIndexByTeamId(TeamID); X = m_TeamStartLocX[idx]; Y = m_TeamStartLocY[idx]; Z = m_TeamStartLocZ[idx]; @@ -441,7 +445,7 @@ class BattleGround virtual void UpdatePlayerScore(Player *Source, uint32 type, uint32 value); - uint8 GetTeamIndexByTeamId(uint32 Team) const { return Team == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE; } + static BattleGroundTeamId GetTeamIndexByTeamId(uint32 Team) { return Team == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE; } uint32 GetPlayersCountByTeam(uint32 Team) const { return m_PlayersCount[GetTeamIndexByTeamId(Team)]; } uint32 GetAlivePlayersCountByTeam(uint32 Team) const; // used in arenas to correctly handle death in spirit of redemption / last stand etc. (killer = killed) cases void UpdatePlayersCountByTeam(uint32 Team, bool remove) diff --git a/src/game/BattleGroundAB.cpp b/src/game/BattleGroundAB.cpp index f5fba6f4186..0ed28112fe7 100644 --- a/src/game/BattleGroundAB.cpp +++ b/src/game/BattleGroundAB.cpp @@ -161,6 +161,18 @@ void BattleGroundAB::Update(uint32 diff) } } + // achievements flags + if (m_TeamScores[BG_TEAM_ALLIANCE] > m_TeamScores[BG_TEAM_HORDE]) + { + if (m_TeamScores[BG_TEAM_ALLIANCE] - m_TeamScores[BG_TEAM_HORDE] >= 500) + m_TeamScores500disadvantage[BG_TEAM_HORDE] = true; + } + else + { + if (m_TeamScores[BG_TEAM_HORDE] - m_TeamScores[BG_TEAM_ALLIANCE] >= 500) + m_TeamScores500disadvantage[BG_TEAM_ALLIANCE] = true; + } + // Test win condition if (m_TeamScores[BG_TEAM_ALLIANCE] >= BG_AB_MAX_TEAM_SCORE) EndBattleGround(ALLIANCE); @@ -428,7 +440,7 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ return; } - uint8 teamIndex = GetTeamIndexByTeamId(source->GetTeam()); + BattleGroundTeamId teamIndex = GetTeamIndexByTeamId(source->GetTeam()); // Check if player really could use this banner, not cheated if (!(m_Nodes[node] == 0 || teamIndex == m_Nodes[node]%2)) @@ -474,7 +486,7 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME; // FIXME: node names not localized - if (teamIndex == 0) + if (teamIndex == BG_TEAM_ALLIANCE) SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node)); else SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node)); @@ -491,15 +503,15 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ _CreateBanner(node, BG_AB_NODE_TYPE_OCCUPIED, teamIndex, true); _SendNodeUpdate(node); m_NodeTimers[node] = 0; - _NodeOccupied(node,(teamIndex == 0) ? ALLIANCE:HORDE); + _NodeOccupied(node,(teamIndex == BG_TEAM_ALLIANCE) ? ALLIANCE:HORDE); // FIXME: node names not localized - if (teamIndex == 0) + if (teamIndex == BG_TEAM_ALLIANCE) SendMessage2ToAll(LANG_BG_AB_NODE_DEFENDED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node)); else SendMessage2ToAll(LANG_BG_AB_NODE_DEFENDED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node)); } - sound = (teamIndex == 0) ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE; + sound = (teamIndex == BG_TEAM_ALLIANCE) ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE; } // If node is occupied, change to enemy-contested else @@ -516,19 +528,19 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME; // FIXME: node names not localized - if (teamIndex == 0) + if (teamIndex == BG_TEAM_ALLIANCE) SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node)); else SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node)); - sound = (teamIndex == 0) ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE; + sound = (teamIndex == BG_TEAM_ALLIANCE) ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE; } // If node is occupied again, send "X has taken the Y" msg. if (m_Nodes[node] >= BG_AB_NODE_TYPE_OCCUPIED) { // FIXME: team and node names not localized - if (teamIndex == 0) + if (teamIndex == BG_TEAM_ALLIANCE) SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN,CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL, LANG_BG_AB_ALLY, _GetNodeNameId(node)); else SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN,CHAT_MSG_BG_SYSTEM_HORDE, NULL, LANG_BG_AB_HORDE, _GetNodeNameId(node)); @@ -591,6 +603,8 @@ void BattleGroundAB::Reset() bool isBGWeekend = false; //TODO FIXME - call sBattleGroundMgr.IsBGWeekend(m_TypeID); - you must also implement that call! m_HonorTics = (isBGWeekend) ? BG_AB_ABBGWeekendHonorTicks : BG_AB_NotABBGWeekendHonorTicks; m_ReputationTics = (isBGWeekend) ? BG_AB_ABBGWeekendReputationTicks : BG_AB_NotABBGWeekendReputationTicks; + m_TeamScores500disadvantage[BG_TEAM_ALLIANCE] = false; + m_TeamScores500disadvantage[BG_TEAM_HORDE] = false; for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) { @@ -621,7 +635,7 @@ void BattleGroundAB::EndBattleGround(uint32 winner) WorldSafeLocsEntry const* BattleGroundAB::GetClosestGraveYard(Player* player) { - uint8 teamIndex = GetTeamIndexByTeamId(player->GetTeam()); + BattleGroundTeamId teamIndex = GetTeamIndexByTeamId(player->GetTeam()); // Is there any occupied node for this team? std::vector<uint8> nodes; @@ -679,3 +693,13 @@ void BattleGroundAB::UpdatePlayerScore(Player *Source, uint32 type, uint32 value } } +bool BattleGroundAB::IsAllNodesConrolledByTeam(uint32 team) const +{ + uint32 count = 0; + for(int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) + if (team == ALLIANCE && m_Nodes[i] == BG_AB_NODE_STATUS_ALLY_OCCUPIED || + team == HORDE && m_Nodes[i] == BG_AB_NODE_STATUS_HORDE_OCCUPIED) + ++count; + + return count == BG_AB_DYNAMIC_NODES_COUNT; +} diff --git a/src/game/BattleGroundAB.h b/src/game/BattleGroundAB.h index 876f17b47ba..1a940a041d4 100644 --- a/src/game/BattleGroundAB.h +++ b/src/game/BattleGroundAB.h @@ -262,6 +262,9 @@ class BattleGroundAB : public BattleGround /* Nodes occupying */ virtual void EventPlayerClickedOnFlag(Player *source, GameObject* target_obj); + /* achievement req. */ + bool IsAllNodesConrolledByTeam(uint32 team) const; // overwrited + bool IsTeamScores500disadvantage(uint32 team) const { return m_TeamScores500disadvantage[GetTeamIndexByTeamId(team)]; } private: /* Gameobject spawning/despawning */ void _CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool delay); @@ -291,8 +294,8 @@ class BattleGroundAB : public BattleGround bool m_IsInformedNearVictory; uint32 m_HonorTics; uint32 m_ReputationTics; - - + // need for achievements + bool m_TeamScores500disadvantage[BG_TEAMS_COUNT]; }; #endif diff --git a/src/game/BattleGroundEY.cpp b/src/game/BattleGroundEY.cpp index 9b54ecce643..39ef126d9e2 100644 --- a/src/game/BattleGroundEY.cpp +++ b/src/game/BattleGroundEY.cpp @@ -128,7 +128,7 @@ void BattleGroundEY::StartingEventOpenDoors() void BattleGroundEY::AddPoints(uint32 Team, uint32 Points) { - uint8 team_index = GetTeamIndexByTeamId(Team); + BattleGroundTeamId team_index = GetTeamIndexByTeamId(Team); m_TeamScores[team_index] += Points; m_HonorScoreTics[team_index] += Points; if (m_HonorScoreTics[team_index] >= m_HonorTics ) @@ -908,3 +908,12 @@ WorldSafeLocsEntry const *BattleGroundEY::GetClosestGraveYard(Player* player) return nearestEntry; } +bool BattleGroundEY::IsAllNodesConrolledByTeam(uint32 team) const +{ + uint32 count = 0; + for(int i = 0; i < EY_POINTS_MAX; ++i) + if (m_PointOwnedByTeam[i] == team && m_PointState[i] == EY_POINT_UNDER_CONTROL) + ++count; + + return count == EY_POINTS_MAX; +} diff --git a/src/game/BattleGroundEY.h b/src/game/BattleGroundEY.h index 2d0377ed8b2..3385a06bfb0 100644 --- a/src/game/BattleGroundEY.h +++ b/src/game/BattleGroundEY.h @@ -350,6 +350,8 @@ class BattleGroundEY : public BattleGround virtual void EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj); virtual void EventPlayerDroppedFlag(Player *Source); + /* achievement req. */ + bool IsAllNodesConrolledByTeam(uint32 team) const; private: void EventPlayerCapturedFlag(Player *Source, uint32 BgObjectType); void EventTeamCapturedPoint(Player *Source, uint32 Point); diff --git a/src/game/BattleGroundWS.h b/src/game/BattleGroundWS.h index a404b36d7e3..16631afecdc 100644 --- a/src/game/BattleGroundWS.h +++ b/src/game/BattleGroundWS.h @@ -200,7 +200,6 @@ class BattleGroundWS : public BattleGround void AddPoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] += Points; } void SetTeamPoint(uint32 TeamID, uint32 Points = 0) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] = Points; } void RemovePoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] -= Points; } - private: uint64 m_FlagKeepers[2]; // 0 - alliance, 1 - horde uint64 m_DroppedFlagGUID[2]; diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h index 910316881a4..a8b5d3ef177 100644 --- a/src/game/DBCStructure.h +++ b/src/game/DBCStructure.h @@ -84,11 +84,14 @@ struct AchievementCriteriaEntry } kill_creature; // ACHIEVEMENT_CRITERIA_TYPE_WIN_BG = 1 - // TODO: there are further criterias instead just winning struct { uint32 bgMapID; // 3 uint32 winCount; // 4 + uint32 additionalRequirement1_type; // 5 additional requirement 1 type + uint32 additionalRequirement1_value; // 6 additional requirement 1 value + uint32 additionalRequirement2_type; // 7 additional requirement 2 type + uint32 additionalRequirement2_value; // 8 additional requirement 1 value } win_bg; // ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL = 5 diff --git a/src/game/Makefile.am b/src/game/Makefile.am index 2e1d2a4bc0f..bc5dace3985 100644 --- a/src/game/Makefile.am +++ b/src/game/Makefile.am @@ -841,14 +841,6 @@ libmangosgame_a_SOURCES = \ GroupRefManager.h >>>>>>> 5a6594330caefc0dc00a5fe792dcb0e344b457cb:src/game/Makefile.am -## Link against shared library -libmangosgame_a_LIBADD = \ - ../shared/libmangosshared.a \ - ../shared/Auth/libmangosauth.a \ - ../shared/Config/libmangosconfig.a \ - ../shared/Database/libmangosdatabase.a \ - ../shared/vmap/libmangosvmaps.a - ## Additional files to include when running 'make dist' # Precompiled Headers for WIN EXTRA_DIST = \ |