Core: Updated to 11.2.5.63704

Port From (https://github.com/TrinityCore/TrinityCore/commit/53068a94e88991ae7196fb247df4b7ca2e47e554)
This commit is contained in:
Hondacrx
2025-12-16 13:57:09 -05:00
parent ed33a88776
commit 3a890782b5
57 changed files with 3079 additions and 2630 deletions
@@ -169,7 +169,7 @@ namespace Game.Entities
}
VisualAnim visualAnim = areaTriggerData.ModifyValue(m_areaTriggerData.VisualAnim);
SetUpdateFieldValue(visualAnim.ModifyValue(visualAnim.AnimationDataID), GetCreateProperties().AnimId);
SetUpdateFieldValue(visualAnim.ModifyValue(visualAnim.AnimationDataID), (ushort)GetCreateProperties().AnimId);
SetUpdateFieldValue(visualAnim.ModifyValue(visualAnim.AnimKitID), GetCreateProperties().AnimKitId);
if (GetCreateProperties() != null && GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.VisualAnimIsDecay))
SetUpdateFieldValue(visualAnim.ModifyValue(visualAnim.IsDecay), true);
+1 -1
View File
@@ -36,7 +36,7 @@ namespace Game.Entities
TrainerList trainerList = new();
trainerList.TrainerGUID = npc.GetGUID();
trainerList.TrainerType = (int)_type;
trainerList.TrainerType = (sbyte)_type;
trainerList.TrainerID = (int)_id;
trainerList.Greeting = GetGreeting(locale);
@@ -15,6 +15,11 @@ namespace Game.Entities
T GetValue();
}
public interface IsUpdateFieldStructureTag<T>
{
void WriteCreate(WorldPacket data, T owner, Player receiver);
void WriteUpdate(WorldPacket data, bool ignoreChangesMask, T owner, Player receiver);
}
public interface IHasChangesMask
{
void ClearChangesMask();
@@ -184,25 +189,18 @@ namespace Game.Entities
public class DynamicUpdateField<T> where T : new()
{
public List<T> _values;
public List<uint> _updateMask;
public List<T> _values = new();
public List<uint> _updateMask = new();
public int BlockBit;
public int Bit;
public DynamicUpdateField()
{
_values = new List<T>();
_updateMask = new List<uint>();
BlockBit = -1;
Bit = -1;
}
public DynamicUpdateField(int blockBit, int bit)
{
_values = new List<T>();
_updateMask = new List<uint>();
BlockBit = blockBit;
Bit = bit;
}
@@ -353,6 +351,81 @@ namespace Game.Entities
}
}
public enum MapUpdateFieldState
{
Unchanged = 0,
Changed = 1,
Deleted = 2
}
public class MapUpdateField<K, V> where V : new()
{
Dictionary<K, (V, MapUpdateFieldState)> _values = new();
public int BlockBit;
public int Bit;
public MapUpdateField(int blockBit, int bit)
{
BlockBit = blockBit;
Bit = bit;
}
public bool Empty()
{
return _values.Empty();
}
public int Size()
{
return _values.Count;
}
public void TryAdd(K key)
{
if (!_values.ContainsKey(key))
_values[key] = (new V(), MapUpdateFieldState.Changed);
}
public void Remove(K key)
{
_values.Remove(key);
}
public void MarkKeyForRemoval(K key)
{
var itr = _values.LookupByKey(key);
if (itr.Item1 != null)
itr.Item2 = MapUpdateFieldState.Deleted;
}
public (V, MapUpdateFieldState) Get(K key)
{
if (_values.TryGetValue(key, out var value))
return value;
return default;
}
public (K, V) FindIf(Predicate<V> predicate)
{
var itr = _values.First(pair => { return predicate(pair.Value.Item1); });
if (itr.Key != null)
return (itr.Key, itr.Value.Item1);
return default;
}
public IEnumerator<KeyValuePair<K, (V, MapUpdateFieldState)>> GetEnumerator()
{
foreach (var obj in _values)
yield return obj;
}
public List<K> GetKeys() { return _values.Keys.ToList(); }
public List<(V, MapUpdateFieldState)> GetValues() { return _values.Values.ToList(); }
}
public class VariantUpdateField(int blockBit, int bit)
{
public object _value;
@@ -435,6 +508,33 @@ namespace Game.Entities
public void ClearChangesMask(UpdateFieldString updateField) { }
public void ClearChangesMask<K, V>(MapUpdateField<K, V> field) where V : new()
{
foreach (var key in field.GetKeys())
{
var value = field.Get(key);
switch (value.Item2)
{
case MapUpdateFieldState.Unchanged:
break;
case MapUpdateFieldState.Changed:
if (typeof(HasChangesMask).IsAssignableFrom(typeof(K)))
((IHasChangesMask)key).ClearChangesMask();
if (typeof(HasChangesMask).IsAssignableFrom(typeof(V)))
((IHasChangesMask)value.Item1).ClearChangesMask();
value.Item2 = MapUpdateFieldState.Unchanged;
break;
case MapUpdateFieldState.Deleted:
field.Remove(key);
continue;
default:
break;
}
}
}
public void ClearChangesMask<U>(OptionalUpdateField<U> updateField) where U : new()
{
if (typeof(IHasChangesMask).IsAssignableFrom(typeof(U)) && updateField.HasValue())
@@ -488,6 +588,19 @@ namespace Game.Entities
return updateField;
}
public MapUpdateField<K, V> ModifyValue<K, V>(MapUpdateField<K, V> updateField) where V : new()
{
MarkChanged(updateField);
return updateField;
}
public V ModifyValue<K, V>(MapUpdateField<K, V> updateField, K key) where V : new()
{
MarkChanged(updateField);
updateField.TryAdd(key);
return updateField.Get(key).Item1;
}
public OptionalUpdateField<U> ModifyValue<U>(OptionalUpdateField<U> updateField) where U : new()
{
MarkChanged(updateField);
@@ -565,6 +678,14 @@ namespace Game.Entities
_changesMask.Set(updateField.Bit);
}
public void MarkChanged<K, V>(MapUpdateField<K, V> updateField) where V : new()
{
if (updateField.BlockBit >= 0)
_changesMask.Set(updateField.BlockBit);
_changesMask.Set(updateField.Bit);
}
public void MarkChanged<U>(OptionalUpdateField<U> updateField) where U : new()
{
_changesMask.Set(updateField.BlockBit);
@@ -613,6 +734,60 @@ namespace Game.Entities
data.WriteBits(0xFFFFFFFFu, size % 32);
}
public void WriteMapFieldCreate<K, V, T>(MapUpdateField<K, V> map, WorldPacket data, T owner, Player receiver) where V : new()
{
data.WriteInt32(map.Size());
foreach (var (k, (v, _)) in map)
{
if (typeof(IsUpdateFieldStructureTag<T>).IsAssignableFrom(typeof(K)))
((IsUpdateFieldStructureTag<T>)k).WriteCreate(data, owner, receiver);
else
data.Write(k);
if (typeof(IsUpdateFieldStructureTag<T>).IsAssignableFrom(typeof(V)))
((IsUpdateFieldStructureTag<T>)v).WriteCreate(data, owner, receiver);
else
data.Write(v);
}
}
public void WriteMapFieldUpdate<K, V, T>(MapUpdateField<K, V> map, WorldPacket data, bool ignoreChangesMask, T owner, Player receiver) where V : new()
{
data.WriteUInt8((byte)(ignoreChangesMask ? 1 : 0));
if (ignoreChangesMask)
WriteMapFieldCreate(map, data, owner, receiver);
else
{
ushort changesCount = 0;
WorldPacket tempBuffer = new();
foreach (var (k, (v, state)) in map)
{
if (state == MapUpdateFieldState.Unchanged)
continue;
++changesCount;
if (typeof(IsUpdateFieldStructureTag<T>).IsAssignableFrom(typeof(K)))
((IsUpdateFieldStructureTag<T>)k).WriteUpdate(tempBuffer, true /*ignoreChangesMask*/, owner, receiver);
else
tempBuffer.Write(k);
tempBuffer.WriteUInt8((byte)state);
if (state == MapUpdateFieldState.Deleted)
continue;
if (typeof(IsUpdateFieldStructureTag<T>).IsAssignableFrom(typeof(V)))
((IsUpdateFieldStructureTag<T>)v).WriteUpdate(tempBuffer, true /*ignoreChangesMask*/, owner, receiver); // client bug replaces unchanged values with 0/default so send everything as if it changed
else
tempBuffer.Write(v);
}
data.WriteUInt16(changesCount);
data.WriteBytes(tempBuffer);
}
}
public UpdateMask GetStaticUpdateMask()
{
return new UpdateMask(ChangeMaskLength);
File diff suppressed because it is too large Load Diff
@@ -844,6 +844,12 @@ namespace Game.Entities
updateField.RemoveValue(index);
}
public void RemoveMapUpdateFieldValue<K, V>(MapUpdateField<K, V> setter, K key) where V : new()
{
AddToObjectUpdateIfNeeded();
setter.MarkKeyForRemoval(key);
}
public void ClearDynamicUpdateFieldValues<T>(DynamicUpdateField<T> updateField) where T : new()
{
AddToObjectUpdateIfNeeded();
+21 -18
View File
@@ -1175,8 +1175,8 @@ namespace Game.Entities
if (!configsResult.IsEmpty())
{
// 0 1 2 3 4 5 6 7
// SELECT traitConfigId, type, chrSpecializationId, combatConfigFlags, localIdentifier, skillLineId, traitSystemId, `name` FROM character_trait_config WHERE guid = ?
// 0 1 2 3 4 5 6 7 8
// SELECT traitConfigId, type, chrSpecializationId, combatConfigFlags, localIdentifier, skillLineId, traitSystemId, variationId, `name` FROM character_trait_config WHERE guid = ?
do
{
TraitConfigPacket traitConfig = new();
@@ -1194,12 +1194,13 @@ namespace Game.Entities
break;
case TraitConfigType.Generic:
traitConfig.TraitSystemID = configsResult.Read<uint>(6);
traitConfig.VariationID = configsResult.Read<int>(7);
break;
default:
break;
}
traitConfig.Name = configsResult.Read<string>(7);
traitConfig.Name = configsResult.Read<string>(8);
foreach (var grantedEntry in TraitMgr.GetGrantedTraitEntriesForConfig(traitConfig, this))
traitConfig.Entries.Add(new TraitEntryPacket(grantedEntry));
@@ -1242,23 +1243,23 @@ namespace Game.Entities
bool hasConfigForSpec(int specId)
{
return m_activePlayerData.TraitConfigs.FindIndexIf(traitConfig =>
return m_activePlayerData.TraitConfigs.FindIf(traitConfig =>
{
return traitConfig.Type == (int)TraitConfigType.Combat
&& traitConfig.ChrSpecializationID == specId
&& (traitConfig.CombatConfigFlags & (int)TraitCombatConfigFlags.ActiveForSpec) != 0;
}) >= 0;
}).Item1 != 0;
}
int findFreeLocalIdentifier(int specId)
{
int index = 1;
while (m_activePlayerData.TraitConfigs.FindIndexIf(traitConfig =>
while (m_activePlayerData.TraitConfigs.FindIf(traitConfig =>
{
return traitConfig.Type == (int)TraitConfigType.Combat
&& traitConfig.ChrSpecializationID == specId
&& traitConfig.LocalIdentifier == index;
}) >= 0)
}).Item1 != 0)
++index;
return index;
@@ -1283,23 +1284,22 @@ namespace Game.Entities
}
}
int activeConfig = m_activePlayerData.TraitConfigs.FindIndexIf(traitConfig =>
TraitConfig activeTraitConfig = m_activePlayerData.TraitConfigs.FindIf(traitConfig =>
{
return traitConfig.Type == (int)TraitConfigType.Combat
&& traitConfig.ChrSpecializationID == (int)GetPrimarySpecialization()
&& (traitConfig.CombatConfigFlags & (int)TraitCombatConfigFlags.ActiveForSpec) != 0;
});
}).Item2;
if (activeConfig >= 0)
if (activeTraitConfig != null)
{
TraitConfig activeTraitConfig = m_activePlayerData.TraitConfigs[activeConfig];
SetActiveCombatTraitConfigID(activeTraitConfig.ID);
int activeSubTree = activeTraitConfig.SubTrees.FindIndexIf(subTree => subTree.Active != 0);
if (activeSubTree >= 0)
SetCurrentCombatTraitConfigSubTreeID(activeTraitConfig.SubTrees[activeSubTree].TraitSubTreeID);
}
foreach (TraitConfig traitConfig in m_activePlayerData.TraitConfigs)
foreach (var (id, (traitConfig, _)) in m_activePlayerData.TraitConfigs)
{
switch ((TraitConfigType)(int)traitConfig.Type)
{
@@ -1315,7 +1315,7 @@ namespace Game.Entities
break;
}
ApplyTraitConfig(traitConfig.ID, true);
ApplyTraitConfig(id, true);
}
}
@@ -2138,16 +2138,16 @@ namespace Game.Entities
TraitConfig traitConfig = GetTraitConfig((int)(uint)m_activePlayerData.ActiveCombatTraitConfigID);
if (traitConfig != null)
{
int usedSavedTraitConfigIndex = m_activePlayerData.TraitConfigs.FindIndexIf(savedConfig =>
int usedSavedTraitConfigId = m_activePlayerData.TraitConfigs.FindIf(savedConfig =>
{
return (TraitConfigType)(int)savedConfig.Type == TraitConfigType.Combat
&& ((TraitCombatConfigFlags)(int)savedConfig.CombatConfigFlags & TraitCombatConfigFlags.ActiveForSpec) == TraitCombatConfigFlags.None
&& ((TraitCombatConfigFlags)(int)savedConfig.CombatConfigFlags & TraitCombatConfigFlags.SharedActionBars) == TraitCombatConfigFlags.None
&& savedConfig.LocalIdentifier == traitConfig.LocalIdentifier;
});
}).Item1;
if (usedSavedTraitConfigIndex >= 0)
traitConfigId = m_activePlayerData.TraitConfigs[usedSavedTraitConfigIndex].ID;
if (usedSavedTraitConfigId != 0)
traitConfigId = usedSavedTraitConfigId;
}
PreparedStatement stmt;
@@ -2480,6 +2480,7 @@ namespace Game.Entities
stmt.AddValue(5, traitConfig.LocalIdentifier);
stmt.AddNull(6);
stmt.AddNull(7);
stmt.AddNull(8);
break;
case TraitConfigType.Profession:
stmt.AddNull(3);
@@ -2487,6 +2488,7 @@ namespace Game.Entities
stmt.AddNull(5);
stmt.AddValue(6, traitConfig.SkillLineID);
stmt.AddNull(7);
stmt.AddNull(8);
break;
case TraitConfigType.Generic:
stmt.AddNull(3);
@@ -2494,12 +2496,13 @@ namespace Game.Entities
stmt.AddNull(5);
stmt.AddNull(6);
stmt.AddValue(7, traitConfig.TraitSystemID);
stmt.AddValue(8, traitConfig.VariationID);
break;
default:
break;
}
stmt.AddValue(8, traitConfig.Name);
stmt.AddValue(9, traitConfig.Name);
trans.Append(stmt);
foreach (var traitEntry in traitConfig.Entries)
+3 -3
View File
@@ -2337,7 +2337,7 @@ namespace Game.Entities
{
var questLogField = m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.QuestLog, slot);
SetUpdateFieldValue(questLogField.ModifyValue(questLogField.QuestID), quest_id);
SetUpdateFieldValue(questLogField.ModifyValue(questLogField.StateFlags), 0u);
SetUpdateFieldValue(questLogField.ModifyValue(questLogField.StateFlags), (ushort)0);
SetUpdateFieldValue(questLogField.ModifyValue(questLogField.EndTime), 0u);
SetUpdateFieldValue(questLogField.ModifyValue(questLogField.ObjectiveFlags), 0u);
@@ -2358,13 +2358,13 @@ namespace Game.Entities
public void SetQuestSlotState(ushort slot, QuestSlotStateMask state)
{
QuestLog questLogField = m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.QuestLog, slot);
SetUpdateFieldFlagValue(questLogField.ModifyValue(questLogField.StateFlags), (uint)state);
SetUpdateFieldFlagValue(questLogField.ModifyValue(questLogField.StateFlags), (ushort)state);
}
public void RemoveQuestSlotState(ushort slot, QuestSlotStateMask state)
{
QuestLog questLogField = m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.QuestLog, slot);
RemoveUpdateFieldFlagValue(questLogField.ModifyValue(questLogField.StateFlags), (uint)state);
RemoveUpdateFieldFlagValue(questLogField.ModifyValue(questLogField.StateFlags), (ushort)state);
}
public void SetQuestSlotEndTime(ushort slot, long endTime)
+66 -96
View File
@@ -358,19 +358,19 @@ namespace Game.Entities
SetActiveTalentGroup(spec.OrderIndex);
SetPrimarySpecialization(spec.Id);
int specTraitConfigIndex = m_activePlayerData.TraitConfigs.FindIndexIf(traitConfig =>
var specTraitConfig = m_activePlayerData.TraitConfigs.FindIf(traitConfig =>
{
return (TraitConfigType)(int)traitConfig.Type == TraitConfigType.Combat
&& traitConfig.ChrSpecializationID == spec.Id
&& ((TraitCombatConfigFlags)(int)traitConfig.CombatConfigFlags & TraitCombatConfigFlags.ActiveForSpec) != TraitCombatConfigFlags.None;
});
if (specTraitConfigIndex >= 0)
}).Item2;
if (specTraitConfig != null)
{
TraitConfig activeTraitConfig = m_activePlayerData.TraitConfigs[specTraitConfigIndex];
SetActiveCombatTraitConfigID(activeTraitConfig.ID);
int activeSubTree = activeTraitConfig.SubTrees.FindIndexIf(subTree => subTree.Active != 0);
SetActiveCombatTraitConfigID(specTraitConfig.ID);
int activeSubTree = specTraitConfig.SubTrees.FindIndexIf(subTree => subTree.Active != 0);
if (activeSubTree >= 0)
SetCurrentCombatTraitConfigSubTreeID(activeTraitConfig.SubTrees[activeSubTree].TraitSubTreeID);
SetCurrentCombatTraitConfigSubTreeID(specTraitConfig.SubTrees[activeSubTree].TraitSubTreeID);
else
SetCurrentCombatTraitConfigSubTreeID(0);
}
@@ -497,16 +497,16 @@ namespace Game.Entities
TraitConfig traitConfig = GetTraitConfig((int)(uint)m_activePlayerData.ActiveCombatTraitConfigID);
if (traitConfig != null)
{
int usedSavedTraitConfigIndex = m_activePlayerData.TraitConfigs.FindIndexIf(savedConfig =>
var usedSavedTraitConfigId = m_activePlayerData.TraitConfigs.FindIf(savedConfig =>
{
return (TraitConfigType)(int)savedConfig.Type == TraitConfigType.Combat
&& ((TraitCombatConfigFlags)(int)savedConfig.CombatConfigFlags & TraitCombatConfigFlags.ActiveForSpec) == TraitCombatConfigFlags.None
&& ((TraitCombatConfigFlags)(int)savedConfig.CombatConfigFlags & TraitCombatConfigFlags.SharedActionBars) == TraitCombatConfigFlags.None
&& savedConfig.LocalIdentifier == traitConfig.LocalIdentifier;
});
}).Item1;
if (usedSavedTraitConfigIndex >= 0)
traitConfigId = (uint)(int)m_activePlayerData.TraitConfigs[usedSavedTraitConfigIndex].ID;
if (usedSavedTraitConfigId != 0)
traitConfigId = (uint)usedSavedTraitConfigId;
}
// load them asynchronously
@@ -873,45 +873,38 @@ namespace Game.Entities
public void CreateTraitConfig(TraitConfigPacket traitConfig)
{
int configId = TraitMgr.GenerateNewTraitConfigId();
bool hasConfigId(int id)
{
return m_activePlayerData.TraitConfigs.FindIndexIf(config => config.ID == id) >= 0;
}
bool hasConfigId(int id) => m_activePlayerData.TraitConfigs.Get(id).Item1 != null;
while (hasConfigId(configId))
configId = TraitMgr.GenerateNewTraitConfigId();
traitConfig.ID = configId;
int traitConfigIndex = m_activePlayerData.TraitConfigs.Size();
AddTraitConfig(traitConfig);
TraitConfig entrySetter = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs, configId);
foreach (TraitEntry grantedEntry in TraitMgr.GetGrantedTraitEntriesForConfig(traitConfig, this))
{
var entryIndex = traitConfig.Entries.Find(entry => entry.TraitNodeID == grantedEntry.TraitNodeID && entry.TraitNodeEntryID == grantedEntry.TraitNodeEntryID);
if (entryIndex == null)
{
TraitConfig value = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs, traitConfigIndex);
AddDynamicUpdateFieldValue(value.ModifyValue(value.Entries), grantedEntry);
}
AddDynamicUpdateFieldValue(entrySetter.ModifyValue(entrySetter.Entries), grantedEntry);
}
m_traitConfigStates[(int)configId] = PlayerSpellState.Changed;
m_traitConfigStates[configId] = PlayerSpellState.Changed;
}
void AddTraitConfig(TraitConfigPacket traitConfig)
{
var setter = new TraitConfig();
setter.ModifyValue(setter.ID).SetValue(traitConfig.ID);
setter.ModifyValue(setter.Name).SetValue(traitConfig.Name);
setter.ModifyValue(setter.Type).SetValue((int)traitConfig.Type);
setter.ModifyValue(setter.SkillLineID).SetValue((int)traitConfig.SkillLineID);
setter.ModifyValue(setter.ChrSpecializationID).SetValue(traitConfig.ChrSpecializationID);
setter.ModifyValue(setter.CombatConfigFlags).SetValue((int)traitConfig.CombatConfigFlags);
setter.ModifyValue(setter.LocalIdentifier).SetValue(traitConfig.LocalIdentifier);
setter.ModifyValue(setter.TraitSystemID).SetValue(traitConfig.TraitSystemID);
AddDynamicUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs), setter);
var setter = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs, traitConfig.ID);
SetUpdateFieldValue(setter.ModifyValue(setter.ID), traitConfig.ID);
SetUpdateFieldValue(setter.ModifyValue(setter.Name), traitConfig.Name);
SetUpdateFieldValue(setter.ModifyValue(setter.Type), (int)traitConfig.Type);
SetUpdateFieldValue(setter.ModifyValue(setter.SkillLineID), (int)traitConfig.SkillLineID);
SetUpdateFieldValue(setter.ModifyValue(setter.ChrSpecializationID), traitConfig.ChrSpecializationID);
SetUpdateFieldValue(setter.ModifyValue(setter.CombatConfigFlags), (int)traitConfig.CombatConfigFlags);
SetUpdateFieldValue(setter.ModifyValue(setter.LocalIdentifier), traitConfig.LocalIdentifier);
SetUpdateFieldValue(setter.ModifyValue(setter.TraitSystemID), traitConfig.TraitSystemID);
foreach (TraitEntryPacket traitEntry in traitConfig.Entries)
{
@@ -945,17 +938,13 @@ namespace Game.Entities
public TraitConfig GetTraitConfig(int configId)
{
int index = m_activePlayerData.TraitConfigs.FindIndexIf(config => config.ID == configId);
if (index < 0)
return null;
return m_activePlayerData.TraitConfigs[index];
return m_activePlayerData.TraitConfigs.Get(configId).Item1;
}
public void UpdateTraitConfig(TraitConfigPacket newConfig, int savedConfigId, bool withCastTime)
{
int index = m_activePlayerData.TraitConfigs.FindIndexIf(config => config.ID == newConfig.ID);
if (index < 0)
var oldConfig = m_activePlayerData.TraitConfigs.Get(newConfig.ID).Item1;
if (oldConfig == null)
return;
if (withCastTime)
@@ -966,14 +955,14 @@ namespace Game.Entities
bool isActiveConfig = true;
bool loadActionButtons = false;
switch ((TraitConfigType)(int)m_activePlayerData.TraitConfigs[index].Type)
switch ((TraitConfigType)(int)oldConfig.Type)
{
case TraitConfigType.Combat:
isActiveConfig = newConfig.ID == m_activePlayerData.ActiveCombatTraitConfigID;
loadActionButtons = m_activePlayerData.TraitConfigs[index].LocalIdentifier != newConfig.LocalIdentifier;
loadActionButtons = oldConfig.LocalIdentifier != newConfig.LocalIdentifier;
break;
case TraitConfigType.Profession:
isActiveConfig = HasSkill((uint)(int)m_activePlayerData.TraitConfigs[index].SkillLineID);
isActiveConfig = HasSkill((uint)(int)oldConfig.SkillLineID);
break;
default:
break;
@@ -981,7 +970,7 @@ namespace Game.Entities
Action finalizeTraitConfigUpdate = () =>
{
TraitConfig newTraitConfig = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs, index);
TraitConfig newTraitConfig = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs, newConfig.ID);
SetUpdateFieldValue(newTraitConfig.ModifyValue(newTraitConfig.LocalIdentifier), newConfig.LocalIdentifier);
ApplyTraitEntryChanges(newConfig.ID, newConfig, isActiveConfig, true);
@@ -1007,11 +996,11 @@ namespace Game.Entities
void ApplyTraitEntryChanges(int editedConfigId, TraitConfigPacket newConfig, bool applyTraits, bool consumeCurrencies)
{
int editedIndex = m_activePlayerData.TraitConfigs.FindIndexIf(config => config.ID == editedConfigId);
if (editedIndex < 0)
var editedConfig = m_activePlayerData.TraitConfigs.Get(editedConfigId).Item1;
if (editedConfig == null)
return;
TraitConfig editedConfig = m_activePlayerData.TraitConfigs[editedIndex];
var configSetter = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs, editedConfigId);
// remove traits not found in new config
SortedSet<int> entryIndicesToRemove = new(Comparer<int>.Create((a, b) => -a.CompareTo(b)));
@@ -1029,10 +1018,7 @@ namespace Game.Entities
}
foreach (int indexToRemove in entryIndicesToRemove)
{
TraitConfig traitConfig = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs, editedIndex);
RemoveDynamicUpdateFieldValue(traitConfig.ModifyValue(traitConfig.Entries), indexToRemove);
}
RemoveDynamicUpdateFieldValue(configSetter.ModifyValue(configSetter.Entries), indexToRemove);
List<TraitEntryPacket> costEntries = new();
@@ -1045,14 +1031,13 @@ namespace Game.Entities
if (consumeCurrencies)
costEntries.Add(newEntry);
TraitConfig newTraitConfig = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs, editedIndex);
TraitEntry newUfEntry = new();
newUfEntry.TraitNodeID = newEntry.TraitNodeID;
newUfEntry.TraitNodeEntryID = newEntry.TraitNodeEntryID;
newUfEntry.Rank = newEntry.Rank;
newUfEntry.GrantedRanks = newEntry.GrantedRanks;
AddDynamicUpdateFieldValue(newTraitConfig.ModifyValue(newTraitConfig.Entries), newUfEntry);
AddDynamicUpdateFieldValue(configSetter.ModifyValue(configSetter.Entries), newUfEntry);
if (applyTraits)
{
@@ -1069,11 +1054,10 @@ namespace Game.Entities
costEntries.Add(newEntry);
}
TraitConfig traitConfig = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs, editedIndex);
TraitEntry traitEntry = traitConfig.ModifyValue(traitConfig.Entries, oldEntryIndex);
TraitEntry traitEntry = configSetter.ModifyValue(configSetter.Entries, oldEntryIndex);
traitEntry.Rank = newEntry.Rank;
traitEntry.GrantedRanks = newEntry.GrantedRanks;
SetUpdateFieldValue(traitConfig.Entries, oldEntryIndex, traitEntry);
SetUpdateFieldValue(configSetter.Entries, oldEntryIndex, traitEntry);
if (applyTraits)
ApplyTraitEntry(newEntry.TraitNodeEntryID, newEntry.Rank, newEntry.GrantedRanks, true);
@@ -1126,19 +1110,17 @@ namespace Game.Entities
newUfSubTree.Active = newSubTree.Active ? 1 : 0u;
newUfSubTree.Entries = subTreeEntries;
TraitConfig traitConfig = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs, editedIndex);
AddDynamicUpdateFieldValue(traitConfig.ModifyValue(traitConfig.SubTrees), newUfSubTree);
AddDynamicUpdateFieldValue(configSetter.ModifyValue(configSetter.SubTrees), newUfSubTree);
}
else
{
bool wasActive = m_activePlayerData.TraitConfigs[editedIndex].SubTrees[oldSubTreeIndex].Active != 0;
bool wasActive = configSetter.SubTrees[oldSubTreeIndex].Active != 0;
TraitConfig traitConfig = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs, editedIndex);
TraitSubTreeCache traitSubTreeCache = traitConfig.ModifyValue(traitConfig.SubTrees, oldSubTreeIndex);
TraitSubTreeCache traitSubTreeCache = configSetter.ModifyValue(configSetter.SubTrees, oldSubTreeIndex);
traitSubTreeCache.Active = newSubTree.Active ? 1 : 0u;
traitSubTreeCache.Entries = subTreeEntries;
SetUpdateFieldValue(traitConfig.ModifyValue(traitConfig.SubTrees, oldSubTreeIndex), traitSubTreeCache);
SetUpdateFieldValue(configSetter.ModifyValue(configSetter.SubTrees, oldSubTreeIndex), traitSubTreeCache);
if (applyTraits && wasActive != newSubTree.Active)
@@ -1163,16 +1145,13 @@ namespace Game.Entities
public void RenameTraitConfig(int editedConfigId, string newName)
{
int editedIndex = m_activePlayerData.TraitConfigs.FindIndexIf(traitConfig =>
{
return traitConfig.ID == editedConfigId
&& (TraitConfigType)(int)traitConfig.Type == TraitConfigType.Combat
&& ((TraitCombatConfigFlags)(int)traitConfig.CombatConfigFlags & TraitCombatConfigFlags.ActiveForSpec) == TraitCombatConfigFlags.None;
});
if (editedIndex < 0)
TraitConfig editedConfig = m_activePlayerData.TraitConfigs.Get(editedConfigId).Item1;
if (editedConfig == null
|| (TraitConfigType)(int)editedConfig.Type != TraitConfigType.Combat
|| ((TraitCombatConfigFlags)(int)editedConfig.CombatConfigFlags & TraitCombatConfigFlags.ActiveForSpec) != TraitCombatConfigFlags.None)
return;
TraitConfig traitConfig = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs, editedIndex);
TraitConfig traitConfig = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs, editedConfigId);
SetUpdateFieldValue(traitConfig.ModifyValue(traitConfig.Name), newName);
m_traitConfigStates[editedConfigId] = PlayerSpellState.Changed;
@@ -1180,17 +1159,14 @@ namespace Game.Entities
public void DeleteTraitConfig(int deletedConfigId)
{
int deletedIndex = m_activePlayerData.TraitConfigs.FindIndexIf(traitConfig =>
{
return traitConfig.ID == deletedConfigId
&& (TraitConfigType)(int)traitConfig.Type == TraitConfigType.Combat
&& ((TraitCombatConfigFlags)(int)traitConfig.CombatConfigFlags & TraitCombatConfigFlags.ActiveForSpec) == TraitCombatConfigFlags.None;
});
if (deletedIndex < 0)
TraitConfig deletedConfig = m_activePlayerData.TraitConfigs.Get(deletedConfigId).Item1;
if (deletedConfig == null
|| (TraitConfigType)(int)deletedConfig.Type != TraitConfigType.Combat
|| ((TraitCombatConfigFlags)(int)deletedConfig.CombatConfigFlags & TraitCombatConfigFlags.ActiveForSpec) != TraitCombatConfigFlags.None)
return;
RemoveDynamicUpdateFieldValue(m_values.ModifyValue(m_activePlayerData)
.ModifyValue(m_activePlayerData.TraitConfigs), deletedIndex);
RemoveMapUpdateFieldValue(m_values.ModifyValue(m_activePlayerData)
.ModifyValue(m_activePlayerData.TraitConfigs), deletedConfigId);
m_traitConfigStates[deletedConfigId] = PlayerSpellState.Removed;
}
@@ -1238,27 +1214,24 @@ namespace Game.Entities
public void SetTraitConfigUseStarterBuild(int traitConfigId, bool useStarterBuild)
{
int configIndex = m_activePlayerData.TraitConfigs.FindIndexIf(traitConfig =>
{
return traitConfig.ID == traitConfigId
&& (TraitConfigType)(int)traitConfig.Type == TraitConfigType.Combat
&& ((TraitCombatConfigFlags)(int)traitConfig.CombatConfigFlags & TraitCombatConfigFlags.ActiveForSpec) != TraitCombatConfigFlags.None;
});
if (configIndex < 0)
TraitConfig config = m_activePlayerData.TraitConfigs.Get(traitConfigId).Item1;
if (config == null
|| (TraitConfigType)(int)config.Type != TraitConfigType.Combat
|| ((TraitCombatConfigFlags)(int)config.CombatConfigFlags & TraitCombatConfigFlags.ActiveForSpec) == TraitCombatConfigFlags.None)
return;
bool currentlyUsesStarterBuild = ((TraitCombatConfigFlags)(int)m_activePlayerData.TraitConfigs[configIndex].CombatConfigFlags).HasFlag(TraitCombatConfigFlags.StarterBuild);
bool currentlyUsesStarterBuild = ((TraitCombatConfigFlags)(int)config.CombatConfigFlags).HasFlag(TraitCombatConfigFlags.StarterBuild);
if (currentlyUsesStarterBuild == useStarterBuild)
return;
if (useStarterBuild)
{
TraitConfig traitConfig = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs, configIndex);
TraitConfig traitConfig = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs, traitConfigId);
SetUpdateFieldFlagValue(traitConfig.ModifyValue(traitConfig.CombatConfigFlags), (int)TraitCombatConfigFlags.StarterBuild);
}
else
{
TraitConfig traitConfig = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs, configIndex);
TraitConfig traitConfig = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs, traitConfigId);
RemoveUpdateFieldFlagValue(traitConfig.ModifyValue(traitConfig.CombatConfigFlags), (int)TraitCombatConfigFlags.StarterBuild);
}
@@ -1267,20 +1240,17 @@ namespace Game.Entities
public void SetTraitConfigUseSharedActionBars(int traitConfigId, bool usesSharedActionBars, bool isLastSelectedSavedConfig)
{
int configIndex = m_activePlayerData.TraitConfigs.FindIndexIf(traitConfig =>
{
return traitConfig.ID == traitConfigId
&& (TraitConfigType)(int)traitConfig.Type == TraitConfigType.Combat
&& ((TraitCombatConfigFlags)(int)traitConfig.CombatConfigFlags & TraitCombatConfigFlags.ActiveForSpec) == TraitCombatConfigFlags.None;
});
if (configIndex < 0)
TraitConfig config = m_activePlayerData.TraitConfigs.Get(traitConfigId).Item1;
if (config == null
|| (TraitConfigType)(int)config.Type != TraitConfigType.Combat
|| ((TraitCombatConfigFlags)(int)config.CombatConfigFlags & TraitCombatConfigFlags.ActiveForSpec) != TraitCombatConfigFlags.None)
return;
bool currentlyUsesSharedActionBars = ((TraitCombatConfigFlags)(int)m_activePlayerData.TraitConfigs[configIndex].CombatConfigFlags).HasFlag(TraitCombatConfigFlags.SharedActionBars);
bool currentlyUsesSharedActionBars = ((TraitCombatConfigFlags)(int)config.CombatConfigFlags).HasFlag(TraitCombatConfigFlags.SharedActionBars);
if (currentlyUsesSharedActionBars == usesSharedActionBars)
return;
TraitConfig traitConfig = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs, configIndex);
TraitConfig traitConfig = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TraitConfigs, traitConfigId);
if (usesSharedActionBars)
{
SetUpdateFieldFlagValue(traitConfig.ModifyValue(traitConfig.CombatConfigFlags), (int)TraitCombatConfigFlags.SharedActionBars);
+2 -2
View File
@@ -1247,7 +1247,7 @@ namespace Game.Entities
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags2.AbandonVehicle);
}
public void SendPlaySpellVisual(Unit target, uint spellVisualId, ushort missReason, ushort reflectStatus, float travelSpeed, bool speedAsTime = false, float launchDelay = 0f)
public void SendPlaySpellVisual(Unit target, uint spellVisualId, byte missReason, byte reflectStatus, float travelSpeed, bool speedAsTime = false, float launchDelay = 0f)
{
PlaySpellVisual playSpellVisual = new();
playSpellVisual.Source = GetGUID();
@@ -1262,7 +1262,7 @@ namespace Game.Entities
SendMessageToSet(playSpellVisual, true);
}
public void SendPlaySpellVisual(Position targetPosition, uint spellVisualId, ushort missReason, ushort reflectStatus, float travelSpeed, bool speedAsTime = false, float launchDelay = 0f)
public void SendPlaySpellVisual(Position targetPosition, uint spellVisualId, byte missReason, byte reflectStatus, float travelSpeed, bool speedAsTime = false, float launchDelay = 0f)
{
PlaySpellVisual playSpellVisual = new();
playSpellVisual.Source = GetGUID();