diff options
-rw-r--r-- | src/server/game/Achievements/AchievementMgr.cpp | 5 | ||||
-rw-r--r-- | src/server/game/Achievements/AchievementMgr.h | 1 | ||||
-rw-r--r-- | src/server/game/Achievements/CriteriaHandler.cpp | 980 | ||||
-rw-r--r-- | src/server/game/Achievements/CriteriaHandler.h | 3 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCEnums.h | 277 | ||||
-rw-r--r-- | src/server/game/Entities/Item/AzeriteItem/AzeriteItem.cpp | 9 | ||||
-rw-r--r-- | src/server/game/Entities/Item/AzeriteItem/AzeriteItem.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateField.h | 5 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 12 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 2 | ||||
-rw-r--r-- | src/server/game/Garrison/Garrison.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Garrison/Garrison.h | 1 | ||||
-rw-r--r-- | src/server/game/Scenarios/Scenario.cpp | 5 | ||||
-rw-r--r-- | src/server/game/Scenarios/Scenario.h | 1 |
14 files changed, 1232 insertions, 79 deletions
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index da0d8264576..91d527d90ef 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -549,7 +549,10 @@ void PlayerAchievementMgr::CompletedAchievement(AchievementEntry const* achievem bool PlayerAchievementMgr::ModifierTreeSatisfied(uint32 modifierTreeId) const { - return AdditionalRequirementsSatisfied(sCriteriaMgr->GetModifierTree(modifierTreeId), 0, 0, nullptr, _owner); + if (ModifierTreeNode const* modifierTree = sCriteriaMgr->GetModifierTree(modifierTreeId)) + return ModifierTreeSatisfied(modifierTree, 0, 0, nullptr, _owner); + + return false; } void PlayerAchievementMgr::SendCriteriaUpdate(Criteria const* criteria, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted) const diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h index 5978da0ab8d..b4b59419d2d 100644 --- a/src/server/game/Achievements/AchievementMgr.h +++ b/src/server/game/Achievements/AchievementMgr.h @@ -91,6 +91,7 @@ public: void CompletedAchievement(AchievementEntry const* entry, Player* referencePlayer) override; + using CriteriaHandler::ModifierTreeSatisfied; bool ModifierTreeSatisfied(uint32 modifierTreeId) const; protected: diff --git a/src/server/game/Achievements/CriteriaHandler.cpp b/src/server/game/Achievements/CriteriaHandler.cpp index aed59d63830..bbbc1d75988 100644 --- a/src/server/game/Achievements/CriteriaHandler.cpp +++ b/src/server/game/Achievements/CriteriaHandler.cpp @@ -16,8 +16,13 @@ */ #include "CriteriaHandler.h" +#include "AchievementMgr.h" #include "ArenaTeamMgr.h" +#include "AzeriteItem.h" +#include "BattlefieldMgr.h" #include "Battleground.h" +#include "BattlePetMgr.h" +#include "CollectionMgr.h" #include "DatabaseEnv.h" #include "DB2Stores.h" #include "DisableMgr.h" @@ -25,11 +30,15 @@ #include "Garrison.h" #include "Group.h" #include "InstanceScript.h" +#include "Item.h" #include "Log.h" #include "MapManager.h" #include "ObjectMgr.h" +#include "PhasingHandler.h" #include "Player.h" +#include "RealmList.h" #include "ReputationMgr.h" +#include "Scenario.h" #include "ScriptMgr.h" #include "SpellInfo.h" #include "SpellMgr.h" @@ -591,16 +600,23 @@ void CriteriaHandler::UpdateCriteria(CriteriaTypes type, uint64 miscValue1 /*= 0 } case CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE: { - uint32 counter = 0; - - const RewardedQuestSet &rewQuests = referencePlayer->getRewardedQuests(); - for (RewardedQuestSet::const_iterator itr = rewQuests.begin(); itr != rewQuests.end(); ++itr) + if (miscValue1) + { + SetCriteriaProgress(criteria, 1, referencePlayer, PROGRESS_ACCUMULATE); + } + else // login case { - Quest const* quest = sObjectMgr->GetQuestTemplate(*itr); - if (quest && quest->GetZoneOrSort() >= 0 && quest->GetZoneOrSort() == criteria->Entry->Asset.ZoneID) - ++counter; + uint32 counter = 0; + + const RewardedQuestSet& rewQuests = referencePlayer->getRewardedQuests(); + for (RewardedQuestSet::const_iterator itr = rewQuests.begin(); itr != rewQuests.end(); ++itr) + { + Quest const* quest = sObjectMgr->GetQuestTemplate(*itr); + if (quest && quest->GetZoneOrSort() >= 0 && quest->GetZoneOrSort() == criteria->Entry->Asset.ZoneID) + ++counter; + } + SetCriteriaProgress(criteria, counter, referencePlayer, PROGRESS_HIGHEST); } - SetCriteriaProgress(criteria, counter, referencePlayer); break; } case CRITERIA_TYPE_FALL_WITHOUT_DYING: @@ -1238,7 +1254,7 @@ bool CriteriaHandler::CanUpdateCriteria(Criteria const* criteria, CriteriaTreeLi return false; } - if (criteria->Modifier && !AdditionalRequirementsSatisfied(criteria->Modifier, miscValue1, miscValue2, unit, referencePlayer)) + if (criteria->Modifier && !ModifierTreeSatisfied(criteria->Modifier, miscValue1, miscValue2, unit, referencePlayer)) { TC_LOG_TRACE("criteria", "CriteriaHandler::CanUpdateCriteria: (Id: %u Type %s) Requirements have not been satisfied", criteria->ID, CriteriaMgr::GetCriteriaTypeString(criteria->Entry->Type)); return false; @@ -1352,8 +1368,12 @@ bool CriteriaHandler::RequirementsSatisfied(Criteria const* criteria, uint64 mis return false; break; case CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE: - if (miscValue1 && miscValue1 != uint32(criteria->Entry->Asset.ZoneID)) - return false; + if (miscValue1) + { + Quest const* quest = sObjectMgr->GetQuestTemplate(miscValue1); + if (!quest || quest->GetZoneOrSort() != criteria->Entry->Asset.ZoneID) + return false; + } break; case CRITERIA_TYPE_DEATH: { @@ -1570,20 +1590,51 @@ bool CriteriaHandler::RequirementsSatisfied(Criteria const* criteria, uint64 mis return true; } -bool CriteriaHandler::AdditionalRequirementsSatisfied(ModifierTreeNode const* tree, uint64 miscValue1, uint64 miscValue2, Unit const* unit, Player* referencePlayer) const +bool CriteriaHandler::ModifierTreeSatisfied(ModifierTreeNode const* tree, uint64 miscValue1, uint64 miscValue2, Unit const* unit, Player* referencePlayer) const { - for (ModifierTreeNode const* node : tree->Children) - if (!AdditionalRequirementsSatisfied(node, miscValue1, miscValue2, unit, referencePlayer)) + switch (ModifierTreeOperator(tree->Entry->Operator)) + { + case ModifierTreeOperator::SingleTrue: + return tree->Entry->Type && ModifierSatisfied(tree->Entry, miscValue1, miscValue2, unit, referencePlayer); + case ModifierTreeOperator::SingleFalse: + return tree->Entry->Type && !ModifierSatisfied(tree->Entry, miscValue1, miscValue2, unit, referencePlayer); + case ModifierTreeOperator::All: + for (ModifierTreeNode const* node : tree->Children) + if (!ModifierTreeSatisfied(node, miscValue1, miscValue2, unit, referencePlayer)) + return false; + return true; + case ModifierTreeOperator::Some: + { + int8 requiredAmount = std::max<int8>(tree->Entry->Amount, 1); + for (ModifierTreeNode const* node : tree->Children) + if (ModifierTreeSatisfied(node, miscValue1, miscValue2, unit, referencePlayer)) + if (!--requiredAmount) + return true; + return false; + } + default: + break; + } - uint32 reqType = tree->Entry->Type; - if (!reqType) - return true; + return false; +} - uint32 reqValue = tree->Entry->Asset; +bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint64 miscValue1, uint64 miscValue2, Unit const* unit, Player* referencePlayer) const +{ + uint32 reqValue = modifier->Asset; + uint32 secondaryAsset = modifier->SecondaryAsset; + uint32 tertiaryAsset = modifier->TertiaryAsset; - switch (CriteriaAdditionalCondition(reqType)) + switch (CriteriaAdditionalCondition(modifier->Type)) { + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_DRUNK_VALUE: // 1 + { + uint32 inebriation = std::min(std::max<uint32>(referencePlayer->GetDrunkValue(), *referencePlayer->m_playerData->FakeInebriation), 100u); + if (inebriation < reqValue) + return false; + break; + } case CRITERIA_ADDITIONAL_CONDITION_SOURCE_PLAYER_CONDITION: // 2 { PlayerConditionEntry const* playerCondition = sPlayerConditionStore.LookupEntry(reqValue); @@ -1655,6 +1706,10 @@ bool CriteriaHandler::AdditionalRequirementsSatisfied(ModifierTreeNode const* tr return false; break; } + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_IS_ALIVE: // 16 + if (referencePlayer->isDead()) + return false; + break; case CRITERIA_ADDITIONAL_CONDITION_SOURCE_AREA_OR_ZONE: // 17 { uint32 zoneId, areaId; @@ -1680,6 +1735,14 @@ bool CriteriaHandler::AdditionalRequirementsSatisfied(ModifierTreeNode const* tr return false; break; } + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL_ABOVE_TARGET: // 22 + if (!unit || referencePlayer->getLevel() + reqValue < unit->getLevel()) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL_EQUAL_TARGET: // 23 + if (!unit || referencePlayer->getLevel() != unit->getLevel()) + return false; + break; case CRITERIA_ADDITIONAL_CONDITION_ARENA_TYPE: // 24 { Battleground* bg = referencePlayer->GetBattleground(); @@ -1715,10 +1778,35 @@ bool CriteriaHandler::AdditionalRequirementsSatisfied(ModifierTreeNode const* tr return false; break; } + case CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_FAMILY: // 31 + { + if (!unit) + return false; + if (unit->GetTypeId() != TYPEID_UNIT || unit->ToCreature()->GetCreatureTemplate()->family != CreatureFamily(reqValue)) + return false; + break; + } case CRITERIA_ADDITIONAL_CONDITION_SOURCE_MAP: // 32 if (referencePlayer->GetMapId() != reqValue) return false; break; + case CRITERIA_ADDITIONAL_CONDITION_CLIENT_VERSION: // 33 + if (reqValue < sRealmList->GetMinorMajorBugfixVersionForBuild(realm.Build)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_BATTLE_PET_TEAM_LEVEL: // 34 + for (WorldPackets::BattlePet::BattlePetSlot const& slot : referencePlayer->GetSession()->GetBattlePetMgr()->GetSlots()) + if (slot.Pet.Level != reqValue) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_NOT_IN_GROUP: // 35 + if (referencePlayer->GetGroup()) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_IN_GROUP: // 36 + if (!referencePlayer->GetGroup()) + return false; + break; case CRITERIA_ADDITIONAL_CONDITION_TITLE_BIT_INDEX: // 38 // miscValue1 is title's bit index if (miscValue1 != reqValue) @@ -1732,12 +1820,74 @@ bool CriteriaHandler::AdditionalRequirementsSatisfied(ModifierTreeNode const* tr if (!unit || unit->GetLevelForTarget(referencePlayer) != reqValue) return false; break; - case CRITERIA_ADDITIONAL_CONDITION_TARGET_ZONE: // 41 - if (!unit || unit->GetZoneId() != reqValue) + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_ZONE: // 41 + { + uint32 zoneId = referencePlayer->GetAreaId(); + if (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(zoneId)) + if (areaEntry->Flags[0] & AREA_FLAG_UNK9) + zoneId = areaEntry->ParentAreaID; + if (zoneId != reqValue) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_TARGET_ZONE: // 42 + { + if (!unit) + return false; + uint32 zoneId = unit->GetAreaId(); + if (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(zoneId)) + if (areaEntry->Flags[0] & AREA_FLAG_UNK9) + zoneId = areaEntry->ParentAreaID; + if (zoneId != reqValue) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_HEALTH_PCT_LOWER: // 43 + if (referencePlayer->GetHealthPct() > float(reqValue)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_HEALTH_PCT_GREATER: // 44 + if (referencePlayer->GetHealthPct() < float(reqValue)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_HEALTH_PCT_EQUAL: // 45 + if (referencePlayer->GetHealthPct() != float(reqValue)) return false; break; - case CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PERCENT_BELOW: // 46 - if (!unit || unit->GetHealthPct() >= reqValue) + case CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PCT_LOWER: // 46 + if (!unit || unit->GetHealthPct() > float(reqValue)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PCT_GREATER: // 47 + if (!unit || unit->GetHealthPct() < float(reqValue)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PCT_EQUAL: // 48 + if (!unit || unit->GetHealthPct() != float(reqValue)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_HEALTH_LOWER: // 49 + if (referencePlayer->GetHealth() > reqValue) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_HEALTH_GREATER: // 50 + if (referencePlayer->GetHealth() < reqValue) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_HEALTH_EQUAL: // 51 + if (referencePlayer->GetHealth() != reqValue) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_LOWER: // 52 + if (!unit || unit->GetHealth() > reqValue) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_GREATER: // 53 + if (!unit || unit->GetHealth() < reqValue) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_EQUAL: // 54 + if (!unit || unit->GetHealth() != reqValue) return false; break; case CRITERIA_ADDITIONAL_CONDITION_TARGET_PLAYER_CONDITION: // 55 @@ -1750,10 +1900,34 @@ bool CriteriaHandler::AdditionalRequirementsSatisfied(ModifierTreeNode const* tr return false; break; } + case CRITERIA_ADDITIONAL_CONDITION_MIN_ACHIEVEMENT_POINTS: // 56 + if (referencePlayer->GetAchievementPoints() <= reqValue) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_IN_LFG_DUNGEON: // 57 + if (!ConditionMgr::GetPlayerConditionLfgValue(referencePlayer, PlayerConditionLfgStatus::InLFGDungeon)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_IN_LFG_RANDOM_DUNGEON: // 58 + if (!ConditionMgr::GetPlayerConditionLfgValue(referencePlayer, PlayerConditionLfgStatus::InLFGRandomDungeon)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_IN_LFG_FIRST_RANDOM_DUNGEON: // 59 + if (!ConditionMgr::GetPlayerConditionLfgValue(referencePlayer, PlayerConditionLfgStatus::InLFGFirstRandomDungeon)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_GUILD_REPUTATION: // 62 + if (referencePlayer->GetReputationMgr().GetReputation(1168) < int32(reqValue)) + return false; + break; case CRITERIA_ADDITIONAL_CONDITION_RATED_BATTLEGROUND_RATING: // 64 if (referencePlayer->GetRBGPersonalRating() < reqValue) return false; break; + case CRITERIA_ADDITIONAL_CONDITION_WORLD_STATE_EXPRESSION: // 67 + if (WorldStateExpressionEntry const* worldStateExpression = sWorldStateExpressionStore.LookupEntry(reqValue)) + return ConditionMgr::IsPlayerMeetingExpression(referencePlayer, worldStateExpression); + return false; case CRITERIA_ADDITIONAL_CONDITION_MAP_DIFFICULTY: // 68 { DifficultyEntry const* difficulty = sDifficultyStore.LookupEntry(referencePlayer->GetMap()->GetDifficultyID()); @@ -1761,10 +1935,112 @@ bool CriteriaHandler::AdditionalRequirementsSatisfied(ModifierTreeNode const* tr return false; break; } + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL_GREATER: // 69 + if (referencePlayer->getLevel() < reqValue) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_TARGET_LEVEL_GREATER: // 70 + if (!unit || unit->getLevel() < reqValue) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL_LOWER: // 71 + if (referencePlayer->getLevel() > reqValue) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_TARGET_LEVEL_LOWER: // 72 + if (!unit || unit->getLevel() > reqValue) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_MODIFIER_TREE: // 73 + if (ModifierTreeNode const* nextModifierTree = sCriteriaMgr->GetModifierTree(reqValue)) + return ModifierTreeSatisfied(nextModifierTree, miscValue1, miscValue2, unit, referencePlayer); + return false; + case CRITERIA_ADDITIONAL_CONDITION_SCENARIO_ID: // 74 + { + Scenario const* scenario = referencePlayer->GetScenario(); + if (!scenario) + return false; + if (scenario->GetEntry()->ID != reqValue) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_THE_TILLERS_REPUTATION: // 75 + if (referencePlayer->GetReputationMgr().GetReputation(1272) < int32(reqValue)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_SCENARIO_STEP_INDEX: // 82 + { + Scenario const* scenario = referencePlayer->GetScenario(); + if (!scenario) + return false; + if (scenario->GetStep()->OrderIndex != (reqValue - 1)) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_IS_ON_QUEST: // 84 + if (referencePlayer->FindQuestSlot(reqValue) == MAX_QUEST_LOG_SIZE) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_EXALTED_WITH_FACTION: // 85 + if (referencePlayer->GetReputationMgr().GetReputation(reqValue) < 42000) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_HAS_ACHIEVEMENT: // 86 + if (!referencePlayer->HasAchieved(reqValue)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_CLOUD_SERPENT_REPUTATION: // 88 + if (referencePlayer->GetReputationMgr().GetReputation(1271) < int32(reqValue)) + return false; + break; case CRITERIA_ADDITIONAL_CONDITION_BATTLE_PET_SPECIES: // 91 if (miscValue1 != reqValue) return false; break; + case CRITERIA_ADDITIONAL_CONDITION_ACTIVE_EXPANSION: // 92 + if (referencePlayer->GetSession()->GetExpansion() < reqValue) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_FACTION_STANDING: // 95 + if (referencePlayer->GetReputationMgr().GetReputation(reqValue) < int32(secondaryAsset)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_SEX: // 97 + if (referencePlayer->getGender() != uint8(reqValue)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_NATIVE_SEX: // 98 + if (referencePlayer->m_playerData->NativeSex != uint8(reqValue)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_SKILL: // 99 + if (referencePlayer->GetPureSkillValue(reqValue) < uint16(secondaryAsset)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_NORMAL_PHASE_SHIFT: // 101 + if (!PhasingHandler::InDbPhaseShift(referencePlayer, 0, 0, 0)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_IN_PHASE: // 102 + if (!PhasingHandler::InDbPhaseShift(referencePlayer, 0, reqValue, 0)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_NOT_IN_PHASE: // 103 + if (PhasingHandler::InDbPhaseShift(referencePlayer, 0, reqValue, 0)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_HAS_SPELL: // 104 + if (!referencePlayer->HasSpell(reqValue)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_ITEM_COUNT: // 105 + if (referencePlayer->GetItemCount(reqValue, false) < secondaryAsset) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_ACCOUNT_EXPANSION: // 106 + if (referencePlayer->GetSession()->GetAccountExpansion() < reqValue) + return false; + break; case CRITERIA_ADDITIONAL_CONDITION_REWARDED_QUEST: // 110 if (!referencePlayer->GetQuestRewardStatus(reqValue)) return false; @@ -1773,62 +2049,676 @@ bool CriteriaHandler::AdditionalRequirementsSatisfied(ModifierTreeNode const* tr if (referencePlayer->GetQuestStatus(reqValue) != QUEST_STATUS_COMPLETE) return false; break; - case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_ENTRY: // 144 + case CRITERIA_ADDITIONAL_CONDITION_EXPLORED_AREA: // 113 + { + AreaTableEntry const* areaTable = sAreaTableStore.LookupEntry(reqValue); + if (!areaTable) + return false; + if (areaTable->AreaBit <= 0) + break; // success + uint32 playerIndexOffset = uint32(areaTable->AreaBit) / 64; + if (playerIndexOffset >= PLAYER_EXPLORED_ZONES_SIZE) + break; + if (!(referencePlayer->m_activePlayerData->ExploredZones[playerIndexOffset] & (UI64LIT(1) << (areaTable->AreaBit % 64)))) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_ITEM_COUNT_INCLUDING_BANK: // 114 + if (referencePlayer->GetItemCount(reqValue, true) < secondaryAsset) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_PVP_FACTION_INDEX: // 116 + { + ChrRacesEntry const* race = sChrRacesStore.LookupEntry(referencePlayer->getRace()); + if (!race) + return false; + FactionTemplateEntry const* faction = sFactionTemplateStore.LookupEntry(race->FactionID); + if (!faction) + return false; + int32 factionIndex = -1; + if (faction->FactionGroup & FACTION_MASK_HORDE) + factionIndex = 0; + else if (faction->FactionGroup & FACTION_MASK_ALLIANCE) + factionIndex = 1; + else if (faction->FactionGroup & FACTION_MASK_PLAYER) + factionIndex = 0; + if (factionIndex != int32(reqValue)) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_LFG_VALUE_EQUAL: // 117 + if (ConditionMgr::GetPlayerConditionLfgValue(referencePlayer, PlayerConditionLfgStatus(reqValue)) != secondaryAsset) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_LFG_VALUE_GREATER: // 118 + if (ConditionMgr::GetPlayerConditionLfgValue(referencePlayer, PlayerConditionLfgStatus(reqValue)) < secondaryAsset) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_CURRENCY_AMOUNT: // 119 + if (!referencePlayer->HasCurrency(reqValue, secondaryAsset)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_CURRENCY_TRACKED_AMOUNT: // 121 + if (referencePlayer->GetTrackedCurrencyCount(reqValue) < secondaryAsset) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_MAP_INSTANCE_TYPE: // 122 + if (referencePlayer->GetMap()->GetEntry()->InstanceType != int8(reqValue)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_MENTOR: // 123 + if (!referencePlayer->HasPlayerFlag(PLAYER_FLAGS_MENTOR)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_LEVEL_ABOVE: // 126 + { + Garrison const* garrison = referencePlayer->GetGarrison(); + if (!garrison || garrison->GetType() != GarrisonType(secondaryAsset) || garrison->GetSiteLevel()->GarrLevel < reqValue) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWERS_ABOVE_LEVEL: // 127 + { + Garrison const* garrison = referencePlayer->GetGarrison(); + if (!garrison || garrison->GetType() != GarrisonType(tertiaryAsset)) + return false; + uint32 followerCount = garrison->CountFollowers([secondaryAsset](Garrison::Follower const& follower) + { + return follower.PacketInfo.FollowerLevel >= secondaryAsset; + }); + if (followerCount < reqValue) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWERS_ABOVE_QUALITY: // 128 + { + Garrison const* garrison = referencePlayer->GetGarrison(); + if (!garrison || garrison->GetType() != GarrisonType(tertiaryAsset)) + return false; + uint32 followerCount = garrison->CountFollowers([secondaryAsset](Garrison::Follower const& follower) + { + return follower.PacketInfo.Quality >= secondaryAsset; + }); + if (followerCount < reqValue) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_ABOVE_LEVEL_WITH_ABILITY: // 129 + { + Garrison const* garrison = referencePlayer->GetGarrison(); + if (!garrison || garrison->GetType() != GarrisonType(tertiaryAsset)) + return false; + uint32 followerCount = garrison->CountFollowers([reqValue, secondaryAsset](Garrison::Follower const& follower) + { + return follower.PacketInfo.FollowerLevel >= reqValue && follower.HasAbility(secondaryAsset); + }); + if (followerCount < 1) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_ABOVE_LEVEL_WITH_TRAIT: // 130 + { + Garrison const* garrison = referencePlayer->GetGarrison(); + if (!garrison || garrison->GetType() != GarrisonType(tertiaryAsset)) + return false; + GarrAbilityEntry const* traitEntry = sGarrAbilityStore.LookupEntry(secondaryAsset); + if (!traitEntry || !(traitEntry->Flags & GARRISON_ABILITY_FLAG_TRAIT)) + return false; + uint32 followerCount = garrison->CountFollowers([reqValue, secondaryAsset](Garrison::Follower const& follower) + { + return follower.PacketInfo.FollowerLevel >= reqValue && follower.HasAbility(secondaryAsset); + }); + if (followerCount < 1) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_WITH_ABILITY_IN_BUILDING: // 131 + { + Garrison const* garrison = referencePlayer->GetGarrison(); + if (!garrison || garrison->GetType() != GarrisonType(tertiaryAsset)) + return false; + uint32 followerCount = garrison->CountFollowers([reqValue, secondaryAsset](Garrison::Follower const& follower) + { + GarrBuildingEntry const* followerBuilding = sGarrBuildingStore.LookupEntry(follower.PacketInfo.CurrentBuildingID); + if (!followerBuilding) + return false; + return followerBuilding->BuildingType == secondaryAsset && follower.HasAbility(reqValue);; + }); + if (followerCount < 1) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_WITH_TRAIT_IN_BUILDING: // 132 { - if (!referencePlayer) + Garrison const* garrison = referencePlayer->GetGarrison(); + if (!garrison || garrison->GetType() != GarrisonType(tertiaryAsset)) return false; + GarrAbilityEntry const* traitEntry = sGarrAbilityStore.LookupEntry(reqValue); + if (!traitEntry || !(traitEntry->Flags & GARRISON_ABILITY_FLAG_TRAIT)) + return false; + uint32 followerCount = garrison->CountFollowers([reqValue, secondaryAsset](Garrison::Follower const& follower) + { + GarrBuildingEntry const* followerBuilding = sGarrBuildingStore.LookupEntry(follower.PacketInfo.CurrentBuildingID); + if (!followerBuilding) + return false; + return followerBuilding->BuildingType == secondaryAsset && follower.HasAbility(reqValue);; + }); + if (followerCount < 1) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_ABOVE_LEVEL_IN_BUILDING: // 133 + { + Garrison const* garrison = referencePlayer->GetGarrison(); + if (!garrison || garrison->GetType() != GarrisonType(tertiaryAsset)) + return false; + uint32 followerCount = garrison->CountFollowers([reqValue, secondaryAsset](Garrison::Follower const& follower) + { + if (follower.PacketInfo.FollowerLevel < reqValue) + return false; + GarrBuildingEntry const* followerBuilding = sGarrBuildingStore.LookupEntry(follower.PacketInfo.CurrentBuildingID); + if (!followerBuilding) + return false; + return followerBuilding->BuildingType == secondaryAsset; + }); + if (followerCount < 1) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_BUILDING_ABOVE_LEVEL: // 134 + { Garrison* garrison = referencePlayer->GetGarrison(); - if (!garrison) + if (!garrison || garrison->GetType() != GarrisonType(tertiaryAsset)) return false; - Garrison::Follower const* follower = garrison->GetFollower(miscValue1); - if (!follower || follower->PacketInfo.GarrFollowerID != reqValue) + for (Garrison::Plot const* plot : garrison->GetPlots()) + { + if (!plot->BuildingInfo.PacketInfo) + continue; + + GarrBuildingEntry const* building = sGarrBuildingStore.LookupEntry(plot->BuildingInfo.PacketInfo->GarrBuildingID); + if (!building || building->UpgradeLevel < reqValue || building->BuildingType != secondaryAsset) + continue; + + return true; + } + return false; + } + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_BLUEPRINT: // 135 + { + GarrBuildingEntry const* blueprintBuilding = sGarrBuildingStore.LookupEntry(reqValue); + if (!blueprintBuilding) + return false; + Garrison const* garrison = referencePlayer->GetGarrison(); + if (!garrison || garrison->GetType() != GarrisonType(blueprintBuilding->GarrTypeID)) + return false; + if (!garrison->HasBlueprint(reqValue)) return false; break; } - case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_QUALITY: // 145 + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_BUILDING_INACTIVE: // 140 { - if (!referencePlayer) + GarrBuildingEntry const* building = sGarrBuildingStore.LookupEntry(reqValue); + if (!building) return false; Garrison* garrison = referencePlayer->GetGarrison(); - if (!garrison) + if (!garrison || garrison->GetType() != GarrisonType(tertiaryAsset)) return false; - Garrison::Follower const* follower = garrison->GetFollower(miscValue1); - if (!follower || follower->PacketInfo.Quality != reqValue) + for (Garrison::Plot const* plot : garrison->GetPlots()) + { + if (!plot->BuildingInfo.PacketInfo || plot->BuildingInfo.PacketInfo->GarrBuildingID != reqValue) + continue; + + return !plot->BuildingInfo.PacketInfo->Active; + } + return false; + } + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_BUILDING_EQUAL_LEVEL: // 142 + { + Garrison* garrison = referencePlayer->GetGarrison(); + if (!garrison || garrison->GetType() != GarrisonType(tertiaryAsset)) return false; + for (Garrison::Plot const* plot : garrison->GetPlots()) + { + if (!plot->BuildingInfo.PacketInfo) + continue; + GarrBuildingEntry const* building = sGarrBuildingStore.LookupEntry(plot->BuildingInfo.PacketInfo->GarrBuildingID); + if (!building || building->UpgradeLevel != reqValue || building->BuildingType != secondaryAsset) + continue; + + return true; + } + return false; + } + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_WITH_ABILITY: // 143 + { + Garrison const* garrison = referencePlayer->GetGarrison(); + if (!garrison || garrison->GetType() != GarrisonType(secondaryAsset)) + return false; + if (miscValue1) + { + Garrison::Follower const* follower = garrison->GetFollower(miscValue1); + if (!follower) + return false; + if (!follower->HasAbility(reqValue)) + return false; + } + else + { + uint32 followerCount = garrison->CountFollowers([reqValue](Garrison::Follower const& follower) + { + return follower.HasAbility(reqValue); + }); + if (followerCount < 1) + return false; + } break; } - case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_LEVEL: // 146 + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_WITH_TRAIT: // 144 { - if (!referencePlayer) + GarrAbilityEntry const* traitEntry = sGarrAbilityStore.LookupEntry(reqValue); + if (!traitEntry || !(traitEntry->Flags & GARRISON_ABILITY_FLAG_TRAIT)) return false; - Garrison* garrison = referencePlayer->GetGarrison(); + Garrison const* garrison = referencePlayer->GetGarrison(); + if (!garrison || garrison->GetType() != GarrisonType(secondaryAsset)) + return false; + if (miscValue1) + { + Garrison::Follower const* follower = garrison->GetFollower(miscValue1); + if (!follower || !follower->HasAbility(reqValue)) + return false; + } + else + { + uint32 followerCount = garrison->CountFollowers([reqValue](Garrison::Follower const& follower) + { + return follower.HasAbility(reqValue); + }); + if (followerCount < 1) + return false; + } + break; + } + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_ABOVE_QUALITY_WOD: // 145 + { + Garrison const* garrison = referencePlayer->GetGarrison(); + if (!garrison || garrison->GetType() != GARRISON_TYPE_GARRISON) + return false; + if (miscValue1) + { + Garrison::Follower const* follower = garrison->GetFollower(miscValue1); + if (!follower || follower->PacketInfo.Quality < reqValue) + return false; + } + else + { + uint32 followerCount = garrison->CountFollowers([reqValue](Garrison::Follower const& follower) + { + return follower.PacketInfo.Quality >= reqValue; + }); + if (followerCount < 1) + return false; + } + break; + } + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_EQUAL_LEVEL: // 146 + { + Garrison const* garrison = referencePlayer->GetGarrison(); + if (!garrison || garrison->GetType() != GarrisonType(secondaryAsset)) + return false; + if (miscValue1) + { + Garrison::Follower const* follower = garrison->GetFollower(miscValue1); + if (!follower || follower->PacketInfo.FollowerLevel < reqValue) + return false; + } + else + { + uint32 followerCount = garrison->CountFollowers([reqValue](Garrison::Follower const& follower) + { + return follower.PacketInfo.FollowerLevel >= reqValue; + }); + if (followerCount < 1) + return false; + } + break; + } + case CRITERIA_ADDITIONAL_CONDITION_BATTLE_PET_SPECIES_IN_TEAM: // 151 + { + uint32 count = 0; + for (WorldPackets::BattlePet::BattlePetSlot const& slot : referencePlayer->GetSession()->GetBattlePetMgr()->GetSlots()) + if (slot.Pet.Species == secondaryAsset) + ++count; + if (count < reqValue) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_BATTLE_PET_FAMILY_IN_TEAM: // 152 + { + uint32 count = 0; + for (WorldPackets::BattlePet::BattlePetSlot const& slot : referencePlayer->GetSession()->GetBattlePetMgr()->GetSlots()) + if (BattlePetSpeciesEntry const* species = sBattlePetSpeciesStore.LookupEntry(slot.Pet.Species)) + if (species->PetTypeEnum == secondaryAsset) + ++count; + if (count < reqValue) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_ID: // 157 + { + Garrison const* garrison = referencePlayer->GetGarrison(); + if (!garrison) + return false; + if (miscValue1) + { + Garrison::Follower const* follower = garrison->GetFollower(miscValue1); + if (!follower || follower->PacketInfo.GarrFollowerID != reqValue) + return false; + } + else + { + uint32 followerCount = garrison->CountFollowers([reqValue](Garrison::Follower const& follower) + { + return follower.PacketInfo.GarrFollowerID == reqValue; + }); + if (followerCount < 1) + return false; + } + break; + } + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_ABOVE_ITEM_LEVEL: // 168 + { + Garrison const* garrison = referencePlayer->GetGarrison(); if (!garrison) return false; - Garrison::Follower const* follower = garrison->GetFollower(miscValue1); - if (!follower || follower->PacketInfo.FollowerLevel < reqValue) + if (miscValue1) + { + Garrison::Follower const* follower = garrison->GetFollower(miscValue1); + if (!follower || follower->PacketInfo.GarrFollowerID != reqValue) + return false; + } + else + { + uint32 followerCount = garrison->CountFollowers([reqValue](Garrison::Follower const& follower) + { + return follower.GetItemLevel() >= reqValue; + }); + if (followerCount < 1) + return false; + } + break; + } + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWERS_ABOVE_ITEM_LEVEL: // 169 + { + Garrison const* garrison = referencePlayer->GetGarrison(); + if (!garrison || garrison->GetType() != GarrisonType(tertiaryAsset)) + return false; + uint32 followerCount = garrison->CountFollowers([secondaryAsset](Garrison::Follower const& follower) + { + return follower.GetItemLevel() >= secondaryAsset; + }); + if (followerCount < reqValue) return false; - break; } - case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_ILVL: // 184 + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_LEVEL_EQUAL: // 170 { - if (!referencePlayer) + Garrison const* garrison = referencePlayer->GetGarrison(); + if (!garrison || garrison->GetType() != GARRISON_TYPE_GARRISON || garrison->GetSiteLevel()->GarrLevel != reqValue) return false; - Garrison* garrison = referencePlayer->GetGarrison(); + break; + } + case CRITERIA_ADDITIONAL_CONDITION_TARGETING_CORPSE: // 173 + if (referencePlayer->GetTarget().GetHigh() != HighGuid::Corpse) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWERS_LEVEL_EQUAL: // 175 + { + Garrison const* garrison = referencePlayer->GetGarrison(); + if (!garrison || garrison->GetType() != GarrisonType(tertiaryAsset)) + return false; + uint32 followerCount = garrison->CountFollowers([secondaryAsset](Garrison::Follower const& follower) + { + return follower.PacketInfo.FollowerLevel >= secondaryAsset; + }); + if (followerCount < reqValue) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_ID_IN_BUILDING: // 176 + { + Garrison const* garrison = referencePlayer->GetGarrison(); + if (!garrison || garrison->GetType() != GARRISON_TYPE_GARRISON) + return false; + uint32 followerCount = garrison->CountFollowers([reqValue, secondaryAsset](Garrison::Follower const& follower) + { + if (follower.PacketInfo.GarrFollowerID != reqValue) + return false; + GarrBuildingEntry const* followerBuilding = sGarrBuildingStore.LookupEntry(follower.PacketInfo.CurrentBuildingID); + if (!followerBuilding) + return false; + return followerBuilding->BuildingType == secondaryAsset; + }); + if (followerCount < 1) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_WORLD_PVP_AREA: // 179 + { + Battlefield const* bf = sBattlefieldMgr->GetBattlefieldToZoneId(referencePlayer->GetZoneId()); + if (!bf || bf->GetBattleId() != reqValue) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWERS_ITEM_LEVEL_ABOVE: // 184 + { + Garrison const* garrison = referencePlayer->GetGarrison(); if (!garrison) return false; - Garrison::Follower const* follower = garrison->GetFollower(miscValue1); - if (!follower || follower->GetItemLevel() < reqValue) + uint32 followerCount = garrison->CountFollowers([secondaryAsset, tertiaryAsset](Garrison::Follower const& follower) + { + GarrFollowerEntry const* garrFollower = sGarrFollowerStore.LookupEntry(follower.PacketInfo.GarrFollowerID); + if (!garrFollower) + return false; + return follower.GetItemLevel() >= secondaryAsset && garrFollower->GarrFollowerTypeID == tertiaryAsset; + }); + if (followerCount < reqValue) return false; break; } case CRITERIA_ADDITIONAL_CONDITION_HONOR_LEVEL: // 193 - if (!referencePlayer || referencePlayer->GetHonorLevel() != reqValue) + if (referencePlayer->GetHonorLevel() != reqValue) return false; break; case CRITERIA_ADDITIONAL_CONDITION_PRESTIGE_LEVEL: // 194 return false; + case CRITERIA_ADDITIONAL_CONDITION_ITEM_MODIFIED_APPEARANCE: // 200 + { + std::pair<bool, bool> hasAppearance = referencePlayer->GetSession()->GetCollectionMgr()->HasItemAppearance(reqValue); + if (!hasAppearance.first || hasAppearance.second) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_HAS_CHARACTER_RESTRICTIONS: // 203 + { + if (referencePlayer->m_activePlayerData->CharacterRestrictions.empty()) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_QUEST_INFO_ID: // 206 + { + Quest const* quest = sObjectMgr->GetQuestTemplate(miscValue1); + if (!quest || quest->GetQuestInfoID() != reqValue) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_ARTIFACT_APPEARANCE_SET_USED: // 208 + { + for (uint8 slot = EQUIPMENT_SLOT_MAINHAND; slot <= EQUIPMENT_SLOT_RANGED; ++slot) + if (Item* artifact = referencePlayer->GetItemByPos(INVENTORY_SLOT_BAG_0, slot)) + if (ArtifactAppearanceEntry const* artifactAppearance = sArtifactAppearanceStore.LookupEntry(artifact->GetModifier(ITEM_MODIFIER_ARTIFACT_APPEARANCE_ID))) + if (artifactAppearance->ArtifactAppearanceSetID == reqValue) + return true; + return false; + } + case CRITERIA_ADDITIONAL_CONDITION_CURRENCY_AMOUNT_EQUAL: // 209 + if (referencePlayer->GetCurrency(reqValue) != secondaryAsset) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_SCENARIO_TYPE: // 211 + { + Scenario const* scenario = referencePlayer->GetScenario(); + if (!scenario) + return false; + if (scenario->GetEntry()->Type != reqValue) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_ACCOUNT_EXPANSION_EQUAL: // 212 + if (referencePlayer->GetSession()->GetAccountExpansion() != reqValue) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_ACHIEVEMENT_GLOBALLY_INCOMPLETED: // 231 + { + AchievementEntry const* achievement = sAchievementStore.LookupEntry(secondaryAsset); + if (!achievement) + return false; + if (sAchievementMgr->IsRealmCompleted(achievement)) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_MAIN_HAND_VISIBLE_SUBCLASS: // 232 + { + uint32 itemSubclass = ITEM_SUBCLASS_WEAPON_FIST_WEAPON; + if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(referencePlayer->m_playerData->VisibleItems[EQUIPMENT_SLOT_MAINHAND].ItemID)) + itemSubclass = itemTemplate->GetSubClass(); + if (itemSubclass != reqValue) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_OFF_HAND_VISIBLE_SUBCLASS: // 233 + { + uint32 itemSubclass = ITEM_SUBCLASS_WEAPON_FIST_WEAPON; + if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(referencePlayer->m_playerData->VisibleItems[EQUIPMENT_SLOT_OFFHAND].ItemID)) + itemSubclass = itemTemplate->GetSubClass(); + if (itemSubclass != reqValue) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_AZERITE_ITEM_LEVEL: // 235 + { + Item const* heartOfAzeroth = referencePlayer->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH); + if (!heartOfAzeroth || heartOfAzeroth->ToAzeriteItem()->m_azeriteItemData->Level < reqValue) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_DISPLAY_RACE: // 252 + { + CreatureDisplayInfoEntry const* creatureDisplayInfo = sCreatureDisplayInfoStore.LookupEntry(referencePlayer->GetDisplayId()); + if (!creatureDisplayInfo) + return false; + CreatureDisplayInfoExtraEntry const* creatureDisplayInfoExtra = sCreatureDisplayInfoExtraStore.LookupEntry(creatureDisplayInfo->ExtendedDisplayInfoID); + if (!creatureDisplayInfoExtra) + return false; + if (uint32(creatureDisplayInfoExtra->DisplayRaceID) != reqValue) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_TARGET_DISPLAY_RACE: // 253 + { + if (!unit) + return false; + CreatureDisplayInfoEntry const* creatureDisplayInfo = sCreatureDisplayInfoStore.LookupEntry(unit->GetDisplayId()); + if (!creatureDisplayInfo) + return false; + CreatureDisplayInfoExtraEntry const* creatureDisplayInfoExtra = sCreatureDisplayInfoExtraStore.LookupEntry(creatureDisplayInfo->ExtendedDisplayInfoID); + if (!creatureDisplayInfoExtra) + return false; + if (uint32(creatureDisplayInfoExtra->DisplayRaceID) != reqValue) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_AURA_COUNT_EQUAL: // 255 + if (referencePlayer->GetAuraCount(secondaryAsset) != reqValue) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_TARGET_AURA_COUNT_EQUAL: // 256 + if (!unit || unit->GetAuraCount(secondaryAsset) != reqValue) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_AURA_COUNT_GREATER: // 257 + if (referencePlayer->GetAuraCount(secondaryAsset) < reqValue) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_TARGET_AURA_COUNT_GREATER: // 258 + if (!unit || unit->GetAuraCount(secondaryAsset) < reqValue) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_UNLOCKED_AZERITE_ESSENCE_RANK_LOWER: // 259 + { + if (Item const* heartOfAzeroth = referencePlayer->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH)) + if (AzeriteItem const* azeriteItem = heartOfAzeroth->ToAzeriteItem()) + for (UF::UnlockedAzeriteEssence const& essence : azeriteItem->m_azeriteItemData->UnlockedEssences) + if (essence.AzeriteEssenceID == reqValue && essence.Rank < secondaryAsset) + return true; + return false; + } + case CRITERIA_ADDITIONAL_CONDITION_UNLOCKED_AZERITE_ESSENCE_RANK_EQUAL: // 260 + { + if (Item const* heartOfAzeroth = referencePlayer->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH)) + if (AzeriteItem const* azeriteItem = heartOfAzeroth->ToAzeriteItem()) + for (UF::UnlockedAzeriteEssence const& essence : azeriteItem->m_azeriteItemData->UnlockedEssences) + if (essence.AzeriteEssenceID == reqValue && essence.Rank == secondaryAsset) + return true; + return false; + } + case CRITERIA_ADDITIONAL_CONDITION_UNLOCKED_AZERITE_ESSENCE_RANK_GREATER: // 261 + { + if (Item const* heartOfAzeroth = referencePlayer->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH)) + if (AzeriteItem const* azeriteItem = heartOfAzeroth->ToAzeriteItem()) + for (UF::UnlockedAzeriteEssence const& essence : azeriteItem->m_azeriteItemData->UnlockedEssences) + if (essence.AzeriteEssenceID == reqValue && essence.Rank > secondaryAsset) + return true; + return false; + } + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_HAS_AURA_EFFECT_INDEX: // 262 + if (!referencePlayer->GetAuraEffect(reqValue, secondaryAsset)) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_SPECIALIZATION_ROLE: // 263 + { + ChrSpecializationEntry const* spec = sChrSpecializationStore.LookupEntry(referencePlayer->GetPrimarySpecialization()); + if (!spec || spec->Role != int32(reqValue)) + return false; + break; + } + case CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL_120: // 264 + if (referencePlayer->getLevel() != 120) + return false; + break; + case CRITERIA_ADDITIONAL_CONDITION_SELECTED_AZERITE_ESSENCE_RANK_LOWER: // 266 + if (Item const* heartOfAzeroth = referencePlayer->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH)) + if (AzeriteItem const* azeriteItem = heartOfAzeroth->ToAzeriteItem()) + if (UF::SelectedAzeriteEssences const* selectedEssences = azeriteItem->GetSelectedAzeriteEssences()) + for (UF::UnlockedAzeriteEssence const& essence : azeriteItem->m_azeriteItemData->UnlockedEssences) + if (essence.AzeriteEssenceID == selectedEssences->AzeriteEssenceID[reqValue] && essence.Rank < secondaryAsset) + return true; + return false; + case CRITERIA_ADDITIONAL_CONDITION_SELECTED_AZERITE_ESSENCE_RANK_GREATER: // 267 + if (Item const* heartOfAzeroth = referencePlayer->GetItemByEntry(ITEM_ID_HEART_OF_AZEROTH)) + if (AzeriteItem const* azeriteItem = heartOfAzeroth->ToAzeriteItem()) + if (UF::SelectedAzeriteEssences const* selectedEssences = azeriteItem->GetSelectedAzeriteEssences()) + for (UF::UnlockedAzeriteEssence const& essence : azeriteItem->m_azeriteItemData->UnlockedEssences) + if (essence.AzeriteEssenceID == selectedEssences->AzeriteEssenceID[reqValue] && essence.Rank > secondaryAsset) + return true; + return false; + case CRITERIA_ADDITIONAL_CONDITION_MAP_OR_COSMETIC_MAP: // 280 + { + MapEntry const* map = referencePlayer->GetMap()->GetEntry(); + if (map->ID != reqValue && map->CosmeticParentMapID != int32(reqValue)) + return false; + break; + } default: break; } diff --git a/src/server/game/Achievements/CriteriaHandler.h b/src/server/game/Achievements/CriteriaHandler.h index 53419d8fd36..9b35d5cb8de 100644 --- a/src/server/game/Achievements/CriteriaHandler.h +++ b/src/server/game/Achievements/CriteriaHandler.h @@ -299,7 +299,8 @@ protected: bool ConditionsSatisfied(Criteria const* criteria, Player* referencePlayer) const; bool RequirementsSatisfied(Criteria const* criteria, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit const* unit, Player* referencePlayer) const; virtual bool RequiredAchievementSatisfied(uint32 /*achievementId*/) const { return false; } - bool AdditionalRequirementsSatisfied(ModifierTreeNode const* parent, uint64 miscValue1, uint64 miscValue2, Unit const* unit, Player* referencePlayer) const; + bool ModifierTreeSatisfied(ModifierTreeNode const* parent, uint64 miscValue1, uint64 miscValue2, Unit const* unit, Player* referencePlayer) const; + bool ModifierSatisfied(ModifierTreeEntry const* modifier, uint64 miscValue1, uint64 miscValue2, Unit const* unit, Player* referencePlayer) const; virtual std::string GetOwnerInfo() const = 0; virtual CriteriaList const& GetCriteriaByType(CriteriaTypes type) const = 0; diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index db3cf14b909..9c760440ccc 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -195,9 +195,9 @@ enum CriteriaCondition enum CriteriaAdditionalCondition { - CRITERIA_ADDITIONAL_CONDITION_SOURCE_DRUNK_VALUE = 1, // NYI + CRITERIA_ADDITIONAL_CONDITION_SOURCE_DRUNK_VALUE = 1, CRITERIA_ADDITIONAL_CONDITION_SOURCE_PLAYER_CONDITION = 2, - CRITERIA_ADDITIONAL_CONDITION_ITEM_LEVEL = 3, // NYI + CRITERIA_ADDITIONAL_CONDITION_ITEM_LEVEL = 3, CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_ENTRY = 4, CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_PLAYER = 5, CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_DEAD = 6, @@ -213,8 +213,11 @@ enum CriteriaAdditionalCondition CRITERIA_ADDITIONAL_CONDITION_SOURCE_IS_ALIVE = 16, CRITERIA_ADDITIONAL_CONDITION_SOURCE_AREA_OR_ZONE = 17, CRITERIA_ADDITIONAL_CONDITION_TARGET_AREA_OR_ZONE = 18, + //CRITERIA_ADDITIONAL_CONDITION_UNK_19 = 19, CRITERIA_ADDITIONAL_CONDITION_MAP_DIFFICULTY_OLD = 20, CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_YIELDS_XP = 21, // NYI + CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL_ABOVE_TARGET = 22, + CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL_EQUAL_TARGET = 23, CRITERIA_ADDITIONAL_CONDITION_ARENA_TYPE = 24, CRITERIA_ADDITIONAL_CONDITION_SOURCE_RACE = 25, CRITERIA_ADDITIONAL_CONDITION_SOURCE_CLASS = 26, @@ -222,57 +225,261 @@ enum CriteriaAdditionalCondition CRITERIA_ADDITIONAL_CONDITION_TARGET_CLASS = 28, CRITERIA_ADDITIONAL_CONDITION_MAX_GROUP_MEMBERS = 29, CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_TYPE = 30, + CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_FAMILY = 31, CRITERIA_ADDITIONAL_CONDITION_SOURCE_MAP = 32, - CRITERIA_ADDITIONAL_CONDITION_ITEM_CLASS = 33, // NYI - CRITERIA_ADDITIONAL_CONDITION_ITEM_SUBCLASS = 34, // NYI - CRITERIA_ADDITIONAL_CONDITION_COMPLETE_QUEST_NOT_IN_GROUP = 35, // NYI - CRITERIA_ADDITIONAL_CONDITION_MIN_PERSONAL_RATING = 37, // NYI (when implementing don't forget about CRITERIA_CONDITION_NO_LOSE) + CRITERIA_ADDITIONAL_CONDITION_CLIENT_VERSION = 33, + CRITERIA_ADDITIONAL_CONDITION_BATTLE_PET_TEAM_LEVEL = 34, + CRITERIA_ADDITIONAL_CONDITION_NOT_IN_GROUP = 35, + CRITERIA_ADDITIONAL_CONDITION_IN_GROUP = 36, + CRITERIA_ADDITIONAL_CONDITION_MIN_PERSONAL_RATING = 37, // NYI CRITERIA_ADDITIONAL_CONDITION_TITLE_BIT_INDEX = 38, CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL = 39, CRITERIA_ADDITIONAL_CONDITION_TARGET_LEVEL = 40, - CRITERIA_ADDITIONAL_CONDITION_TARGET_ZONE = 41, - CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PERCENT_BELOW = 46, + CRITERIA_ADDITIONAL_CONDITION_SOURCE_ZONE = 41, + CRITERIA_ADDITIONAL_CONDITION_TARGET_ZONE = 42, + CRITERIA_ADDITIONAL_CONDITION_SOURCE_HEALTH_PCT_LOWER = 43, + CRITERIA_ADDITIONAL_CONDITION_SOURCE_HEALTH_PCT_GREATER = 44, + CRITERIA_ADDITIONAL_CONDITION_SOURCE_HEALTH_PCT_EQUAL = 45, + CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PCT_LOWER = 46, + CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PCT_GREATER = 47, + CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PCT_EQUAL = 48, + CRITERIA_ADDITIONAL_CONDITION_SOURCE_HEALTH_LOWER = 49, + CRITERIA_ADDITIONAL_CONDITION_SOURCE_HEALTH_GREATER = 50, + CRITERIA_ADDITIONAL_CONDITION_SOURCE_HEALTH_EQUAL = 51, + CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_LOWER = 52, + CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_GREATER = 53, + CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_EQUAL = 54, CRITERIA_ADDITIONAL_CONDITION_TARGET_PLAYER_CONDITION = 55, - CRITERIA_ADDITIONAL_CONDITION_MIN_ACHIEVEMENT_POINTS = 56, // NYI - CRITERIA_ADDITIONAL_CONDITION_REQUIRES_LFG_GROUP = 58, // NYI - CRITERIA_ADDITIONAL_CONDITION_UNK60 = 60, + CRITERIA_ADDITIONAL_CONDITION_MIN_ACHIEVEMENT_POINTS = 56, + CRITERIA_ADDITIONAL_CONDITION_IN_LFG_DUNGEON = 57, + CRITERIA_ADDITIONAL_CONDITION_IN_LFG_RANDOM_DUNGEON = 58, + CRITERIA_ADDITIONAL_CONDITION_IN_LFG_FIRST_RANDOM_DUNGEON = 59, + //CRITERIA_ADDITIONAL_CONDITION_UNK_60 = 60, // NYI CRITERIA_ADDITIONAL_CONDITION_REQUIRES_GUILD_GROUP = 61, // NYI - CRITERIA_ADDITIONAL_CONDITION_GUILD_REPUTATION = 62, // NYI + CRITERIA_ADDITIONAL_CONDITION_GUILD_REPUTATION = 62, CRITERIA_ADDITIONAL_CONDITION_RATED_BATTLEGROUND = 63, // NYI CRITERIA_ADDITIONAL_CONDITION_RATED_BATTLEGROUND_RATING = 64, CRITERIA_ADDITIONAL_CONDITION_PROJECT_RARITY = 65, CRITERIA_ADDITIONAL_CONDITION_PROJECT_RACE = 66, - CRITERIA_ADDITIONAL_CONDITION_WORLD_STATE = 67, // NYI - CRITERIA_ADDITIONAL_CONDITION_MAP_DIFFICULTY = 68, // NYI - CRITERIA_ADDITIONAL_CONDITION_PLAYER_LEVEL = 69, // NYI - CRITERIA_ADDITIONAL_CONDITION_TARGET_PLAYER_LEVEL = 70, // NYI - //CRITERIA_ADDITIONAL_CONDITION_PLAYER_LEVEL_ON_ACCOUNT = 71, // Not verified - //CRITERIA_ADDITIONAL_CONDITION_UNK73 = 73, // References another modifier tree id - CRITERIA_ADDITIONAL_CONDITION_SCENARIO_ID = 74, // NYI + CRITERIA_ADDITIONAL_CONDITION_WORLD_STATE_EXPRESSION = 67, + CRITERIA_ADDITIONAL_CONDITION_MAP_DIFFICULTY = 68, + CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL_GREATER = 69, + CRITERIA_ADDITIONAL_CONDITION_TARGET_LEVEL_GREATER = 70, + CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL_LOWER = 71, + CRITERIA_ADDITIONAL_CONDITION_TARGET_LEVEL_LOWER = 72, + CRITERIA_ADDITIONAL_CONDITION_MODIFIER_TREE = 73, + CRITERIA_ADDITIONAL_CONDITION_SCENARIO_ID = 74, + CRITERIA_ADDITIONAL_CONDITION_THE_TILLERS_REPUTATION = 75, + CRITERIA_ADDITIONAL_CONDITION_PET_BATTLE_ACHIEVEMENT_POINTS = 76, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_77 = 77, // NYI CRITERIA_ADDITIONAL_CONDITION_BATTLE_PET_FAMILY = 78, // NYI CRITERIA_ADDITIONAL_CONDITION_BATTLE_PET_HEALTH_PCT = 79, // NYI - //CRITERIA_ADDITIONAL_CONDITION_UNK80 = 80 // Something to do with world bosses + CRITERIA_ADDITIONAL_CONDITION_GUILD_GROUP_MEMBERS = 80, // NYI CRITERIA_ADDITIONAL_CONDITION_BATTLE_PET_ENTRY = 81, // NYI - //CRITERIA_ADDITIONAL_CONDITION_BATTLE_PET_ENTRY_ID = 82, // Some sort of data id? + CRITERIA_ADDITIONAL_CONDITION_SCENARIO_STEP_INDEX = 82, CRITERIA_ADDITIONAL_CONDITION_CHALLENGE_MODE_MEDAL = 83, // NYI - //CRITERIA_ADDITIONAL_CONDITION_UNK84 = 84, // Quest id - //CRITERIA_ADDITIONAL_CONDITION_UNK86 = 86, // Some external event id - //CRITERIA_ADDITIONAL_CONDITION_UNK87 = 87, // Achievement id + CRITERIA_ADDITIONAL_CONDITION_IS_ON_QUEST = 84, + CRITERIA_ADDITIONAL_CONDITION_EXALTED_WITH_FACTION = 85, // NYI + CRITERIA_ADDITIONAL_CONDITION_HAS_ACHIEVEMENT = 86, + CRITERIA_ADDITIONAL_CONDITION_HAS_ACHIEVEMENT_ON_CHARACTER = 87, // NYI + CRITERIA_ADDITIONAL_CONDITION_CLOUD_SERPENT_REPUTATION = 88, + CRITERIA_ADDITIONAL_CONDITION_BATTLE_PET_BREED_QUALITY_ID = 89, // NYI + CRITERIA_ADDITIONAL_CONDITION_PET_BATTLE_IS_PVP = 90, // NYI CRITERIA_ADDITIONAL_CONDITION_BATTLE_PET_SPECIES = 91, - CRITERIA_ADDITIONAL_CONDITION_EXPANSION = 92, + CRITERIA_ADDITIONAL_CONDITION_ACTIVE_EXPANSION = 92, + //CRITERIA_ADDITIONAL_CONDITION_UNK_93 = 93, // NYI + CRITERIA_ADDITIONAL_CONDITION_FRIENDSHIP_REP_REACTION = 94, // NYI + CRITERIA_ADDITIONAL_CONDITION_FACTION_STANDING = 95, + CRITERIA_ADDITIONAL_CONDITION_ITEM_CLASS_AND_SUBCLASS = 96, // NYI + CRITERIA_ADDITIONAL_CONDITION_SOURCE_SEX = 97, + CRITERIA_ADDITIONAL_CONDITION_SOURCE_NATIVE_SEX = 98, + CRITERIA_ADDITIONAL_CONDITION_SKILL = 99, + //CRITERIA_ADDITIONAL_CONDITION_UNK_100 = 100, // NYI + CRITERIA_ADDITIONAL_CONDITION_NORMAL_PHASE_SHIFT = 101, + CRITERIA_ADDITIONAL_CONDITION_IN_PHASE = 102, + CRITERIA_ADDITIONAL_CONDITION_NOT_IN_PHASE = 103, + CRITERIA_ADDITIONAL_CONDITION_HAS_SPELL = 104, + CRITERIA_ADDITIONAL_CONDITION_ITEM_COUNT = 105, + CRITERIA_ADDITIONAL_CONDITION_ACCOUNT_EXPANSION = 106, + CRITERIA_ADDITIONAL_CONDITION_SOURCE_HAS_AURA_LABEL = 107, // NYI, SpellLabel + //CRITERIA_ADDITIONAL_CONDITION_UNK_108 = 108, // NYI + CRITERIA_ADDITIONAL_CONDITION_TIME_IN_RANGE = 109, // NYI, packed time between asset and secondaryAsset CRITERIA_ADDITIONAL_CONDITION_REWARDED_QUEST = 110, CRITERIA_ADDITIONAL_CONDITION_COMPLETED_QUEST = 111, CRITERIA_ADDITIONAL_CONDITION_COMPLETED_QUEST_OBJECTIVE = 112, // NYI, QuestObjectiveID - CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_ENTRY = 144, - CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_QUALITY = 145, - CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_LEVEL = 146, + CRITERIA_ADDITIONAL_CONDITION_EXPLORED_AREA = 113, + CRITERIA_ADDITIONAL_CONDITION_ITEM_COUNT_INCLUDING_BANK = 114, + //CRITERIA_ADDITIONAL_CONDITION_UNK_115 = 115, // NYI + CRITERIA_ADDITIONAL_CONDITION_SOURCE_PVP_FACTION_INDEX = 116, + CRITERIA_ADDITIONAL_CONDITION_LFG_VALUE_EQUAL = 117, + CRITERIA_ADDITIONAL_CONDITION_LFG_VALUE_GREATER = 118, + CRITERIA_ADDITIONAL_CONDITION_CURRENCY_AMOUNT = 119, + //CRITERIA_ADDITIONAL_CONDITION_UNK_120 = 120, // NYI + CRITERIA_ADDITIONAL_CONDITION_CURRENCY_TRACKED_AMOUNT = 121, + CRITERIA_ADDITIONAL_CONDITION_MAP_INSTANCE_TYPE = 122, + CRITERIA_ADDITIONAL_CONDITION_MENTOR = 123, + //CRITERIA_ADDITIONAL_CONDITION_UNK_124 = 124, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_125 = 125, // NYI + CRITERIA_ADDITIONAL_CONDITION_GARRISON_LEVEL_ABOVE = 126, // asset: garrLevel, secondaryAsset: garrType + CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWERS_ABOVE_LEVEL = 127, // asset: count, secondaryAsset: followerLevel, tertiaryAsset: garrType + CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWERS_ABOVE_QUALITY = 128, // asset: count, secondaryAsset: followerQuality, tertiaryAsset: garrType + CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_ABOVE_LEVEL_WITH_ABILITY = 129, // asset: followerLevel, secondaryAsset: ability, tertiaryAsset: garrType + CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_ABOVE_LEVEL_WITH_TRAIT = 130, // asset: followerLevel, secondaryAsset: ability, tertiaryAsset: garrType (same as above but ability must have GARRISON_ABILITY_FLAG_TRAIT) + CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_WITH_ABILITY_IN_BUILDING = 131, // asset: ability, secondaryAsset: buildingType, tertiaryAsset: garrType + CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_WITH_TRAIT_IN_BUILDING = 132, // asset: ability, secondaryAsset: buildingType, tertiaryAsset: garrType + CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_ABOVE_LEVEL_IN_BUILDING = 133, // asset: followerLevel, secondaryAsset: buildingType, tertiaryAsset: garrType + CRITERIA_ADDITIONAL_CONDITION_GARRISON_BUILDING_ABOVE_LEVEL = 134, // asset: buildingType, secondaryAsset: buildingLevel, tertiaryAsset: garrType + CRITERIA_ADDITIONAL_CONDITION_GARRISON_BLUEPRINT = 135, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_136 = 136, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_137 = 137, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_138 = 138, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_139 = 139, // NYI + CRITERIA_ADDITIONAL_CONDITION_GARRISON_BUILDING_INACTIVE = 140, + //CRITERIA_ADDITIONAL_CONDITION_UNK_141 = 141, // NYI + CRITERIA_ADDITIONAL_CONDITION_GARRISON_BUILDING_EQUAL_LEVEL = 142, // asset: buildingType, secondaryAsset: buildingLevel, tertiaryAsset: garrType + CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_WITH_ABILITY= 143, // asset: ability, secondaryAsset: garrType + CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_WITH_TRAIT = 144, // asset: ability, secondaryAsset: garrType + CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_ABOVE_QUALITY_WOD = 145, // asset: followerQuality + CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_EQUAL_LEVEL = 146, // asset: followerLevel, secondaryAsset: garrType CRITERIA_ADDITIONAL_CONDITION_GARRISON_RARE_MISSION = 147, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_148 = 148, // NYI CRITERIA_ADDITIONAL_CONDITION_GARRISON_BUILDING_LEVEL = 149, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_150 = 150, // NYI + CRITERIA_ADDITIONAL_CONDITION_BATTLE_PET_SPECIES_IN_TEAM = 151, // asset: count, secondaryAsset: battlePetSpeciesId + CRITERIA_ADDITIONAL_CONDITION_BATTLE_PET_FAMILY_IN_TEAM = 152, // asset: count, secondaryAsset: battlePetFamily + //CRITERIA_ADDITIONAL_CONDITION_UNK_153 = 153, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_154 = 154, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_155 = 155, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_156 = 156, // NYI + CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_ID = 157, // follower with id, in any garrison + CRITERIA_ADDITIONAL_CONDITION_QUEST_OBJECTIVE_PROGRESS_EQUAL= 158, // NYI asset: questObjectiveId, secondaryAsset: progress + CRITERIA_ADDITIONAL_CONDITION_QUEST_OBJECTIVE_PROGRESS_ABOVE= 159, // NYI asset: questObjectiveId, secondaryAsset: progress + //CRITERIA_ADDITIONAL_CONDITION_UNK_160 = 160, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_161 = 161, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_162 = 162, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_163 = 163, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_164 = 164, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_165 = 165, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_166 = 166, // NYI CRITERIA_ADDITIONAL_CONDITION_GARRISON_MISSION_TYPE = 167, // NYI - CRITERIA_ADDITIONAL_CONDITION_PLAYER_ITEM_LEVEL = 169, // NYI - CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_ILVL = 184, + CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_ABOVE_ITEM_LEVEL = 168, // asset: followerItemLevel + CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWERS_ABOVE_ITEM_LEVEL = 169, // asset: count, secondaryAsset: followerItemLevel, tertiaryAsset: garrType + CRITERIA_ADDITIONAL_CONDITION_GARRISON_LEVEL_EQUAL = 170, // asset: count + CRITERIA_ADDITIONAL_CONDITION_GARRISON_GROUP_SIZE = 171, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_172 = 172, // NYI something to do with currency but only used on criterias that require the same currency + CRITERIA_ADDITIONAL_CONDITION_TARGETING_CORPSE = 173, + //CRITERIA_ADDITIONAL_CONDITION_UNK_174 = 174, // NYI + CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWERS_LEVEL_EQUAL= 175, // asset: count, secondaryAsset: followerLevel, tertiaryAsset: garrType + CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_ID_IN_BUILDING = 176, // asset: followerId, secondaryAsset: buildingType + //CRITERIA_ADDITIONAL_CONDITION_UNK_177 = 177, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_178 = 178, // NYI + CRITERIA_ADDITIONAL_CONDITION_WORLD_PVP_AREA = 179, // NYI + CRITERIA_ADDITIONAL_CONDITION_NON_OWN_GARRISON = 180, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_181 = 181, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_182 = 183, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_183 = 183, // NYI + CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWERS_ITEM_LEVEL_ABOVE = 184, + //CRITERIA_ADDITIONAL_CONDITION_UNK_185 = 185, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_186 = 186, // NYI + CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_TYPE = 187, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_188 = 188, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_189 = 189, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_190 = 190, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_191 = 191, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_192 = 192, // NYI CRITERIA_ADDITIONAL_CONDITION_HONOR_LEVEL = 193, - CRITERIA_ADDITIONAL_CONDITION_PRESTIGE_LEVEL = 194 + CRITERIA_ADDITIONAL_CONDITION_PRESTIGE_LEVEL = 194, + //CRITERIA_ADDITIONAL_CONDITION_UNK_195 = 195, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_196 = 196, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_197 = 197, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_198 = 198, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_198 = 199, // NYI + CRITERIA_ADDITIONAL_CONDITION_ITEM_MODIFIED_APPEARANCE = 200, + CRITERIA_ADDITIONAL_CONDITION_GARRISON_SELECTED_TALENT = 201, // NYI asset: garrTalentId (talent selected, research timer doesn't matter) + CRITERIA_ADDITIONAL_CONDITION_GARRISON_RESEARCHED_TALENT = 202, // NYI asset: garrTalentId (talent selected, research must be finished) + CRITERIA_ADDITIONAL_CONDITION_HAS_CHARACTER_RESTRICTIONS = 203, + //CRITERIA_ADDITIONAL_CONDITION_UNK_204 = 204, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_205 = 205, // NYI + CRITERIA_ADDITIONAL_CONDITION_QUEST_INFO_ID = 206, + CRITERIA_ADDITIONAL_CONDITION_GARRISON_RESEARCHING_TALENT = 207, // NYI asset: garrTalentId (talent selected, research must be in progress) + CRITERIA_ADDITIONAL_CONDITION_ARTIFACT_APPEARANCE_SET_USED = 208, + CRITERIA_ADDITIONAL_CONDITION_CURRENCY_AMOUNT_EQUAL = 209, + //CRITERIA_ADDITIONAL_CONDITION_UNK_210 = 210, // NYI + CRITERIA_ADDITIONAL_CONDITION_SCENARIO_TYPE = 211, + CRITERIA_ADDITIONAL_CONDITION_ACCOUNT_EXPANSION_EQUAL = 212, + //CRITERIA_ADDITIONAL_CONDITION_UNK_213 = 213, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_214 = 214, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_215 = 215, // NYI + CRITERIA_ADDITIONAL_CONDITION_CHALLENGE_MODE_MEDAL_2 = 216, // NYI keystone master, asset = 3 + //CRITERIA_ADDITIONAL_CONDITION_UNK_217 = 217, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_218 = 218, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_219 = 219, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_220 = 220, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_221 = 221, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_222 = 222, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_223 = 223, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_224 = 224, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_225 = 225, // NYI + CRITERIA_ADDITIONAL_CONDITION_USED_LEVEL_BOOST = 226, // NYI + CRITERIA_ADDITIONAL_CONDITION_USED_RACE_CHANGE = 227, // NYI + CRITERIA_ADDITIONAL_CONDITION_USED_FACTION_CHANGE = 228, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_229 = 229, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_230 = 230, // NYI + CRITERIA_ADDITIONAL_CONDITION_ACHIEVEMENT_GLOBALLY_INCOMPLETED = 231, // hall of fame stuff, asset: unk, secondaryAsset: achievementId + CRITERIA_ADDITIONAL_CONDITION_MAIN_HAND_VISIBLE_SUBCLASS = 232, + CRITERIA_ADDITIONAL_CONDITION_OFF_HAND_VISIBLE_SUBCLASS = 233, + CRITERIA_ADDITIONAL_CONDITION_PVP_TIER = 234, // NYI asset: pvpTierId + CRITERIA_ADDITIONAL_CONDITION_AZERITE_ITEM_LEVEL = 235, + //CRITERIA_ADDITIONAL_CONDITION_UNK_236 = 236, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_237 = 237, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_238 = 238, // NYI + CRITERIA_ADDITIONAL_CONDITION_PVP_TIER_GREATER = 239, // NYI asset: pvpTierEnum, secondaryAsset: pvpBracket + //CRITERIA_ADDITIONAL_CONDITION_UNK_240 = 240, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_241 = 241, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_242 = 242, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_243 = 243, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_244 = 244, // NYI + CRITERIA_ADDITIONAL_CONDITION_IN_WAR_MODE = 245, + //CRITERIA_ADDITIONAL_CONDITION_UNK_246 = 246, // NYI + CRITERIA_ADDITIONAL_CONDITION_KEYSTONE_LEVEL = 247, // NYI + //CRITERIA_ADDITIONAL_CONDITION_UNK_248 = 248, // NYI + CRITERIA_ADDITIONAL_CONDITION_KEYSTONE_DUNGEON = 249, // NYI asset: mapChallengeModeId + //CRITERIA_ADDITIONAL_CONDITION_UNK_250 = 250, // NYI + CRITERIA_ADDITIONAL_CONDITION_PVP_SEASON = 251, // NYI asset: that unknown column in PvpSeason.db2 + CRITERIA_ADDITIONAL_CONDITION_SOURCE_DISPLAY_RACE = 252, + CRITERIA_ADDITIONAL_CONDITION_TARGET_DISPLAY_RACE = 253, + CRITERIA_ADDITIONAL_CONDITION_FRIENDSHIP_REP_REACTION_EXACT = 254, // NYI + CRITERIA_ADDITIONAL_CONDITION_SOURCE_AURA_COUNT_EQUAL = 255, + CRITERIA_ADDITIONAL_CONDITION_TARGET_AURA_COUNT_EQUAL = 256, + CRITERIA_ADDITIONAL_CONDITION_SOURCE_AURA_COUNT_GREATER = 257, + CRITERIA_ADDITIONAL_CONDITION_TARGET_AURA_COUNT_GREATER = 258, + CRITERIA_ADDITIONAL_CONDITION_UNLOCKED_AZERITE_ESSENCE_RANK_LOWER = 259, + CRITERIA_ADDITIONAL_CONDITION_UNLOCKED_AZERITE_ESSENCE_RANK_EQUAL = 260, + CRITERIA_ADDITIONAL_CONDITION_UNLOCKED_AZERITE_ESSENCE_RANK_GREATER = 261, + CRITERIA_ADDITIONAL_CONDITION_SOURCE_HAS_AURA_EFFECT_INDEX = 262, // asset: spellId, secondaryAsset: index + CRITERIA_ADDITIONAL_CONDITION_SOURCE_SPECIALIZATION_ROLE = 263, + CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL_120 = 264, + //CRITERIA_ADDITIONAL_CONDITION_UNK_265 = 265, + CRITERIA_ADDITIONAL_CONDITION_SELECTED_AZERITE_ESSENCE_RANK_LOWER = 266, + CRITERIA_ADDITIONAL_CONDITION_SELECTED_AZERITE_ESSENCE_RANK_GREATER = 267, + //CRITERIA_ADDITIONAL_CONDITION_UNK_268 = 268, + //CRITERIA_ADDITIONAL_CONDITION_UNK_269 = 269, + //CRITERIA_ADDITIONAL_CONDITION_UNK_270 = 270, + //CRITERIA_ADDITIONAL_CONDITION_UNK_271 = 271, + //CRITERIA_ADDITIONAL_CONDITION_UNK_272 = 272, + //CRITERIA_ADDITIONAL_CONDITION_UNK_273 = 273, + //CRITERIA_ADDITIONAL_CONDITION_UNK_274 = 274, + //CRITERIA_ADDITIONAL_CONDITION_UNK_275 = 275, + //CRITERIA_ADDITIONAL_CONDITION_UNK_276 = 276, + //CRITERIA_ADDITIONAL_CONDITION_UNK_277 = 277, + //CRITERIA_ADDITIONAL_CONDITION_UNK_278 = 278, + //CRITERIA_ADDITIONAL_CONDITION_UNK_279 = 279, + CRITERIA_ADDITIONAL_CONDITION_MAP_OR_COSMETIC_MAP = 280, + //CRITERIA_ADDITIONAL_CONDITION_UNK_281 = 281, + CRITERIA_ADDITIONAL_CONDITION_HAS_ENTITLEMENT = 282, + CRITERIA_ADDITIONAL_CONDITION_HAS_QUEST_SESSION = 283, + //CRITERIA_ADDITIONAL_CONDITION_UNK_284 = 284, + //CRITERIA_ADDITIONAL_CONDITION_UNK_285 = 285, }; enum CriteriaFlags @@ -900,6 +1107,14 @@ enum MapDifficultyFlags : uint8 MAP_DIFFICULTY_FLAG_CANNOT_EXTEND = 0x10 }; +enum class ModifierTreeOperator : int8 +{ + SingleTrue = 2, + SingleFalse = 3, + All = 4, + Some = 8 +}; + enum MountCapabilityFlags { MOUNT_CAPABILITY_FLAG_GROUND = 0x1, diff --git a/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.cpp b/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.cpp index 284aa202d7e..8366b2dadd4 100644 --- a/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.cpp +++ b/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.cpp @@ -200,6 +200,15 @@ void AzeriteItem::GiveXP(uint64 xp) owner->SendDirectMessage(xpGain.Write()); } +UF::SelectedAzeriteEssences const* AzeriteItem::GetSelectedAzeriteEssences() const +{ + for (UF::SelectedAzeriteEssences const& essences : m_azeriteItemData->SelectedEssences) + if (essences.Enabled) + return &essences; + + return nullptr; +} + void AzeriteItem::BuildValuesCreate(ByteBuffer* data, Player const* target) const { UF::UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target); diff --git a/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.h b/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.h index b255e094358..f9afbf2e0df 100644 --- a/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.h +++ b/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.h @@ -41,6 +41,8 @@ public: static uint64 CalcTotalXPToNextLevel(uint32 level, uint32 knowledgeLevel); void GiveXP(uint64 xp); + UF::SelectedAzeriteEssences const* GetSelectedAzeriteEssences() const; + void BuildValuesCreate(ByteBuffer* data, Player const* target) const override; void BuildValuesUpdate(ByteBuffer* data, Player const* target) const override; void BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override; diff --git a/src/server/game/Entities/Object/Updates/UpdateField.h b/src/server/game/Entities/Object/Updates/UpdateField.h index 952bc97370f..f99960fa451 100644 --- a/src/server/game/Entities/Object/Updates/UpdateField.h +++ b/src/server/game/Entities/Object/Updates/UpdateField.h @@ -615,6 +615,11 @@ namespace UF return _values.end(); } + bool empty() const + { + return _values.empty(); + } + std::size_t size() const { return _values.size(); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 1764de1c30c..4666423626a 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -6719,6 +6719,15 @@ uint32 Player::GetCurrencyOnWeek(uint32 id) const return itr->second.WeeklyQuantity; } +uint32 Player::GetTrackedCurrencyCount(uint32 id) const +{ + PlayerCurrenciesMap::const_iterator itr = _currencyStorage.find(id); + if (itr == _currencyStorage.end()) + return 0; + + return itr->second.TrackedQuantity; +} + bool Player::HasCurrency(uint32 id, uint32 count) const { PlayerCurrenciesMap::const_iterator itr = _currencyStorage.find(id); @@ -15003,6 +15012,7 @@ void Player::AddQuestAndCheckCompletion(Quest const* quest, Object* questGiver) case TYPEID_ITEM: case TYPEID_CONTAINER: case TYPEID_AZERITE_ITEM: + case TYPEID_AZERITE_EMPOWERED_ITEM: { Item* item = static_cast<Item*>(questGiver); sScriptMgr->OnQuestAccept(this, item, quest); @@ -15541,7 +15551,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, } if (quest->GetZoneOrSort() > 0) - UpdateCriteria(CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE, quest->GetZoneOrSort()); + UpdateCriteria(CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE, quest->GetQuestId()); UpdateCriteria(CRITERIA_TYPE_COMPLETE_QUEST_COUNT); UpdateCriteria(CRITERIA_TYPE_COMPLETE_QUEST, quest->GetQuestId()); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 83ae71d25a1..679ff1fa40e 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1188,6 +1188,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> uint32 GetCurrencyOnWeek(uint32 id) const; /// return week cap by currency id uint32 GetCurrencyWeekCap(uint32 id) const; + /// return tracked currency count by currency id + uint32 GetTrackedCurrencyCount(uint32 id) const; /// return presence related currency bool HasCurrency(uint32 id, uint32 count) const; /// initialize currency count for custom initialization at create character diff --git a/src/server/game/Garrison/Garrison.cpp b/src/server/game/Garrison/Garrison.cpp index c4bd9c256e9..466c6b4d15d 100644 --- a/src/server/game/Garrison/Garrison.cpp +++ b/src/server/game/Garrison/Garrison.cpp @@ -843,3 +843,11 @@ uint32 Garrison::Follower::GetItemLevel() const { return (PacketInfo.ItemLevelWeapon + PacketInfo.ItemLevelArmor) / 2; } + +bool Garrison::Follower::HasAbility(uint32 garrAbilityId) const +{ + return std::find_if(PacketInfo.AbilityID.begin(), PacketInfo.AbilityID.end(), [garrAbilityId](GarrAbilityEntry const* garrAbility) + { + return garrAbility->ID == garrAbilityId; + }) != PacketInfo.AbilityID.end(); +} diff --git a/src/server/game/Garrison/Garrison.h b/src/server/game/Garrison/Garrison.h index 0dd41482ec7..67408fdc764 100644 --- a/src/server/game/Garrison/Garrison.h +++ b/src/server/game/Garrison/Garrison.h @@ -204,6 +204,7 @@ public: struct Follower { uint32 GetItemLevel() const; + bool HasAbility(uint32 garrAbilityId) const; WorldPackets::Garrison::GarrisonFollower PacketInfo; }; diff --git a/src/server/game/Scenarios/Scenario.cpp b/src/server/game/Scenarios/Scenario.cpp index 6fa62caede0..3deb4cb0057 100644 --- a/src/server/game/Scenarios/Scenario.cpp +++ b/src/server/game/Scenarios/Scenario.cpp @@ -124,6 +124,11 @@ bool Scenario::IsComplete() return true; } +ScenarioEntry const* Scenario::GetEntry() const +{ + return _data->Entry; +} + ScenarioStepState Scenario::GetStepState(ScenarioStepEntry const* step) { std::map<ScenarioStepEntry const*, ScenarioStepState>::const_iterator itr = _stepStates.find(step); diff --git a/src/server/game/Scenarios/Scenario.h b/src/server/game/Scenarios/Scenario.h index 7fe81c13517..480c8a54c95 100644 --- a/src/server/game/Scenarios/Scenario.h +++ b/src/server/game/Scenarios/Scenario.h @@ -64,6 +64,7 @@ class TC_GAME_API Scenario : public CriteriaHandler bool IsComplete(); void SetStepState(ScenarioStepEntry const* step, ScenarioStepState state) { _stepStates[step] = state; } + ScenarioEntry const* GetEntry() const; ScenarioStepState GetStepState(ScenarioStepEntry const* step); ScenarioStepEntry const* GetStep() const { return _currentstep; } ScenarioStepEntry const* GetFirstStep() const; |