mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Core/Players: Fixed traits not updating aura values when changing rank
This commit is contained in:
@@ -2754,7 +2754,7 @@ WorldLocation const* Player::GetStoredAuraTeleportLocation(uint32 spellId) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading /*= false*/, int32 fromSkill /*= 0*/, bool favorite /*= false*/, Optional<int32> traitDefinitionId /*= {}*/)
|
||||
bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading /*= false*/, int32 fromSkill /*= 0*/, bool favorite /*= false*/, Optional<PlayerSpellTrait> trait /*= {}*/)
|
||||
{
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE);
|
||||
if (!spellInfo)
|
||||
@@ -2834,13 +2834,13 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
|
||||
dependent_set = true;
|
||||
}
|
||||
|
||||
if (itr->second.TraitDefinitionId != traitDefinitionId)
|
||||
if (itr->second.Trait != trait)
|
||||
{
|
||||
if (itr->second.TraitDefinitionId)
|
||||
if (TraitDefinitionEntry const* traitDefinition = sTraitDefinitionStore.LookupEntry(*itr->second.TraitDefinitionId))
|
||||
if (itr->second.Trait)
|
||||
if (TraitDefinitionEntry const* traitDefinition = sTraitDefinitionStore.LookupEntry(itr->second.Trait->DefinitionId))
|
||||
RemoveOverrideSpell(traitDefinition->OverridesSpellID, spellId);
|
||||
|
||||
itr->second.TraitDefinitionId = traitDefinitionId;
|
||||
itr->second.Trait = trait;
|
||||
}
|
||||
|
||||
itr->second.favorite = favorite;
|
||||
@@ -2918,7 +2918,7 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
|
||||
LearnSpell(prev_spell, true, fromSkill);
|
||||
}
|
||||
|
||||
std::pair<PlayerSpellMap::iterator, bool> inserted = m_spells.emplace(std::piecewise_construct, std::forward_as_tuple(spellId), std::forward_as_tuple());
|
||||
std::pair<PlayerSpellMap::iterator, bool> inserted = m_spells.try_emplace(spellId);
|
||||
PlayerSpell& newspell = inserted.first->second;
|
||||
// learning a previous rank might have given us this spell already from a skill autolearn, most likely with PLAYERSPELL_NEW state
|
||||
// we dont want to do double insert if this happened during load from db so we force state to CHANGED, just in case
|
||||
@@ -2927,8 +2927,7 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
|
||||
newspell.dependent = dependent;
|
||||
newspell.disabled = disabled;
|
||||
newspell.favorite = favorite;
|
||||
if (traitDefinitionId)
|
||||
newspell.TraitDefinitionId = *traitDefinitionId;
|
||||
newspell.Trait = trait;
|
||||
|
||||
// replace spells in action bars and spellbook to bigger rank if only one spell rank must be accessible
|
||||
if (newspell.active && !newspell.disabled && spellInfo->IsRanked())
|
||||
@@ -2994,48 +2993,13 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
|
||||
|
||||
if (castSpell)
|
||||
{
|
||||
CastSpellExtraArgs args;
|
||||
args.SetTriggerFlags(TRIGGERED_FULL_MASK);
|
||||
|
||||
if (traitDefinitionId)
|
||||
{
|
||||
if (UF::TraitConfig const* traitConfig = GetTraitConfig(m_activePlayerData->ActiveCombatTraitConfigID))
|
||||
{
|
||||
int32 traitEntryIndex = traitConfig->Entries.FindIndexIf([traitDefinitionId](UF::TraitEntry const& traitEntry)
|
||||
{
|
||||
return sTraitNodeEntryStore.AssertEntry(traitEntry.TraitNodeEntryID)->TraitDefinitionID == traitDefinitionId;
|
||||
});
|
||||
int32 rank = 0;
|
||||
if (traitEntryIndex >= 0)
|
||||
rank = traitConfig->Entries[traitEntryIndex].Rank + traitConfig->Entries[traitEntryIndex].GrantedRanks;
|
||||
|
||||
if (rank > 0)
|
||||
{
|
||||
if (std::vector<TraitDefinitionEffectPointsEntry const*> const* traitDefinitionEffectPoints = TraitMgr::GetTraitDefinitionEffectPointModifiers(*traitDefinitionId))
|
||||
{
|
||||
for (TraitDefinitionEffectPointsEntry const* traitDefinitionEffectPoint : *traitDefinitionEffectPoints)
|
||||
{
|
||||
if (traitDefinitionEffectPoint->EffectIndex >= int32(spellInfo->GetEffects().size()))
|
||||
continue;
|
||||
|
||||
float basePoints = sDB2Manager.GetCurveValueAt(traitDefinitionEffectPoint->CurveID, rank);
|
||||
if (traitDefinitionEffectPoint->GetOperationType() == TraitPointsOperationType::Multiply)
|
||||
basePoints *= spellInfo->GetEffect(SpellEffIndex(traitDefinitionEffectPoint->EffectIndex)).CalcBaseValue(this, nullptr, 0, -1);
|
||||
|
||||
args.AddSpellMod(SpellValueMod(SPELLVALUE_BASE_POINT0 + traitDefinitionEffectPoint->EffectIndex), basePoints);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CastSpell(this, spellId, args);
|
||||
CastSpell(this, spellId, true);
|
||||
if (spellInfo->HasEffect(SPELL_EFFECT_SKILL_STEP))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (traitDefinitionId)
|
||||
if (TraitDefinitionEntry const* traitDefinition = sTraitDefinitionStore.LookupEntry(*traitDefinitionId))
|
||||
if (trait)
|
||||
if (TraitDefinitionEntry const* traitDefinition = sTraitDefinitionStore.LookupEntry(trait->DefinitionId))
|
||||
if (traitDefinition->OverridesSpellID)
|
||||
AddOverrideSpell(traitDefinition->OverridesSpellID, spellId);
|
||||
|
||||
@@ -3206,7 +3170,7 @@ bool Player::HandlePassiveSpellLearn(SpellInfo const* spellInfo)
|
||||
return need_cast && (!spellInfo->CasterAuraState || HasAuraState(AuraStateType(spellInfo->CasterAuraState)));
|
||||
}
|
||||
|
||||
void Player::LearnSpell(uint32 spell_id, bool dependent, int32 fromSkill /*= 0*/, bool suppressMessaging /*= false*/, Optional<int32> traitDefinitionId /*= {}*/)
|
||||
void Player::LearnSpell(uint32 spell_id, bool dependent, int32 fromSkill /*= 0*/, bool suppressMessaging /*= false*/, Optional<PlayerSpellTrait> trait /*= {}*/)
|
||||
{
|
||||
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
|
||||
|
||||
@@ -3214,7 +3178,7 @@ void Player::LearnSpell(uint32 spell_id, bool dependent, int32 fromSkill /*= 0*/
|
||||
bool active = disabled ? itr->second.active : true;
|
||||
bool favorite = itr != m_spells.end() ? itr->second.favorite : false;
|
||||
|
||||
bool learning = AddSpell(spell_id, active, true, dependent, false, false, fromSkill, favorite, traitDefinitionId);
|
||||
bool learning = AddSpell(spell_id, active, true, dependent, false, false, fromSkill, favorite, trait);
|
||||
|
||||
// prevent duplicated entires in spell book, also not send if not in world (loading)
|
||||
if (learning && IsInWorld())
|
||||
@@ -3223,7 +3187,8 @@ void Player::LearnSpell(uint32 spell_id, bool dependent, int32 fromSkill /*= 0*/
|
||||
WorldPackets::Spells::LearnedSpellInfo& learnedSpellInfo = learnedSpells.ClientLearnedSpellData.emplace_back();
|
||||
learnedSpellInfo.SpellID = spell_id;
|
||||
learnedSpellInfo.Favorite = favorite;
|
||||
learnedSpellInfo.TraitDefinitionID = traitDefinitionId;
|
||||
if (trait)
|
||||
learnedSpellInfo.TraitDefinitionID = int32(trait->DefinitionId);
|
||||
learnedSpells.SuppressMessaging = suppressMessaging;
|
||||
SendDirectMessage(learnedSpells.Write());
|
||||
}
|
||||
@@ -3278,7 +3243,7 @@ void Player::RemoveSpell(uint32 spell_id, bool disabled /*= false*/, bool learn_
|
||||
|
||||
bool cur_active = itr->second.active;
|
||||
bool cur_dependent = itr->second.dependent;
|
||||
Optional<int32> traitDefinitionId = itr->second.TraitDefinitionId;
|
||||
Optional<PlayerSpellTrait> trait = itr->second.Trait;
|
||||
|
||||
if (disabled)
|
||||
{
|
||||
@@ -3437,8 +3402,8 @@ void Player::RemoveSpell(uint32 spell_id, bool disabled /*= false*/, bool learn_
|
||||
}
|
||||
}
|
||||
|
||||
if (traitDefinitionId)
|
||||
if (TraitDefinitionEntry const* traitDefinition = sTraitDefinitionStore.LookupEntry(*traitDefinitionId))
|
||||
if (trait)
|
||||
if (TraitDefinitionEntry const* traitDefinition = sTraitDefinitionStore.LookupEntry(trait->DefinitionId))
|
||||
RemoveOverrideSpell(traitDefinition->OverridesSpellID, spell_id);
|
||||
|
||||
m_overrideSpells.erase(spell_id);
|
||||
@@ -17643,9 +17608,6 @@ void Player::_LoadEquipmentSets(PreparedQueryResult result)
|
||||
if (ObjectGuid::LowType guid = fields[6 + i].GetUInt64())
|
||||
eqSet.Data.Pieces[i] = ObjectGuid::Create<HighGuid::Item>(guid);
|
||||
|
||||
eqSet.Data.Appearances.fill(0);
|
||||
eqSet.Data.Enchants.fill(0);
|
||||
|
||||
if (eqSet.Data.SetID >= MAX_EQUIPMENT_SET_INDEX) // client limit
|
||||
continue;
|
||||
|
||||
@@ -17676,7 +17638,6 @@ void Player::_LoadTransmogOutfits(PreparedQueryResult result)
|
||||
eqSet.Data.SetIcon = fields[3].GetString();
|
||||
eqSet.Data.IgnoreMask = fields[4].GetUInt32();
|
||||
eqSet.State = EQUIPMENT_SET_UNCHANGED;
|
||||
eqSet.Data.Pieces.fill(ObjectGuid::Empty);
|
||||
|
||||
for (uint32 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
|
||||
eqSet.Data.Appearances[i] = fields[5 + i].GetInt32();
|
||||
@@ -28789,7 +28750,7 @@ void Player::ApplyTraitEntryChanges(int32 editedConfigId, WorldPackets::Traits::
|
||||
|
||||
// remove traits not found in new config
|
||||
std::set<int32, std::greater<>> entryIndicesToRemove;
|
||||
for (int32 i = 0; i < int32(editedConfig.Entries.size()); ++i)
|
||||
for (int32 i = 0; i < std::ssize(editedConfig.Entries); ++i)
|
||||
{
|
||||
UF::TraitEntry const& oldEntry = editedConfig.Entries[i];
|
||||
auto entryItr = std::ranges::find_if(newConfig.Entries, makeTraitEntryFinder(oldEntry.TraitNodeID, oldEntry.TraitNodeEntryID));
|
||||
@@ -28812,9 +28773,8 @@ void Player::ApplyTraitEntryChanges(int32 editedConfigId, WorldPackets::Traits::
|
||||
std::vector<WorldPackets::Traits::TraitEntry> costEntries;
|
||||
|
||||
// apply new traits
|
||||
for (std::size_t i = 0; i < newConfig.Entries.size(); ++i)
|
||||
for (WorldPackets::Traits::TraitEntry const& newEntry : newConfig.Entries)
|
||||
{
|
||||
WorldPackets::Traits::TraitEntry const& newEntry = newConfig.Entries[i];
|
||||
int32 oldEntryIndex = editedConfig.Entries.FindIndexIf(makeTraitEntryFinder(newEntry.TraitNodeID, newEntry.TraitNodeEntryID));
|
||||
if (oldEntryIndex < 0)
|
||||
{
|
||||
@@ -28851,7 +28811,10 @@ void Player::ApplyTraitEntryChanges(int32 editedConfigId, WorldPackets::Traits::
|
||||
.ModifyValue(&UF::TraitEntry::GrantedRanks), newEntry.GrantedRanks);
|
||||
|
||||
if (applyTraits)
|
||||
{
|
||||
ApplyTraitEntry(newEntry.TraitNodeEntryID, 0, 0, false);
|
||||
ApplyTraitEntry(newEntry.TraitNodeEntryID, newEntry.Rank, newEntry.GrantedRanks, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28880,9 +28843,8 @@ void Player::ApplyTraitEntryChanges(int32 editedConfigId, WorldPackets::Traits::
|
||||
}
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < newConfig.SubTrees.size(); ++i)
|
||||
for (WorldPackets::Traits::TraitSubTreeCache const& newSubTree : newConfig.SubTrees)
|
||||
{
|
||||
WorldPackets::Traits::TraitSubTreeCache const& newSubTree = newConfig.SubTrees[i];
|
||||
int32 oldSubTreeIndex = editedConfig.SubTrees.FindIndexIf([&](UF::TraitSubTreeCache const& ufSubTree) { return ufSubTree.TraitSubTreeID == newSubTree.TraitSubTreeID; });
|
||||
std::vector<UF::TraitEntry> subTreeEntries;
|
||||
subTreeEntries.resize(newSubTree.Entries.size());
|
||||
@@ -28894,6 +28856,7 @@ void Player::ApplyTraitEntryChanges(int32 editedConfigId, WorldPackets::Traits::
|
||||
newUfEntry.Rank = newSubTree.Entries[j].Rank;
|
||||
newUfEntry.GrantedRanks = newSubTree.Entries[j].GrantedRanks;
|
||||
}
|
||||
|
||||
if (oldSubTreeIndex < 0)
|
||||
{
|
||||
UF::TraitSubTreeCache& newUfSubTree = AddDynamicUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData)
|
||||
@@ -28972,7 +28935,7 @@ void Player::ApplyTraitConfig(int32 configId, bool apply)
|
||||
ApplyTraitEntry(traitEntry.TraitNodeEntryID, traitEntry.Rank, traitEntry.GrantedRanks, apply);
|
||||
}
|
||||
|
||||
void Player::ApplyTraitEntry(int32 traitNodeEntryId, int32 /*rank*/, int32 /*grantedRanks*/, bool apply)
|
||||
void Player::ApplyTraitEntry(int32 traitNodeEntryId, int32 rank, int32 grantedRanks, bool apply)
|
||||
{
|
||||
TraitNodeEntryEntry const* traitNodeEntry = sTraitNodeEntryStore.LookupEntry(traitNodeEntryId);
|
||||
if (!traitNodeEntry)
|
||||
@@ -28984,8 +28947,10 @@ void Player::ApplyTraitEntry(int32 traitNodeEntryId, int32 /*rank*/, int32 /*gra
|
||||
|
||||
if (traitDefinition->SpellID)
|
||||
{
|
||||
ASSERT(traitNodeEntry->TraitDefinitionID <= 0xFFFFFF && rank + grantedRanks <= 0xFF);
|
||||
|
||||
if (apply)
|
||||
LearnSpell(traitDefinition->SpellID, true, 0, false, traitNodeEntry->TraitDefinitionID);
|
||||
LearnSpell(traitDefinition->SpellID, true, 0, false, PlayerSpellTrait{ .DefinitionId = traitNodeEntry->TraitDefinitionID, .Rank = rank + grantedRanks });
|
||||
else
|
||||
RemoveSpell(traitDefinition->SpellID);
|
||||
}
|
||||
@@ -29064,6 +29029,13 @@ void Player::SetTraitConfigUseSharedActionBars(int32 traitConfigId, bool usesSha
|
||||
m_traitConfigStates[traitConfigId] = PLAYERSPELL_CHANGED;
|
||||
}
|
||||
|
||||
Optional<PlayerSpellTrait> Player::GetTraitInfoForSpell(uint32 spellId) const
|
||||
{
|
||||
if (PlayerSpell const* spell = Trinity::Containers::MapGetValuePtr(m_spells, spellId))
|
||||
return spell->Trait;
|
||||
return {};
|
||||
}
|
||||
|
||||
void Player::SetReputation(uint32 factionentry, int32 value)
|
||||
{
|
||||
GetReputationMgr().SetReputation(sFactionStore.LookupEntry(factionentry), value);
|
||||
|
||||
@@ -200,6 +200,14 @@ enum PlayerSpellState : uint8
|
||||
PLAYERSPELL_TEMPORARY = 4
|
||||
};
|
||||
|
||||
struct PlayerSpellTrait
|
||||
{
|
||||
int32 DefinitionId : 24;
|
||||
int32 Rank : 8;
|
||||
|
||||
friend bool operator==(PlayerSpellTrait const&, PlayerSpellTrait const&) noexcept = default;
|
||||
};
|
||||
|
||||
struct PlayerSpell
|
||||
{
|
||||
PlayerSpellState state;
|
||||
@@ -207,7 +215,7 @@ struct PlayerSpell
|
||||
bool dependent : 1; // learned as result another spell learn, skill grow, quest reward, etc
|
||||
bool disabled : 1; // first rank has been learned in result talent learn but currently talent unlearned, save max learned ranks
|
||||
bool favorite : 1;
|
||||
Optional<int32> TraitDefinitionId;
|
||||
Optional<PlayerSpellTrait> Trait;
|
||||
};
|
||||
|
||||
struct StoredAuraTeleportLocation
|
||||
@@ -1891,8 +1899,8 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
|
||||
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask) const;
|
||||
void SendKnownSpells();
|
||||
void SendUnlearnSpells();
|
||||
bool AddSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading = false, int32 fromSkill = 0, bool favorite = false, Optional<int32> traitDefinitionId = {});
|
||||
void LearnSpell(uint32 spell_id, bool dependent, int32 fromSkill = 0, bool suppressMessaging = false, Optional<int32> traitDefinitionId = {});
|
||||
bool AddSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading = false, int32 fromSkill = 0, bool favorite = false, Optional<PlayerSpellTrait> trait = {});
|
||||
void LearnSpell(uint32 spell_id, bool dependent, int32 fromSkill = 0, bool suppressMessaging = false, Optional<PlayerSpellTrait> trait = {});
|
||||
void RemoveSpell(uint32 spell_id, bool disabled = false, bool learn_low_rank = true, bool suppressMessaging = false);
|
||||
void ResetSpells(bool myClassOnly = false);
|
||||
void LearnCustomSpells();
|
||||
@@ -1986,6 +1994,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
|
||||
void SetActiveCombatTraitConfigID(int32 traitConfigId) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::ActiveCombatTraitConfigID), traitConfigId); }
|
||||
void SetTraitConfigUseStarterBuild(int32 traitConfigId, bool useStarterBuild);
|
||||
void SetTraitConfigUseSharedActionBars(int32 traitConfigId, bool usesSharedActionBars, bool isLastSelectedSavedConfig);
|
||||
Optional<PlayerSpellTrait> GetTraitInfoForSpell(uint32 spellId) const;
|
||||
|
||||
uint32 GetFreePrimaryProfessionPoints() const { return m_activePlayerData->CharacterPoints; }
|
||||
void SetFreePrimaryProfessions(uint16 profs) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::CharacterPoints), profs); }
|
||||
|
||||
@@ -47,7 +47,7 @@ void WorldSession::HandleTraitsCommitConfig(WorldPackets::Traits::TraitsCommitCo
|
||||
|
||||
auto findEntry = [](WorldPackets::Traits::TraitConfig& config, int32 traitNodeId, int32 traitNodeEntryId) -> WorldPackets::Traits::TraitEntry*
|
||||
{
|
||||
auto entryItr = std::find_if(config.Entries.begin(), config.Entries.end(), [=](WorldPackets::Traits::TraitEntry const& traitEntry)
|
||||
auto entryItr = std::ranges::find_if(config.Entries, [=](WorldPackets::Traits::TraitEntry const& traitEntry)
|
||||
{
|
||||
return traitEntry.TraitNodeID == traitNodeId && traitEntry.TraitNodeEntryID == traitNodeEntryId;
|
||||
});
|
||||
@@ -118,10 +118,10 @@ void WorldSession::HandleTraitsCommitConfig(WorldPackets::Traits::TraitsCommitCo
|
||||
if (newEntry.Rank)
|
||||
traitEntry->Rank = newEntry.Rank;
|
||||
else
|
||||
newConfigState.Entries.erase(std::remove_if(newConfigState.Entries.begin(), newConfigState.Entries.end(), [&newEntry](WorldPackets::Traits::TraitEntry const& traitEntry)
|
||||
std::erase_if(newConfigState.Entries, [&newEntry](WorldPackets::Traits::TraitEntry const& traitEntry)
|
||||
{
|
||||
return traitEntry.TraitNodeID == newEntry.TraitNodeID && traitEntry.TraitNodeEntryID == newEntry.TraitNodeEntryID;
|
||||
}), newConfigState.Entries.end());
|
||||
});
|
||||
}
|
||||
else
|
||||
newConfigState.Entries.emplace_back() = newEntry;
|
||||
@@ -152,7 +152,7 @@ void WorldSession::HandleClassTalentsRequestNewConfig(WorldPackets::Traits::Clas
|
||||
if ((classTalentsRequestNewConfig.Config.CombatConfigFlags & TraitCombatConfigFlags::ActiveForSpec) != TraitCombatConfigFlags::None)
|
||||
return;
|
||||
|
||||
int64 configCount = std::count_if(_player->m_activePlayerData->TraitConfigs.begin(), _player->m_activePlayerData->TraitConfigs.end(), [](UF::TraitConfig const& traitConfig)
|
||||
int64 configCount = std::ranges::count_if(_player->m_activePlayerData->TraitConfigs, [](UF::TraitConfig const& traitConfig)
|
||||
{
|
||||
return static_cast<TraitConfigType>(*traitConfig.Type) == TraitConfigType::Combat
|
||||
&& (static_cast<TraitCombatConfigFlags>(*traitConfig.CombatConfigFlags) & TraitCombatConfigFlags::ActiveForSpec) == TraitCombatConfigFlags::None;
|
||||
@@ -179,7 +179,7 @@ void WorldSession::HandleClassTalentsRequestNewConfig(WorldPackets::Traits::Clas
|
||||
|
||||
for (UF::TraitEntry const& grantedEntry : TraitMgr::GetGrantedTraitEntriesForConfig(classTalentsRequestNewConfig.Config, _player))
|
||||
{
|
||||
auto entryItr = std::find_if(classTalentsRequestNewConfig.Config.Entries.begin(), classTalentsRequestNewConfig.Config.Entries.end(),
|
||||
auto entryItr = std::ranges::find_if(classTalentsRequestNewConfig.Config.Entries,
|
||||
[&](WorldPackets::Traits::TraitEntry const& entry) { return entry.TraitNodeID == grantedEntry.TraitNodeID && entry.TraitNodeEntryID == grantedEntry.TraitNodeEntryID; });
|
||||
|
||||
WorldPackets::Traits::TraitEntry& newEntry = entryItr != classTalentsRequestNewConfig.Config.Entries.end() ? *entryItr : classTalentsRequestNewConfig.Config.Entries.emplace_back();
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "Spell.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "TraitMgr.h"
|
||||
#include "Vehicle.h"
|
||||
#include <G3D/g3dmath.h>
|
||||
#include <bit>
|
||||
@@ -503,7 +504,35 @@ int32 SpellEffectInfo::CalcValue(WorldObject const* caster /*= nullptr*/, int32
|
||||
|
||||
Unit const* casterUnit = nullptr;
|
||||
if (caster)
|
||||
{
|
||||
casterUnit = caster->ToUnit();
|
||||
if (Player const* playerCaster = caster->ToPlayer())
|
||||
{
|
||||
if (Optional<PlayerSpellTrait> trait = playerCaster->GetTraitInfoForSpell(_spellInfo->Id))
|
||||
{
|
||||
if (std::vector<TraitDefinitionEffectPointsEntry const*> const* traitDefinitionEffectPoints = TraitMgr::GetTraitDefinitionEffectPointModifiers(trait->DefinitionId))
|
||||
{
|
||||
auto pointsOverride = std::ranges::find(*traitDefinitionEffectPoints, EffectIndex, &TraitDefinitionEffectPointsEntry::EffectIndex);
|
||||
if (pointsOverride != traitDefinitionEffectPoints->end())
|
||||
{
|
||||
float traitBasePoints = sDB2Manager.GetCurveValueAt((*pointsOverride)->CurveID, trait->Rank);
|
||||
switch ((*pointsOverride)->GetOperationType())
|
||||
{
|
||||
case TraitPointsOperationType::Set:
|
||||
value = traitBasePoints;
|
||||
break;
|
||||
case TraitPointsOperationType::Multiply:
|
||||
value *= traitBasePoints;
|
||||
break;
|
||||
case TraitPointsOperationType::None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Scaling.Variance)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user