From d6fafae9ba4adb846ac9fa2215a79873a2002ef7 Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Sat, 15 Dec 2018 22:47:05 +0100 Subject: [PATCH] Core/Guilds: merged and ported more guild achievement implementations --- .../game/Achievements/AchievementMgr.cpp | 31 +++++++++++++- src/server/game/Conditions/ConditionMgr.cpp | 8 +++- src/server/game/DataStores/DBCEnums.h | 6 +-- .../game/Entities/Player/KillRewarder.cpp | 40 +++++++++++++++---- src/server/game/Groups/Group.cpp | 20 +++++----- src/server/game/Handlers/CharacterHandler.cpp | 7 ++++ src/server/game/Spells/SpellEffects.cpp | 7 +++- 7 files changed, 93 insertions(+), 26 deletions(-) diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 1a2866a50e0..7b54fe62364 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -1262,6 +1262,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM: case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM: case ACHIEVEMENT_CRITERIA_TYPE_CURRENCY: + case ACHIEVEMENT_CRITERIA_TYPE_CRAFT_ITEMS_GUILD: case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ARCHAEOLOGY_PROJECTS: SetCriteriaProgress(achievementCriteria, miscValue2, referencePlayer, PROGRESS_ACCUMULATE); break; @@ -1354,7 +1355,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, break; case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION: { - int32 reputation = referencePlayer->GetReputationMgr().GetReputation(achievementCriteria->gain_reputation.factionID); + int32 reputation = referencePlayer->GetReputation(achievementCriteria->gain_reputation.factionID); if (reputation > 0) SetCriteriaProgress(achievementCriteria, reputation, referencePlayer); break; @@ -1490,7 +1491,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID: case ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA: case ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK: - case ACHIEVEMENT_CRITERIA_TYPE_CRAFT_ITEMS_GUILD: case ACHIEVEMENT_CRITERIA_TYPE_CATCH_FROM_POOL: case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_BATTLEGROUND: case ACHIEVEMENT_CRITERIA_TYPE_REACH_BG_RATING: @@ -1662,6 +1662,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achi return progress->counter >= achievementCriteria->get_killing_blow.killCount; case ACHIEVEMENT_CRITERIA_TYPE_CURRENCY: return progress->counter >= achievementCriteria->currencyGain.count; + case ACHIEVEMENT_CRITERIA_TYPE_CRAFT_ITEMS_GUILD: + return progress->counter >= achievementCriteria->raw.count; case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA: return achievementCriteria->win_arena.count && progress->counter >= achievementCriteria->win_arena.count; case ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN: @@ -2525,6 +2527,10 @@ bool AchievementMgr::RequirementsSatisfied(AchievementCriteriaEntry const* ac if (m_completedAchievements.find(achievementCriteria->complete_achievement.linkedAchievement) == m_completedAchievements.end()) return false; break; + case ACHIEVEMENT_CRITERIA_TYPE_CRAFT_ITEMS_GUILD: + if (!miscValue1 || !miscValue2) + return false; + break; case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: if (!miscValue1 || achievementCriteria->win_bg.bgMapID != referencePlayer->GetMapId()) return false; @@ -2829,6 +2835,13 @@ bool AchievementMgr::AdditionalRequirementsSatisfied(AchievementCriteriaEntry switch (AchievementCriteriaAdditionalCondition(reqType)) { + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_LEVEL: // 3 + { + ItemTemplate const* const item = sObjectMgr->GetItemTemplate(uint32(miscValue1)); + if (!item || item->ItemLevel < reqValue) + return false; + break; + } case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_ENTRY: // 4 if (!unit || unit->GetEntry() != reqValue) return false; @@ -2927,6 +2940,20 @@ bool AchievementMgr::AdditionalRequirementsSatisfied(AchievementCriteriaEntry if (referencePlayer->GetMapId() != reqValue) return false; break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_CLASS: // 33 + { + ItemTemplate const* const item = sObjectMgr->GetItemTemplate(uint32(miscValue1)); + if (!item || item->Class != reqValue) + return false; + break; + } + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_SUBCLASS: // 34 + { + ItemTemplate const* const item = sObjectMgr->GetItemTemplate(uint32(miscValue1)); + if (!item || item->SubClass != reqValue) + return false; + break; + } case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TITLE_BIT_INDEX: // 38 // miscValue1 is title's bit index if (miscValue1 != reqValue) diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 96f7347ed46..4c69cae38f7 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -21,6 +21,7 @@ #include "DatabaseEnv.h" #include "GameEventMgr.h" #include "GameObject.h" +#include "Guild.h" #include "InstanceScript.h" #include "Log.h" #include "LootMgr.h" @@ -174,7 +175,12 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const case CONDITION_ACHIEVEMENT: { if (Player* player = object->ToPlayer()) - condMeets = player->HasAchieved(ConditionValue1); + { + if (ConditionValue2 == 1) + condMeets = player->HasAchieved(ConditionValue1); + else if (Guild *guild = player->GetGuild()) + condMeets = guild->HasAchieved(ConditionValue1); + } break; } case CONDITION_TEAM: diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index 389ebb4208a..1a853ba0072 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -122,7 +122,7 @@ enum AchievementCriteriaAdditionalCondition { ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_DRUNK_VALUE = 1, // NYI ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK2 = 2, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_LEVEL = 3, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_LEVEL = 3, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_ENTRY = 4, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_PLAYER = 5, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_DEAD = 6, @@ -145,8 +145,8 @@ enum AchievementCriteriaAdditionalCondition ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAX_GROUP_MEMBERS = 29, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_TYPE = 30, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_MAP = 32, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_CLASS = 33, // NYI - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_SUBCLASS = 34, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_CLASS = 33, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_SUBCLASS = 34, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_COMPLETE_QUEST_NOT_IN_GROUP = 35, // NYI ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MIN_PERSONAL_RATING = 37, // NYI (when implementing don't forget about ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE) ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TITLE_BIT_INDEX = 38, diff --git a/src/server/game/Entities/Player/KillRewarder.cpp b/src/server/game/Entities/Player/KillRewarder.cpp index 27022e731be..280d8d7f3b5 100644 --- a/src/server/game/Entities/Player/KillRewarder.cpp +++ b/src/server/game/Entities/Player/KillRewarder.cpp @@ -239,6 +239,8 @@ void KillRewarder::_RewardGroup() } // 3.1.3. Reward each group member (even dead or corpse) within reward distance. + // 3.1.4. Update guild achievements. + std::vector guildList; for (GroupReference* itr = _group->GetFirstMember(); itr != nullptr; itr = itr->next()) { if (Player* member = itr->GetSource()) @@ -248,6 +250,26 @@ void KillRewarder::_RewardGroup() { _RewardPlayer(member, isDungeon); member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, 0, _victim); + + bool guildAlreadyUpdated = false; + for (auto itr : guildList) + { + if (itr == member->GetGuildId()) + guildAlreadyUpdated = true; + } + + if (!guildAlreadyUpdated) + { + if (Creature* victim = _victim->ToCreature()) + { + if (Guild* guild = member->GetGuild()) + { + guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, victim->GetEntry(), 1, 0, victim, member); + guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE_GUILD, 0, 0, 0, victim, member); + guildList.push_back(member->GetGuildId()); + } + } + } } } } @@ -302,21 +324,23 @@ void KillRewarder::Reward() if (!_isBattleGround || _xp) // 3.2.2. Reward killer. _RewardPlayer(_killer, false); + + if (Creature* victim = _victim->ToCreature()) + { + if (Guild* guild = _killer->GetGuild()) + { + guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, victim->GetEntry(), 1, 0, victim, _killer); + guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE_GUILD, 0, 0, 0, victim, _killer); + } + } } // 5. Credit instance encounter. - // 6. Update guild achievements. if (Creature* victim = _victim->ToCreature()) { if (victim->IsDungeonBoss()) - if (InstanceScript* instance = _victim->GetInstanceScript()) + if (InstanceScript* instance = victim->GetInstanceScript()) instance->UpdateEncounterStateForKilledCreature(_victim->GetEntry(), _victim); - - if (Guild* guild = _killer->GetGuild()) - { - guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, victim->GetEntry(), 1, 0, victim, _killer); - guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE_GUILD, 0, 0, 0, victim, _killer); - } } } diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 3fdbf79c3c4..2a31e08f264 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -1877,16 +1877,6 @@ bool Group::_setMembersGroup(ObjectGuid guid, uint8 group) return true; } -bool Group::MemberLevelIsInRange(uint32 levelMin, uint32 levelMax) -{ - for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr) - if (Player *member = ObjectAccessor::FindPlayer(itr->guid)) - if (member->getLevel() < levelMin || member->getLevel() > levelMax) - return false; - - return true; -} - bool Group::IsGuildGroupFor(Player* player) { if (!IsMember(player->GetGUID())) @@ -1973,6 +1963,16 @@ float Group::GetGuildXpRateForPlayer(Player* player) return 1.0f; } +bool Group::MemberLevelIsInRange(uint32 levelMin, uint32 levelMax) +{ + for (auto itr : m_memberSlots) + if (Player* member = ObjectAccessor::FindPlayer(itr.guid)) + if (member->getLevel() < levelMin || member->getLevel() > levelMax) + return false; + + return true; +} + void Group::UpdateGuildFor(ObjectGuid guid, uint32 guildId) { for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr) diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index b2e573dd376..6e67e8a01ad 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -894,7 +894,14 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt8()); if (Guild* guild = sGuildMgr->GetGuildById(pCurrChar->GetGuildId())) + { pCurrChar->SetGuildLevel(guild->GetLevel()); + + guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL, 0, 0, 0, nullptr, pCurrChar); + guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, 0, 0, 0, nullptr, pCurrChar); + guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION, 0, 0, 0, nullptr, pCurrChar); + guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION, 0, 0, 0, nullptr, pCurrChar); + } } else if (pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about non existed membership { diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 4dc4fcc2842..b712da04c75 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -1432,10 +1432,13 @@ void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype) // send info to the client player->SendNewItem(pItem, num_to_add, true, bgType == 0); - if (pProto->Quality > ITEM_QUALITY_EPIC || (pProto->Quality == ITEM_QUALITY_EPIC && pProto->ItemLevel >= MinNewsItemLevel[sWorld->getIntConfig(CONFIG_EXPANSION)])) - if (Guild* guild = player->GetGuild()) + if (Guild* guild = player->GetGuild()) + { + if (pProto->Quality > ITEM_QUALITY_EPIC || (pProto->Quality == ITEM_QUALITY_EPIC && pProto->ItemLevel >= MinNewsItemLevel[sWorld->getIntConfig(CONFIG_EXPANSION)])) guild->AddGuildNews(GUILD_NEWS_ITEM_CRAFTED, player->GetGUID(), 0, pProto->ItemId); + guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CRAFT_ITEMS_GUILD, pItem->GetEntry(), num_to_add, 0, nullptr, player); + } // we succeeded in creating at least one item, so a levelup is possible if (bgType == 0)