diff options
| -rw-r--r-- | sql/base/characters_database.sql | 3 | ||||
| -rw-r--r-- | sql/updates/characters/master/2022_12_30_00_characters.sql | 3 | ||||
| -rw-r--r-- | src/server/game/Spells/TraitMgr.cpp | 48 |
3 files changed, 38 insertions, 16 deletions
diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index ae7a7b33efb..1395c96ae3e 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -3690,7 +3690,8 @@ INSERT INTO `updates` VALUES ('2022_11_20_00_characters.sql','4EB8BB24CAF16B0962DF3EF92C77BE05E234CFA6','ARCHIVED','2022-11-20 11:05:20',0), ('2022_12_16_00_characters.sql','36D6220143109ECD37219CC4A84773B31EAE9E50','ARCHIVED','2022-12-16 22:52:19',0), ('2022_12_17_00_characters.sql','3E005BD6B9C60653749B0B3C19CBC497092B9CCB','ARCHIVED','2022-12-17 18:26:43',0), -('2022_12_20_00_characters.sql','75A37A085AF1B953926E4352E439C7916B290924','ARCHIVED','2022-12-20 03:10:07',0); +('2022_12_20_00_characters.sql','75A37A085AF1B953926E4352E439C7916B290924','ARCHIVED','2022-12-20 03:10:07',0), +('2022_12_30_00_characters.sql','5F90C2BFFBB8F6CE0A3327A2CAABCD5CA3C2BA60','RELEASED','2022-12-30 22:50:16',0); /*!40000 ALTER TABLE `updates` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/characters/master/2022_12_30_00_characters.sql b/sql/updates/characters/master/2022_12_30_00_characters.sql new file mode 100644 index 00000000000..ce1280de0d7 --- /dev/null +++ b/sql/updates/characters/master/2022_12_30_00_characters.sql @@ -0,0 +1,3 @@ +-- delete corrupted trait configs +DELETE FROM `character_trait_entry`; +DELETE FROM `character_trait_config`; diff --git a/src/server/game/Spells/TraitMgr.cpp b/src/server/game/Spells/TraitMgr.cpp index 33d5f215f2c..694cfd31ec7 100644 --- a/src/server/game/Spells/TraitMgr.cpp +++ b/src/server/game/Spells/TraitMgr.cpp @@ -454,8 +454,15 @@ bool MeetsTraitCondition(WorldPackets::Traits::TraitConfig const& traitConfig, P if (condition->AchievementID && !player->HasAchieved(condition->AchievementID)) return false; - if (condition->SpecSetID && !sDB2Manager.IsSpecSetMember(condition->SpecSetID, player->GetPrimarySpecialization())) - return false; + if (condition->SpecSetID) + { + uint32 chrSpecializationId = player->GetPrimarySpecialization(); + if (traitConfig.Type == TraitConfigType::Combat) + chrSpecializationId = traitConfig.ChrSpecializationID; + + if (!sDB2Manager.IsSpecSetMember(condition->SpecSetID, chrSpecializationId)) + return false; + } if (condition->TraitCurrencyID && condition->SpentAmountRequired) { @@ -587,6 +594,23 @@ TalentLearnResult ValidateConfig(WorldPackets::Traits::TraitConfig const& traitC Optional<std::map<int32, int32>> spentCurrencies; FillSpentCurrenciesMap(traitConfig, spentCurrencies.emplace()); + auto meetsConditions = [&](std::vector<TraitCondEntry const*> const& conditions) + { + bool hasConditions = false; + for (TraitCondEntry const* condition : conditions) + { + if (condition->GetCondType() == TraitConditionType::Available || condition->GetCondType() == TraitConditionType::Visible) + { + if (MeetsTraitCondition(traitConfig, player, condition, spentCurrencies)) + return true; + + hasConditions = true; + } + } + + return !hasConditions; + }; + for (WorldPackets::Traits::TraitEntry const& traitEntry : traitConfig.Entries) { if (!IsValidEntry(traitEntry)) @@ -598,21 +622,15 @@ TalentLearnResult ValidateConfig(WorldPackets::Traits::TraitConfig const& traitC return TALENT_FAILED_UNKNOWN; for (NodeEntry const& entry : node->Entries) - for (TraitCondEntry const* condition : entry.Conditions) - if ((condition->GetCondType() == TraitConditionType::Available || condition->GetCondType() == TraitConditionType::Visible) - && !MeetsTraitCondition(traitConfig, player, condition, spentCurrencies)) - return TALENT_FAILED_UNKNOWN; - - for (TraitCondEntry const* condition : node->Conditions) - if ((condition->GetCondType() == TraitConditionType::Available || condition->GetCondType() == TraitConditionType::Visible) - && !MeetsTraitCondition(traitConfig, player, condition, spentCurrencies)) + if (!meetsConditions(entry.Conditions)) return TALENT_FAILED_UNKNOWN; + if (!meetsConditions(node->Conditions)) + return TALENT_FAILED_UNKNOWN; + for (NodeGroup const* group : node->Groups) - for (TraitCondEntry const* condition : group->Conditions) - if ((condition->GetCondType() == TraitConditionType::Available || condition->GetCondType() == TraitConditionType::Visible) - && !MeetsTraitCondition(traitConfig, player, condition, spentCurrencies)) - return TALENT_FAILED_UNKNOWN; + if (!meetsConditions(group->Conditions)) + return TALENT_FAILED_UNKNOWN; if (!node->ParentNodes.empty()) { @@ -721,7 +739,7 @@ void InitializeStarterBuildTraitConfig(WorldPackets::Traits::TraitConfig& traitC newEntry.Rank = addedRanks; if (!HasEnoughCurrency(newEntry, currencies)) - break; + continue; if (entryInConfig) entryInConfig->Rank += addedRanks; |
