Core/Players: Fixed traits not updating aura values when changing rank
Port From (https://github.com/TrinityCore/TrinityCore/commit/e6b553b913152667bcd1cfb79790ec70790d0f6e)
This commit is contained in:
@@ -2141,7 +2141,7 @@ namespace Game.Entities
|
||||
SendPacket(new SendUnlearnSpells());
|
||||
}
|
||||
|
||||
public void LearnSpell(uint spellId, bool dependent, uint fromSkill = 0, bool suppressMessaging = false, int? traitDefinitionId = null)
|
||||
public void LearnSpell(uint spellId, bool dependent, uint fromSkill = 0, bool suppressMessaging = false, PlayerSpellTrait trait = null)
|
||||
{
|
||||
PlayerSpell spell = m_spells.LookupByKey(spellId);
|
||||
|
||||
@@ -2149,7 +2149,7 @@ namespace Game.Entities
|
||||
bool active = !disabled || spell.Active;
|
||||
bool favorite = spell != null ? spell.Favorite : false;
|
||||
|
||||
bool learning = AddSpell(spellId, active, true, dependent, false, false, fromSkill, favorite, traitDefinitionId);
|
||||
bool learning = AddSpell(spellId, 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)
|
||||
@@ -2158,7 +2158,8 @@ namespace Game.Entities
|
||||
LearnedSpellInfo learnedSpellInfo = new();
|
||||
learnedSpellInfo.SpellID = spellId;
|
||||
learnedSpellInfo.Favorite = favorite;
|
||||
learnedSpellInfo.TraitDefinitionID = traitDefinitionId;
|
||||
if (trait != null)
|
||||
learnedSpellInfo.TraitDefinitionID = trait.DefinitionId;
|
||||
learnedSpells.SuppressMessaging = suppressMessaging;
|
||||
learnedSpells.ClientLearnedSpellData.Add(learnedSpellInfo);
|
||||
SendPacket(learnedSpells);
|
||||
@@ -2216,7 +2217,7 @@ namespace Game.Entities
|
||||
|
||||
bool cur_active = pSpell.Active;
|
||||
bool cur_dependent = pSpell.Dependent;
|
||||
int? traitDefinitionId = pSpell.TraitDefinitionId;
|
||||
PlayerSpellTrait trait = pSpell.Trait;
|
||||
|
||||
if (disabled)
|
||||
{
|
||||
@@ -2380,9 +2381,9 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
if (traitDefinitionId.HasValue)
|
||||
if (trait != null)
|
||||
{
|
||||
var traitDefinition = CliDB.TraitDefinitionStorage.LookupByKey(traitDefinitionId.Value);
|
||||
var traitDefinition = CliDB.TraitDefinitionStorage.LookupByKey(trait.DefinitionId);
|
||||
if (traitDefinition != null)
|
||||
RemoveOverrideSpell(traitDefinition.OverridesSpellID, spellId);
|
||||
}
|
||||
@@ -2480,7 +2481,7 @@ namespace Game.Entities
|
||||
return null;
|
||||
}
|
||||
|
||||
bool AddSpell(uint spellId, bool active, bool learning, bool dependent, bool disabled, bool loading = false, uint fromSkill = 0, bool favorite = false, int? traitDefinitionId = null)
|
||||
bool AddSpell(uint spellId, bool active, bool learning, bool dependent, bool disabled, bool loading = false, uint fromSkill = 0, bool favorite = false, PlayerSpellTrait? trait = null)
|
||||
{
|
||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, Difficulty.None);
|
||||
if (spellInfo == null)
|
||||
@@ -2559,16 +2560,16 @@ namespace Game.Entities
|
||||
dependent_set = true;
|
||||
}
|
||||
|
||||
if (spell.TraitDefinitionId != traitDefinitionId)
|
||||
if (spell.Trait != trait)
|
||||
{
|
||||
if (spell.TraitDefinitionId.HasValue)
|
||||
if (spell.Trait != null)
|
||||
{
|
||||
TraitDefinitionRecord traitDefinition = CliDB.TraitDefinitionStorage.LookupByKey(spell.TraitDefinitionId.Value);
|
||||
TraitDefinitionRecord traitDefinition = CliDB.TraitDefinitionStorage.LookupByKey(spell.Trait.DefinitionId);
|
||||
if (traitDefinition != null)
|
||||
RemoveOverrideSpell((uint)traitDefinition.OverridesSpellID, spellId);
|
||||
RemoveOverrideSpell(traitDefinition.OverridesSpellID, spellId);
|
||||
}
|
||||
|
||||
spell.TraitDefinitionId = traitDefinitionId;
|
||||
spell.Trait = trait;
|
||||
}
|
||||
|
||||
spell.Favorite = favorite;
|
||||
@@ -2655,8 +2656,7 @@ namespace Game.Entities
|
||||
newspell.Dependent = dependent;
|
||||
newspell.Disabled = disabled;
|
||||
newspell.Favorite = favorite;
|
||||
if (traitDefinitionId.HasValue)
|
||||
newspell.TraitDefinitionId = traitDefinitionId.Value;
|
||||
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())
|
||||
@@ -2725,51 +2725,14 @@ namespace Game.Entities
|
||||
|
||||
if (castSpell)
|
||||
{
|
||||
CastSpellExtraArgs args = new(TriggerCastFlags.FullMask);
|
||||
|
||||
if (traitDefinitionId.HasValue)
|
||||
{
|
||||
TraitConfig traitConfig = GetTraitConfig((int)(uint)m_activePlayerData.ActiveCombatTraitConfigID);
|
||||
if (traitConfig != null)
|
||||
{
|
||||
int traitEntryIndex = traitConfig.Entries.FindIndexIf(traitEntry =>
|
||||
{
|
||||
return CliDB.TraitNodeEntryStorage.LookupByKey(traitEntry.TraitNodeEntryID)?.TraitDefinitionID == traitDefinitionId;
|
||||
});
|
||||
|
||||
int rank = 0;
|
||||
if (traitEntryIndex >= 0)
|
||||
rank = traitConfig.Entries[traitEntryIndex].Rank + traitConfig.Entries[traitEntryIndex].GrantedRanks;
|
||||
|
||||
if (rank > 0)
|
||||
{
|
||||
var traitDefinitionEffectPoints = TraitMgr.GetTraitDefinitionEffectPointModifiers(traitDefinitionId.Value);
|
||||
if (traitDefinitionEffectPoints != null)
|
||||
{
|
||||
foreach (TraitDefinitionEffectPointsRecord traitDefinitionEffectPoint in traitDefinitionEffectPoints)
|
||||
{
|
||||
if (traitDefinitionEffectPoint.EffectIndex >= spellInfo.GetEffects().Count)
|
||||
continue;
|
||||
|
||||
float basePoints = Global.DB2Mgr.GetCurveValueAt((uint)traitDefinitionEffectPoint.CurveID, rank);
|
||||
if (traitDefinitionEffectPoint.GetOperationType() == TraitPointsOperationType.Multiply)
|
||||
basePoints *= spellInfo.GetEffect((uint)traitDefinitionEffectPoint.EffectIndex).CalcBaseValue(this, null, 0, -1);
|
||||
|
||||
args.AddSpellMod(SpellValueMod.BasePoint0 + traitDefinitionEffectPoint.EffectIndex, (int)basePoints);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CastSpell(this, spellId, args);
|
||||
CastSpell(this, spellId, true);
|
||||
if (spellInfo.HasEffect(SpellEffectName.SkillStep))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (traitDefinitionId.HasValue)
|
||||
if (trait != null)
|
||||
{
|
||||
TraitDefinitionRecord traitDefinition = CliDB.TraitDefinitionStorage.LookupByKey(traitDefinitionId.Value);
|
||||
TraitDefinitionRecord traitDefinition = CliDB.TraitDefinitionStorage.LookupByKey(trait.DefinitionId);
|
||||
if (traitDefinition != null && traitDefinition.OverridesSpellID != 0)
|
||||
AddOverrideSpell(traitDefinition.OverridesSpellID, spellId);
|
||||
}
|
||||
@@ -4043,6 +4006,6 @@ namespace Game.Entities
|
||||
public bool Dependent;
|
||||
public bool Disabled;
|
||||
public bool Favorite;
|
||||
public int? TraitDefinitionId;
|
||||
public PlayerSpellTrait Trait;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1014,9 +1014,8 @@ namespace Game.Entities
|
||||
List<TraitEntryPacket> costEntries = new();
|
||||
|
||||
// apply new traits
|
||||
for (var i = 0; i < newConfig.Entries.Count; ++i)
|
||||
foreach (TraitEntryPacket newEntry in newConfig.Entries)
|
||||
{
|
||||
TraitEntryPacket newEntry = newConfig.Entries[i];
|
||||
int oldEntryIndex = editedConfig.Entries.FindIndexIf(ufEntry => ufEntry.TraitNodeID == newEntry.TraitNodeID && ufEntry.TraitNodeEntryID == newEntry.TraitNodeEntryID);
|
||||
if (oldEntryIndex < 0)
|
||||
{
|
||||
@@ -1033,7 +1032,10 @@ namespace Game.Entities
|
||||
AddDynamicUpdateFieldValue(newTraitConfig.ModifyValue(newTraitConfig.Entries), newUfEntry);
|
||||
|
||||
if (applyTraits)
|
||||
{
|
||||
ApplyTraitEntry(newEntry.TraitNodeEntryID, 0, 0, false);
|
||||
ApplyTraitEntry(newUfEntry.TraitNodeEntryID, newUfEntry.Rank, 0, true);
|
||||
}
|
||||
}
|
||||
else if (newEntry.Rank != editedConfig.Entries[oldEntryIndex].Rank || newEntry.GrantedRanks != editedConfig.Entries[oldEntryIndex].GrantedRanks)
|
||||
{
|
||||
@@ -1080,9 +1082,8 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < newConfig.SubTrees.Count; ++i)
|
||||
foreach (TraitSubTreeCachePacket newSubTree in newConfig.SubTrees)
|
||||
{
|
||||
var newSubTree = newConfig.SubTrees[i];
|
||||
int oldSubTreeIndex = editedConfig.SubTrees.FindIndexIf(ufSubTree => ufSubTree.TraitSubTreeID == newSubTree.TraitSubTreeID);
|
||||
|
||||
List<TraitEntry> subTreeEntries = new();
|
||||
@@ -1094,6 +1095,7 @@ namespace Game.Entities
|
||||
newUfEntry.Rank = newSubTree.Entries[j].Rank;
|
||||
newUfEntry.GrantedRanks = newSubTree.Entries[j].GrantedRanks;
|
||||
}
|
||||
|
||||
if (oldSubTreeIndex < 0)
|
||||
{
|
||||
TraitSubTreeCache newUfSubTree = new();
|
||||
@@ -1182,13 +1184,24 @@ namespace Game.Entities
|
||||
|
||||
if (traitDefinition.SpellID != 0)
|
||||
{
|
||||
Cypher.Assert(traitNodeEntry.TraitDefinitionID <= 0xFFFFFF && rank + grantedRanks <= 0xFF);
|
||||
|
||||
if (apply)
|
||||
LearnSpell(traitDefinition.SpellID, true, 0, false, traitNodeEntry.TraitDefinitionID);
|
||||
LearnSpell(traitDefinition.SpellID, true, 0, false, new PlayerSpellTrait(traitNodeEntry.TraitDefinitionID, rank + grantedRanks));
|
||||
else
|
||||
RemoveSpell(traitDefinition.SpellID);
|
||||
}
|
||||
}
|
||||
|
||||
public PlayerSpellTrait GetTraitInfoForSpell(uint spellId)
|
||||
{
|
||||
PlayerSpell spell = m_spells.LookupByKey(spellId);
|
||||
if (spell != null)
|
||||
return spell.Trait;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void SetTraitConfigUseStarterBuild(int traitConfigId, bool useStarterBuild)
|
||||
{
|
||||
int configIndex = m_activePlayerData.TraitConfigs.FindIndexIf(traitConfig =>
|
||||
|
||||
@@ -8068,4 +8068,28 @@ namespace Game.Entities
|
||||
public uint? InstanceId;
|
||||
public uint? LfgDungeonsId;
|
||||
}
|
||||
|
||||
public class PlayerSpellTrait
|
||||
{
|
||||
public int DefinitionId;
|
||||
public int Rank;
|
||||
|
||||
public PlayerSpellTrait(int definitionId, int rank)
|
||||
{
|
||||
DefinitionId = definitionId;
|
||||
Rank = rank;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is PlayerSpellTrait trait &&
|
||||
DefinitionId == trait.DefinitionId &&
|
||||
Rank == trait.Rank;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(DefinitionId, Rank);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user