Core/Items: Fixed crash in selecting azerite essences

* Also fixed OVERRIDE_SPELLS auras for SPELLFAMILY_GENERIC
This commit is contained in:
Shauren
2019-12-01 00:13:51 +01:00
parent 1238583312
commit bec4ed0f16
6 changed files with 68 additions and 55 deletions

View File

@@ -99,7 +99,7 @@ void AzeriteItem::SaveToDB(CharacterDatabaseTransaction& trans)
}
}
void AzeriteItem::LoadAzeriteItemData(Player* owner, AzeriteItemData& azeriteItemData)
void AzeriteItem::LoadAzeriteItemData(Player const* owner, AzeriteItemData& azeriteItemData)
{
bool needSave = false;
@@ -159,12 +159,12 @@ void AzeriteItem::LoadAzeriteItemData(Player* owner, AzeriteItemData& azeriteIte
selectedEssences.ModifyValue(&UF::SelectedAzeriteEssences::AzeriteEssenceID, i).SetValue(selectedEssenceData.AzeriteEssenceId[i]);
}
if (owner->GetPrimarySpecialization() == selectedEssenceData.SpecializationId)
if (owner && owner->GetPrimarySpecialization() == selectedEssenceData.SpecializationId)
selectedEssences.ModifyValue(&UF::SelectedAzeriteEssences::Enabled).SetValue(1);
}
// add selected essences for current spec
if (!GetSelectedAzeriteEssences())
if (owner && !GetSelectedAzeriteEssences())
CreateSelectedAzeriteEssences(owner->GetPrimarySpecialization());
if (needSave)
@@ -359,6 +359,13 @@ void AzeriteItem::SetSelectedAzeriteEssences(uint32 specializationId)
CreateSelectedAzeriteEssences(specializationId);
}
void AzeriteItem::CreateSelectedAzeriteEssences(uint32 specializationId)
{
auto selectedEssences = AddDynamicUpdateFieldValue(m_values.ModifyValue(&AzeriteItem::m_azeriteItemData).ModifyValue(&UF::AzeriteItemData::SelectedEssences));
selectedEssences.ModifyValue(&UF::SelectedAzeriteEssences::SpecializationID).SetValue(specializationId);
selectedEssences.ModifyValue(&UF::SelectedAzeriteEssences::Enabled).SetValue(1);
}
void AzeriteItem::SetSelectedAzeriteEssence(uint8 slot, uint32 azeriteEssenceId)
{
ASSERT(slot < MAX_AZERITE_ESSENCE_SLOT);
@@ -449,10 +456,3 @@ void AzeriteItem::UnlockDefaultMilestones()
hasPreviousMilestone = false;
}
}
void AzeriteItem::CreateSelectedAzeriteEssences(uint32 specializationId)
{
auto selectedEssences = AddDynamicUpdateFieldValue(m_values.ModifyValue(&AzeriteItem::m_azeriteItemData).ModifyValue(&UF::AzeriteItemData::SelectedEssences));
selectedEssences.ModifyValue(&UF::SelectedAzeriteEssences::SpecializationID).SetValue(specializationId);
selectedEssences.ModifyValue(&UF::SelectedAzeriteEssences::Enabled).SetValue(1);
}

View File

@@ -34,7 +34,7 @@ public:
bool Create(ObjectGuid::LowType guidlow, uint32 itemId, ItemContext context, Player const* owner) override;
void SaveToDB(CharacterDatabaseTransaction& trans) override;
void LoadAzeriteItemData(Player* owner, AzeriteItemData& azeriteItem);
void LoadAzeriteItemData(Player const* owner, AzeriteItemData& azeriteItem);
void DeleteFromDB(CharacterDatabaseTransaction& trans) override;
uint32 GetLevel() const { return m_azeriteItemData->Level; }
@@ -69,6 +69,7 @@ public:
UF::SelectedAzeriteEssences const* GetSelectedAzeriteEssences() const;
void SetSelectedAzeriteEssences(uint32 specializationId);
void CreateSelectedAzeriteEssences(uint32 specializationId);
void SetSelectedAzeriteEssence(uint8 slot, uint32 azeriteEssenceId);
void BuildValuesCreate(ByteBuffer* data, Player const* target) const override;
@@ -80,7 +81,6 @@ public:
private:
void UnlockDefaultMilestones();
void CreateSelectedAzeriteEssences(uint32 specializationId);
};
#endif // AzeriteItem_h__

View File

@@ -900,7 +900,7 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie
return true;
}
void Item::LoadArtifactData(Player* owner, uint64 xp, uint32 artifactAppearanceId, uint32 artifactTier, std::vector<ArtifactPowerData>& powers)
void Item::LoadArtifactData(Player const* owner, uint64 xp, uint32 artifactAppearanceId, uint32 artifactTier, std::vector<ArtifactPowerData>& powers)
{
for (uint8 i = 0; i <= artifactTier; ++i)
InitArtifactPowers(GetTemplate()->GetArtifactID(), i);
@@ -941,7 +941,7 @@ void Item::LoadArtifactData(Player* owner, uint64 xp, uint32 artifactAppearanceI
if (ArtifactPowerPickerEntry const* artifactPowerPicker = sArtifactPowerPickerStore.LookupEntry(enchant->EffectArg[i]))
{
PlayerConditionEntry const* playerCondition = sPlayerConditionStore.LookupEntry(artifactPowerPicker->PlayerConditionID);
if (!playerCondition || sConditionMgr->IsPlayerMeetingCondition(owner, playerCondition))
if (!playerCondition || (owner && sConditionMgr->IsPlayerMeetingCondition(owner, playerCondition)))
if (artifactPower->Label == _bonusData.GemRelicType[e - SOCK_ENCHANTMENT_SLOT])
power.CurrentRankWithBonus += enchant->EffectPointsMin[i];
}
@@ -966,7 +966,7 @@ void Item::LoadArtifactData(Player* owner, uint64 xp, uint32 artifactAppearanceI
SetArtifactPower(power.ArtifactPowerId, power.PurchasedRank, totalPurchasedRanks + 1);
}
CheckArtifactRelicSlotUnlock(owner ? owner : GetOwner());
CheckArtifactRelicSlotUnlock(owner);
}
void Item::CheckArtifactRelicSlotUnlock(Player const* owner)

View File

@@ -208,7 +208,7 @@ class TC_GAME_API Item : public Object
bool IsBoundByEnchant() const;
virtual void SaveToDB(CharacterDatabaseTransaction& trans);
virtual bool LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fields, uint32 entry);
void LoadArtifactData(Player* owner, uint64 xp, uint32 artifactAppearanceId, uint32 artifactTier, std::vector<ArtifactPowerData>& powers); // must be called after LoadFromDB to have gems (relics) initialized
void LoadArtifactData(Player const* owner, uint64 xp, uint32 artifactAppearanceId, uint32 artifactTier, std::vector<ArtifactPowerData>& powers); // must be called after LoadFromDB to have gems (relics) initialized
void CheckArtifactRelicSlotUnlock(Player const* owner);
void AddBonuses(uint32 bonusListID);

View File

@@ -14304,17 +14304,24 @@ void Unit::Whisper(uint32 textId, Player* target, bool isBossWhisper /*= false*/
SpellInfo const* Unit::GetCastSpellInfo(SpellInfo const* spellInfo) const
{
Unit::AuraEffectList swaps = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS);
Unit::AuraEffectList const& swaps2 = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS_TRIGGERED);
if (!swaps2.empty())
swaps.insert(swaps.end(), swaps2.begin(), swaps2.end());
for (AuraEffect const* auraEffect : swaps)
auto findMatchingAuraEffectIn = [this, spellInfo](AuraType type) -> SpellInfo const*
{
if (uint32(auraEffect->GetMiscValue()) == spellInfo->Id || auraEffect->IsAffectingSpell(spellInfo))
if (SpellInfo const* newInfo = sSpellMgr->GetSpellInfo(auraEffect->GetAmount()))
return newInfo;
}
for (AuraEffect const* auraEffect : GetAuraEffectsByType(type))
{
bool matches = auraEffect->GetMiscValue() ? uint32(auraEffect->GetMiscValue()) == spellInfo->Id : auraEffect->IsAffectingSpell(spellInfo);
if (matches)
if (SpellInfo const* newInfo = sSpellMgr->GetSpellInfo(auraEffect->GetAmount()))
return newInfo;
}
return nullptr;
};
if (SpellInfo const* newInfo = findMatchingAuraEffectIn(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS))
return newInfo;
if (SpellInfo const* newInfo = findMatchingAuraEffectIn(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS_TRIGGERED))
return newInfo;
return spellInfo;
}

View File

@@ -84,7 +84,7 @@ void WorldSession::HandleAzeriteEssenceActivateEssence(WorldPackets::Azerite::Az
UF::SelectedAzeriteEssences const* selectedEssences = azeriteItem->GetSelectedAzeriteEssences();
// essence is already in that slot, nothing to do
if (selectedEssences->AzeriteEssenceID[azeriteEssenceActivateEssence.Slot] == uint32(azeriteEssenceActivateEssence.AzeriteEssenceID))
if (selectedEssences && selectedEssences->AzeriteEssenceID[azeriteEssenceActivateEssence.Slot] == uint32(azeriteEssenceActivateEssence.AzeriteEssenceID))
return;
uint32 rank = azeriteItem->GetEssenceRank(azeriteEssenceActivateEssence.AzeriteEssenceID);
@@ -120,45 +120,51 @@ void WorldSession::HandleAzeriteEssenceActivateEssence(WorldPackets::Azerite::Az
return;
}
// need to remove selected essence from another slot if selected
int32 removeEssenceFromSlot = -1;
for (int32 slot = 0; slot < MAX_AZERITE_ESSENCE_SLOT; ++slot)
if (azeriteEssenceActivateEssence.Slot != uint8(slot) && selectedEssences->AzeriteEssenceID[slot] == uint32(azeriteEssenceActivateEssence.AzeriteEssenceID))
removeEssenceFromSlot = slot;
// check cooldown of major essence slot
if (selectedEssences->AzeriteEssenceID[0] && (azeriteEssenceActivateEssence.Slot == 0 || removeEssenceFromSlot == 0))
if (selectedEssences)
{
for (uint32 essenceRank = 1; essenceRank <= rank; ++essenceRank)
// need to remove selected essence from another slot if selected
int32 removeEssenceFromSlot = -1;
for (int32 slot = 0; slot < MAX_AZERITE_ESSENCE_SLOT; ++slot)
if (azeriteEssenceActivateEssence.Slot != uint8(slot) && selectedEssences->AzeriteEssenceID[slot] == uint32(azeriteEssenceActivateEssence.AzeriteEssenceID))
removeEssenceFromSlot = slot;
// check cooldown of major essence slot
if (selectedEssences->AzeriteEssenceID[0] && (azeriteEssenceActivateEssence.Slot == 0 || removeEssenceFromSlot == 0))
{
AzeriteEssencePowerEntry const* azeriteEssencePower = ASSERT_NOTNULL(sDB2Manager.GetAzeriteEssencePower(selectedEssences->AzeriteEssenceID[0], essenceRank));
if (_player->GetSpellHistory()->HasCooldown(azeriteEssencePower->MajorPowerDescription))
for (uint32 essenceRank = 1; essenceRank <= rank; ++essenceRank)
{
activateEssenceResult.Reason = AzeriteEssenceActivateResult::CantRemoveEssence;
activateEssenceResult.Arg = azeriteEssencePower->MajorPowerDescription;
activateEssenceResult.Slot = azeriteEssenceActivateEssence.Slot;
SendPacket(activateEssenceResult.Write());
return;
AzeriteEssencePowerEntry const* azeriteEssencePower = ASSERT_NOTNULL(sDB2Manager.GetAzeriteEssencePower(selectedEssences->AzeriteEssenceID[0], essenceRank));
if (_player->GetSpellHistory()->HasCooldown(azeriteEssencePower->MajorPowerDescription))
{
activateEssenceResult.Reason = AzeriteEssenceActivateResult::CantRemoveEssence;
activateEssenceResult.Arg = azeriteEssencePower->MajorPowerDescription;
activateEssenceResult.Slot = azeriteEssenceActivateEssence.Slot;
SendPacket(activateEssenceResult.Write());
return;
}
}
}
}
if (removeEssenceFromSlot != -1)
{
_player->ApplyAzeriteEssence(azeriteItem, selectedEssences->AzeriteEssenceID[removeEssenceFromSlot], MAX_AZERITE_ESSENCE_RANK,
AzeriteItemMilestoneType(sDB2Manager.GetAzeriteItemMilestonePower(removeEssenceFromSlot)->Type) == AzeriteItemMilestoneType::MajorEssence, false);
azeriteItem->SetSelectedAzeriteEssence(removeEssenceFromSlot, 0);
}
if (removeEssenceFromSlot != -1)
{
_player->ApplyAzeriteEssence(azeriteItem, selectedEssences->AzeriteEssenceID[removeEssenceFromSlot], MAX_AZERITE_ESSENCE_RANK,
AzeriteItemMilestoneType(sDB2Manager.GetAzeriteItemMilestonePower(removeEssenceFromSlot)->Type) == AzeriteItemMilestoneType::MajorEssence, false);
azeriteItem->SetSelectedAzeriteEssence(removeEssenceFromSlot, 0);
}
if (selectedEssences->AzeriteEssenceID[azeriteEssenceActivateEssence.Slot])
{
_player->ApplyAzeriteEssence(azeriteItem, selectedEssences->AzeriteEssenceID[azeriteEssenceActivateEssence.Slot], MAX_AZERITE_ESSENCE_RANK,
AzeriteItemMilestoneType(sDB2Manager.GetAzeriteItemMilestonePower(azeriteEssenceActivateEssence.Slot)->Type) == AzeriteItemMilestoneType::MajorEssence, false);
if (selectedEssences->AzeriteEssenceID[azeriteEssenceActivateEssence.Slot])
{
_player->ApplyAzeriteEssence(azeriteItem, selectedEssences->AzeriteEssenceID[azeriteEssenceActivateEssence.Slot], MAX_AZERITE_ESSENCE_RANK,
AzeriteItemMilestoneType(sDB2Manager.GetAzeriteItemMilestonePower(azeriteEssenceActivateEssence.Slot)->Type) == AzeriteItemMilestoneType::MajorEssence, false);
}
}
else
azeriteItem->CreateSelectedAzeriteEssences(_player->GetPrimarySpecialization());
azeriteItem->SetSelectedAzeriteEssence(azeriteEssenceActivateEssence.Slot, azeriteEssenceActivateEssence.AzeriteEssenceID);
_player->ApplyAzeriteEssence(azeriteItem, azeriteEssenceActivateEssence.AzeriteEssenceID, rank,
AzeriteItemMilestoneType(sDB2Manager.GetAzeriteItemMilestonePower(azeriteEssenceActivateEssence.Slot)->Type) == AzeriteItemMilestoneType::MajorEssence, true);
azeriteItem->SetSelectedAzeriteEssence(azeriteEssenceActivateEssence.Slot, azeriteEssenceActivateEssence.AzeriteEssenceID);
azeriteItem->SetState(ITEM_CHANGED, _player);
}