Пример #1
0
        private static MovementInfo ReadMovementUpdateBlock(Packet packet, CreateObject createObject, WowGuid guid, WoWObject obj, object index)
        {
            var moveInfo = new MovementInfo();

            packet.ResetBitReader();

            packet.ReadBit("NoBirthAnim", index);
            packet.ReadBit("EnablePortals", index);
            packet.ReadBit("PlayHoverAnim", index);

            var hasMovementUpdate     = packet.ReadBit("HasMovementUpdate", index);
            var hasMovementTransport  = packet.ReadBit("HasMovementTransport", index);
            var hasStationaryPosition = packet.ReadBit("Stationary", index);
            var hasCombatVictim       = packet.ReadBit("HasCombatVictim", index);
            var hasServerTime         = packet.ReadBit("HasServerTime", index);
            var hasVehicleCreate      = packet.ReadBit("HasVehicleCreate", index);
            var hasAnimKitCreate      = packet.ReadBit("HasAnimKitCreate", index);
            var hasRotation           = packet.ReadBit("HasRotation", index);
            var hasAreaTrigger        = packet.ReadBit("HasAreaTrigger", index);
            var hasGameObject         = packet.ReadBit("HasGameObject", index);
            var hasSmoothPhasing      = packet.ReadBit("HasSmoothPhasing", index);

            packet.ReadBit("ThisIsYou", index);

            var sceneObjCreate   = packet.ReadBit("SceneObjCreate", index);
            var playerCreateData = packet.ReadBit("HasPlayerCreateData", index);
            var hasConversation  = packet.ReadBit("HasConversation", index);

            if (hasMovementUpdate)
            {
                var movementUpdate = createObject.Movement = new();
                packet.ResetBitReader();
                movementUpdate.Mover = packet.ReadPackedGuid128("MoverGUID", index);

                movementUpdate.MoveTime    = packet.ReadUInt32("MoveTime", index);
                movementUpdate.Position    = moveInfo.Position = packet.ReadVector3("Position", index);
                movementUpdate.Orientation = moveInfo.Orientation = packet.ReadSingle("Orientation", index);

                movementUpdate.Pitch = packet.ReadSingle("Pitch", index);
                movementUpdate.StepUpStartElevation = packet.ReadSingle("StepUpStartElevation", index);

                var removeForcesIDsCount = packet.ReadInt32();
                movementUpdate.MoveIndex = packet.ReadInt32("MoveIndex", index);

                for (var i = 0; i < removeForcesIDsCount; i++)
                {
                    packet.ReadPackedGuid128("RemoveForcesIDs", index, i);
                }

                moveInfo.Flags      = (MovementFlag)packet.ReadBitsE <V6_0_2_19033.Enums.MovementFlag>("Movement Flags", 30, index);
                moveInfo.FlagsExtra = (MovementFlagExtra)packet.ReadBitsE <Enums.MovementFlags2>("Extra Movement Flags", 18, index);

                var hasTransport = packet.ReadBit("Has Transport Data", index);
                var hasFall      = packet.ReadBit("Has Fall Data", index);
                packet.ReadBit("HasSpline", index);
                packet.ReadBit("HeightChangeFailed", index);
                packet.ReadBit("RemoteTimeValid", index);

                if (hasTransport)
                {
                    movementUpdate.Transport = ReadTransportData(moveInfo, guid, packet, index);
                }

                if (hasFall)
                {
                    packet.ResetBitReader();
                    movementUpdate.FallTime     = packet.ReadUInt32("Fall Time", index);
                    movementUpdate.JumpVelocity = packet.ReadSingle("JumpVelocity", index);

                    var hasFallDirection = packet.ReadBit("Has Fall Direction", index);
                    if (hasFallDirection)
                    {
                        packet.ReadVector2("Fall", index);
                        packet.ReadSingle("Horizontal Speed", index);
                    }
                }

                movementUpdate.WalkSpeed = moveInfo.WalkSpeed = packet.ReadSingle("WalkSpeed", index) / 2.5f;
                movementUpdate.RunSpeed  = moveInfo.RunSpeed = packet.ReadSingle("RunSpeed", index) / 7.0f;
                packet.ReadSingle("RunBackSpeed", index);
                packet.ReadSingle("SwimSpeed", index);
                packet.ReadSingle("SwimBackSpeed", index);
                packet.ReadSingle("FlightSpeed", index);
                packet.ReadSingle("FlightBackSpeed", index);
                packet.ReadSingle("TurnRate", index);
                packet.ReadSingle("PitchRate", index);

                var movementForceCount = packet.ReadUInt32("MovementForceCount", index);

                if (ClientVersion.AddedInVersion(ClientVersionBuild.V8_1_0_28724))
                {
                    packet.ReadSingle("MovementForcesModMagnitude", index);
                }

                packet.ResetBitReader();

                moveInfo.HasSplineData = packet.ReadBit("HasMovementSpline", index);

                for (var i = 0; i < movementForceCount; ++i)
                {
                    packet.ResetBitReader();
                    packet.ReadPackedGuid128("Id", index);
                    packet.ReadVector3("Origin", index);
                    packet.ReadVector3("Direction", index);
                    packet.ReadUInt32("TransportID", index);
                    packet.ReadSingle("Magnitude", index);
                    packet.ReadBits("Type", 2, index);

                    if (ClientVersion.AddedInVersion(ClientVersionBuild.V9_1_0_39185))
                    {
                        var unused910 = packet.ReadBit();
                        if (unused910)
                        {
                            packet.ReadInt32("Unused910", index);
                        }
                    }
                }

                if (moveInfo.HasSplineData)
                {
                    var splineData = movementUpdate.SplineData = new();
                    packet.ResetBitReader();
                    splineData.Id          = packet.ReadInt32("ID", index);
                    splineData.Destination = packet.ReadVector3("Destination", index);

                    var hasMovementSplineMove = packet.ReadBit("MovementSplineMove", index);
                    if (hasMovementSplineMove)
                    {
                        var moveData = splineData.MoveData = new();
                        packet.ResetBitReader();

                        moveData.Flags                = packet.ReadUInt32E <SplineFlag>("SplineFlags", index).ToUniversal();
                        moveData.Elapsed              = packet.ReadInt32("Elapsed", index);
                        moveData.Duration             = packet.ReadUInt32("Duration", index);
                        moveData.DurationModifier     = packet.ReadSingle("DurationModifier", index);
                        moveData.NextDurationModifier = packet.ReadSingle("NextDurationModifier", index);

                        var face           = packet.ReadBits("Face", 2, index);
                        var hasSpecialTime = packet.ReadBit("HasSpecialTime", index);

                        var pointsCount = packet.ReadBits("PointsCount", 16, index);

                        if (ClientVersion.RemovedInVersion(ClientType.Shadowlands))
                        {
                            packet.ReadBitsE <SplineMode>("Mode", 2, index);
                        }

                        var hasSplineFilterKey      = packet.ReadBit("HasSplineFilterKey", index);
                        var hasSpellEffectExtraData = packet.ReadBit("HasSpellEffectExtraData", index);
                        var hasJumpExtraData        = packet.ReadBit("HasJumpExtraData", index);

                        var hasAnimationTierTransition = false;
                        var hasUnknown901 = false;
                        if (ClientVersion.AddedInVersion(ClientType.Shadowlands))
                        {
                            hasAnimationTierTransition = packet.ReadBit("HasAnimationTierTransition", index);
                            hasUnknown901 = packet.ReadBit("Unknown901", index);
                        }

                        if (hasSplineFilterKey)
                        {
                            packet.ResetBitReader();
                            var filterKeysCount = packet.ReadUInt32("FilterKeysCount", index);
                            for (var i = 0; i < filterKeysCount; ++i)
                            {
                                packet.ReadSingle("In", index, i);
                                packet.ReadSingle("Out", index, i);
                            }

                            packet.ReadBits("FilterFlags", 2, index);
                        }

                        switch (face)
                        {
                        case 1:
                            moveData.LookPosition = packet.ReadVector3("FaceSpot", index);
                            break;

                        case 2:
                            moveData.LookTarget = new() { Target = packet.ReadPackedGuid128("FaceGUID", index) };
                            break;

                        case 3:
                            moveData.LookOrientation = packet.ReadSingle("FaceDirection", index);
                            break;

                        default:
                            break;
                        }

                        if (hasSpecialTime)
                        {
                            packet.ReadUInt32("SpecialTime", index);
                        }

                        for (var i = 0; i < pointsCount; ++i)
                        {
                            moveData.Points.Add(packet.ReadVector3("Points", index, i));
                        }

                        if (hasSpellEffectExtraData)
                        {
                            MovementHandler.ReadMonsterSplineSpellEffectExtraData(packet, index);
                        }

                        if (hasJumpExtraData)
                        {
                            moveData.Jump = MovementHandler.ReadMonsterSplineJumpExtraData(packet, index);
                        }

                        if (hasAnimationTierTransition)
                        {
                            packet.ReadInt32("TierTransitionID", index);
                            packet.ReadInt32("StartTime", index);
                            packet.ReadInt32("EndTime", index);
                            packet.ReadByte("AnimTier", index);
                        }

                        if (hasUnknown901)
                        {
                            for (var i = 0; i < 16; ++i)
                            {
                                packet.ReadInt32("Unknown1", index, "Unknown901", i);
                                packet.ReadInt32("Unknown2", index, "Unknown901", i);
                                packet.ReadInt32("Unknown3", index, "Unknown901", i);
                                packet.ReadInt32("Unknown4", index, "Unknown901", i);
                            }
                        }
                    }
                }
            }

            var pauseTimesCount = packet.ReadUInt32("PauseTimesCount", index);

            if (hasStationaryPosition)
            {
                moveInfo.Position    = packet.ReadVector3();
                moveInfo.Orientation = packet.ReadSingle();

                packet.AddValue("Stationary Position", moveInfo.Position, index);
                packet.AddValue("Stationary Orientation", moveInfo.Orientation, index);
                createObject.Stationary = new() { Position = moveInfo.Position, Orientation = moveInfo.Orientation };
            }

            if (hasCombatVictim)
            {
                packet.ReadPackedGuid128("CombatVictim Guid", index);
            }

            if (hasServerTime)
            {
                packet.ReadUInt32("ServerTime", index);
            }

            if (hasVehicleCreate)
            {
                var vehicle = createObject.Vehicle = new();
                moveInfo.VehicleId       = (uint)packet.ReadInt32("RecID", index);
                vehicle.VehicleId        = (int)moveInfo.VehicleId;
                vehicle.InitialRawFacing = packet.ReadSingle("InitialRawFacing", index);
            }

            if (hasAnimKitCreate)
            {
                var aiId       = packet.ReadUInt16("AiID", index);
                var movementId = packet.ReadUInt16("MovementID", index);
                var meleeId    = packet.ReadUInt16("MeleeID", index);
                if (obj is Unit unit)
                {
                    unit.AIAnimKit       = aiId;
                    unit.MovementAnimKit = movementId;
                    unit.MeleeAnimKit    = meleeId;
                }
                else if (obj is GameObject gob)
                {
                    gob.AIAnimKitID = aiId;
                }
            }

            if (hasRotation)
            {
                createObject.Rotation = moveInfo.Rotation = packet.ReadPackedQuaternion("GameObject Rotation", index);
            }

            for (var i = 0; i < pauseTimesCount; ++i)
            {
                packet.ReadUInt32("PauseTimes", index, i);
            }

            if (hasMovementTransport)
            {
                createObject.Transport = ReadTransportData(moveInfo, guid, packet, index);
            }

            if (hasAreaTrigger && obj is AreaTriggerCreateProperties)
            {
                AreaTriggerTemplate areaTriggerTemplate = new AreaTriggerTemplate
                {
                    Id = guid.GetEntry()
                };

                AreaTriggerCreateProperties spellAreaTrigger = (AreaTriggerCreateProperties)obj;
                spellAreaTrigger.AreaTriggerId = guid.GetEntry();

                packet.ResetBitReader();

                // CliAreaTrigger
                packet.ReadUInt32("ElapsedMs", index);

                packet.ReadVector3("RollPitchYaw1", index);

                areaTriggerTemplate.Flags = 0;

                if (packet.ReadBit("HasAbsoluteOrientation", index))
                {
                    areaTriggerTemplate.Flags |= (uint)AreaTriggerFlags.HasAbsoluteOrientation;
                }

                if (packet.ReadBit("HasDynamicShape", index))
                {
                    areaTriggerTemplate.Flags |= (uint)AreaTriggerFlags.HasDynamicShape;
                }

                if (packet.ReadBit("HasAttached", index))
                {
                    areaTriggerTemplate.Flags |= (uint)AreaTriggerFlags.HasAttached;
                }

                if (packet.ReadBit("HasFaceMovementDir", index))
                {
                    areaTriggerTemplate.Flags |= (uint)AreaTriggerFlags.FaceMovementDirection;
                }

                if (packet.ReadBit("HasFollowsTerrain", index))
                {
                    areaTriggerTemplate.Flags |= (uint)AreaTriggerFlags.FollowsTerrain;
                }

                if (packet.ReadBit("Unk bit WoD62x", index))
                {
                    areaTriggerTemplate.Flags |= (uint)AreaTriggerFlags.Unk1;
                }

                if (packet.ReadBit("HasTargetRollPitchYaw", index))
                {
                    areaTriggerTemplate.Flags |= (uint)AreaTriggerFlags.HasTargetRollPitchYaw;
                }

                bool hasScaleCurveID  = packet.ReadBit("HasScaleCurveID", index);
                bool hasMorphCurveID  = packet.ReadBit("HasMorphCurveID", index);
                bool hasFacingCurveID = packet.ReadBit("HasFacingCurveID", index);
                bool hasMoveCurveID   = packet.ReadBit("HasMoveCurveID", index);
                bool hasAnimProgress  = false;

                if (ClientVersion.RemovedInVersion(ClientVersionBuild.V9_1_5_40772))
                {
                    if (packet.ReadBit("HasAnimID", index))
                    {
                        areaTriggerTemplate.Flags |= (uint)AreaTriggerFlags.HasAnimId;
                    }

                    if (packet.ReadBit("HasAnimKitID", index))
                    {
                        areaTriggerTemplate.Flags |= (uint)AreaTriggerFlags.HasAnimKitId;
                    }

                    if (packet.ReadBit("unkbit50", index))
                    {
                        areaTriggerTemplate.Flags |= (uint)AreaTriggerFlags.Unk3;
                    }

                    hasAnimProgress = packet.ReadBit("HasAnimProgress", index);
                }

                if (packet.ReadBit("HasAreaTriggerSphere", index))
                {
                    areaTriggerTemplate.Type = (byte)AreaTriggerType.Sphere;
                }

                if (packet.ReadBit("HasAreaTriggerBox", index))
                {
                    areaTriggerTemplate.Type = (byte)AreaTriggerType.Box;
                }

                if (packet.ReadBit("HasAreaTriggerPolygon", index))
                {
                    areaTriggerTemplate.Type = (byte)AreaTriggerType.Polygon;
                }

                if (packet.ReadBit("HasAreaTriggerCylinder", index))
                {
                    areaTriggerTemplate.Type = (byte)AreaTriggerType.Cylinder;
                }

                bool hasAreaTriggerSpline = packet.ReadBit("HasAreaTriggerSpline", index);

                if (packet.ReadBit("HasAreaTriggerOrbit", index))
                {
                    areaTriggerTemplate.Flags |= (uint)AreaTriggerFlags.HasOrbit;
                }

                if (ClientVersion.AddedInVersion(ClientType.Shadowlands))
                {
                    if (packet.ReadBit("HasAreaTriggerMovementScript", index)) // seen with spellid 343597
                    {
                        areaTriggerTemplate.Flags |= (uint)AreaTriggerFlags.HasMovementScript;
                    }
                }

                if ((areaTriggerTemplate.Flags & (uint)AreaTriggerFlags.Unk3) != 0)
                {
                    packet.ReadBit();
                }

                if (hasAreaTriggerSpline)
                {
                    foreach (var splinePoint in AreaTriggerHandler.ReadAreaTriggerSpline(spellAreaTrigger, packet, index, "AreaTriggerSpline"))
                    {
                        Storage.AreaTriggerCreatePropertiesSplinePoints.Add(splinePoint);
                    }
                }

                if ((areaTriggerTemplate.Flags & (uint)AreaTriggerFlags.HasTargetRollPitchYaw) != 0)
                {
                    packet.ReadVector3("TargetRollPitchYaw", index);
                }

                if (hasScaleCurveID)
                {
                    spellAreaTrigger.ScaleCurveId = (int)packet.ReadUInt32("ScaleCurveID", index);
                }

                if (hasMorphCurveID)
                {
                    spellAreaTrigger.MorphCurveId = (int)packet.ReadUInt32("MorphCurveID", index);
                }

                if (hasFacingCurveID)
                {
                    spellAreaTrigger.FacingCurveId = (int)packet.ReadUInt32("FacingCurveID", index);
                }

                if (hasMoveCurveID)
                {
                    spellAreaTrigger.MoveCurveId = (int)packet.ReadUInt32("MoveCurveID", index);
                }

                if ((areaTriggerTemplate.Flags & (int)AreaTriggerFlags.HasAnimId) != 0)
                {
                    spellAreaTrigger.AnimId = packet.ReadInt32("AnimId", index);
                }

                if ((areaTriggerTemplate.Flags & (int)AreaTriggerFlags.HasAnimKitId) != 0)
                {
                    spellAreaTrigger.AnimKitId = packet.ReadInt32("AnimKitId", index);
                }

                if (hasAnimProgress)
                {
                    packet.ReadUInt32("AnimProgress", index);
                }

                if (areaTriggerTemplate.Type == (byte)AreaTriggerType.Sphere)
                {
                    areaTriggerTemplate.Data[0] = packet.ReadSingle("Radius", index);
                    areaTriggerTemplate.Data[1] = packet.ReadSingle("RadiusTarget", index);
                }

                if (areaTriggerTemplate.Type == (byte)AreaTriggerType.Box)
                {
                    Vector3 Extents       = packet.ReadVector3("Extents", index);
                    Vector3 ExtentsTarget = packet.ReadVector3("ExtentsTarget", index);

                    areaTriggerTemplate.Data[0] = Extents.X;
                    areaTriggerTemplate.Data[1] = Extents.Y;
                    areaTriggerTemplate.Data[2] = Extents.Z;

                    areaTriggerTemplate.Data[3] = ExtentsTarget.X;
                    areaTriggerTemplate.Data[4] = ExtentsTarget.Y;
                    areaTriggerTemplate.Data[5] = ExtentsTarget.Z;
                }

                if (areaTriggerTemplate.Type == (byte)AreaTriggerType.Polygon)
                {
                    var verticesCount       = packet.ReadUInt32("VerticesCount", index);
                    var verticesTargetCount = packet.ReadUInt32("VerticesTargetCount", index);

                    List <AreaTriggerCreatePropertiesPolygonVertex> verticesList = new List <AreaTriggerCreatePropertiesPolygonVertex>();

                    areaTriggerTemplate.Data[0] = packet.ReadSingle("Height", index);
                    areaTriggerTemplate.Data[1] = packet.ReadSingle("HeightTarget", index);

                    for (uint i = 0; i < verticesCount; ++i)
                    {
                        AreaTriggerCreatePropertiesPolygonVertex spellAreatriggerVertices = new AreaTriggerCreatePropertiesPolygonVertex
                        {
                            areatriggerGuid = guid,
                            Idx             = i
                        };

                        Vector2 vertices = packet.ReadVector2("Vertices", index, i);

                        spellAreatriggerVertices.VerticeX = vertices.X;
                        spellAreatriggerVertices.VerticeY = vertices.Y;

                        verticesList.Add(spellAreatriggerVertices);
                    }

                    for (var i = 0; i < verticesTargetCount; ++i)
                    {
                        Vector2 verticesTarget = packet.ReadVector2("VerticesTarget", index, i);

                        verticesList[i].VerticeTargetX = verticesTarget.X;
                        verticesList[i].VerticeTargetY = verticesTarget.Y;
                    }

                    foreach (AreaTriggerCreatePropertiesPolygonVertex vertice in verticesList)
                    {
                        Storage.AreaTriggerCreatePropertiesPolygonVertices.Add(vertice);
                    }
                }

                if (areaTriggerTemplate.Type == (byte)AreaTriggerType.Cylinder)
                {
                    areaTriggerTemplate.Data[0] = packet.ReadSingle("Radius", index);
                    areaTriggerTemplate.Data[1] = packet.ReadSingle("RadiusTarget", index);
                    areaTriggerTemplate.Data[2] = packet.ReadSingle("Height", index);
                    areaTriggerTemplate.Data[3] = packet.ReadSingle("HeightTarget", index);
                    areaTriggerTemplate.Data[4] = packet.ReadSingle("LocationZOffset", index);
                    areaTriggerTemplate.Data[5] = packet.ReadSingle("LocationZOffsetTarget", index);
                }

                if ((areaTriggerTemplate.Flags & (uint)AreaTriggerFlags.HasMovementScript) != 0)
                {
                    packet.ReadInt32("SpellScriptID");
                    packet.ReadVector3("Center");
                }

                if ((areaTriggerTemplate.Flags & (uint)AreaTriggerFlags.HasOrbit) != 0)
                {
                    Storage.AreaTriggerCreatePropertiesOrbits.Add(AreaTriggerHandler.ReadAreaTriggerOrbit(guid, packet, index, "AreaTriggerOrbit"));
                }

                spellAreaTrigger.Shape = areaTriggerTemplate.Type;
                Array.Copy(areaTriggerTemplate.Data, spellAreaTrigger.ShapeData, Math.Min(areaTriggerTemplate.Data.Length, spellAreaTrigger.ShapeData.Length));

                Storage.AreaTriggerTemplates.Add(areaTriggerTemplate);
            }

            if (hasGameObject)
            {
                packet.ResetBitReader();
                var worldEffectId = packet.ReadUInt32("WorldEffectID", index);
                if (worldEffectId != 0 && obj is GameObject gob)
                {
                    gob.WorldEffectID = worldEffectId;
                }

                var bit8 = packet.ReadBit("bit8", index);
                if (bit8)
                {
                    packet.ReadUInt32("Int1", index);
                }
            }

            if (hasSmoothPhasing)
            {
                packet.ResetBitReader();
                packet.ReadBit("ReplaceActive", index);
                if (ClientVersion.AddedInVersion(ClientType.Shadowlands))
                {
                    packet.ReadBit("StopAnimKits", index);
                }

                var replaceObject = packet.ReadBit();
                if (replaceObject)
                {
                    packet.ReadPackedGuid128("ReplaceObject", index);
                }
            }

            if (sceneObjCreate)
            {
                packet.ResetBitReader();

                var hasSceneLocalScriptData = packet.ReadBit("HasSceneLocalScriptData", index);
                var petBattleFullUpdate     = packet.ReadBit("HasPetBattleFullUpdate", index);

                if (hasSceneLocalScriptData)
                {
                    packet.ResetBitReader();
                    var dataLength = packet.ReadBits(7);
                    packet.ReadWoWString("Data", dataLength, index);
                }

                if (petBattleFullUpdate)
                {
                    V6_0_2_19033.Parsers.BattlePetHandler.ReadPetBattleFullUpdate(packet, index);
                }
            }

            if (playerCreateData)
            {
                packet.ResetBitReader();
                var hasSceneInstanceIDs = packet.ReadBit("ScenePendingInstances", index);
                var hasRuneState        = packet.ReadBit("Runes", index);

                if (hasSceneInstanceIDs)
                {
                    var sceneInstanceIDs = packet.ReadUInt32("SceneInstanceIDsCount");
                    for (var i = 0; i < sceneInstanceIDs; ++i)
                    {
                        packet.ReadInt32("SceneInstanceIDs", index, i);
                    }
                }

                if (hasRuneState)
                {
                    packet.ReadByte("RechargingRuneMask", index);
                    packet.ReadByte("UsableRuneMask", index);
                    var runeCount = packet.ReadUInt32();
                    for (var i = 0; i < runeCount; ++i)
                    {
                        packet.ReadByte("RuneCooldown", index, i);
                    }
                }
            }

            if (hasConversation)
            {
                packet.ResetBitReader();
                if (packet.ReadBit("HasTextureKitID", index))
                {
                    (obj as ConversationTemplate).TextureKitId = packet.ReadUInt32("TextureKitID", index);
                }
            }

            return(moveInfo);
        }
    }