/* * Copyright (C) 2012-2019 CypherCore * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ using Framework.Constants; using Game.Network; using System; using System.Collections.Generic; using System.Linq; using Framework.GameMath; using System.Runtime.CompilerServices; using Game.Spells; using Game.DataStorage; namespace Game.Entities { public class ObjectFieldData : BaseUpdateData { public UpdateField EntryId = new UpdateField(0, 1); public UpdateField DynamicFlags = new UpdateField(0, 2); public UpdateField Scale = new UpdateField(0, 3); public ObjectFieldData() : base(0, TypeId.Object, 4) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, WorldObject owner, Player receiver) { data.WriteUInt32(EntryId); data.WriteUInt32(GetViewerDependentDynamicFlags(DynamicFlags, owner, receiver)); data.WriteFloat(Scale); } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, WorldObject owner, Player receiver) { data.WriteBits(_changesMask.GetBlock(0), 4); data.FlushBits(); if (_changesMask[0]) { if (_changesMask[1]) { data.WriteUInt32(EntryId); } if (_changesMask[2]) { data.WriteUInt32(GetViewerDependentDynamicFlags(DynamicFlags, owner, receiver)); } if (_changesMask[3]) { data.WriteFloat(Scale); } } } public override void ClearChangesMask() { ClearChangesMask(EntryId); ClearChangesMask(DynamicFlags); ClearChangesMask(Scale); _changesMask.ResetAll(); } uint GetViewerDependentDynamicFlags(uint dynamicFlags, WorldObject obj, Player receiver) { UnitDynFlags unitDynFlags = (UnitDynFlags)dynamicFlags; Unit unit = obj.ToUnit(); if (unit != null) { unitDynFlags &= ~UnitDynFlags.Tapped; Creature creature = obj.ToCreature(); if (creature != null) { if (creature.hasLootRecipient() && !creature.isTappedBy(receiver)) unitDynFlags |= UnitDynFlags.Tapped; if (!receiver.isAllowedToLoot(creature)) unitDynFlags &= ~UnitDynFlags.Lootable; } // unit UNIT_DYNFLAG_TRACK_UNIT should only be sent to caster of SPELL_AURA_MOD_STALKED auras if (unitDynFlags.HasAnyFlag(UnitDynFlags.TrackUnit)) if (!unit.HasAuraTypeWithCaster(AuraType.ModStalked, receiver.GetGUID())) unitDynFlags &= ~UnitDynFlags.TrackUnit; } else { GameObject gameObject = obj.ToGameObject(); if (gameObject != null) { GameObjectDynamicLowFlags dynFlags = 0; ushort pathProgress = 0xFFFF; switch (gameObject.GetGoType()) { case GameObjectTypes.QuestGiver: if (gameObject.ActivateToQuest(receiver)) dynFlags |= GameObjectDynamicLowFlags.Activate; break; case GameObjectTypes.Chest: case GameObjectTypes.Goober: if (gameObject.ActivateToQuest(receiver)) dynFlags |= GameObjectDynamicLowFlags.Activate | GameObjectDynamicLowFlags.Sparkle; else if (receiver.IsGameMaster()) dynFlags |= GameObjectDynamicLowFlags.Activate; break; case GameObjectTypes.Generic: if (gameObject.ActivateToQuest(receiver)) dynFlags |= GameObjectDynamicLowFlags.Sparkle; break; case GameObjectTypes.Transport: case GameObjectTypes.MapObjTransport: { uint transportPeriod = gameObject.GetTransportPeriod(); if (transportPeriod != 0) { float timer = (float)(gameObject.GetGoValue().Transport.PathProgress % transportPeriod); pathProgress = (ushort)(timer / (float)transportPeriod * 65535.0f); } break; } default: break; } unitDynFlags = (UnitDynFlags)((pathProgress << 16) | (ushort)dynFlags); } } return (uint)unitDynFlags; } } public class ItemEnchantment : BaseUpdateData { public UpdateField ID = new UpdateField(0, 1); public UpdateField Duration = new UpdateField(0, 2); public UpdateField Charges = new UpdateField(0, 3); public UpdateField Inactive = new UpdateField(0, 4); public ItemEnchantment() : base(5) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { data.WriteUInt32(ID); data.WriteUInt32(Duration); data.WriteInt16(Charges); data.WriteUInt16(Inactive); } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { data.WriteBits(_changesMask.GetBlock(0), 5); data.FlushBits(); if (_changesMask[0]) { if (_changesMask[1]) { data.WriteUInt32(ID); } if (_changesMask[2]) { data.WriteUInt32(Duration); } if (_changesMask[3]) { data.WriteInt16(Charges); } if (_changesMask[4]) { data.WriteUInt16(Inactive); } } } public override void ClearChangesMask() { ClearChangesMask(ID); ClearChangesMask(Duration); ClearChangesMask(Charges); ClearChangesMask(Inactive); _changesMask.ResetAll(); } } public class ArtifactPower { public ushort ArtifactPowerId; public byte PurchasedRank; public byte CurrentRankWithBonus; public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { data.WriteUInt16(ArtifactPowerId); data.WriteUInt8(PurchasedRank); data.WriteUInt8(CurrentRankWithBonus); } public void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { data.FlushBits(); data.WriteUInt16(ArtifactPowerId); data.WriteUInt8(PurchasedRank); data.WriteUInt8(CurrentRankWithBonus); } } public class SocketedGem : BaseUpdateData { public UpdateField ItemId = new UpdateField(0, 1); public UpdateField Context = new UpdateField(0, 2); public UpdateFieldArray BonusListIDs = new UpdateFieldArray(16, 3, 4); public SocketedGem() : base(20) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { data.WriteUInt32(ItemId); for (int i = 0; i < 16; ++i) data.WriteUInt16(BonusListIDs[i]); data.WriteUInt8(Context); } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { data.WriteBits(_changesMask.GetBlocksMask(0), 1); if (_changesMask.GetBlock(0) != 0) data.WriteBits(_changesMask.GetBlock(0), 32); data.FlushBits(); if (_changesMask[0]) { if (_changesMask[1]) { data.WriteUInt32(ItemId); } if (_changesMask[2]) { data.WriteUInt8(Context); } } if (_changesMask[3]) { for (int i = 0; i < 16; ++i) { if (_changesMask[4 + i]) { data.WriteUInt16(BonusListIDs[i]); } } } } public override void ClearChangesMask() { ClearChangesMask(ItemId); ClearChangesMask(Context); ClearChangesMask(BonusListIDs); _changesMask.ResetAll(); } } public class ItemData : BaseUpdateData { public UpdateField> BonusListIDs = new UpdateField>(0, 1); public DynamicUpdateField Modifiers = new DynamicUpdateField(0, 2); public DynamicUpdateField ArtifactPowers = new DynamicUpdateField(0, 3); public DynamicUpdateField Gems = new DynamicUpdateField(0, 4); public UpdateField Owner = new UpdateField(0, 5); public UpdateField ContainedIn = new UpdateField(0, 6); public UpdateField Creator = new UpdateField(0, 7); public UpdateField GiftCreator = new UpdateField(0, 8); public UpdateField StackCount = new UpdateField(0, 9); public UpdateField Expiration = new UpdateField(0, 10); public UpdateField DynamicFlags = new UpdateField(0, 11); public UpdateField Durability = new UpdateField(0, 12); public UpdateField MaxDurability = new UpdateField(0, 13); public UpdateField CreatePlayedTime = new UpdateField(0, 14); public UpdateField ModifiersMask = new UpdateField(0, 15); public UpdateField Context = new UpdateField(0, 16); public UpdateField ArtifactXP = new UpdateField(0, 17); public UpdateField ItemAppearanceModID = new UpdateField(0, 18); public UpdateField Field_130 = new UpdateField(0, 19); public UpdateFieldArray SpellCharges = new UpdateFieldArray(5, 20, 21); public UpdateFieldArray Enchantment = new UpdateFieldArray(13, 26, 27); public ItemData() : base(0, TypeId.Item, 40) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { List bonusList = BonusListIDs; data.WriteInt32(bonusList.Count); for (int i = 0; i < bonusList.Count; ++i) data.WriteUInt32(bonusList[i]); data.WritePackedGuid(Owner); data.WritePackedGuid(ContainedIn); data.WritePackedGuid(Creator); data.WritePackedGuid(GiftCreator); if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) { data.WriteUInt32(StackCount); data.WriteUInt32(Expiration); for (int i = 0; i < 5; ++i) { data.WriteInt32(SpellCharges[i]); } } data.WriteUInt32(DynamicFlags); for (int i = 0; i < 13; ++i) { Enchantment[i].WriteCreate(data, fieldVisibilityFlags, owner, receiver); } if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) { data.WriteUInt32(Durability); data.WriteUInt32(MaxDurability); } data.WriteUInt32(CreatePlayedTime); if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) { data.WriteUInt32(ModifiersMask); } data.WriteInt32(Context); if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) { data.WriteUInt64(ArtifactXP); data.WriteUInt8(ItemAppearanceModID); } data.WriteInt32(Modifiers.Size()); data.WriteInt32(ArtifactPowers.Size()); data.WriteInt32(Gems.Size()); if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) { data.WriteUInt32(Field_130); } for (int i = 0; i < Modifiers.Size(); ++i) { data.WriteUInt32(Modifiers[i]); } for (int i = 0; i < ArtifactPowers.Size(); ++i) { ArtifactPowers[i].WriteCreate(data, fieldVisibilityFlags, owner, receiver); } for (int i = 0; i < Gems.Size(); ++i) { Gems[i].WriteCreate(data, fieldVisibilityFlags, owner, receiver); } } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { UpdateMask allowedMaskForTarget = new UpdateMask(40, new uint[] { 0xFC0149FFu, 0x000000FFu }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); WriteUpdate(data, _changesMask & allowedMaskForTarget, fieldVisibilityFlags, owner, receiver); } public void AppendAllowedFieldsMaskForFlag(UpdateMask allowedMaskForTarget, UpdateFieldFlag fieldVisibilityFlags) { if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) allowedMaskForTarget |= new UpdateMask(40, new uint[] { 0x03FEB600u, 0x00000000u }); } public void WriteUpdate(WorldPacket data, UpdateMask changesMask, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { data.WriteBits(_changesMask.GetBlocksMask(0), 2); for (uint i = 0; i < 2; ++i) if (_changesMask.GetBlock(i) != 0) data.WriteBits(_changesMask.GetBlock(i), 32); if (_changesMask[0]) { if (_changesMask[1]) { List bonusList = BonusListIDs; data.WriteBits(bonusList.Count, 32); for (int i = 0; i < bonusList.Count; ++i) data.WriteUInt32(bonusList[i]); } } data.FlushBits(); if (_changesMask[0]) { if (_changesMask[2]) { Modifiers.WriteUpdateMask(data); } if (_changesMask[3]) { ArtifactPowers.WriteUpdateMask(data); } if (_changesMask[4]) { Gems.WriteUpdateMask(data); } } data.FlushBits(); if (_changesMask[0]) { if (_changesMask[2]) { for (int i = 0; i < Modifiers.Size(); ++i) { if (Modifiers.HasChanged(i)) { data.WriteUInt32(Modifiers[i]); } } } if (_changesMask[3]) { for (int i = 0; i < ArtifactPowers.Size(); ++i) { if (ArtifactPowers.HasChanged(i)) { ArtifactPowers[i].WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } } } if (_changesMask[4]) { for (int i = 0; i < Gems.Size(); ++i) { if (Gems.HasChanged(i)) { Gems[i].WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } } } if (_changesMask[5]) { data.WritePackedGuid(Owner); } if (_changesMask[6]) { data.WritePackedGuid(ContainedIn); } if (_changesMask[7]) { data.WritePackedGuid(Creator); } if (_changesMask[8]) { data.WritePackedGuid(GiftCreator); } if (_changesMask[9]) { data.WriteUInt32(StackCount); } if (_changesMask[10]) { data.WriteUInt32(Expiration); } if (_changesMask[11]) { data.WriteUInt32(DynamicFlags); } if (_changesMask[12]) { data.WriteUInt32(Durability); } if (_changesMask[13]) { data.WriteUInt32(MaxDurability); } if (_changesMask[14]) { data.WriteUInt32(CreatePlayedTime); } if (_changesMask[15]) { data.WriteUInt32(ModifiersMask); } if (_changesMask[16]) { data.WriteInt32(Context); } if (_changesMask[17]) { data.WriteUInt64(ArtifactXP); } if (_changesMask[18]) { data.WriteUInt8(ItemAppearanceModID); } if (_changesMask[19]) { data.WriteUInt32(Field_130); } } if (_changesMask[20]) { for (int i = 0; i < 5; ++i) { if (_changesMask[21 + i]) { data.WriteInt32(SpellCharges[i]); } } } if (_changesMask[26]) { for (int i = 0; i < 13; ++i) { if (_changesMask[27 + i]) { Enchantment[i].WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } } } } public override void ClearChangesMask() { ClearChangesMask(BonusListIDs); ClearChangesMask(Modifiers); ClearChangesMask(ArtifactPowers); ClearChangesMask(Gems); ClearChangesMask(Owner); ClearChangesMask(ContainedIn); ClearChangesMask(Creator); ClearChangesMask(GiftCreator); ClearChangesMask(StackCount); ClearChangesMask(Expiration); ClearChangesMask(DynamicFlags); ClearChangesMask(Durability); ClearChangesMask(MaxDurability); ClearChangesMask(CreatePlayedTime); ClearChangesMask(ModifiersMask); ClearChangesMask(Context); ClearChangesMask(ArtifactXP); ClearChangesMask(ItemAppearanceModID); ClearChangesMask(Field_130); ClearChangesMask(SpellCharges); ClearChangesMask(Enchantment); _changesMask.ResetAll(); } } public class ContainerData : BaseUpdateData { public UpdateField NumSlots = new UpdateField(0, 1); public UpdateFieldArray Slots = new UpdateFieldArray(36, 2, 3); public ContainerData() : base(0, TypeId.Item, 39) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Bag owner, Player receiver) { for (int i = 0; i < 36; ++i) { data.WritePackedGuid(Slots[i]); } data.WriteUInt32(NumSlots); } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Bag owner, Player receiver) { data.WriteBits(_changesMask.GetBlocksMask(0), 2); for (uint i = 0; i < 2; ++i) if (_changesMask.GetBlock(i) != 0) data.WriteBits(_changesMask.GetBlock(i), 32); data.FlushBits(); if (_changesMask[0]) { if (_changesMask[1]) { data.WriteUInt32(NumSlots); } } if (_changesMask[2]) { for (int i = 0; i < 36; ++i) { if (_changesMask[3 + i]) { data.WritePackedGuid(Slots[i]); } } } } public override void ClearChangesMask() { ClearChangesMask(NumSlots); ClearChangesMask(Slots); _changesMask.ResetAll(); } } public class AzeriteEmpoweredItemData : BaseUpdateData { public UpdateFieldArray Selections = new UpdateFieldArray(5, 0, 1); public AzeriteEmpoweredItemData() : base(6) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { for (int i = 0; i < 5; ++i) { data.WriteInt32(Selections[i]); } } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { data.WriteBits(_changesMask.GetBlocksMask(0), 1); if (_changesMask.GetBlock(0) != 0) data.WriteBits(_changesMask.GetBlock(0), 32); data.FlushBits(); if (_changesMask[0]) { for (int i = 0; i < 5; ++i) { if (_changesMask[1 + i]) { data.WriteInt32(Selections[i]); } } } } public override void ClearChangesMask() { ClearChangesMask(Selections); _changesMask.ResetAll(); } } public class UnlockedAzeriteEssence { uint AzeriteEssenceID; uint Rank; public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { data.WriteUInt32(AzeriteEssenceID); data.WriteUInt32(Rank); } public void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { data.FlushBits(); data.WriteUInt32(AzeriteEssenceID); data.WriteUInt32(Rank); } } public class SelectedAzeriteEssences { uint Field_0; uint Enabled; uint[] AzeriteEssenceID = new uint[3]; public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { for (int i = 0; i < 3; ++i) { data.WriteUInt32(AzeriteEssenceID[i]); } data.WriteUInt32(Field_0); data.WriteBits(Enabled, 1); data.FlushBits(); } public void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { data.FlushBits(); data.WriteUInt32(Field_0); data.WriteBits(Enabled, 1); for (int i = 0; i < 3; ++i) { data.WriteUInt32(AzeriteEssenceID[i]); } data.FlushBits(); } } public class AzeriteItemData : BaseUpdateData { public DynamicUpdateField UnlockedEssences = new DynamicUpdateField(0, 1); public DynamicUpdateField UnlockedEssenceMilestones = new DynamicUpdateField(0, 2); public DynamicUpdateField SelectedEssences = new DynamicUpdateField(0, 3); public UpdateField Xp = new UpdateField(0, 4); public UpdateField Level = new UpdateField(0, 5); public UpdateField AuraLevel = new UpdateField(0, 6); public UpdateField KnowledgeLevel = new UpdateField(0, 7); public UpdateField DEBUGknowledgeWeek = new UpdateField(0, 8); public AzeriteItemData() : base(9) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) { data.WriteUInt64(Xp); data.WriteUInt32(Level); data.WriteUInt32(AuraLevel); data.WriteUInt32(KnowledgeLevel); data.WriteUInt32(DEBUGknowledgeWeek); } data.WriteInt32(UnlockedEssences.Size()); data.WriteInt32(SelectedEssences.Size()); data.WriteInt32(UnlockedEssenceMilestones.Size()); for (int i = 0; i < UnlockedEssences.Size(); ++i) { UnlockedEssences[i].WriteCreate(data, fieldVisibilityFlags, owner, receiver); } for (int i = 0; i < UnlockedEssenceMilestones.Size(); ++i) { data.WriteUInt32(UnlockedEssenceMilestones[i]); } for (int i = 0; i < SelectedEssences.Size(); ++i) { SelectedEssences[i].WriteCreate(data, fieldVisibilityFlags, owner, receiver); } } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { UpdateMask allowedMaskForTarget = new UpdateMask(9, new[] { 0x0000000Fu }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); WriteUpdate(data, _changesMask & allowedMaskForTarget, fieldVisibilityFlags, owner, receiver); } void AppendAllowedFieldsMaskForFlag(UpdateMask allowedMaskForTarget, UpdateFieldFlag fieldVisibilityFlags) { if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) allowedMaskForTarget |= new UpdateMask(9, new[] { 0x000001F0u }); } public void WriteUpdate(WorldPacket data, UpdateMask changesMask, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { data.WriteBits(_changesMask.GetBlock(0), 9); if (_changesMask[0]) { if (_changesMask[1]) { UnlockedEssences.WriteUpdateMask(data); } if (_changesMask[2]) { UnlockedEssenceMilestones.WriteUpdateMask(data); } if (_changesMask[3]) { SelectedEssences.WriteUpdateMask(data); } } data.FlushBits(); if (_changesMask[0]) { if (_changesMask[1]) { for (int i = 0; i < UnlockedEssences.Size(); ++i) { if (UnlockedEssences.HasChanged(i)) { UnlockedEssences[i].WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } } } if (_changesMask[2]) { for (int i = 0; i < UnlockedEssenceMilestones.Size(); ++i) { if (UnlockedEssenceMilestones.HasChanged(i)) { data.WriteUInt32(UnlockedEssenceMilestones[i]); } } } if (_changesMask[3]) { for (int i = 0; i < SelectedEssences.Size(); ++i) { if (SelectedEssences.HasChanged(i)) { SelectedEssences[i].WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } } } if (_changesMask[4]) { data.WriteUInt64(Xp); } if (_changesMask[5]) { data.WriteUInt32(Level); } if (_changesMask[6]) { data.WriteUInt32(AuraLevel); } if (_changesMask[7]) { data.WriteUInt32(KnowledgeLevel); } if (_changesMask[8]) { data.WriteUInt32(DEBUGknowledgeWeek); } } } public override void ClearChangesMask() { ClearChangesMask(UnlockedEssences); ClearChangesMask(UnlockedEssenceMilestones); ClearChangesMask(SelectedEssences); ClearChangesMask(Xp); ClearChangesMask(Level); ClearChangesMask(AuraLevel); ClearChangesMask(KnowledgeLevel); ClearChangesMask(DEBUGknowledgeWeek); _changesMask.ResetAll(); } } public class UnitChannel { public uint SpellID; public uint SpellXSpellVisualID; public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Unit owner, Player receiver) { data.WriteUInt32(SpellID); data.WriteUInt32(SpellXSpellVisualID); } public void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Unit owner, Player receiver) { data.FlushBits(); data.WriteUInt32(SpellID); data.WriteUInt32(SpellXSpellVisualID); } } public class VisibleItem : BaseUpdateData { public UpdateField ItemID = new UpdateField(0, 1); public UpdateField ItemAppearanceModID = new UpdateField(0, 2); public UpdateField ItemVisual = new UpdateField(0, 3); public VisibleItem() : base(4) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Unit owner, Player receiver) { data.WriteUInt32(ItemID); data.WriteUInt16(ItemAppearanceModID); data.WriteUInt16(ItemVisual); } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Unit owner, Player receiver) { data.WriteBits(_changesMask.GetBlock(0), 4); data.FlushBits(); if (_changesMask[0]) { if (_changesMask[1]) { data.WriteUInt32(ItemID); } if (_changesMask[2]) { data.WriteUInt16(ItemAppearanceModID); } if (_changesMask[3]) { data.WriteUInt16(ItemVisual); } } } public override void ClearChangesMask() { ClearChangesMask(ItemID); ClearChangesMask(ItemAppearanceModID); ClearChangesMask(ItemVisual); _changesMask.ResetAll(); } } public class PassiveSpellHistory { int SpellID; int AuraSpellID; public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Unit owner, Player receiver) { data.WriteInt32(SpellID); data.WriteInt32(AuraSpellID); } public void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Unit owner, Player receiver) { data.FlushBits(); data.WriteInt32(SpellID); data.WriteInt32(AuraSpellID); } } public class UnitData : BaseUpdateData { public UpdateField> StateWorldEffectIDs = new UpdateField>(0, 1); public DynamicUpdateField PassiveSpells = new DynamicUpdateField(0, 2); public DynamicUpdateField WorldEffects = new DynamicUpdateField(0, 3); public DynamicUpdateField ChannelObjects = new DynamicUpdateField(0, 4); public UpdateField DisplayID = new UpdateField(0, 5); public UpdateField StateSpellVisualID = new UpdateField(0, 6); public UpdateField StateAnimID = new UpdateField(0, 7); public UpdateField StateAnimKitID = new UpdateField(0, 8); public UpdateField StateWorldEffectsQuestObjectiveID = new UpdateField(0, 9); public UpdateField Charm = new UpdateField(0, 10); public UpdateField Summon = new UpdateField(0, 11); public UpdateField Critter = new UpdateField(0, 12); public UpdateField CharmedBy = new UpdateField(0, 13); public UpdateField SummonedBy = new UpdateField(0, 14); public UpdateField CreatedBy = new UpdateField(0, 15); public UpdateField DemonCreator = new UpdateField(0, 16); public UpdateField LookAtControllerTarget = new UpdateField(0, 17); public UpdateField Target = new UpdateField(0, 18); public UpdateField BattlePetCompanionGUID = new UpdateField(0, 19); public UpdateField BattlePetDBID = new UpdateField(0, 20); public UpdateField ChannelData = new UpdateField(0, 21); public UpdateField SummonedByHomeRealm = new UpdateField(0, 22); public UpdateField Race = new UpdateField(0, 23); public UpdateField ClassId = new UpdateField(0, 24); public UpdateField PlayerClassId = new UpdateField(0, 25); public UpdateField Sex = new UpdateField(0, 26); public UpdateField DisplayPower = new UpdateField(0, 27); public UpdateField OverrideDisplayPowerID = new UpdateField(0, 28); public UpdateField Health = new UpdateField(0, 29); public UpdateField MaxHealth = new UpdateField(0, 30); public UpdateField Level = new UpdateField(0, 31); public UpdateField EffectiveLevel = new UpdateField(32, 33); public UpdateField ContentTuningID = new UpdateField(32, 34); public UpdateField ScalingLevelMin = new UpdateField(32, 35); public UpdateField ScalingLevelMax = new UpdateField(32, 36); public UpdateField ScalingLevelDelta = new UpdateField(32, 37); public UpdateField ScalingFactionGroup = new UpdateField(32, 38); public UpdateField ScalingHealthItemLevelCurveID = new UpdateField(32, 39); public UpdateField ScalingDamageItemLevelCurveID = new UpdateField(32, 40); public UpdateField FactionTemplate = new UpdateField(32, 41); public UpdateField Flags = new UpdateField(32, 42); public UpdateField Flags2 = new UpdateField(32, 43); public UpdateField Flags3 = new UpdateField(32, 44); public UpdateField AuraState = new UpdateField(32, 45); public UpdateField RangedAttackRoundBaseTime = new UpdateField(32, 46); public UpdateField BoundingRadius = new UpdateField(32, 47); public UpdateField CombatReach = new UpdateField(32, 48); public UpdateField DisplayScale = new UpdateField(32, 49); public UpdateField NativeDisplayID = new UpdateField(32, 50); public UpdateField NativeXDisplayScale = new UpdateField(32, 51); public UpdateField MountDisplayID = new UpdateField(32, 52); public UpdateField CosmeticMountDisplayID = new UpdateField(32, 53); public UpdateField MinDamage = new UpdateField(32, 54); public UpdateField MaxDamage = new UpdateField(32, 55); public UpdateField MinOffHandDamage = new UpdateField(32, 56); public UpdateField MaxOffHandDamage = new UpdateField(32, 57); public UpdateField StandState = new UpdateField(32, 58); public UpdateField PetTalentPoints = new UpdateField(32, 59); public UpdateField VisFlags = new UpdateField(32, 60); public UpdateField AnimTier = new UpdateField(32, 61); public UpdateField PetNumber = new UpdateField(32, 62); public UpdateField PetNameTimestamp = new UpdateField(32, 63); public UpdateField PetExperience = new UpdateField(64, 65); public UpdateField PetNextLevelExperience = new UpdateField(64, 66); public UpdateField ModCastingSpeed = new UpdateField(64, 67); public UpdateField ModSpellHaste = new UpdateField(64, 68); public UpdateField ModHaste = new UpdateField(64, 69); public UpdateField ModRangedHaste = new UpdateField(64, 70); public UpdateField ModHasteRegen = new UpdateField(64, 71); public UpdateField ModTimeRate = new UpdateField(64, 72); public UpdateField CreatedBySpell = new UpdateField(64, 73); public UpdateField EmoteState = new UpdateField(64, 74); public UpdateField BaseMana = new UpdateField(64, 75); public UpdateField BaseHealth = new UpdateField(64, 76); public UpdateField SheatheState = new UpdateField(64, 77); public UpdateField PvpFlags = new UpdateField(64, 78); public UpdateField PetFlags = new UpdateField(64, 79); public UpdateField ShapeshiftForm = new UpdateField(64, 80); public UpdateField AttackPower = new UpdateField(64, 81); public UpdateField AttackPowerModPos = new UpdateField(64, 82); public UpdateField AttackPowerModNeg = new UpdateField(64, 83); public UpdateField AttackPowerMultiplier = new UpdateField(64, 84); public UpdateField RangedAttackPower = new UpdateField(64, 85); public UpdateField RangedAttackPowerModPos = new UpdateField(64, 86); public UpdateField RangedAttackPowerModNeg = new UpdateField(64, 87); public UpdateField RangedAttackPowerMultiplier = new UpdateField(64, 88); public UpdateField MainHandWeaponAttackPower = new UpdateField(64, 89); public UpdateField OffHandWeaponAttackPower = new UpdateField(64, 90); public UpdateField RangedWeaponAttackPower = new UpdateField(64, 91); public UpdateField SetAttackSpeedAura = new UpdateField(64, 92); public UpdateField Lifesteal = new UpdateField(64, 93); public UpdateField MinRangedDamage = new UpdateField(64, 94); public UpdateField MaxRangedDamage = new UpdateField(64, 95); public UpdateField ManaCostModifierModifier = new UpdateField(96, 97); public UpdateField MaxHealthModifier = new UpdateField(96, 98); public UpdateField HoverHeight = new UpdateField(96, 99); public UpdateField MinItemLevelCutoff = new UpdateField(96, 100); public UpdateField MinItemLevel = new UpdateField(96, 101); public UpdateField MaxItemLevel = new UpdateField(96, 102); public UpdateField AzeriteItemLevel = new UpdateField(96, 103); public UpdateField WildBattlePetLevel = new UpdateField(96, 104); public UpdateField BattlePetCompanionNameTimestamp = new UpdateField(96, 105); public UpdateField InteractSpellID = new UpdateField(96, 106); public UpdateField ScaleDuration = new UpdateField(96, 107); public UpdateField SpellOverrideNameID = new UpdateField(96, 108); public UpdateField LooksLikeMountID = new UpdateField(96, 109); public UpdateField LooksLikeCreatureID = new UpdateField(96, 110); public UpdateField LookAtControllerID = new UpdateField(96, 111); public UpdateField TaxiNodesID = new UpdateField(96, 112); public UpdateField GuildGUID = new UpdateField(96, 113); public UpdateFieldArray NpcFlags = new UpdateFieldArray(2, 114, 115); public UpdateFieldArray Power = new UpdateFieldArray(6, 117, 118); public UpdateFieldArray MaxPower = new UpdateFieldArray(6, 117, 124); public UpdateFieldArray PowerRegenFlatModifier = new UpdateFieldArray(6, 117, 130); public UpdateFieldArray PowerRegenInterruptedFlatModifier = new UpdateFieldArray(6, 117, 136); public UpdateFieldArray VirtualItems = new UpdateFieldArray(3, 142, 143); public UpdateFieldArray AttackRoundBaseTime = new UpdateFieldArray(2, 146, 147); public UpdateFieldArray Stats = new UpdateFieldArray(4, 149, 150); public UpdateFieldArray StatPosBuff = new UpdateFieldArray(4, 149, 154); public UpdateFieldArray StatNegBuff = new UpdateFieldArray(4, 149, 158); public UpdateFieldArray Resistances = new UpdateFieldArray(7, 162, 163); public UpdateFieldArray BonusResistanceMods = new UpdateFieldArray(7, 162, 170); public UpdateFieldArray PowerCostModifier = new UpdateFieldArray(7, 162, 177); public UpdateFieldArray PowerCostMultiplier = new UpdateFieldArray(7, 162, 184); public UnitData() : base(191) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Unit owner, Player receiver) { data.WriteUInt32(GetViewerDependentDisplayId(DisplayID, owner, receiver)); for (int i = 0; i < 2; ++i) data.WriteUInt32(GetViewerDependentNpcFlags(NpcFlags[i], i, owner, receiver)); data.WriteUInt32(StateSpellVisualID); data.WriteUInt32(StateAnimID); data.WriteUInt32(StateAnimKitID); data.WriteInt32(((List)StateWorldEffectIDs).Count); data.WriteUInt32(StateWorldEffectsQuestObjectiveID); for (int i = 0; i < ((List)StateWorldEffectIDs).Count; ++i) data.WriteUInt32(((List)StateWorldEffectIDs)[i]); data.WritePackedGuid(Charm); data.WritePackedGuid(Summon); if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) data.WritePackedGuid(Critter); data.WritePackedGuid(CharmedBy); data.WritePackedGuid(SummonedBy); data.WritePackedGuid(CreatedBy); data.WritePackedGuid(DemonCreator); data.WritePackedGuid(LookAtControllerTarget); data.WritePackedGuid(Target); data.WritePackedGuid(BattlePetCompanionGUID); data.WriteUInt64(BattlePetDBID); ((UnitChannel)ChannelData).WriteCreate(data, fieldVisibilityFlags, owner, receiver); data.WriteUInt32(SummonedByHomeRealm); data.WriteUInt8(Race); data.WriteUInt8(ClassId); data.WriteUInt8(PlayerClassId); data.WriteUInt8(Sex); data.WriteUInt8(DisplayPower); data.WriteUInt32(OverrideDisplayPowerID); data.WriteUInt64(Health); for (int i = 0; i < 6; ++i) { data.WriteInt32(Power[i]); data.WriteUInt32(MaxPower[i]); } if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner) || fieldVisibilityFlags.HasFlag(UpdateFieldFlag.UnitAll)) { for (int i = 0; i < 6; ++i) { data.WriteFloat(PowerRegenFlatModifier[i]); data.WriteFloat(PowerRegenInterruptedFlatModifier[i]); } } data.WriteUInt64(MaxHealth); data.WriteUInt32(Level); data.WriteInt32(EffectiveLevel); data.WriteInt32(ContentTuningID); data.WriteInt32(ScalingLevelMin); data.WriteInt32(ScalingLevelMax); data.WriteInt32(ScalingLevelDelta); data.WriteInt32(ScalingFactionGroup); data.WriteInt32(ScalingHealthItemLevelCurveID); data.WriteInt32(ScalingDamageItemLevelCurveID); data.WriteUInt32(GetViewerDependentFactionTemplate(FactionTemplate, owner, receiver)); for (int i = 0; i < 3; ++i) VirtualItems[i].WriteCreate(data, fieldVisibilityFlags, owner, receiver); data.WriteUInt32(GetViewerDependentFlags(Flags, owner, receiver)); data.WriteUInt32(Flags2); data.WriteUInt32(Flags3); data.WriteUInt32(GetViewerDependentAuraState(AuraState, owner, receiver)); for (int i = 0; i < 2; ++i) data.WriteUInt32(AttackRoundBaseTime[i]); if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) data.WriteUInt32(RangedAttackRoundBaseTime); data.WriteFloat(BoundingRadius); data.WriteFloat(CombatReach); data.WriteFloat(DisplayScale); data.WriteUInt32(NativeDisplayID); data.WriteFloat(NativeXDisplayScale); data.WriteUInt32(MountDisplayID); data.WriteInt32(CosmeticMountDisplayID); if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner) || fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Empath)) { data.WriteFloat(MinDamage); data.WriteFloat(MaxDamage); data.WriteFloat(MinOffHandDamage); data.WriteFloat(MaxOffHandDamage); } data.WriteUInt8(StandState); data.WriteUInt8(PetTalentPoints); data.WriteUInt8(VisFlags); data.WriteUInt8(AnimTier); data.WriteUInt32(PetNumber); data.WriteUInt32(PetNameTimestamp); data.WriteUInt32(PetExperience); data.WriteUInt32(PetNextLevelExperience); data.WriteFloat(ModCastingSpeed); data.WriteFloat(ModSpellHaste); data.WriteFloat(ModHaste); data.WriteFloat(ModRangedHaste); data.WriteFloat(ModHasteRegen); data.WriteFloat(ModTimeRate); data.WriteUInt32(CreatedBySpell); data.WriteInt32(EmoteState); if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) { for (int i = 0; i < 4; ++i) { data.WriteInt32(Stats[i]); data.WriteInt32(StatPosBuff[i]); data.WriteInt32(StatNegBuff[i]); } } if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner) || fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Empath)) { for (int i = 0; i < 7; ++i) { data.WriteInt32(Resistances[i]); } } if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) { for (int i = 0; i < 7; ++i) { data.WriteInt32(BonusResistanceMods[i]); data.WriteInt32(PowerCostModifier[i]); data.WriteFloat(PowerCostMultiplier[i]); } } data.WriteUInt32(BaseMana); if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) data.WriteUInt32(BaseHealth); data.WriteUInt8(SheatheState); data.WriteUInt8((byte)GetViewerDependentPvpFlags(PvpFlags, owner, receiver)); data.WriteUInt8(PetFlags); data.WriteUInt8(ShapeshiftForm); if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) { data.WriteInt32(AttackPower); data.WriteInt32(AttackPowerModPos); data.WriteInt32(AttackPowerModNeg); data.WriteFloat(AttackPowerMultiplier); data.WriteInt32(RangedAttackPower); data.WriteInt32(RangedAttackPowerModPos); data.WriteInt32(RangedAttackPowerModNeg); data.WriteFloat(RangedAttackPowerMultiplier); data.WriteInt32(MainHandWeaponAttackPower); data.WriteInt32(OffHandWeaponAttackPower); data.WriteInt32(RangedWeaponAttackPower); data.WriteInt32(SetAttackSpeedAura); data.WriteFloat(Lifesteal); data.WriteFloat(MinRangedDamage); data.WriteFloat(MaxRangedDamage); data.WriteFloat(ManaCostModifierModifier); data.WriteFloat(MaxHealthModifier); } data.WriteFloat(HoverHeight); data.WriteUInt32(MinItemLevelCutoff); data.WriteUInt32(MinItemLevel); data.WriteUInt32(MaxItemLevel); data.WriteInt32(AzeriteItemLevel); data.WriteInt32(WildBattlePetLevel); data.WriteUInt32(BattlePetCompanionNameTimestamp); data.WriteInt32(InteractSpellID); data.WriteInt32(ScaleDuration); data.WriteInt32(SpellOverrideNameID); data.WriteInt32(LooksLikeMountID); data.WriteInt32(LooksLikeCreatureID); data.WriteInt32(LookAtControllerID); data.WriteInt32(TaxiNodesID); data.WritePackedGuid(GuildGUID); data.WriteInt32(PassiveSpells.Size()); data.WriteInt32(WorldEffects.Size()); data.WriteInt32(ChannelObjects.Size()); for (int i = 0; i < PassiveSpells.Size(); ++i) PassiveSpells[i].WriteCreate(data, fieldVisibilityFlags, owner, receiver); for (int i = 0; i < WorldEffects.Size(); ++i) data.WriteInt32(WorldEffects[i]); for (int i = 0; i < ChannelObjects.Size(); ++i) data.WritePackedGuid(ChannelObjects[i]); } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Unit owner, Player receiver) { UpdateMask allowedMaskForTarget = new UpdateMask(191, new uint[] { 0xFFFFEFFFu, 0xFC3FBFFFu, 0x0001EFFFu, 0xFFDFFFF9u, 0x001FC003u, 0x00000000u }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); WriteUpdate(data, _changesMask & allowedMaskForTarget, fieldVisibilityFlags, owner, receiver); } public void AppendAllowedFieldsMaskForFlag(UpdateMask allowedMaskForTarget, UpdateFieldFlag fieldVisibilityFlags) { if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) allowedMaskForTarget |= new UpdateMask(191, new uint[] { 0x00001000u, 0x03C04000u, 0xFFFE1000u, 0x00200006u, 0xFFE03FFCu, 0x7FFFFFFFu }); if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.UnitAll)) allowedMaskForTarget |= new UpdateMask(191, new uint[] { 0x00000000u, 0x00000000u, 0x00000000u, 0x00200000u, 0x00003FFCu, 0x00000000u }); if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Empath)) allowedMaskForTarget |= new UpdateMask(191, new uint[] { 0x00000000u, 0x03C00000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x000003FCu }); } public void WriteUpdate(WorldPacket data, UpdateMask changesMask, UpdateFieldFlag fieldVisibilityFlags, Unit owner, Player receiver) { data.WriteBits(_changesMask.GetBlocksMask(0), 6); for (uint i = 0; i < 6; ++i) if (_changesMask.GetBlock(i) != 0) data.WriteBits(_changesMask.GetBlock(i), 32); if (_changesMask[0]) { if (_changesMask[1]) { List list = StateWorldEffectIDs; data.WriteBits(list.Count, 32); for (int i = 0; i < list.Count; ++i) { data.WriteUInt32(list[i]); } } } data.FlushBits(); if (_changesMask[0]) { if (_changesMask[2]) { PassiveSpells.WriteUpdateMask(data); } if (_changesMask[3]) { WorldEffects.WriteUpdateMask(data); } if (_changesMask[4]) { ChannelObjects.WriteUpdateMask(data); } } data.FlushBits(); if (_changesMask[0]) { if (_changesMask[2]) { for (int i = 0; i < PassiveSpells.Size(); ++i) { if (PassiveSpells.HasChanged(i)) { PassiveSpells[i].WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } } } if (_changesMask[3]) { for (int i = 0; i < WorldEffects.Size(); ++i) { if (WorldEffects.HasChanged(i)) { data.WriteInt32(WorldEffects[i]); } } } if (_changesMask[4]) { for (int i = 0; i < ChannelObjects.Size(); ++i) { if (ChannelObjects.HasChanged(i)) { data.WritePackedGuid(ChannelObjects[i]); } } } if (_changesMask[5]) { data.WriteUInt32(GetViewerDependentDisplayId(DisplayID, owner, receiver)); } if (_changesMask[6]) { data.WriteUInt32(StateSpellVisualID); } if (_changesMask[7]) { data.WriteUInt32(StateAnimID); } if (_changesMask[8]) { data.WriteUInt32(StateAnimKitID); } if (_changesMask[9]) { data.WriteUInt32(StateWorldEffectsQuestObjectiveID); } if (_changesMask[10]) { data.WritePackedGuid(Charm); } if (_changesMask[11]) { data.WritePackedGuid(Summon); } if (_changesMask[12]) { data.WritePackedGuid(Critter); } if (_changesMask[13]) { data.WritePackedGuid(CharmedBy); } if (_changesMask[14]) { data.WritePackedGuid(SummonedBy); } if (_changesMask[15]) { data.WritePackedGuid(CreatedBy); } if (_changesMask[16]) { data.WritePackedGuid(DemonCreator); } if (_changesMask[17]) { data.WritePackedGuid(LookAtControllerTarget); } if (_changesMask[18]) { data.WritePackedGuid(Target); } if (_changesMask[19]) { data.WritePackedGuid(BattlePetCompanionGUID); } if (_changesMask[20]) { data.WriteUInt64(BattlePetDBID); } if (_changesMask[21]) { ((UnitChannel)ChannelData).WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } if (_changesMask[22]) { data.WriteUInt32(SummonedByHomeRealm); } if (_changesMask[23]) { data.WriteUInt8(Race); } if (_changesMask[24]) { data.WriteUInt8(ClassId); } if (_changesMask[25]) { data.WriteUInt8(PlayerClassId); } if (_changesMask[26]) { data.WriteUInt8(Sex); } if (_changesMask[27]) { data.WriteUInt8(DisplayPower); } if (_changesMask[28]) { data.WriteUInt32(OverrideDisplayPowerID); } if (_changesMask[29]) { data.WriteUInt64(Health); } if (_changesMask[30]) { data.WriteUInt64(MaxHealth); } if (_changesMask[31]) { data.WriteUInt32(Level); } } if (_changesMask[32]) { if (_changesMask[33]) { data.WriteInt32(EffectiveLevel); } if (_changesMask[34]) { data.WriteInt32(ContentTuningID); } if (_changesMask[35]) { data.WriteInt32(ScalingLevelMin); } if (_changesMask[36]) { data.WriteInt32(ScalingLevelMax); } if (_changesMask[37]) { data.WriteInt32(ScalingLevelDelta); } if (_changesMask[38]) { data.WriteInt32(ScalingFactionGroup); } if (_changesMask[39]) { data.WriteInt32(ScalingHealthItemLevelCurveID); } if (_changesMask[40]) { data.WriteInt32(ScalingDamageItemLevelCurveID); } if (_changesMask[41]) { data.WriteUInt32(GetViewerDependentFactionTemplate(FactionTemplate, owner, receiver)); } if (_changesMask[42]) { data.WriteUInt32(GetViewerDependentFlags(Flags, owner, receiver)); } if (_changesMask[43]) { data.WriteUInt32(Flags2); } if (_changesMask[44]) { data.WriteUInt32(Flags3); } if (_changesMask[45]) { data.WriteUInt32(GetViewerDependentAuraState(AuraState, owner, receiver)); } if (_changesMask[46]) { data.WriteUInt32(RangedAttackRoundBaseTime); } if (_changesMask[47]) { data.WriteFloat(BoundingRadius); } if (_changesMask[48]) { data.WriteFloat(CombatReach); } if (_changesMask[49]) { data.WriteFloat(DisplayScale); } if (_changesMask[50]) { data.WriteUInt32(NativeDisplayID); } if (_changesMask[51]) { data.WriteFloat(NativeXDisplayScale); } if (_changesMask[52]) { data.WriteUInt32(MountDisplayID); } if (_changesMask[53]) { data.WriteInt32(CosmeticMountDisplayID); } if (_changesMask[54]) { data.WriteFloat(MinDamage); } if (_changesMask[55]) { data.WriteFloat(MaxDamage); } if (_changesMask[56]) { data.WriteFloat(MinOffHandDamage); } if (_changesMask[57]) { data.WriteFloat(MaxOffHandDamage); } if (_changesMask[58]) { data.WriteUInt8(StandState); } if (_changesMask[59]) { data.WriteUInt8(PetTalentPoints); } if (_changesMask[60]) { data.WriteUInt8(VisFlags); } if (_changesMask[61]) { data.WriteUInt8(AnimTier); } if (_changesMask[62]) { data.WriteUInt32(PetNumber); } if (_changesMask[63]) { data.WriteUInt32(PetNameTimestamp); } } if (_changesMask[64]) { if (_changesMask[65]) { data.WriteUInt32(PetExperience); } if (_changesMask[66]) { data.WriteUInt32(PetNextLevelExperience); } if (_changesMask[67]) { data.WriteFloat(ModCastingSpeed); } if (_changesMask[68]) { data.WriteFloat(ModSpellHaste); } if (_changesMask[69]) { data.WriteFloat(ModHaste); } if (_changesMask[70]) { data.WriteFloat(ModRangedHaste); } if (_changesMask[71]) { data.WriteFloat(ModHasteRegen); } if (_changesMask[72]) { data.WriteFloat(ModTimeRate); } if (_changesMask[73]) { data.WriteUInt32(CreatedBySpell); } if (_changesMask[74]) { data.WriteInt32(EmoteState); } if (_changesMask[75]) { data.WriteUInt32(BaseMana); } if (_changesMask[76]) { data.WriteUInt32(BaseHealth); } if (_changesMask[77]) { data.WriteUInt8(SheatheState); } if (_changesMask[78]) { data.WriteUInt8((byte)GetViewerDependentPvpFlags(PvpFlags, owner, receiver)); } if (_changesMask[79]) { data.WriteUInt8(PetFlags); } if (_changesMask[80]) { data.WriteUInt8(ShapeshiftForm); } if (_changesMask[81]) { data.WriteInt32(AttackPower); } if (_changesMask[82]) { data.WriteInt32(AttackPowerModPos); } if (_changesMask[83]) { data.WriteInt32(AttackPowerModNeg); } if (_changesMask[84]) { data.WriteFloat(AttackPowerMultiplier); } if (_changesMask[85]) { data.WriteInt32(RangedAttackPower); } if (_changesMask[86]) { data.WriteInt32(RangedAttackPowerModPos); } if (_changesMask[87]) { data.WriteInt32(RangedAttackPowerModNeg); } if (_changesMask[88]) { data.WriteFloat(RangedAttackPowerMultiplier); } if (_changesMask[89]) { data.WriteInt32(MainHandWeaponAttackPower); } if (_changesMask[90]) { data.WriteInt32(OffHandWeaponAttackPower); } if (_changesMask[91]) { data.WriteInt32(RangedWeaponAttackPower); } if (_changesMask[92]) { data.WriteInt32(SetAttackSpeedAura); } if (_changesMask[93]) { data.WriteFloat(Lifesteal); } if (_changesMask[94]) { data.WriteFloat(MinRangedDamage); } if (_changesMask[95]) { data.WriteFloat(MaxRangedDamage); } } if (_changesMask[96]) { if (_changesMask[97]) { data.WriteFloat(ManaCostModifierModifier); } if (_changesMask[98]) { data.WriteFloat(MaxHealthModifier); } if (_changesMask[99]) { data.WriteFloat(HoverHeight); } if (_changesMask[100]) { data.WriteUInt32(MinItemLevelCutoff); } if (_changesMask[101]) { data.WriteUInt32(MinItemLevel); } if (_changesMask[102]) { data.WriteUInt32(MaxItemLevel); } if (_changesMask[103]) { data.WriteInt32(AzeriteItemLevel); } if (_changesMask[104]) { data.WriteInt32(WildBattlePetLevel); } if (_changesMask[105]) { data.WriteUInt32(BattlePetCompanionNameTimestamp); } if (_changesMask[106]) { data.WriteInt32(InteractSpellID); } if (_changesMask[107]) { data.WriteInt32(ScaleDuration); } if (_changesMask[108]) { data.WriteInt32(SpellOverrideNameID); } if (_changesMask[109]) { data.WriteInt32(LooksLikeMountID); } if (_changesMask[110]) { data.WriteInt32(LooksLikeCreatureID); } if (_changesMask[111]) { data.WriteInt32(LookAtControllerID); } if (_changesMask[112]) { data.WriteInt32(TaxiNodesID); } if (_changesMask[113]) { data.WritePackedGuid(GuildGUID); } } if (_changesMask[114]) { for (int i = 0; i < 2; ++i) { if (_changesMask[115 + i]) { data.WriteUInt32(GetViewerDependentNpcFlags(NpcFlags[i], i, owner, receiver)); } } } if (_changesMask[117]) { for (int i = 0; i < 6; ++i) { if (_changesMask[118 + i]) { data.WriteInt32(Power[i]); } if (_changesMask[124 + i]) { data.WriteUInt32(MaxPower[i]); } if (_changesMask[130 + i]) { data.WriteFloat(PowerRegenFlatModifier[i]); } if (_changesMask[136 + i]) { data.WriteFloat(PowerRegenInterruptedFlatModifier[i]); } } } if (_changesMask[142]) { for (int i = 0; i < 3; ++i) { if (_changesMask[143 + i]) { VirtualItems[i].WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } } } if (_changesMask[146]) { for (int i = 0; i < 2; ++i) { if (_changesMask[147 + i]) { data.WriteUInt32(AttackRoundBaseTime[i]); } } } if (_changesMask[149]) { for (int i = 0; i < 4; ++i) { if (_changesMask[150 + i]) { data.WriteInt32(Stats[i]); } if (_changesMask[154 + i]) { data.WriteInt32(StatPosBuff[i]); } if (_changesMask[158 + i]) { data.WriteInt32(StatNegBuff[i]); } } } if (_changesMask[162]) { for (int i = 0; i < 7; ++i) { if (_changesMask[163 + i]) { data.WriteInt32(Resistances[i]); } if (_changesMask[170 + i]) { data.WriteInt32(BonusResistanceMods[i]); } if (_changesMask[177 + i]) { data.WriteInt32(PowerCostModifier[i]); } if (_changesMask[184 + i]) { data.WriteFloat(PowerCostMultiplier[i]); } } } } public override void ClearChangesMask() { ClearChangesMask(StateWorldEffectIDs); ClearChangesMask(PassiveSpells); ClearChangesMask(WorldEffects); ClearChangesMask(ChannelObjects); ClearChangesMask(DisplayID); ClearChangesMask(StateSpellVisualID); ClearChangesMask(StateAnimID); ClearChangesMask(StateAnimKitID); ClearChangesMask(StateWorldEffectsQuestObjectiveID); ClearChangesMask(Charm); ClearChangesMask(Summon); ClearChangesMask(Critter); ClearChangesMask(CharmedBy); ClearChangesMask(SummonedBy); ClearChangesMask(CreatedBy); ClearChangesMask(DemonCreator); ClearChangesMask(LookAtControllerTarget); ClearChangesMask(Target); ClearChangesMask(BattlePetCompanionGUID); ClearChangesMask(BattlePetDBID); ClearChangesMask(ChannelData); ClearChangesMask(SummonedByHomeRealm); ClearChangesMask(Race); ClearChangesMask(ClassId); ClearChangesMask(PlayerClassId); ClearChangesMask(Sex); ClearChangesMask(DisplayPower); ClearChangesMask(OverrideDisplayPowerID); ClearChangesMask(Health); ClearChangesMask(MaxHealth); ClearChangesMask(Level); ClearChangesMask(EffectiveLevel); ClearChangesMask(ContentTuningID); ClearChangesMask(ScalingLevelMin); ClearChangesMask(ScalingLevelMax); ClearChangesMask(ScalingLevelDelta); ClearChangesMask(ScalingFactionGroup); ClearChangesMask(ScalingHealthItemLevelCurveID); ClearChangesMask(ScalingDamageItemLevelCurveID); ClearChangesMask(FactionTemplate); ClearChangesMask(Flags); ClearChangesMask(Flags2); ClearChangesMask(Flags3); ClearChangesMask(AuraState); ClearChangesMask(RangedAttackRoundBaseTime); ClearChangesMask(BoundingRadius); ClearChangesMask(CombatReach); ClearChangesMask(DisplayScale); ClearChangesMask(NativeDisplayID); ClearChangesMask(NativeXDisplayScale); ClearChangesMask(MountDisplayID); ClearChangesMask(CosmeticMountDisplayID); ClearChangesMask(MinDamage); ClearChangesMask(MaxDamage); ClearChangesMask(MinOffHandDamage); ClearChangesMask(MaxOffHandDamage); ClearChangesMask(StandState); ClearChangesMask(PetTalentPoints); ClearChangesMask(VisFlags); ClearChangesMask(AnimTier); ClearChangesMask(PetNumber); ClearChangesMask(PetNameTimestamp); ClearChangesMask(PetExperience); ClearChangesMask(PetNextLevelExperience); ClearChangesMask(ModCastingSpeed); ClearChangesMask(ModSpellHaste); ClearChangesMask(ModHaste); ClearChangesMask(ModRangedHaste); ClearChangesMask(ModHasteRegen); ClearChangesMask(ModTimeRate); ClearChangesMask(CreatedBySpell); ClearChangesMask(EmoteState); ClearChangesMask(BaseMana); ClearChangesMask(BaseHealth); ClearChangesMask(SheatheState); ClearChangesMask(PvpFlags); ClearChangesMask(PetFlags); ClearChangesMask(ShapeshiftForm); ClearChangesMask(AttackPower); ClearChangesMask(AttackPowerModPos); ClearChangesMask(AttackPowerModNeg); ClearChangesMask(AttackPowerMultiplier); ClearChangesMask(RangedAttackPower); ClearChangesMask(RangedAttackPowerModPos); ClearChangesMask(RangedAttackPowerModNeg); ClearChangesMask(RangedAttackPowerMultiplier); ClearChangesMask(MainHandWeaponAttackPower); ClearChangesMask(OffHandWeaponAttackPower); ClearChangesMask(RangedWeaponAttackPower); ClearChangesMask(SetAttackSpeedAura); ClearChangesMask(Lifesteal); ClearChangesMask(MinRangedDamage); ClearChangesMask(MaxRangedDamage); ClearChangesMask(ManaCostModifierModifier); ClearChangesMask(MaxHealthModifier); ClearChangesMask(HoverHeight); ClearChangesMask(MinItemLevelCutoff); ClearChangesMask(MinItemLevel); ClearChangesMask(MaxItemLevel); ClearChangesMask(AzeriteItemLevel); ClearChangesMask(WildBattlePetLevel); ClearChangesMask(BattlePetCompanionNameTimestamp); ClearChangesMask(InteractSpellID); ClearChangesMask(ScaleDuration); ClearChangesMask(SpellOverrideNameID); ClearChangesMask(LooksLikeMountID); ClearChangesMask(LooksLikeCreatureID); ClearChangesMask(LookAtControllerID); ClearChangesMask(TaxiNodesID); ClearChangesMask(GuildGUID); ClearChangesMask(NpcFlags); ClearChangesMask(Power); ClearChangesMask(MaxPower); ClearChangesMask(PowerRegenFlatModifier); ClearChangesMask(PowerRegenInterruptedFlatModifier); ClearChangesMask(VirtualItems); ClearChangesMask(AttackRoundBaseTime); ClearChangesMask(Stats); ClearChangesMask(StatPosBuff); ClearChangesMask(StatNegBuff); ClearChangesMask(Resistances); ClearChangesMask(BonusResistanceMods); ClearChangesMask(PowerCostModifier); ClearChangesMask(PowerCostMultiplier); _changesMask.ResetAll(); } uint GetViewerDependentDisplayId(uint displayId, Unit unit, Player receiver) { if (unit.IsCreature()) { CreatureTemplate cinfo = unit.ToCreature().GetCreatureTemplate(); // this also applies for transform auras SpellInfo transform = Global.SpellMgr.GetSpellInfo(unit.getTransForm()); if (transform != null) { foreach (SpellEffectInfo effect in transform.GetEffectsForDifficulty(unit.GetMap().GetDifficultyID())) { if (effect != null && effect.IsAura(AuraType.Transform)) { CreatureTemplate transformInfo = Global.ObjectMgr.GetCreatureTemplate((uint)effect.MiscValue); if (transformInfo != null) { cinfo = transformInfo; break; } } } } if (cinfo.FlagsExtra.HasAnyFlag(CreatureFlagsExtra.Trigger)) if (receiver.IsGameMaster()) displayId = cinfo.GetFirstVisibleModel().CreatureDisplayID; } return displayId; } uint GetViewerDependentNpcFlags(uint npcFlag, int i, Unit unit, Player receiver) { if (i == 0 && unit.IsCreature() && !receiver.CanSeeSpellClickOn(unit.ToCreature())) npcFlag &= ~(uint)NPCFlags.SpellClick; return npcFlag; } uint GetViewerDependentFactionTemplate(uint factionTemplate, Unit unit, Player receiver) { if (unit.IsControlledByPlayer() && receiver != unit && WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionGroup) && unit.IsInRaidWith(receiver)) { FactionTemplateRecord ft1 = unit.GetFactionTemplateEntry(); FactionTemplateRecord ft2 = receiver.GetFactionTemplateEntry(); if (ft1 != null && ft2 != null && !ft1.IsFriendlyTo(ft2)) // pretend that all other HOSTILE players have own faction, to allow follow, heal, rezz (trade wont work) factionTemplate = receiver.GetFaction(); } return factionTemplate; } uint GetViewerDependentFlags(uint flags, Unit unit, Player receiver) { // Gamemasters should be always able to select units - remove not selectable flag if (receiver.IsGameMaster()) flags &= ~(uint)UnitFlags.NotSelectable; return flags; } uint GetViewerDependentAuraState(uint auraState, Unit unit, Player receiver) { // Check per caster aura states to not enable using a spell in client if specified aura is not by target return unit.BuildAuraStateUpdateForTarget(receiver); } uint GetViewerDependentPvpFlags(uint pvpFlags, Unit unit, Player receiver) { if (unit.IsControlledByPlayer() && receiver != unit && WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionGroup) && unit.IsInRaidWith(receiver)) { FactionTemplateRecord ft1 = unit.GetFactionTemplateEntry(); FactionTemplateRecord ft2 = receiver.GetFactionTemplateEntry(); if (ft1 != null && ft2 != null && !ft1.IsFriendlyTo(ft2)) // Allow targeting opposite faction in party when enabled in config pvpFlags &= (uint)UnitPVPStateFlags.Sanctuary; } return pvpFlags; } } public class QuestLog : BaseUpdateData { public UpdateField QuestID = new UpdateField(0, 1); public UpdateField StateFlags = new UpdateField(0, 2); public UpdateField EndTime = new UpdateField(0, 3); public UpdateField AcceptTime = new UpdateField(0, 4); public UpdateFieldArray ObjectiveProgress = new UpdateFieldArray(24, 5, 6); public QuestLog() : base(30) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { data.WriteUInt32(QuestID); data.WriteUInt32(StateFlags); data.WriteUInt32(EndTime); data.WriteUInt32(AcceptTime); for (int i = 0; i < 24; ++i) { data.WriteUInt16(ObjectiveProgress[i]); } } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { data.WriteBits(_changesMask.GetBlocksMask(0), 1); if (_changesMask.GetBlock(0) != 0) data.WriteBits(_changesMask.GetBlock(0), 32); data.FlushBits(); if (_changesMask[0]) { if (_changesMask[1]) { data.WriteUInt32(QuestID); } if (_changesMask[2]) { data.WriteUInt32(StateFlags); } if (_changesMask[3]) { data.WriteUInt32(EndTime); } if (_changesMask[4]) { data.WriteUInt32(AcceptTime); } } if (_changesMask[5]) { for (int i = 0; i < 24; ++i) { if (_changesMask[6 + i]) { data.WriteUInt16(ObjectiveProgress[i]); } } } } public override void ClearChangesMask() { ClearChangesMask(QuestID); ClearChangesMask(StateFlags); ClearChangesMask(EndTime); ClearChangesMask(AcceptTime); ClearChangesMask(ObjectiveProgress); _changesMask.ResetAll(); } } public class ArenaCooldown : BaseUpdateData { public UpdateField SpellID = new UpdateField(0, 1); public UpdateField Charges = new UpdateField(0, 2); public UpdateField Flags = new UpdateField(0, 3); public UpdateField StartTime = new UpdateField(0, 4); public UpdateField EndTime = new UpdateField(0, 5); public UpdateField NextChargeTime = new UpdateField(0, 6); public UpdateField MaxCharges = new UpdateField(0, 7); public ArenaCooldown() : base(8) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { data.WriteInt32(SpellID); data.WriteInt32(Charges); data.WriteUInt32(Flags); data.WriteUInt32(StartTime); data.WriteUInt32(EndTime); data.WriteUInt32(NextChargeTime); data.WriteUInt8(MaxCharges); } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { data.WriteBits(_changesMask.GetBlock(0), 8); data.FlushBits(); if (_changesMask[0]) { if (_changesMask[1]) { data.WriteInt32(SpellID); } if (_changesMask[2]) { data.WriteInt32(Charges); } if (_changesMask[3]) { data.WriteUInt32(Flags); } if (_changesMask[4]) { data.WriteUInt32(StartTime); } if (_changesMask[5]) { data.WriteUInt32(EndTime); } if (_changesMask[6]) { data.WriteUInt32(NextChargeTime); } if (_changesMask[7]) { data.WriteUInt8(MaxCharges); } } } public override void ClearChangesMask() { ClearChangesMask(SpellID); ClearChangesMask(Charges); ClearChangesMask(Flags); ClearChangesMask(StartTime); ClearChangesMask(EndTime); ClearChangesMask(NextChargeTime); ClearChangesMask(MaxCharges); _changesMask.ResetAll(); } } public class PlayerData : BaseUpdateData { public DynamicUpdateField ArenaCooldowns = new DynamicUpdateField(0, 1); public UpdateField DuelArbiter = new UpdateField(0, 2); public UpdateField WowAccount = new UpdateField(0, 3); public UpdateField LootTargetGUID = new UpdateField(0, 4); public UpdateField PlayerFlags = new UpdateField(0, 5); public UpdateField PlayerFlagsEx = new UpdateField(0, 6); public UpdateField GuildRankID = new UpdateField(0, 7); public UpdateField GuildDeleteDate = new UpdateField(0, 8); public UpdateField GuildLevel = new UpdateField(0, 9); public UpdateField SkinID = new UpdateField(0, 10); public UpdateField FaceID = new UpdateField(0, 11); public UpdateField HairStyleID = new UpdateField(0, 12); public UpdateField HairColorID = new UpdateField(0, 13); public UpdateField FacialHairStyleID = new UpdateField(0, 14); public UpdateField PartyType = new UpdateField(0, 15); public UpdateField NativeSex = new UpdateField(0, 16); public UpdateField Inebriation = new UpdateField(0, 17); public UpdateField PvpTitle = new UpdateField(0, 18); public UpdateField ArenaFaction = new UpdateField(0, 19); public UpdateField DuelTeam = new UpdateField(0, 20); public UpdateField GuildTimeStamp = new UpdateField(0, 21); public UpdateField PlayerTitle = new UpdateField(0, 22); public UpdateField FakeInebriation = new UpdateField(0, 23); public UpdateField VirtualPlayerRealm = new UpdateField(0, 24); public UpdateField CurrentSpecID = new UpdateField(0, 25); public UpdateField TaxiMountAnimKitID = new UpdateField(0, 26); public UpdateField CurrentBattlePetBreedQuality = new UpdateField(0, 27); public UpdateField HonorLevel = new UpdateField(0, 28); public UpdateField Field_B0 = new UpdateField(0, 29); public UpdateField Field_B4 = new UpdateField(0, 30); public UpdateFieldArray CustomDisplayOption = new UpdateFieldArray(3, 31, 32); public UpdateFieldArray QuestLog = new UpdateFieldArray(100, 35, 36); public UpdateFieldArray VisibleItems = new UpdateFieldArray(19, 136, 137); public UpdateFieldArray AvgItemLevel = new UpdateFieldArray(4, 156, 157); public PlayerData() : base(161) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { data.WritePackedGuid(DuelArbiter); data.WritePackedGuid(WowAccount); data.WritePackedGuid(LootTargetGUID); data.WriteUInt32(PlayerFlags); data.WriteUInt32(PlayerFlagsEx); data.WriteUInt32(GuildRankID); data.WriteUInt32(GuildDeleteDate); data.WriteUInt32(GuildLevel); data.WriteUInt8(SkinID); data.WriteUInt8(FaceID); data.WriteUInt8(HairStyleID); data.WriteUInt8(HairColorID); for (int i = 0; i < 3; ++i) { data.WriteUInt8(CustomDisplayOption[i]); } data.WriteUInt8(FacialHairStyleID); data.WriteUInt8(PartyType); data.WriteUInt8(NativeSex); data.WriteUInt8(Inebriation); data.WriteUInt8(PvpTitle); data.WriteUInt8(ArenaFaction); data.WriteUInt32(DuelTeam); data.WriteInt32(GuildTimeStamp); if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.PartyMember)) { for (int i = 0; i < 100; ++i) { QuestLog[i].WriteCreate(data, fieldVisibilityFlags, owner, receiver); } } for (int i = 0; i < 19; ++i) { VisibleItems[i].WriteCreate(data, fieldVisibilityFlags, owner, receiver); } data.WriteUInt32(PlayerTitle); data.WriteInt32(FakeInebriation); data.WriteUInt32(VirtualPlayerRealm); data.WriteUInt32(CurrentSpecID); data.WriteInt32(TaxiMountAnimKitID); for (int i = 0; i < 4; ++i) { data.WriteFloat(AvgItemLevel[i]); } data.WriteUInt8(CurrentBattlePetBreedQuality); data.WriteUInt32(HonorLevel); data.WriteInt32(ArenaCooldowns.Size()); data.WriteInt32(Field_B0); data.WriteInt32(Field_B4); for (int i = 0; i < ArenaCooldowns.Size(); ++i) { ArenaCooldown arenaCooldown = ArenaCooldowns[i]; arenaCooldown.WriteCreate(data, fieldVisibilityFlags, owner, receiver); } } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { UpdateMask allowedMaskForTarget = new UpdateMask(161, new[] { 0xFFFFFFFFu, 0x00000007u, 0x00000000u, 0x00000000u, 0xFFFFFF00u, 0x00000001u }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); WriteUpdate(data, _changesMask & allowedMaskForTarget, fieldVisibilityFlags, owner, receiver); } public void AppendAllowedFieldsMaskForFlag(UpdateMask allowedMaskForTarget, UpdateFieldFlag fieldVisibilityFlags) { if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.PartyMember)) allowedMaskForTarget |= new UpdateMask(161, new[] { 0x00000000u, 0xFFFFFFF8u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x000000FFu, 0x00000000u }); } public void WriteUpdate(WorldPacket data, UpdateMask changesMask, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { data.WriteBits(_changesMask.GetBlocksMask(0), 6); for (uint i = 0; i < 6; ++i) if (_changesMask.GetBlock(i) != 0) data.WriteBits(_changesMask.GetBlock(i), 32); if (_changesMask[0]) { if (_changesMask[1]) { ArenaCooldowns.WriteUpdateMask(data); } } data.FlushBits(); if (_changesMask[0]) { if (_changesMask[1]) { for (int i = 0; i < ArenaCooldowns.Size(); ++i) { if (ArenaCooldowns.HasChanged(i)) { ArenaCooldown arenaCooldown = ArenaCooldowns[i]; arenaCooldown.WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } } } if (_changesMask[2]) { data.WritePackedGuid(DuelArbiter); } if (_changesMask[3]) { data.WritePackedGuid(WowAccount); } if (_changesMask[4]) { data.WritePackedGuid(LootTargetGUID); } if (_changesMask[5]) { data.WriteUInt32(PlayerFlags); } if (_changesMask[6]) { data.WriteUInt32(PlayerFlagsEx); } if (_changesMask[7]) { data.WriteUInt32(GuildRankID); } if (_changesMask[8]) { data.WriteUInt32(GuildDeleteDate); } if (_changesMask[9]) { data.WriteUInt32(GuildLevel); } if (_changesMask[10]) { data.WriteUInt8(SkinID); } if (_changesMask[11]) { data.WriteUInt8(FaceID); } if (_changesMask[12]) { data.WriteUInt8(HairStyleID); } if (_changesMask[13]) { data.WriteUInt8(HairColorID); } if (_changesMask[14]) { data.WriteUInt8(FacialHairStyleID); } if (_changesMask[15]) { data.WriteUInt8(PartyType); } if (_changesMask[16]) { data.WriteUInt8(NativeSex); } if (_changesMask[17]) { data.WriteUInt8(Inebriation); } if (_changesMask[18]) { data.WriteUInt8(PvpTitle); } if (_changesMask[19]) { data.WriteUInt8(ArenaFaction); } if (_changesMask[20]) { data.WriteUInt32(DuelTeam); } if (_changesMask[21]) { data.WriteInt32(GuildTimeStamp); } if (_changesMask[22]) { data.WriteUInt32(PlayerTitle); } if (_changesMask[23]) { data.WriteInt32(FakeInebriation); } if (_changesMask[24]) { data.WriteUInt32(VirtualPlayerRealm); } if (_changesMask[25]) { data.WriteUInt32(CurrentSpecID); } if (_changesMask[26]) { data.WriteInt32(TaxiMountAnimKitID); } if (_changesMask[27]) { data.WriteUInt8(CurrentBattlePetBreedQuality); } if (_changesMask[28]) { data.WriteUInt32(HonorLevel); } if (_changesMask[29]) { data.WriteInt32(Field_B0); } if (_changesMask[30]) { data.WriteInt32(Field_B4); } } if (_changesMask[31]) { for (int i = 0; i < 3; ++i) { if (_changesMask[32 + i]) { data.WriteUInt8(CustomDisplayOption[i]); } } } if (_changesMask[35]) { for (int i = 0; i < 100; ++i) { if (_changesMask[36 + i]) { QuestLog[i].WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } } } if (_changesMask[136]) { for (int i = 0; i < 19; ++i) { if (_changesMask[137 + i]) { VisibleItems[i].WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } } } if (_changesMask[156]) { for (int i = 0; i < 4; ++i) { if (_changesMask[157 + i]) { data.WriteFloat(AvgItemLevel[i]); } } } } public override void ClearChangesMask() { ClearChangesMask(ArenaCooldowns); ClearChangesMask(DuelArbiter); ClearChangesMask(WowAccount); ClearChangesMask(LootTargetGUID); ClearChangesMask(PlayerFlags); ClearChangesMask(PlayerFlagsEx); ClearChangesMask(GuildRankID); ClearChangesMask(GuildDeleteDate); ClearChangesMask(GuildLevel); ClearChangesMask(SkinID); ClearChangesMask(FaceID); ClearChangesMask(HairStyleID); ClearChangesMask(HairColorID); ClearChangesMask(FacialHairStyleID); ClearChangesMask(PartyType); ClearChangesMask(NativeSex); ClearChangesMask(Inebriation); ClearChangesMask(PvpTitle); ClearChangesMask(ArenaFaction); ClearChangesMask(DuelTeam); ClearChangesMask(GuildTimeStamp); ClearChangesMask(PlayerTitle); ClearChangesMask(FakeInebriation); ClearChangesMask(VirtualPlayerRealm); ClearChangesMask(CurrentSpecID); ClearChangesMask(TaxiMountAnimKitID); ClearChangesMask(CurrentBattlePetBreedQuality); ClearChangesMask(HonorLevel); ClearChangesMask(Field_B0); ClearChangesMask(Field_B4); ClearChangesMask(CustomDisplayOption); ClearChangesMask(QuestLog); ClearChangesMask(VisibleItems); ClearChangesMask(AvgItemLevel); _changesMask.ResetAll(); } } public class SkillInfo : BaseUpdateData { public UpdateFieldArray SkillLineID = new UpdateFieldArray(256, 0, 1); public UpdateFieldArray SkillStep = new UpdateFieldArray(256, 0, 257); public UpdateFieldArray SkillRank = new UpdateFieldArray(256, 0, 513); public UpdateFieldArray SkillStartingRank = new UpdateFieldArray(256, 0, 769); public UpdateFieldArray SkillMaxRank = new UpdateFieldArray(256, 0, 1025); public UpdateFieldArray SkillTempBonus = new UpdateFieldArray(256, 0, 1281); public UpdateFieldArray SkillPermBonus = new UpdateFieldArray(256, 0, 1537); public SkillInfo() : base(1793) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { for (int i = 0; i < 256; ++i) { data.WriteUInt16(SkillLineID[i]); data.WriteUInt16(SkillStep[i]); data.WriteUInt16(SkillRank[i]); data.WriteUInt16(SkillStartingRank[i]); data.WriteUInt16(SkillMaxRank[i]); data.WriteUInt16(SkillTempBonus[i]); data.WriteUInt16(SkillPermBonus[i]); } } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { for (uint i = 0; i < 1; ++i) data.WriteUInt32(_changesMask.GetBlocksMask(i)); data.WriteBits(_changesMask.GetBlocksMask(1), 25); for (uint i = 0; i < 57; ++i) if (_changesMask.GetBlock(i) != 0) data.WriteBits(_changesMask.GetBlock(i), 32); data.FlushBits(); if (_changesMask[0]) { for (int i = 0; i < 256; ++i) { if (_changesMask[1 + i]) { data.WriteUInt16(SkillLineID[i]); } if (_changesMask[257 + i]) { data.WriteUInt16(SkillStep[i]); } if (_changesMask[513 + i]) { data.WriteUInt16(SkillRank[i]); } if (_changesMask[769 + i]) { data.WriteUInt16(SkillStartingRank[i]); } if (_changesMask[1025 + i]) { data.WriteUInt16(SkillMaxRank[i]); } if (_changesMask[1281 + i]) { data.WriteUInt16(SkillTempBonus[i]); } if (_changesMask[1537 + i]) { data.WriteUInt16(SkillPermBonus[i]); } } } } public override void ClearChangesMask() { ClearChangesMask(SkillLineID); ClearChangesMask(SkillStep); ClearChangesMask(SkillRank); ClearChangesMask(SkillStartingRank); ClearChangesMask(SkillMaxRank); ClearChangesMask(SkillTempBonus); ClearChangesMask(SkillPermBonus); _changesMask.ResetAll(); } } public class RestInfo : BaseUpdateData { public UpdateField Threshold = new UpdateField(0, 1); public UpdateField StateID = new UpdateField(0, 2); public RestInfo() : base(3) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { data.WriteUInt32(Threshold); data.WriteUInt8(StateID); } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { data.WriteBits(_changesMask.GetBlock(0), 3); data.FlushBits(); if (_changesMask[0]) { if (_changesMask[1]) { data.WriteUInt32(Threshold); } if (_changesMask[2]) { data.WriteUInt8(StateID); } } } public override void ClearChangesMask() { ClearChangesMask(Threshold); ClearChangesMask(StateID); _changesMask.ResetAll(); } } public class PVPInfo : BaseUpdateData { public UpdateField Field_0 = new UpdateField(0, 1); public UpdateField Field_4 = new UpdateField(0, 2); public UpdateField Field_8 = new UpdateField(0, 3); public UpdateField Field_C = new UpdateField(0, 4); public UpdateField Rating = new UpdateField(0, 5); public UpdateField Field_14 = new UpdateField(0, 6); public UpdateField Field_18 = new UpdateField(0, 7); public UpdateField PvpTierID = new UpdateField(0, 8); public UpdateField Field_20 = new UpdateField(0, 9); public PVPInfo() : base(10) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { data.WriteUInt32(Field_0); data.WriteUInt32(Field_4); data.WriteUInt32(Field_8); data.WriteUInt32(Field_C); data.WriteUInt32(Rating); data.WriteUInt32(Field_14); data.WriteUInt32(Field_18); data.WriteUInt32(PvpTierID); data.WriteBits((uint)Field_20, 1); data.FlushBits(); } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { data.WriteBits(_changesMask.GetBlock(0), 10); data.FlushBits(); if (_changesMask[0]) { if (_changesMask[1]) { data.WriteUInt32(Field_0); } if (_changesMask[2]) { data.WriteUInt32(Field_4); } if (_changesMask[3]) { data.WriteUInt32(Field_8); } if (_changesMask[4]) { data.WriteUInt32(Field_C); } if (_changesMask[5]) { data.WriteUInt32(Rating); } if (_changesMask[6]) { data.WriteUInt32(Field_14); } if (_changesMask[7]) { data.WriteUInt32(Field_18); } if (_changesMask[8]) { data.WriteUInt32(PvpTierID); } if (_changesMask[9]) { data.WriteBits(Field_20, 1); } } data.FlushBits(); } public override void ClearChangesMask() { ClearChangesMask(Field_0); ClearChangesMask(Field_4); ClearChangesMask(Field_8); ClearChangesMask(Field_C); ClearChangesMask(Rating); ClearChangesMask(Field_14); ClearChangesMask(Field_18); ClearChangesMask(PvpTierID); ClearChangesMask(Field_20); _changesMask.ResetAll(); } } public class CharacterRestriction { public int Field_0; public int Field_4; public int Field_8; public uint Type; public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { data.WriteInt32(Field_0); data.WriteInt32(Field_4); data.WriteInt32(Field_8); data.WriteBits(Type, 5); data.FlushBits(); } public void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { data.FlushBits(); data.WriteInt32(Field_0); data.WriteInt32(Field_4); data.WriteInt32(Field_8); data.WriteBits(Type, 5); data.FlushBits(); } } public class SpellPctModByLabel { public int ModIndex; public float ModifierValue; public int LabelID; public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { data.WriteInt32(ModIndex); data.WriteFloat(ModifierValue); data.WriteInt32(LabelID); } public void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { data.FlushBits(); data.WriteInt32(ModIndex); data.WriteFloat(ModifierValue); data.WriteInt32(LabelID); } } public class SpellFlatModByLabel { public int ModIndex; public int ModifierValue; public int LabelID; public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { data.WriteInt32(ModIndex); data.WriteInt32(ModifierValue); data.WriteInt32(LabelID); } public void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { data.FlushBits(); data.WriteInt32(ModIndex); data.WriteInt32(ModifierValue); data.WriteInt32(LabelID); } } public class Research { public short ResearchProjectID; public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { data.WriteInt16(ResearchProjectID); } public void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { data.FlushBits(); data.WriteInt16(ResearchProjectID); } } public class ActivePlayerData : BaseUpdateData { public UpdateField BackpackAutoSortDisabled = new UpdateField(0, 1); public UpdateField BankAutoSortDisabled = new UpdateField(0, 2); public UpdateField SortBagsRightToLeft = new UpdateField(0, 3); public UpdateField InsertItemsLeftToRight = new UpdateField(0, 4); public UpdateFieldArray> Research = new UpdateFieldArray>(1, 20, 21);//-1-1 public DynamicUpdateField KnownTitles = new DynamicUpdateField(0, 5); public DynamicUpdateField ResearchSites = new DynamicUpdateField(0, 6); public DynamicUpdateField ResearchSiteProgress = new DynamicUpdateField(0, 7); public DynamicUpdateField DailyQuestsCompleted = new DynamicUpdateField(0, 8); public DynamicUpdateField AvailableQuestLineXQuestIDs = new DynamicUpdateField(0, 9); public DynamicUpdateField Heirlooms = new DynamicUpdateField(0, 10); public DynamicUpdateField HeirloomFlags = new DynamicUpdateField(0, 11); public DynamicUpdateField Toys = new DynamicUpdateField(0, 12); public DynamicUpdateField ToyFlags = new DynamicUpdateField(0, 13); public DynamicUpdateField Transmog = new DynamicUpdateField(0, 14); public DynamicUpdateField ConditionalTransmog = new DynamicUpdateField(0, 15); public DynamicUpdateField SelfResSpells = new DynamicUpdateField(0, 16); public DynamicUpdateField SpellPctModByLabel = new DynamicUpdateField(0, 17); public DynamicUpdateField SpellFlatModByLabel = new DynamicUpdateField(0, 18); public DynamicUpdateField CharacterRestrictions = new DynamicUpdateField(0, 19); public UpdateField FarsightObject = new UpdateField(0, 22); public UpdateField SummonedBattlePetGUID = new UpdateField(0, 23); public UpdateField Coinage = new UpdateField(0, 24); public UpdateField XP = new UpdateField(0, 25); public UpdateField NextLevelXP = new UpdateField(0, 26); public UpdateField TrialXP = new UpdateField(0, 27); public UpdateField Skill = new UpdateField(0, 28); public UpdateField CharacterPoints = new UpdateField(0, 29); public UpdateField MaxTalentTiers = new UpdateField(0, 30); public UpdateField TrackCreatureMask = new UpdateField(0, 31); public UpdateField MainhandExpertise = new UpdateField(0, 32); public UpdateField OffhandExpertise = new UpdateField(0, 33); public UpdateField RangedExpertise = new UpdateField(34, 35); public UpdateField CombatRatingExpertise = new UpdateField(34, 36); public UpdateField BlockPercentage = new UpdateField(34, 37); public UpdateField DodgePercentage = new UpdateField(34, 38); public UpdateField DodgePercentageFromAttribute = new UpdateField(34, 39); public UpdateField ParryPercentage = new UpdateField(34, 40); public UpdateField ParryPercentageFromAttribute = new UpdateField(34, 41); public UpdateField CritPercentage = new UpdateField(34, 42); public UpdateField RangedCritPercentage = new UpdateField(34, 43); public UpdateField OffhandCritPercentage = new UpdateField(34, 44); public UpdateField SpellCritPercentage = new UpdateField(34, 45); public UpdateField ShieldBlock = new UpdateField(34, 46); public UpdateField ShieldBlockCritPercentage = new UpdateField(34, 47); public UpdateField Mastery = new UpdateField(34, 48); public UpdateField Speed = new UpdateField(34, 49); public UpdateField Avoidance = new UpdateField(34, 50); public UpdateField Sturdiness = new UpdateField(34, 51); public UpdateField Versatility = new UpdateField(34, 52); public UpdateField VersatilityBonus = new UpdateField(34, 53); public UpdateField PvpPowerDamage = new UpdateField(34, 54); public UpdateField PvpPowerHealing = new UpdateField(34, 55); public UpdateField ModHealingDonePos = new UpdateField(34, 56); public UpdateField ModHealingPercent = new UpdateField(34, 57); public UpdateField ModHealingDonePercent = new UpdateField(34, 58); public UpdateField ModPeriodicHealingDonePercent = new UpdateField(34, 59); public UpdateField ModSpellPowerPercent = new UpdateField(34, 60); public UpdateField ModResiliencePercent = new UpdateField(34, 61); public UpdateField OverrideSpellPowerByAPPercent = new UpdateField(34, 62); public UpdateField OverrideAPBySpellPowerPercent = new UpdateField(34, 63); public UpdateField ModTargetResistance = new UpdateField(34, 64); public UpdateField ModTargetPhysicalResistance = new UpdateField(34, 65); public UpdateField LocalFlags = new UpdateField(66, 67); public UpdateField GrantableLevels = new UpdateField(66, 68); public UpdateField MultiActionBars = new UpdateField(66, 69); public UpdateField LifetimeMaxRank = new UpdateField(66, 70); public UpdateField NumRespecs = new UpdateField(66, 71); public UpdateField PvpMedals = new UpdateField(66, 72); public UpdateField TodayHonorableKills = new UpdateField(66, 73); public UpdateField YesterdayHonorableKills = new UpdateField(66, 74); public UpdateField LifetimeHonorableKills = new UpdateField(66, 75); public UpdateField WatchedFactionIndex = new UpdateField(66, 76); public UpdateField MaxLevel = new UpdateField(66, 77); public UpdateField ScalingPlayerLevelDelta = new UpdateField(66, 78); public UpdateField MaxCreatureScalingLevel = new UpdateField(66, 79); public UpdateField PetSpellPower = new UpdateField(66, 80); public UpdateField UiHitModifier = new UpdateField(66, 81); public UpdateField UiSpellHitModifier = new UpdateField(66, 82); public UpdateField HomeRealmTimeOffset = new UpdateField(66, 83); public UpdateField ModPetHaste = new UpdateField(66, 84); public UpdateField LocalRegenFlags = new UpdateField(66, 85); public UpdateField AuraVision = new UpdateField(66, 86); public UpdateField NumBackpackSlots = new UpdateField(66, 87); public UpdateField OverrideSpellsID = new UpdateField(66, 88); public UpdateField LfgBonusFactionID = new UpdateField(66, 89); public UpdateField LootSpecID = new UpdateField(66, 90); public UpdateField OverrideZonePVPType = new UpdateField(66, 91); public UpdateField Honor = new UpdateField(66, 92); public UpdateField HonorNextLevel = new UpdateField(66, 93); public UpdateField PvpRewardAchieved = new UpdateField(66, 94); public UpdateField PvpTierMaxFromWins = new UpdateField(66, 95); public UpdateField PvpLastWeeksRewardAchieved = new UpdateField(66, 96); public UpdateField PvpLastWeeksTierMaxFromWins = new UpdateField(66, 97); public UpdateField PvpLastWeeksRewardClaimed = new UpdateField(98, 99); public UpdateField NumBankSlots = new UpdateField(98, 100); public UpdateFieldArray InvSlots = new UpdateFieldArray(195, 101, 102); public UpdateFieldArray TrackResourceMask = new UpdateFieldArray(2, 297, 298); public UpdateFieldArray ExploredZones = new UpdateFieldArray(192, 300, 301); public UpdateFieldArray RestInfo = new UpdateFieldArray(2, 493, 494); public UpdateFieldArray ModDamageDonePos = new UpdateFieldArray(7, 496, 497); public UpdateFieldArray ModDamageDoneNeg = new UpdateFieldArray(7, 496, 504); public UpdateFieldArray ModDamageDonePercent = new UpdateFieldArray(7, 496, 511); public UpdateFieldArray WeaponDmgMultipliers = new UpdateFieldArray(3, 518, 519); public UpdateFieldArray WeaponAtkSpeedMultipliers = new UpdateFieldArray(3, 518, 522); public UpdateFieldArray BuybackPrice = new UpdateFieldArray(12, 525, 526); public UpdateFieldArray BuybackTimestamp = new UpdateFieldArray(12, 525, 538); public UpdateFieldArray CombatRatings = new UpdateFieldArray(32, 550, 551); public UpdateFieldArray PvpInfo = new UpdateFieldArray(6, 583, 584); public UpdateFieldArray NoReagentCostMask = new UpdateFieldArray(4, 590, 591); public UpdateFieldArray ProfessionSkillLine = new UpdateFieldArray(2, 595, 596); public UpdateFieldArray BagSlotFlags = new UpdateFieldArray(4, 598, 599); public UpdateFieldArray BankBagSlotFlags = new UpdateFieldArray(7, 603, 604); public UpdateFieldArray QuestCompleted = new UpdateFieldArray(875, 611, 612); public ActivePlayerData() : base(1487) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { for (int i = 0; i < 195; ++i) { data.WritePackedGuid(InvSlots[i]); } data.WritePackedGuid(FarsightObject); data.WritePackedGuid(SummonedBattlePetGUID); data.WriteInt32(KnownTitles.Size()); data.WriteUInt64(Coinage); data.WriteUInt32(XP); data.WriteUInt32(NextLevelXP); data.WriteInt32(TrialXP); ((SkillInfo)Skill).WriteCreate(data, fieldVisibilityFlags, owner, receiver); data.WriteUInt32(CharacterPoints); data.WriteUInt32(MaxTalentTiers); data.WriteUInt32(TrackCreatureMask); for (int i = 0; i < 2; ++i) { data.WriteUInt32(TrackResourceMask[i]); } data.WriteFloat(MainhandExpertise); data.WriteFloat(OffhandExpertise); data.WriteFloat(RangedExpertise); data.WriteFloat(CombatRatingExpertise); data.WriteFloat(BlockPercentage); data.WriteFloat(DodgePercentage); data.WriteFloat(DodgePercentageFromAttribute); data.WriteFloat(ParryPercentage); data.WriteFloat(ParryPercentageFromAttribute); data.WriteFloat(CritPercentage); data.WriteFloat(RangedCritPercentage); data.WriteFloat(OffhandCritPercentage); data.WriteFloat(SpellCritPercentage); data.WriteUInt32(ShieldBlock); data.WriteFloat(ShieldBlockCritPercentage); data.WriteFloat(Mastery); data.WriteFloat(Speed); data.WriteFloat(Avoidance); data.WriteFloat(Sturdiness); data.WriteInt32(Versatility); data.WriteFloat(VersatilityBonus); data.WriteFloat(PvpPowerDamage); data.WriteFloat(PvpPowerHealing); for (int i = 0; i < 192; ++i) { data.WriteUInt64(ExploredZones[i]); } for (int i = 0; i < 2; ++i) { RestInfo[i].WriteCreate(data, fieldVisibilityFlags, owner, receiver); } for (int i = 0; i < 7; ++i) { data.WriteInt32(ModDamageDonePos[i]); data.WriteInt32(ModDamageDoneNeg[i]); data.WriteFloat(ModDamageDonePercent[i]); } data.WriteInt32(ModHealingDonePos); data.WriteFloat(ModHealingPercent); data.WriteFloat(ModHealingDonePercent); data.WriteFloat(ModPeriodicHealingDonePercent); for (int i = 0; i < 3; ++i) { data.WriteFloat(WeaponDmgMultipliers[i]); data.WriteFloat(WeaponAtkSpeedMultipliers[i]); } data.WriteFloat(ModSpellPowerPercent); data.WriteFloat(ModResiliencePercent); data.WriteFloat(OverrideSpellPowerByAPPercent); data.WriteFloat(OverrideAPBySpellPowerPercent); data.WriteInt32(ModTargetResistance); data.WriteInt32(ModTargetPhysicalResistance); data.WriteInt32(LocalFlags); data.WriteUInt8(GrantableLevels); data.WriteUInt8(MultiActionBars); data.WriteUInt8(LifetimeMaxRank); data.WriteUInt8(NumRespecs); data.WriteUInt32(PvpMedals); for (int i = 0; i < 12; ++i) { data.WriteUInt32(BuybackPrice[i]); data.WriteUInt32(BuybackTimestamp[i]); } data.WriteUInt16(TodayHonorableKills); data.WriteUInt16(YesterdayHonorableKills); data.WriteUInt32(LifetimeHonorableKills); data.WriteInt32(WatchedFactionIndex); for (int i = 0; i < 32; ++i) { data.WriteUInt32(CombatRatings[i]); } data.WriteInt32(MaxLevel); data.WriteInt32(ScalingPlayerLevelDelta); data.WriteInt32(MaxCreatureScalingLevel); for (int i = 0; i < 4; ++i) { data.WriteUInt32(NoReagentCostMask[i]); } data.WriteUInt32(PetSpellPower); for (int i = 0; i < 2; ++i) { data.WriteUInt32(ProfessionSkillLine[i]); } data.WriteFloat(UiHitModifier); data.WriteFloat(UiSpellHitModifier); data.WriteInt32(HomeRealmTimeOffset); data.WriteFloat(ModPetHaste); data.WriteUInt8(LocalRegenFlags); data.WriteUInt8(AuraVision); data.WriteUInt8(NumBackpackSlots); data.WriteUInt32(OverrideSpellsID); data.WriteInt32(LfgBonusFactionID); data.WriteUInt16(LootSpecID); data.WriteUInt32(OverrideZonePVPType); for (int i = 0; i < 4; ++i) { data.WriteUInt32(BagSlotFlags[i]); } for (int i = 0; i < 7; ++i) { data.WriteUInt32(BankBagSlotFlags[i]); } for (int i = 0; i < 875; ++i) { data.WriteUInt64(QuestCompleted[i]); } data.WriteUInt32(Honor); data.WriteUInt32(HonorNextLevel); data.WriteInt32(PvpRewardAchieved); data.WriteInt32(PvpTierMaxFromWins); data.WriteInt32(PvpLastWeeksRewardAchieved); data.WriteInt32(PvpLastWeeksTierMaxFromWins); data.WriteInt32(PvpLastWeeksRewardClaimed); data.WriteUInt8(NumBankSlots); data.WriteInt32(ResearchSites.Size()); data.WriteInt32(ResearchSiteProgress.Size()); data.WriteInt32(DailyQuestsCompleted.Size()); data.WriteInt32(AvailableQuestLineXQuestIDs.Size()); data.WriteInt32(Heirlooms.Size()); data.WriteInt32(HeirloomFlags.Size()); data.WriteInt32(Toys.Size()); data.WriteInt32(ToyFlags.Size()); data.WriteInt32(Transmog.Size()); data.WriteInt32(ConditionalTransmog.Size()); data.WriteInt32(SelfResSpells.Size()); data.WriteInt32(CharacterRestrictions.Size()); data.WriteInt32(SpellPctModByLabel.Size()); data.WriteInt32(SpellFlatModByLabel.Size()); for (int i = 0; i < 1; ++i) { data.WriteInt32(Research[i].Size()); for (int j = 0; j < Research[i].Size(); ++j) { Research[i][j].WriteCreate(data, fieldVisibilityFlags, owner, receiver); } } for (int i = 0; i < KnownTitles.Size(); ++i) { data.WriteUInt64(KnownTitles[i]); } for (int i = 0; i < ResearchSites.Size(); ++i) { data.WriteUInt16(ResearchSites[i]); } for (int i = 0; i < ResearchSiteProgress.Size(); ++i) { data.WriteUInt32(ResearchSiteProgress[i]); } for (int i = 0; i < DailyQuestsCompleted.Size(); ++i) { data.WriteUInt32(DailyQuestsCompleted[i]); } for (int i = 0; i < AvailableQuestLineXQuestIDs.Size(); ++i) { data.WriteInt32(AvailableQuestLineXQuestIDs[i]); } for (int i = 0; i < Heirlooms.Size(); ++i) { data.WriteUInt32(Heirlooms[i]); } for (int i = 0; i < HeirloomFlags.Size(); ++i) { data.WriteUInt32(HeirloomFlags[i]); } for (int i = 0; i < Toys.Size(); ++i) { data.WriteUInt32(Toys[i]); } for (int i = 0; i < ToyFlags.Size(); ++i) { data.WriteUInt32(ToyFlags[i]); } for (int i = 0; i < Transmog.Size(); ++i) { data.WriteUInt32(Transmog[i]); } for (int i = 0; i < ConditionalTransmog.Size(); ++i) { data.WriteUInt32(ConditionalTransmog[i]); } for (int i = 0; i < SelfResSpells.Size(); ++i) { data.WriteUInt32(SelfResSpells[i]); } for (int i = 0; i < SpellPctModByLabel.Size(); ++i) { SpellPctModByLabel[i].WriteCreate(data, fieldVisibilityFlags, owner, receiver); } for (int i = 0; i < SpellFlatModByLabel.Size(); ++i) { SpellFlatModByLabel[i].WriteCreate(data, fieldVisibilityFlags, owner, receiver); } for (int i = 0; i < 6; ++i) { PvpInfo[i].WriteCreate(data, fieldVisibilityFlags, owner, receiver); } data.WriteBit((bool)BackpackAutoSortDisabled); data.WriteBit((bool)BankAutoSortDisabled); data.WriteBit((bool)SortBagsRightToLeft); data.WriteBit((bool)InsertItemsLeftToRight); for (int i = 0; i < CharacterRestrictions.Size(); ++i) { CharacterRestrictions[i].WriteCreate(data, fieldVisibilityFlags, owner, receiver); } data.FlushBits(); } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { for (uint i = 0; i < 1; ++i) data.WriteUInt32(_changesMask.GetBlocksMask(i)); data.WriteBits(_changesMask.GetBlocksMask(1), 15); for (uint i = 0; i < 47; ++i) if (_changesMask.GetBlock(i) != 0) data.WriteBits(_changesMask.GetBlock(i), 32); if (_changesMask[0]) { if (_changesMask[1]) { data.WriteBit(BackpackAutoSortDisabled); } if (_changesMask[2]) { data.WriteBit(BankAutoSortDisabled); } if (_changesMask[3]) { data.WriteBit(SortBagsRightToLeft); } if (_changesMask[4]) { data.WriteBit(InsertItemsLeftToRight); } if (_changesMask[5]) { KnownTitles.WriteUpdateMask(data); } if (_changesMask[6]) { ResearchSites.WriteUpdateMask(data); } if (_changesMask[7]) { ResearchSiteProgress.WriteUpdateMask(data); } if (_changesMask[8]) { DailyQuestsCompleted.WriteUpdateMask(data); } if (_changesMask[9]) { AvailableQuestLineXQuestIDs.WriteUpdateMask(data); } if (_changesMask[10]) { Heirlooms.WriteUpdateMask(data); } if (_changesMask[11]) { HeirloomFlags.WriteUpdateMask(data); } if (_changesMask[12]) { Toys.WriteUpdateMask(data); } if (_changesMask[13]) { ToyFlags.WriteUpdateMask(data); } if (_changesMask[14]) { Transmog.WriteUpdateMask(data); } if (_changesMask[15]) { ConditionalTransmog.WriteUpdateMask(data); } if (_changesMask[16]) { SelfResSpells.WriteUpdateMask(data); } if (_changesMask[17]) { SpellPctModByLabel.WriteUpdateMask(data); } if (_changesMask[18]) { SpellFlatModByLabel.WriteUpdateMask(data); } if (_changesMask[19]) { CharacterRestrictions.WriteUpdateMask(data); } } if (_changesMask[20]) { for (int i = 0; i < 1; ++i) { if (_changesMask[21 + i]) { Research[i].WriteUpdateMask(data); } } } data.FlushBits(); if (_changesMask[20]) { for (int i = 0; i < 1; ++i) { if (_changesMask[21 + i]) { for (int j = 0; j < Research[i].Size(); ++j) { if (Research[i].HasChanged(j)) { Research[i][j].WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } } } } } if (_changesMask[0]) { if (_changesMask[5]) { for (int i = 0; i < KnownTitles.Size(); ++i) { if (KnownTitles.HasChanged(i)) { data.WriteUInt64(KnownTitles[i]); } } } if (_changesMask[6]) { for (int i = 0; i < ResearchSites.Size(); ++i) { if (ResearchSites.HasChanged(i)) { data.WriteUInt16(ResearchSites[i]); } } } if (_changesMask[7]) { for (int i = 0; i < ResearchSiteProgress.Size(); ++i) { if (ResearchSiteProgress.HasChanged(i)) { data.WriteUInt32(ResearchSiteProgress[i]); } } } if (_changesMask[8]) { for (int i = 0; i < DailyQuestsCompleted.Size(); ++i) { if (DailyQuestsCompleted.HasChanged(i)) { data.WriteUInt32(DailyQuestsCompleted[i]); } } } if (_changesMask[9]) { for (int i = 0; i < AvailableQuestLineXQuestIDs.Size(); ++i) { if (AvailableQuestLineXQuestIDs.HasChanged(i)) { data.WriteInt32(AvailableQuestLineXQuestIDs[i]); } } } if (_changesMask[10]) { for (int i = 0; i < Heirlooms.Size(); ++i) { if (Heirlooms.HasChanged(i)) { data.WriteUInt32(Heirlooms[i]); } } } if (_changesMask[11]) { for (int i = 0; i < HeirloomFlags.Size(); ++i) { if (HeirloomFlags.HasChanged(i)) { data.WriteUInt32(HeirloomFlags[i]); } } } if (_changesMask[12]) { for (int i = 0; i < Toys.Size(); ++i) { if (Toys.HasChanged(i)) { data.WriteUInt32(Toys[i]); } } } if (_changesMask[13]) { for (int i = 0; i < ToyFlags.Size(); ++i) { if (ToyFlags.HasChanged(i)) { data.WriteUInt32(ToyFlags[i]); } } } if (_changesMask[14]) { for (int i = 0; i < Transmog.Size(); ++i) { if (Transmog.HasChanged(i)) { data.WriteUInt32(Transmog[i]); } } } if (_changesMask[15]) { for (int i = 0; i < ConditionalTransmog.Size(); ++i) { if (ConditionalTransmog.HasChanged(i)) { data.WriteUInt32(ConditionalTransmog[i]); } } } if (_changesMask[16]) { for (int i = 0; i < SelfResSpells.Size(); ++i) { if (SelfResSpells.HasChanged(i)) { data.WriteUInt32(SelfResSpells[i]); } } } if (_changesMask[17]) { for (int i = 0; i < SpellPctModByLabel.Size(); ++i) { if (SpellPctModByLabel.HasChanged(i)) { SpellPctModByLabel[i].WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } } } if (_changesMask[18]) { for (int i = 0; i < SpellFlatModByLabel.Size(); ++i) { if (SpellFlatModByLabel.HasChanged(i)) { SpellFlatModByLabel[i].WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } } } if (_changesMask[19]) { for (int i = 0; i < CharacterRestrictions.Size(); ++i) { if (CharacterRestrictions.HasChanged(i)) { CharacterRestrictions[i].WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } } } if (_changesMask[22]) { data.WritePackedGuid(FarsightObject); } if (_changesMask[23]) { data.WritePackedGuid(SummonedBattlePetGUID); } if (_changesMask[24]) { data.WriteUInt64(Coinage); } if (_changesMask[25]) { data.WriteUInt32(XP); } if (_changesMask[26]) { data.WriteUInt32(NextLevelXP); } if (_changesMask[27]) { data.WriteInt32(TrialXP); } if (_changesMask[28]) { ((SkillInfo)Skill).WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } if (_changesMask[29]) { data.WriteUInt32(CharacterPoints); } if (_changesMask[30]) { data.WriteUInt32(MaxTalentTiers); } if (_changesMask[31]) { data.WriteUInt32(TrackCreatureMask); } if (_changesMask[32]) { data.WriteFloat(MainhandExpertise); } if (_changesMask[33]) { data.WriteFloat(OffhandExpertise); } } if (_changesMask[34]) { if (_changesMask[35]) { data.WriteFloat(RangedExpertise); } if (_changesMask[36]) { data.WriteFloat(CombatRatingExpertise); } if (_changesMask[37]) { data.WriteFloat(BlockPercentage); } if (_changesMask[38]) { data.WriteFloat(DodgePercentage); } if (_changesMask[39]) { data.WriteFloat(DodgePercentageFromAttribute); } if (_changesMask[40]) { data.WriteFloat(ParryPercentage); } if (_changesMask[41]) { data.WriteFloat(ParryPercentageFromAttribute); } if (_changesMask[42]) { data.WriteFloat(CritPercentage); } if (_changesMask[43]) { data.WriteFloat(RangedCritPercentage); } if (_changesMask[44]) { data.WriteFloat(OffhandCritPercentage); } if (_changesMask[45]) { data.WriteFloat(SpellCritPercentage); } if (_changesMask[46]) { data.WriteUInt32(ShieldBlock); } if (_changesMask[47]) { data.WriteFloat(ShieldBlockCritPercentage); } if (_changesMask[48]) { data.WriteFloat(Mastery); } if (_changesMask[49]) { data.WriteFloat(Speed); } if (_changesMask[50]) { data.WriteFloat(Avoidance); } if (_changesMask[51]) { data.WriteFloat(Sturdiness); } if (_changesMask[52]) { data.WriteInt32(Versatility); } if (_changesMask[53]) { data.WriteFloat(VersatilityBonus); } if (_changesMask[54]) { data.WriteFloat(PvpPowerDamage); } if (_changesMask[55]) { data.WriteFloat(PvpPowerHealing); } if (_changesMask[56]) { data.WriteInt32(ModHealingDonePos); } if (_changesMask[57]) { data.WriteFloat(ModHealingPercent); } if (_changesMask[58]) { data.WriteFloat(ModHealingDonePercent); } if (_changesMask[59]) { data.WriteFloat(ModPeriodicHealingDonePercent); } if (_changesMask[60]) { data.WriteFloat(ModSpellPowerPercent); } if (_changesMask[61]) { data.WriteFloat(ModResiliencePercent); } if (_changesMask[62]) { data.WriteFloat(OverrideSpellPowerByAPPercent); } if (_changesMask[63]) { data.WriteFloat(OverrideAPBySpellPowerPercent); } if (_changesMask[64]) { data.WriteInt32(ModTargetResistance); } if (_changesMask[65]) { data.WriteInt32(ModTargetPhysicalResistance); } } if (_changesMask[66]) { if (_changesMask[67]) { data.WriteInt32(LocalFlags); } if (_changesMask[68]) { data.WriteUInt8(GrantableLevels); } if (_changesMask[69]) { data.WriteUInt8(MultiActionBars); } if (_changesMask[70]) { data.WriteUInt8(LifetimeMaxRank); } if (_changesMask[71]) { data.WriteUInt8(NumRespecs); } if (_changesMask[72]) { data.WriteUInt32(PvpMedals); } if (_changesMask[73]) { data.WriteUInt16(TodayHonorableKills); } if (_changesMask[74]) { data.WriteUInt16(YesterdayHonorableKills); } if (_changesMask[75]) { data.WriteUInt32(LifetimeHonorableKills); } if (_changesMask[76]) { data.WriteInt32(WatchedFactionIndex); } if (_changesMask[77]) { data.WriteInt32(MaxLevel); } if (_changesMask[78]) { data.WriteInt32(ScalingPlayerLevelDelta); } if (_changesMask[79]) { data.WriteInt32(MaxCreatureScalingLevel); } if (_changesMask[80]) { data.WriteUInt32(PetSpellPower); } if (_changesMask[81]) { data.WriteFloat(UiHitModifier); } if (_changesMask[82]) { data.WriteFloat(UiSpellHitModifier); } if (_changesMask[83]) { data.WriteInt32(HomeRealmTimeOffset); } if (_changesMask[84]) { data.WriteFloat(ModPetHaste); } if (_changesMask[85]) { data.WriteUInt8(LocalRegenFlags); } if (_changesMask[86]) { data.WriteUInt8(AuraVision); } if (_changesMask[87]) { data.WriteUInt8(NumBackpackSlots); } if (_changesMask[88]) { data.WriteUInt32(OverrideSpellsID); } if (_changesMask[89]) { data.WriteInt32(LfgBonusFactionID); } if (_changesMask[90]) { data.WriteUInt16(LootSpecID); } if (_changesMask[91]) { data.WriteUInt32(OverrideZonePVPType); } if (_changesMask[92]) { data.WriteUInt32(Honor); } if (_changesMask[93]) { data.WriteUInt32(HonorNextLevel); } if (_changesMask[94]) { data.WriteInt32(PvpRewardAchieved); } if (_changesMask[95]) { data.WriteInt32(PvpTierMaxFromWins); } if (_changesMask[96]) { data.WriteInt32(PvpLastWeeksRewardAchieved); } if (_changesMask[97]) { data.WriteInt32(PvpLastWeeksTierMaxFromWins); } } if (_changesMask[98]) { if (_changesMask[99]) { data.WriteInt32(PvpLastWeeksRewardClaimed); } if (_changesMask[100]) { data.WriteUInt8(NumBankSlots); } } if (_changesMask[101]) { for (int i = 0; i < 195; ++i) { if (_changesMask[102 + i]) { data.WritePackedGuid(InvSlots[i]); } } } if (_changesMask[297]) { for (int i = 0; i < 2; ++i) { if (_changesMask[298 + i]) { data.WriteUInt32(TrackResourceMask[i]); } } } if (_changesMask[300]) { for (int i = 0; i < 192; ++i) { if (_changesMask[301 + i]) { data.WriteUInt64(ExploredZones[i]); } } } if (_changesMask[493]) { for (int i = 0; i < 2; ++i) { if (_changesMask[494 + i]) { RestInfo[i].WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } } } if (_changesMask[496]) { for (int i = 0; i < 7; ++i) { if (_changesMask[497 + i]) { data.WriteInt32(ModDamageDonePos[i]); } if (_changesMask[504 + i]) { data.WriteInt32(ModDamageDoneNeg[i]); } if (_changesMask[511 + i]) { data.WriteFloat(ModDamageDonePercent[i]); } } } if (_changesMask[518]) { for (int i = 0; i < 3; ++i) { if (_changesMask[519 + i]) { data.WriteFloat(WeaponDmgMultipliers[i]); } if (_changesMask[522 + i]) { data.WriteFloat(WeaponAtkSpeedMultipliers[i]); } } } if (_changesMask[525]) { for (int i = 0; i < 12; ++i) { if (_changesMask[526 + i]) { data.WriteUInt32(BuybackPrice[i]); } if (_changesMask[538 + i]) { data.WriteUInt32(BuybackTimestamp[i]); } } } if (_changesMask[550]) { for (int i = 0; i < 32; ++i) { if (_changesMask[551 + i]) { data.WriteUInt32(CombatRatings[i]); } } } if (_changesMask[590]) { for (int i = 0; i < 4; ++i) { if (_changesMask[591 + i]) { data.WriteUInt32(NoReagentCostMask[i]); } } } if (_changesMask[595]) { for (int i = 0; i < 2; ++i) { if (_changesMask[596 + i]) { data.WriteUInt32(ProfessionSkillLine[i]); } } } if (_changesMask[598]) { for (int i = 0; i < 4; ++i) { if (_changesMask[599 + i]) { data.WriteUInt32(BagSlotFlags[i]); } } } if (_changesMask[603]) { for (int i = 0; i < 7; ++i) { if (_changesMask[604 + i]) { data.WriteUInt32(BankBagSlotFlags[i]); } } } if (_changesMask[611]) { for (int i = 0; i < 875; ++i) { if (_changesMask[612 + i]) { data.WriteUInt64(QuestCompleted[i]); } } } if (_changesMask[583]) { for (int i = 0; i < 6; ++i) { if (_changesMask[584 + i]) { PvpInfo[i].WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } } } data.FlushBits(); } public override void ClearChangesMask() { ClearChangesMask(BackpackAutoSortDisabled); ClearChangesMask(BankAutoSortDisabled); ClearChangesMask(SortBagsRightToLeft); ClearChangesMask(InsertItemsLeftToRight); ClearChangesMask(Research); ClearChangesMask(KnownTitles); ClearChangesMask(ResearchSites); ClearChangesMask(ResearchSiteProgress); ClearChangesMask(DailyQuestsCompleted); ClearChangesMask(AvailableQuestLineXQuestIDs); ClearChangesMask(Heirlooms); ClearChangesMask(HeirloomFlags); ClearChangesMask(Toys); ClearChangesMask(ToyFlags); ClearChangesMask(Transmog); ClearChangesMask(ConditionalTransmog); ClearChangesMask(SelfResSpells); ClearChangesMask(SpellPctModByLabel); ClearChangesMask(SpellFlatModByLabel); ClearChangesMask(CharacterRestrictions); ClearChangesMask(FarsightObject); ClearChangesMask(SummonedBattlePetGUID); ClearChangesMask(Coinage); ClearChangesMask(XP); ClearChangesMask(NextLevelXP); ClearChangesMask(TrialXP); ClearChangesMask(Skill); ClearChangesMask(CharacterPoints); ClearChangesMask(MaxTalentTiers); ClearChangesMask(TrackCreatureMask); ClearChangesMask(MainhandExpertise); ClearChangesMask(OffhandExpertise); ClearChangesMask(RangedExpertise); ClearChangesMask(CombatRatingExpertise); ClearChangesMask(BlockPercentage); ClearChangesMask(DodgePercentage); ClearChangesMask(DodgePercentageFromAttribute); ClearChangesMask(ParryPercentage); ClearChangesMask(ParryPercentageFromAttribute); ClearChangesMask(CritPercentage); ClearChangesMask(RangedCritPercentage); ClearChangesMask(OffhandCritPercentage); ClearChangesMask(SpellCritPercentage); ClearChangesMask(ShieldBlock); ClearChangesMask(ShieldBlockCritPercentage); ClearChangesMask(Mastery); ClearChangesMask(Speed); ClearChangesMask(Avoidance); ClearChangesMask(Sturdiness); ClearChangesMask(Versatility); ClearChangesMask(VersatilityBonus); ClearChangesMask(PvpPowerDamage); ClearChangesMask(PvpPowerHealing); ClearChangesMask(ModHealingDonePos); ClearChangesMask(ModHealingPercent); ClearChangesMask(ModHealingDonePercent); ClearChangesMask(ModPeriodicHealingDonePercent); ClearChangesMask(ModSpellPowerPercent); ClearChangesMask(ModResiliencePercent); ClearChangesMask(OverrideSpellPowerByAPPercent); ClearChangesMask(OverrideAPBySpellPowerPercent); ClearChangesMask(ModTargetResistance); ClearChangesMask(ModTargetPhysicalResistance); ClearChangesMask(LocalFlags); ClearChangesMask(GrantableLevels); ClearChangesMask(MultiActionBars); ClearChangesMask(LifetimeMaxRank); ClearChangesMask(NumRespecs); ClearChangesMask(PvpMedals); ClearChangesMask(TodayHonorableKills); ClearChangesMask(YesterdayHonorableKills); ClearChangesMask(LifetimeHonorableKills); ClearChangesMask(WatchedFactionIndex); ClearChangesMask(MaxLevel); ClearChangesMask(ScalingPlayerLevelDelta); ClearChangesMask(MaxCreatureScalingLevel); ClearChangesMask(PetSpellPower); ClearChangesMask(UiHitModifier); ClearChangesMask(UiSpellHitModifier); ClearChangesMask(HomeRealmTimeOffset); ClearChangesMask(ModPetHaste); ClearChangesMask(LocalRegenFlags); ClearChangesMask(AuraVision); ClearChangesMask(NumBackpackSlots); ClearChangesMask(OverrideSpellsID); ClearChangesMask(LfgBonusFactionID); ClearChangesMask(LootSpecID); ClearChangesMask(OverrideZonePVPType); ClearChangesMask(Honor); ClearChangesMask(HonorNextLevel); ClearChangesMask(PvpRewardAchieved); ClearChangesMask(PvpTierMaxFromWins); ClearChangesMask(PvpLastWeeksRewardAchieved); ClearChangesMask(PvpLastWeeksTierMaxFromWins); ClearChangesMask(PvpLastWeeksRewardClaimed); ClearChangesMask(NumBankSlots); ClearChangesMask(InvSlots); ClearChangesMask(TrackResourceMask); ClearChangesMask(ExploredZones); ClearChangesMask(RestInfo); ClearChangesMask(ModDamageDonePos); ClearChangesMask(ModDamageDoneNeg); ClearChangesMask(ModDamageDonePercent); ClearChangesMask(WeaponDmgMultipliers); ClearChangesMask(WeaponAtkSpeedMultipliers); ClearChangesMask(BuybackPrice); ClearChangesMask(BuybackTimestamp); ClearChangesMask(CombatRatings); ClearChangesMask(PvpInfo); ClearChangesMask(NoReagentCostMask); ClearChangesMask(ProfessionSkillLine); ClearChangesMask(BagSlotFlags); ClearChangesMask(BankBagSlotFlags); ClearChangesMask(QuestCompleted); _changesMask.ResetAll(); } } public class GameObjectFieldData : BaseUpdateData { public UpdateField> StateWorldEffectIDs = new UpdateField>(0, 1); public DynamicUpdateField EnableDoodadSets = new DynamicUpdateField(0, 2); public UpdateField DisplayID = new UpdateField(0, 3); public UpdateField SpellVisualID = new UpdateField(0, 4); public UpdateField StateSpellVisualID = new UpdateField(0, 5); public UpdateField SpawnTrackingStateAnimID = new UpdateField(0, 6); public UpdateField SpawnTrackingStateAnimKitID = new UpdateField(0, 7); public UpdateField StateWorldEffectsQuestObjectiveID = new UpdateField(0, 8); public UpdateField CreatedBy = new UpdateField(0, 9); public UpdateField GuildGUID = new UpdateField(0, 10); public UpdateField Flags = new UpdateField(0, 11); public UpdateField ParentRotation = new UpdateField(0, 12); public UpdateField FactionTemplate = new UpdateField(0, 13); public UpdateField Level = new UpdateField(0, 14); public UpdateField State = new UpdateField(0, 15); public UpdateField TypeID = new UpdateField(0, 16); public UpdateField PercentHealth = new UpdateField(0, 17); public UpdateField ArtKit = new UpdateField(0, 18); public UpdateField CustomParam = new UpdateField(0, 19); public GameObjectFieldData() : base(20) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, GameObject owner, Player receiver) { data.WriteUInt32(DisplayID); data.WriteUInt32(SpellVisualID); data.WriteUInt32(StateSpellVisualID); data.WriteUInt32(SpawnTrackingStateAnimID); data.WriteUInt32(SpawnTrackingStateAnimKitID); data.WriteInt32(((List)StateWorldEffectIDs).Count); data.WriteUInt32(StateWorldEffectsQuestObjectiveID); for (int i = 0; i < ((List)StateWorldEffectIDs).Count; ++i) { data.WriteUInt32(((List)StateWorldEffectIDs)[i]); } data.WritePackedGuid(CreatedBy); data.WritePackedGuid(GuildGUID); data.WriteUInt32(GetViewerGameObjectFlags(Flags, owner, receiver)); Quaternion rotation = ParentRotation; data.WriteFloat(rotation.X); data.WriteFloat(rotation.Y); data.WriteFloat(rotation.Z); data.WriteFloat(rotation.W); data.WriteUInt32(FactionTemplate); data.WriteUInt32(GetViewerGameObjectLevel(Level, owner, receiver)); data.WriteInt8((sbyte)GetViewerGameObjectState(State, owner, receiver)); data.WriteInt8((sbyte)TypeID); data.WriteUInt8(PercentHealth); data.WriteUInt32(ArtKit); data.WriteInt32(EnableDoodadSets.Size()); data.WriteUInt32(CustomParam); for (int i = 0; i < EnableDoodadSets.Size(); ++i) { data.WriteInt32(EnableDoodadSets[i]); } } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, GameObject owner, Player receiver) { data.WriteBits(_changesMask.GetBlock(0), 20); if (_changesMask[0]) { if (_changesMask[1]) { List list = StateWorldEffectIDs; data.WriteBits(list.Count, 32); for (int i = 0; i < list.Count; ++i) { data.WriteUInt32(list[i]); } } } data.FlushBits(); if (_changesMask[0]) { if (_changesMask[2]) { EnableDoodadSets.WriteUpdateMask(data); } } data.FlushBits(); if (_changesMask[0]) { if (_changesMask[2]) { for (int i = 0; i < EnableDoodadSets.Size(); ++i) { if (EnableDoodadSets.HasChanged(i)) { data.WriteInt32(EnableDoodadSets[i]); } } } if (_changesMask[3]) { data.WriteUInt32(DisplayID); } if (_changesMask[4]) { data.WriteUInt32(SpellVisualID); } if (_changesMask[5]) { data.WriteUInt32(StateSpellVisualID); } if (_changesMask[6]) { data.WriteUInt32(SpawnTrackingStateAnimID); } if (_changesMask[7]) { data.WriteUInt32(SpawnTrackingStateAnimKitID); } if (_changesMask[8]) { data.WriteUInt32(StateWorldEffectsQuestObjectiveID); } if (_changesMask[9]) { data.WritePackedGuid(CreatedBy); } if (_changesMask[10]) { data.WritePackedGuid(GuildGUID); } if (_changesMask[11]) { data.WriteUInt32(GetViewerGameObjectFlags(Flags, owner, receiver)); } if (_changesMask[12]) { Quaternion rotation = ParentRotation; data.WriteFloat(rotation.X); data.WriteFloat(rotation.Y); data.WriteFloat(rotation.Z); data.WriteFloat(rotation.W); } if (_changesMask[13]) { data.WriteUInt32(FactionTemplate); } if (_changesMask[14]) { data.WriteUInt32(GetViewerGameObjectLevel(Level, owner, receiver)); } if (_changesMask[15]) { data.WriteInt8((sbyte)GetViewerGameObjectState(State, owner, receiver)); } if (_changesMask[16]) { data.WriteInt8((sbyte)TypeID); } if (_changesMask[17]) { data.WriteUInt8(PercentHealth); } if (_changesMask[18]) { data.WriteUInt32(ArtKit); } if (_changesMask[19]) { data.WriteUInt32(CustomParam); } } } public override void ClearChangesMask() { ClearChangesMask(StateWorldEffectIDs); ClearChangesMask(EnableDoodadSets); ClearChangesMask(DisplayID); ClearChangesMask(SpellVisualID); ClearChangesMask(StateSpellVisualID); ClearChangesMask(SpawnTrackingStateAnimID); ClearChangesMask(SpawnTrackingStateAnimKitID); ClearChangesMask(StateWorldEffectsQuestObjectiveID); ClearChangesMask(CreatedBy); ClearChangesMask(GuildGUID); ClearChangesMask(Flags); ClearChangesMask(ParentRotation); ClearChangesMask(FactionTemplate); ClearChangesMask(Level); ClearChangesMask(State); ClearChangesMask(TypeID); ClearChangesMask(PercentHealth); ClearChangesMask(ArtKit); ClearChangesMask(CustomParam); _changesMask.ResetAll(); } uint GetViewerGameObjectFlags(uint flags, GameObject gameObject, Player receiver) { if (gameObject.GetGoType() == GameObjectTypes.Chest) if (gameObject.GetGoInfo().Chest.usegrouplootrules != 0 && !gameObject.IsLootAllowedFor(receiver)) flags |= (uint)(GameObjectFlags.Locked | GameObjectFlags.NotSelectable); return (uint)flags; } uint GetViewerGameObjectLevel(uint level, GameObject gameObject, Player receiver) { bool isStoppableTransport = gameObject.GetGoType() == GameObjectTypes.Transport && !gameObject.GetGoValue().Transport.StopFrames.Empty(); return isStoppableTransport ? gameObject.GetGoValue().Transport.PathProgress : level; } sbyte GetViewerGameObjectState(sbyte state, GameObject gameObject, Player receiver) { bool isStoppableTransport = gameObject.GetGoType() == GameObjectTypes.Transport && !gameObject.GetGoValue().Transport.StopFrames.Empty(); if (isStoppableTransport && gameObject.GetGoState() == GameObjectState.TransportActive) if (((gameObject.GetGoValue().Transport.StateUpdateTimer / 20000) & 1) != 0) state = (sbyte)GameObjectState.TransportStopped; return state; } } public class DynamicObjectData : BaseUpdateData { public UpdateField Caster = new UpdateField(0, 1); public UpdateField SpellXSpellVisualID = new UpdateField(0, 2); public UpdateField SpellID = new UpdateField(0, 3); public UpdateField Radius = new UpdateField(0, 4); public UpdateField CastTime = new UpdateField(0, 5); public UpdateField Type = new UpdateField(0, 6); public DynamicObjectData() : base(7) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, DynamicObject owner, Player receiver) { data.WritePackedGuid(Caster); data.WriteUInt32(SpellXSpellVisualID); data.WriteUInt32(SpellID); data.WriteFloat(Radius); data.WriteUInt32(CastTime); data.WriteUInt8(Type); } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, DynamicObject owner, Player receiver) { data.WriteBits(_changesMask.GetBlock(0), 7); data.FlushBits(); if (_changesMask[0]) { if (_changesMask[1]) { data.WritePackedGuid(Caster); } if (_changesMask[2]) { data.WriteUInt32(SpellXSpellVisualID); } if (_changesMask[3]) { data.WriteUInt32(SpellID); } if (_changesMask[4]) { data.WriteFloat(Radius); } if (_changesMask[5]) { data.WriteUInt32(CastTime); } if (_changesMask[6]) { data.WriteUInt8(Type); } } } public override void ClearChangesMask() { ClearChangesMask(Caster); ClearChangesMask(SpellXSpellVisualID); ClearChangesMask(SpellID); ClearChangesMask(Radius); ClearChangesMask(CastTime); ClearChangesMask(Type); _changesMask.ResetAll(); } } public class CorpseData : BaseUpdateData { public UpdateField DynamicFlags = new UpdateField(0, 1); public UpdateField Owner = new UpdateField(0, 2); public UpdateField PartyGUID = new UpdateField(0, 3); public UpdateField GuildGUID = new UpdateField(0, 4); public UpdateField DisplayID = new UpdateField(0, 5); public UpdateField Unused = new UpdateField(0, 6); public UpdateField RaceID = new UpdateField(0, 7); public UpdateField Sex = new UpdateField(0, 8); public UpdateField SkinID = new UpdateField(0, 9); public UpdateField FaceID = new UpdateField(0, 10); public UpdateField HairStyleID = new UpdateField(0, 11); public UpdateField HairColorID = new UpdateField(0, 12); public UpdateField FacialHairStyleID = new UpdateField(0, 13); public UpdateField Flags = new UpdateField(0, 14); public UpdateField FactionTemplate = new UpdateField(0, 15); public UpdateFieldArray Items = new UpdateFieldArray(19, 16, 17); public UpdateFieldArray CustomDisplayOption = new UpdateFieldArray(3, 36, 37); public CorpseData() : base(40) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Corpse owner, Player receiver) { data.WriteUInt32(DynamicFlags); data.WritePackedGuid(Owner); data.WritePackedGuid(PartyGUID); data.WritePackedGuid(GuildGUID); data.WriteUInt32(DisplayID); for (int i = 0; i < 19; ++i) { data.WriteUInt32(Items[i]); } data.WriteUInt8(Unused); data.WriteUInt8(RaceID); data.WriteUInt8(Sex); data.WriteUInt8(SkinID); data.WriteUInt8(FaceID); data.WriteUInt8(HairStyleID); data.WriteUInt8(HairColorID); data.WriteUInt8(FacialHairStyleID); data.WriteUInt32(Flags); data.WriteInt32(FactionTemplate); for (int i = 0; i < 3; ++i) { data.WriteUInt8(CustomDisplayOption[i]); } } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Corpse owner, Player receiver) { data.WriteBits(_changesMask.GetBlocksMask(0), 2); for (uint i = 0; i < 2; ++i) if (_changesMask.GetBlock(i) != 0) data.WriteBits(_changesMask.GetBlock(i), 32); data.FlushBits(); if (_changesMask[0]) { if (_changesMask[1]) { data.WriteUInt32(DynamicFlags); } if (_changesMask[2]) { data.WritePackedGuid(Owner); } if (_changesMask[3]) { data.WritePackedGuid(PartyGUID); } if (_changesMask[4]) { data.WritePackedGuid(GuildGUID); } if (_changesMask[5]) { data.WriteUInt32(DisplayID); } if (_changesMask[6]) { data.WriteUInt8(Unused); } if (_changesMask[7]) { data.WriteUInt8(RaceID); } if (_changesMask[8]) { data.WriteUInt8(Sex); } if (_changesMask[9]) { data.WriteUInt8(SkinID); } if (_changesMask[10]) { data.WriteUInt8(FaceID); } if (_changesMask[11]) { data.WriteUInt8(HairStyleID); } if (_changesMask[12]) { data.WriteUInt8(HairColorID); } if (_changesMask[13]) { data.WriteUInt8(FacialHairStyleID); } if (_changesMask[14]) { data.WriteUInt32(Flags); } if (_changesMask[15]) { data.WriteInt32(FactionTemplate); } } if (_changesMask[16]) { for (int i = 0; i < 19; ++i) { if (_changesMask[17 + i]) { data.WriteUInt32(Items[i]); } } } if (_changesMask[36]) { for (int i = 0; i < 3; ++i) { if (_changesMask[37 + i]) { data.WriteUInt8(CustomDisplayOption[i]); } } } } public override void ClearChangesMask() { ClearChangesMask(DynamicFlags); ClearChangesMask(Owner); ClearChangesMask(PartyGUID); ClearChangesMask(GuildGUID); ClearChangesMask(DisplayID); ClearChangesMask(Unused); ClearChangesMask(RaceID); ClearChangesMask(Sex); ClearChangesMask(SkinID); ClearChangesMask(FaceID); ClearChangesMask(HairStyleID); ClearChangesMask(HairColorID); ClearChangesMask(FacialHairStyleID); ClearChangesMask(Flags); ClearChangesMask(FactionTemplate); ClearChangesMask(Items); ClearChangesMask(CustomDisplayOption); _changesMask.ResetAll(); } } public class ScaleCurve { public bool OverrideActive; public uint StartTimeOffset; public uint ParameterCurve; public Vector2[] Points = new Vector2[2]; public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, AreaTrigger owner, Player receiver) { data.WriteUInt32(StartTimeOffset); for (int i = 0; i < 2; ++i) { data.WriteVector2(Points[i]); } data.WriteUInt32(ParameterCurve); data.WriteBit(OverrideActive); data.FlushBits(); } public void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, AreaTrigger owner, Player receiver) { data.WriteBit(OverrideActive); data.FlushBits(); data.WriteUInt32(StartTimeOffset); data.WriteUInt32(ParameterCurve); for (int i = 0; i < 2; ++i) { data.WriteVector2(Points[i]); } data.FlushBits(); } } public class AreaTriggerFieldData : BaseUpdateData { public UpdateField OverrideScaleCurve = new UpdateField(0, 1); public UpdateField ExtraScaleCurve = new UpdateField(0, 2); public UpdateField Caster = new UpdateField(0, 3); public UpdateField Duration = new UpdateField(0, 4); public UpdateField TimeToTarget = new UpdateField(0, 5); public UpdateField TimeToTargetScale = new UpdateField(0, 6); public UpdateField TimeToTargetExtraScale = new UpdateField(0, 7); public UpdateField SpellID = new UpdateField(0, 8); public UpdateField SpellForVisuals = new UpdateField(0, 9); public UpdateField SpellXSpellVisualID = new UpdateField(0, 10); public UpdateField BoundsRadius2D = new UpdateField(0, 11); public UpdateField DecalPropertiesID = new UpdateField(0, 12); public UpdateField CreatingEffectGUID = new UpdateField(0, 13); public AreaTriggerFieldData() : base(14) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, AreaTrigger owner, Player receiver) { ((ScaleCurve)OverrideScaleCurve).WriteCreate(data, fieldVisibilityFlags, owner, receiver); data.WritePackedGuid(Caster); data.WriteUInt32(Duration); data.WriteUInt32(TimeToTarget); data.WriteUInt32(TimeToTargetScale); data.WriteUInt32(TimeToTargetExtraScale); data.WriteUInt32(SpellID); data.WriteUInt32(SpellForVisuals); data.WriteUInt32(SpellXSpellVisualID); data.WriteFloat(BoundsRadius2D); data.WriteUInt32(DecalPropertiesID); data.WritePackedGuid(CreatingEffectGUID); ((ScaleCurve)ExtraScaleCurve).WriteCreate(data, fieldVisibilityFlags, owner, receiver); } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, AreaTrigger owner, Player receiver) { data.WriteBits(_changesMask.GetBlock(0), 14); data.FlushBits(); if (_changesMask[0]) { if (_changesMask[1]) { ((ScaleCurve)OverrideScaleCurve).WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } if (_changesMask[3]) { data.WritePackedGuid(Caster); } if (_changesMask[4]) { data.WriteUInt32(Duration); } if (_changesMask[5]) { data.WriteUInt32(TimeToTarget); } if (_changesMask[6]) { data.WriteUInt32(TimeToTargetScale); } if (_changesMask[7]) { data.WriteUInt32(TimeToTargetExtraScale); } if (_changesMask[8]) { data.WriteUInt32(SpellID); } if (_changesMask[9]) { data.WriteUInt32(SpellForVisuals); } if (_changesMask[10]) { data.WriteUInt32(SpellXSpellVisualID); } if (_changesMask[11]) { data.WriteFloat(BoundsRadius2D); } if (_changesMask[12]) { data.WriteUInt32(DecalPropertiesID); } if (_changesMask[13]) { data.WritePackedGuid(CreatingEffectGUID); } if (_changesMask[2]) { ((ScaleCurve)ExtraScaleCurve).WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } } } public override void ClearChangesMask() { ClearChangesMask(OverrideScaleCurve); ClearChangesMask(ExtraScaleCurve); ClearChangesMask(Caster); ClearChangesMask(Duration); ClearChangesMask(TimeToTarget); ClearChangesMask(TimeToTargetScale); ClearChangesMask(TimeToTargetExtraScale); ClearChangesMask(SpellID); ClearChangesMask(SpellForVisuals); ClearChangesMask(SpellXSpellVisualID); ClearChangesMask(BoundsRadius2D); ClearChangesMask(DecalPropertiesID); ClearChangesMask(CreatingEffectGUID); _changesMask.ResetAll(); } } public class SceneObjectData : BaseUpdateData { public UpdateField ScriptPackageID = new UpdateField(0, 1); public UpdateField RndSeedVal = new UpdateField(0, 2); public UpdateField CreatedBy = new UpdateField(0, 3); public UpdateField SceneType = new UpdateField(0, 4); public SceneObjectData() : base(5) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, WorldObject owner, Player receiver) { data.WriteInt32(ScriptPackageID); data.WriteUInt32(RndSeedVal); data.WritePackedGuid(CreatedBy); data.WriteUInt32(SceneType); } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, WorldObject owner, Player receiver) { data.WriteBits(_changesMask.GetBlock(0), 5); data.FlushBits(); if (_changesMask[0]) { if (_changesMask[1]) { data.WriteInt32(ScriptPackageID); } if (_changesMask[2]) { data.WriteUInt32(RndSeedVal); } if (_changesMask[3]) { data.WritePackedGuid(CreatedBy); } if (_changesMask[4]) { data.WriteUInt32(SceneType); } } } public override void ClearChangesMask() { ClearChangesMask(ScriptPackageID); ClearChangesMask(RndSeedVal); ClearChangesMask(CreatedBy); ClearChangesMask(SceneType); _changesMask.ResetAll(); } } public class ConversationLine { public uint ConversationLineID; public uint StartTime; public uint UiCameraID; public byte ActorIndex; public byte Flags; public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Conversation owner, Player receiver) { data.WriteUInt32(ConversationLineID); data.WriteUInt32(StartTime); data.WriteUInt32(UiCameraID); data.WriteUInt8(ActorIndex); data.WriteUInt8(Flags); } public void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Conversation owner, Player receiver) { data.FlushBits(); data.WriteUInt32(ConversationLineID); data.WriteUInt32(StartTime); data.WriteUInt32(UiCameraID); data.WriteUInt8(ActorIndex); data.WriteUInt8(Flags); } } public class ConversationActor { public uint CreatureID; public uint CreatureDisplayInfoID; public ObjectGuid ActorGUID; public int Field_18; public ConversationActorType Type; public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Conversation owner, Player receiver) { data.WriteUInt32(CreatureID); data.WriteUInt32(CreatureDisplayInfoID); data.WritePackedGuid(ActorGUID); data.WriteInt32(Field_18); data.WriteBits(Type, 1); data.FlushBits(); } public void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Conversation owner, Player receiver) { data.FlushBits(); data.WriteUInt32(CreatureID); data.WriteUInt32(CreatureDisplayInfoID); data.WritePackedGuid(ActorGUID); data.WriteInt32(Field_18); data.WriteBits(Type, 1); data.FlushBits(); } } public class ConversationData : BaseUpdateData { public UpdateField> Lines = new UpdateField>(0, 1); public DynamicUpdateField Actors = new DynamicUpdateField(0, 2); public UpdateField LastLineEndTime = new UpdateField(0, 3); public UpdateField Field_1C = new UpdateField(0, 4); public ConversationData() : base(5) { } public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Conversation owner, Player receiver) { data.WriteInt32(((List)Lines).Count); data.WriteUInt32(LastLineEndTime); data.WriteUInt32(Field_1C); for (int i = 0; i < ((List)Lines).Count; ++i) { ((List)Lines)[i].WriteCreate(data, fieldVisibilityFlags, owner, receiver); } data.WriteInt32(Actors.Size()); for (int i = 0; i < Actors.Size(); ++i) { Actors[i].WriteCreate(data, fieldVisibilityFlags, owner, receiver); } } public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Conversation owner, Player receiver) { data.WriteBits(_changesMask.GetBlock(0), 5); if (_changesMask[0]) { if (_changesMask[1]) { List list = Lines; data.WriteBits(list.Count, 32); for (int i = 0; i < list.Count; ++i) { list[i].WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } } } data.FlushBits(); if (_changesMask[0]) { if (_changesMask[2]) { Actors.WriteUpdateMask(data); } } data.FlushBits(); if (_changesMask[0]) { if (_changesMask[2]) { for (int i = 0; i < Actors.Size(); ++i) { if (Actors.HasChanged(i)) { Actors[i].WriteUpdate(data, fieldVisibilityFlags, owner, receiver); } } } if (_changesMask[3]) { data.WriteUInt32(LastLineEndTime); } if (_changesMask[4]) { data.WriteUInt32(Field_1C); } } } public override void ClearChangesMask() { ClearChangesMask(Lines); ClearChangesMask(Actors); ClearChangesMask(LastLineEndTime); ClearChangesMask(Field_1C); _changesMask.ResetAll(); } } }