protected override void ElementWrite(StreamHandler writer, int index)
 {
     if (index == -3)
         writer.UnalignedWriteInt(this.UnkByte, 2);
     else
         base.ElementWrite(writer, index);
 }
 protected override void ElementWrite(StreamHandler writer, int index)
 {
     if (index == -3)
     {
         writer.UnalignedWriteInt(this.UnkByte, 2);
     }
     else
     {
         base.ElementWrite(writer, index);
     }
 }
        protected virtual void WriteElement(StreamHandler writer, MovementStatusElements element, MovementStatus status, byte[] guid, byte[] tguid)
        {
            if (element >= MovementStatusElements.GuidByte0 && element <= MovementStatusElements.GuidByte7)
            {
                WriteByteMask(writer, guid[element - MovementStatusElements.GuidByte0]);
                return;
            }

            if (element >= MovementStatusElements.TransportGuidByte0 &&
                element <= MovementStatusElements.TransportGuidByte7)
            {
                if (status.HaveTransportData)
                    WriteByteMask(writer, tguid[element - MovementStatusElements.TransportGuidByte0]);
                return;
            }

            if (element >= MovementStatusElements.GuidByte0_2 && element <= MovementStatusElements.GuidByte7_2)
            {
                WriteByteSeq(writer, guid[element - MovementStatusElements.GuidByte0_2]);
                return;
            }

            if (element >= MovementStatusElements.TransportGuidByte0_2 &&
                element <= MovementStatusElements.TransportGuidByte7_2)
            {
                if (status.HaveTransportData)
                    WriteByteSeq(writer, tguid[element - MovementStatusElements.TransportGuidByte0_2]);
                return;
            }

            switch (element)
            {
                case MovementStatusElements.Flags:
                    writer.UnalignedWriteBit(status.Flags == 0);
                    break;
                case MovementStatusElements.Flags_2:
                    if (status.Flags != 0)
                        writer.UnalignedWriteInt((uint)status.Flags, 30);
                    break;
                case MovementStatusElements.Flags2:
                    writer.UnalignedWriteBit(status.Flags2 == 0);
                    break;
                case MovementStatusElements.Flags2_2:
                    if (status.Flags2 != 0)
                        writer.UnalignedWriteInt((ushort)status.Flags2, 12);
                    break;
                case MovementStatusElements.Timestamp:
                    writer.UnalignedWriteBit(status.TimeStamp == 0);
                    break;
                case MovementStatusElements.Timestamp_2:
                    if (status.TimeStamp != 0)
                        writer.WriteUInt32(status.TimeStamp);
                    break;
                case MovementStatusElements.Pitch:
                    writer.UnalignedWriteBit(!status.HavePitch);
                    break;
                case MovementStatusElements.Pitch_2:
                    if (status.HavePitch)
                        writer.WriteSingle(status.Pitch);
                    break;
                case MovementStatusElements.HaveFallData:
                    writer.UnalignedWriteBit(status.HaveFallData);
                    break;
                case MovementStatusElements.HaveFallDirection:
                    if (status.HaveFallData)
                        writer.UnalignedWriteBit(status.HaveFallDirection);
                    break;
                case MovementStatusElements.HaveTransportData:
                    writer.UnalignedWriteBit(status.HaveTransportData);
                    break;
                case MovementStatusElements.TransportHaveTime2:
                    if (status.HaveTransportData)
                        writer.UnalignedWriteBit(status.HaveTransportTime2);
                    break;
                case MovementStatusElements.TransportHaveTime3:
                    if (status.HaveTransportData)
                        writer.UnalignedWriteBit(status.HaveTransportTime3);
                    break;
                case MovementStatusElements.HaveSpline:
                    writer.UnalignedWriteBit(status.HaveSpline);
                    break;
                case MovementStatusElements.HaveSpline2:
                    writer.UnalignedWriteBit(status.HaveSpline2);
                    break;
                case MovementStatusElements.SplineElev:
                    writer.UnalignedWriteBit(!status.HaveSplineElevation);
                    break;
                case MovementStatusElements.SplineElev_2:
                    if (status.HaveSplineElevation)
                        writer.WriteSingle(status.SplineElevation);
                    break;
                case MovementStatusElements.PositionX:
                    writer.WriteSingle(status.Position.X);
                    break;
                case MovementStatusElements.PositionY:
                    writer.WriteSingle(status.Position.Y);
                    break;
                case MovementStatusElements.PositionZ:
                    writer.WriteSingle(status.Position.Z);
                    break;
                case MovementStatusElements.PositionO:
                    writer.UnalignedWriteBit(status.Orientation == 0.0f);
                    break;
                case MovementStatusElements.PositionO_2:
                    if (status.Orientation != 0.0f)
                        writer.WriteSingle(status.Orientation);
                    break;
                case MovementStatusElements.FallTime:
                    if (status.HaveFallData)
                        writer.WriteUInt32(status.FallTime);
                    break;
                case MovementStatusElements.FallHorizontalSpeed:
                    if (status.HaveFallDirection)
                        writer.WriteSingle(status.FallHorizontalSpeed);
                    break;
                case MovementStatusElements.FallVerticalSpeed:
                    if (status.HaveFallData)
                        writer.WriteSingle(status.FallVerticalSpeed);
                    break;
                case MovementStatusElements.FallCosAngle:
                    if (status.HaveFallDirection)
                        writer.WriteSingle(status.FallCosAngle);
                    break;
                case MovementStatusElements.FallSinAngle:
                    if (status.HaveFallDirection)
                        writer.WriteSingle(status.FallSinAngle);
                    break;
                case MovementStatusElements.TransportSeat:
                    if (status.HaveTransportData)
                        writer.WriteSByte(status.TransportSeat);
                    break;
                case MovementStatusElements.TransportPositionO:
                    if (status.HaveTransportData)
                        writer.WriteSingle(status.TransportFacing);
                    break;
                case MovementStatusElements.TransportPositionX:
                    if (status.HaveTransportData)
                        writer.WriteSingle(status.TransportPosition.X);
                    break;
                case MovementStatusElements.TransportPositionY:
                    if (status.HaveTransportData)
                        writer.WriteSingle(status.TransportPosition.Y);
                    break;
                case MovementStatusElements.TransportPositionZ:
                    if (status.HaveTransportData)
                        writer.WriteSingle(status.TransportPosition.Z);
                    break;
                case MovementStatusElements.TransportTime:
                    if (status.HaveTransportData)
                        writer.WriteUInt32(status.TransportTime);
                    break;
                case MovementStatusElements.TransportTime2:
                    if (status.HaveTransportTime2)
                        writer.WriteUInt32(status.TransportTime2);
                    break;
                case MovementStatusElements.TransportTime3:
                    if (status.HaveTransportTime3)
                        writer.WriteUInt32(status.TransportTime3);
                    break;
                default:
                    throw new InvalidOperationException("Unknown element: " + element);
            }
        }
Exemple #4
0
        public unsafe void Save(StreamHandler Writer)
        {
            var guid = this.Guid;

            Writer
                .UnalignedWriteBit(this.HaveAttackingTarget)
                .UnalignedWriteBit(guid.Bytes[2] != 0)
                .UnalignedWriteBit(this.HaveVehicleData)
                .UnalignedWriteBit(guid.Bytes[1] != 0)
                .UnalignedWriteBit(guid.Bytes[4] != 0)
                .UnalignedWriteBit(guid.Bytes[3] != 0)
                .UnalignedWriteBit(this.HaveTransportTime)
                .UnalignedWriteBit(this.HaveGameObjectPosition)
                .UnalignedWriteBit(false) // TODO
                .UnalignedWriteBit(false) // TODO
                .UnalignedWriteBit(this.HaveGameObjectRotation)
                .UnalignedWriteBit(this.Living)
                .UnalignedWriteBit(this.HavePosition)
                .UnalignedWriteInt((uint)this.UnkUInt32.Length, 24)
                .UnalignedWriteBit(guid.Bytes[0] != 0)
                ;

            var p_guid = this.Guid;

            if (this.Living)
            {
                Writer.UnalignedWriteBit(this.HaveTransportData);
                if (this.HaveTransportData)
                {
                    fixed (byte* bytes = this.TransportGuid.Bytes)
                    {
                        Writer
                            .UnalignedWriteBit(bytes[2] != 0)
                            .UnalignedWriteBit(bytes[7] != 0)
                            .UnalignedWriteBit(bytes[5] != 0)
                            .UnalignedWriteBit(this.HaveTransportTime3)
                            .UnalignedWriteBit(bytes[3] != 0)
                            .UnalignedWriteBit(bytes[0] != 0)
                            .UnalignedWriteBit(bytes[4] != 0)
                            .UnalignedWriteBit(bytes[1] != 0)
                            .UnalignedWriteBit(this.HaveTransportTime2)
                            .UnalignedWriteBit(bytes[6] != 0);
                    }
                }

                Writer
                    .UnalignedWriteBit(this.HaveSpline2)
                    .UnalignedWriteBit(p_guid.Bytes[7] != 0)
                    .UnalignedWriteBit(p_guid.Bytes[6] != 0)
                    .UnalignedWriteBit(p_guid.Bytes[5] != 0)
                    .UnalignedWriteBit(p_guid.Bytes[2] != 0)
                    .UnalignedWriteBit(p_guid.Bytes[4] != 0)
                    .UnalignedWriteBit(!(this.Flags != 0))
                    .UnalignedWriteBit(p_guid.Bytes[1] != 0)
                    .UnalignedWriteBit(this.SelfTarget)
                    .UnalignedWriteBit(!(this.TimeStamp != 0))
                    .UnalignedWriteBit(!(this.Flags2 != 0));

                if (this.HaveSpline2)
                {
                    Writer.UnalignedWriteBit(this.HaveSpline);
                    if (this.HaveSpline)
                    {
                        Writer
                            .UnalignedWriteBit(this.Spline.HaveDurationMultiplier)
                            .UnalignedWriteInt((uint)this.Spline.Flags, 25)
                            .UnalignedWriteInt((byte)this.Spline.SplineMode, 2)
                            .UnalignedWriteBit(this.Spline.HaveUnknown1)
                            .UnalignedWriteInt((uint)this.Spline.Points.Count, 22);

                        byte v;
                        switch (this.Spline.SplineType)
                        {
                            case SplineType.FacingSpot:
                                v = 0;
                                break;
                            case SplineType.Normal:
                                v = 1;
                                break;
                            case SplineType.FacingTarget:
                                v = 2;
                                break;
                            case SplineType.FacingAngle:
                                v = 3;
                                break;
                            default:
                                throw new InvalidOperationException();
                        }
                        Writer.UnalignedWriteInt(v, 2);

                        if (this.Spline.SplineType == SplineType.FacingTarget)
                        {
                            fixed (byte* bytes = this.Spline.FacingTarget.Bytes)
                            {
                                Writer
                                    .UnalignedWriteBit(bytes[7] != 0)
                                    .UnalignedWriteBit(bytes[3] != 0)
                                    .UnalignedWriteBit(bytes[4] != 0)
                                    .UnalignedWriteBit(bytes[2] != 0)
                                    .UnalignedWriteBit(bytes[1] != 0)
                                    .UnalignedWriteBit(bytes[6] != 0)
                                    .UnalignedWriteBit(bytes[0] != 0)
                                    .UnalignedWriteBit(bytes[5] != 0);
                            }
                        }
                    }
                }

                Writer
                    .UnalignedWriteBit(p_guid.Bytes[3] != 0);

                if (this.Flags != 0)
                    Writer.UnalignedWriteInt((uint)this.Flags, 30);

                Writer
                    .UnalignedWriteBit(!this.HavePitch)
                    .UnalignedWriteBit(this.HaveFallData);
                if (this.Flags2 != 0)
                    Writer.UnalignedWriteInt((ushort)this.Flags2, 12);
                Writer
                    .UnalignedWriteBit(p_guid.Bytes[0] != 0)
                    .UnalignedWriteBit(!(this.Orientation != 0.0f)); // !haveOrient

                if (this.HaveFallData)
                    Writer.UnalignedWriteBit(this.HaveFallDirection);

                Writer.UnalignedWriteBit(!this.HaveSplineElevation);
            }

            if (this.HaveGameObjectPosition)
            {
                fixed (byte* bytes = this.TransportGuid.Bytes)
                {
                    Writer
                        .UnalignedWriteBit(bytes[1] != 0)
                        .UnalignedWriteBit(this.HaveTransportTime3)
                        .UnalignedWriteBit(bytes[3] != 0)
                        .UnalignedWriteBit(bytes[2] != 0)
                        .UnalignedWriteBit(bytes[6] != 0)
                        .UnalignedWriteBit(bytes[5] != 0)
                        .UnalignedWriteBit(bytes[0] != 0)
                        .UnalignedWriteBit(bytes[4] != 0)
                        .UnalignedWriteBit(this.HaveTransportTime2)
                        .UnalignedWriteBit(bytes[7] != 0);
                }
            }

            // TODO: shorts here

            if (this.HaveAttackingTarget)
            {
                fixed (byte* bytes = this.AttackingTarget.Bytes)
                {
                    Writer
                        .UnalignedWriteBit(bytes[3] != 0)
                        .UnalignedWriteBit(bytes[4] != 0)
                        .UnalignedWriteBit(bytes[6] != 0)
                        .UnalignedWriteBit(bytes[0] != 0)
                        .UnalignedWriteBit(bytes[1] != 0)
                        .UnalignedWriteBit(bytes[7] != 0)
                        .UnalignedWriteBit(bytes[5] != 0)
                        .UnalignedWriteBit(bytes[2] != 0);
                }
            }

            Writer.FlushUnalignedBits();

            foreach (var val in this.UnkUInt32)
                Writer.WriteUInt32(val);

            if (this.HavePosition)
            {
                Writer
                    .WriteSingle(this.Position.Z)
                    .WriteSingle(this.Orientation)
                    .WriteSingle(this.Position.X)
                    .WriteSingle(this.Position.Y);
            }

            if (this.HaveVehicleData)
            {
                Writer
                    .WriteUInt32(this.VehicleId)
                    .WriteSingle(this.VehicleAimAdjustement);
            }

            if (this.HaveGameObjectPosition)
            {
                fixed (byte* bytes = this.TransportGuid.Bytes)
                {
                    Writer
                        .WriteXorByte(bytes[1])
                        .WriteXorByte(bytes[4])
                        .WriteSingle(this.TransportPosition.Z);

                    if (this.HaveTransportTime3)
                        Writer.WriteUInt32(this.TransportTime3);

                    Writer.WriteUInt32(this.TransportTime);

                    Writer
                        .WriteXorByte(bytes[5])
                        .WriteXorByte(bytes[6])
                        .WriteSingle(this.TransportPosition.X)
                        .WriteXorByte(bytes[2]);

                    if (this.HaveTransportTime2)
                        Writer.WriteUInt32(this.TransportTime2);

                    Writer
                        .WriteSByte(this.TransportSeat)
                        .WriteXorByte(bytes[3])
                        .WriteSingle(this.TransportPosition.Y)
                        .WriteSingle(this.TransportFacing)
                        .WriteXorByte(bytes[7])
                        .WriteXorByte(bytes[0]);
                }
            }

            if (this.Living)
            {
                if (this.HaveSpline2)
                {
                    if (this.HaveSpline)
                    {
                        foreach (var point in this.Spline.Points)
                            Writer.WriteSingle(point.Y).WriteSingle(point.X).WriteSingle(point.Z);

                        if (this.Spline.HaveDurationMultiplier)
                        {
                            Writer.WriteSingle(this.Spline.DurationMultiplier);
                        }

                        Writer.WriteSingle(this.Spline.UnknownFloat2);

                        if (this.Spline.SplineType == SplineType.FacingTarget)
                        {
                            fixed (byte* bytes = this.Spline.FacingTarget.Bytes)
                            {
                                Writer
                                    .WriteXorByte(bytes[3])
                                    .WriteXorByte(bytes[4])
                                    .WriteXorByte(bytes[5])
                                    .WriteXorByte(bytes[7])
                                    .WriteXorByte(bytes[2])
                                    .WriteXorByte(bytes[0])
                                    .WriteXorByte(bytes[6])
                                    .WriteXorByte(bytes[1]);
                            }
                        }

                        if (this.Spline.HaveUnknown1)
                        {
                            Writer.WriteUInt32(this.Spline.Unknown1);
                        }

                        Writer.WriteSingle(this.Spline.UnknownFloat3);
                        Writer.WriteUInt32(this.Spline.Unknown2);

                        if (this.Spline.SplineType == SplineType.FacingSpot)
                        {
                            Writer
                                .WriteSingle(this.Spline.FacingSpot.Y)
                                .WriteSingle(this.Spline.FacingSpot.Z)
                                .WriteSingle(this.Spline.FacingSpot.X);
                        }

                        Writer.WriteUInt32(this.Spline.CurrentTime);

                        if (this.Spline.SplineType == SplineType.FacingAngle)
                            Writer.WriteSingle(this.Spline.FacingAngle);
                    }

                    Writer
                        .WriteSingle(this.Spline.EndPoint.Z)
                        .WriteSingle(this.Spline.EndPoint.Y)
                        .WriteUInt32(this.Spline.FullTime)
                        .WriteSingle(this.Spline.EndPoint.X);
                }

                Writer.WriteSingle(this.Speeds[8]);

                // Transport Data
                if (this.HaveTransportData)
                {
                    fixed (byte* bytes = this.TransportGuid.Bytes)
                    {
                        Writer
                            .WriteXorByte(bytes[4])
                            .WriteSingle(this.TransportPosition.Z)
                            .WriteXorByte(bytes[7])
                            .WriteXorByte(bytes[5])
                            .WriteXorByte(bytes[1])
                            .WriteSingle(this.TransportPosition.X)
                            .WriteXorByte(bytes[3])
                            .WriteXorByte(bytes[6]);

                        if (this.HaveTransportTime3)
                            Writer.WriteUInt32(this.TransportTime3);

                        Writer
                            .WriteSingle(this.TransportPosition.Y)
                            .WriteSByte(this.TransportSeat)
                            .WriteSingle(this.TransportFacing);

                        if (this.HaveTransportTime2)
                            Writer.WriteUInt32(this.TransportTime2);

                        Writer
                            .WriteXorByte(bytes[2])
                            .WriteUInt32(this.TransportTime)
                            .WriteXorByte(bytes[0]);
                    }
                }

                Writer
                    .WriteSingle(this.Speeds[7])
                    .WriteSingle(this.Position.X);

                if (this.HavePitch)
                    Writer.WriteSingle(this.Pitch);

                // Fall Data
                if (this.HaveFallData)
                {
                    Writer.WriteUInt32(this.FallTime);
                    if (this.HaveFallDirection)
                    {
                        Writer
                            .WriteSingle(this.FallSinAngle)
                            .WriteSingle(this.FallHorizontalSpeed)
                            .WriteSingle(this.FallCosAngle);
                    }
                    Writer.WriteSingle(this.FallVerticalSpeed);
                }

                Writer
                    .WriteXorByte(p_guid.Bytes[7])
                    .WriteSingle(this.Speeds[4])
                    .WriteXorByte(p_guid.Bytes[0])
                    .WriteXorByte(p_guid.Bytes[5]);

                if (this.TimeStamp != 0)
                    Writer.WriteUInt32(this.TimeStamp);

                Writer
                    .WriteSingle(this.Position.Z)
                    .WriteSingle(this.Speeds[6])
                    .WriteXorByte(p_guid.Bytes[1])
                    .WriteSingle(this.Speeds[2])
                    .WriteSingle(this.Speeds[5])
                    .WriteSingle(this.Speeds[3])
                    .WriteSingle(this.Speeds[0])
                    .WriteXorByte(p_guid.Bytes[3])
                    .WriteXorByte(p_guid.Bytes[4])
                    .WriteXorByte(p_guid.Bytes[2])
                    .WriteXorByte(p_guid.Bytes[6]);

                if (this.HaveSplineElevation)
                    Writer.WriteSingle(this.SplineElevation);

                Writer.WriteSingle(this.Position.Y);
                if (this.Orientation != 0.0f)
                    Writer.WriteSingle(this.Orientation);
                Writer.WriteSingle(this.Speeds[1]);
            }

            // floats here

            // transport time
            if (this.HaveTransportTime)
                Writer.WriteUInt32(this.TransportTime);

            // shorts here

            // go rotation?
            if (this.HaveGameObjectRotation)
                Writer.WriteUInt64(this.GameObjectRotation.Pack());

            // target guid?
            if (this.HaveAttackingTarget)
            {
                fixed (byte* bytes = this.AttackingTarget.Bytes)
                {
                    Writer
                        .WriteXorByte(bytes[3])
                        .WriteXorByte(bytes[5])
                        .WriteXorByte(bytes[0])
                        .WriteXorByte(bytes[7])
                        .WriteXorByte(bytes[2])
                        .WriteXorByte(bytes[4])
                        .WriteXorByte(bytes[6])
                        .WriteXorByte(bytes[1]);
                }
            }
        }
        public unsafe void Save(StreamHandler Writer)
        {
            var guid = this.Guid;

            Writer
            .UnalignedWriteBit(this.HaveAttackingTarget)
            .UnalignedWriteBit(guid.Bytes[2] != 0)
            .UnalignedWriteBit(this.HaveVehicleData)
            .UnalignedWriteBit(guid.Bytes[1] != 0)
            .UnalignedWriteBit(guid.Bytes[4] != 0)
            .UnalignedWriteBit(guid.Bytes[3] != 0)
            .UnalignedWriteBit(this.HaveTransportTime)
            .UnalignedWriteBit(this.HaveGameObjectPosition)
            .UnalignedWriteBit(false)     // TODO
            .UnalignedWriteBit(false)     // TODO
            .UnalignedWriteBit(this.HaveGameObjectRotation)
            .UnalignedWriteBit(this.Living)
            .UnalignedWriteBit(this.HavePosition)
            .UnalignedWriteInt((uint)this.UnkUInt32.Length, 24)
            .UnalignedWriteBit(guid.Bytes[0] != 0)
            ;

            var p_guid = this.Guid;

            if (this.Living)
            {
                Writer.UnalignedWriteBit(this.HaveTransportData);
                if (this.HaveTransportData)
                {
                    fixed(byte *bytes = this.TransportGuid.Bytes)
                    {
                        Writer
                        .UnalignedWriteBit(bytes[2] != 0)
                        .UnalignedWriteBit(bytes[7] != 0)
                        .UnalignedWriteBit(bytes[5] != 0)
                        .UnalignedWriteBit(this.HaveTransportTime3)
                        .UnalignedWriteBit(bytes[3] != 0)
                        .UnalignedWriteBit(bytes[0] != 0)
                        .UnalignedWriteBit(bytes[4] != 0)
                        .UnalignedWriteBit(bytes[1] != 0)
                        .UnalignedWriteBit(this.HaveTransportTime2)
                        .UnalignedWriteBit(bytes[6] != 0);
                    }
                }

                Writer
                .UnalignedWriteBit(this.HaveSpline2)
                .UnalignedWriteBit(p_guid.Bytes[7] != 0)
                .UnalignedWriteBit(p_guid.Bytes[6] != 0)
                .UnalignedWriteBit(p_guid.Bytes[5] != 0)
                .UnalignedWriteBit(p_guid.Bytes[2] != 0)
                .UnalignedWriteBit(p_guid.Bytes[4] != 0)
                .UnalignedWriteBit(!(this.Flags != 0))
                .UnalignedWriteBit(p_guid.Bytes[1] != 0)
                .UnalignedWriteBit(this.SelfTarget)
                .UnalignedWriteBit(!(this.TimeStamp != 0))
                .UnalignedWriteBit(!(this.Flags2 != 0));

                if (this.HaveSpline2)
                {
                    Writer.UnalignedWriteBit(this.HaveSpline);
                    if (this.HaveSpline)
                    {
                        Writer
                        .UnalignedWriteBit(this.Spline.HaveDurationMultiplier)
                        .UnalignedWriteInt((uint)this.Spline.Flags, 25)
                        .UnalignedWriteInt((byte)this.Spline.SplineMode, 2)
                        .UnalignedWriteBit(this.Spline.HaveUnknown1)
                        .UnalignedWriteInt((uint)this.Spline.Points.Count, 22);

                        byte v;
                        switch (this.Spline.SplineType)
                        {
                        case SplineType.FacingSpot:
                            v = 0;
                            break;

                        case SplineType.Normal:
                            v = 1;
                            break;

                        case SplineType.FacingTarget:
                            v = 2;
                            break;

                        case SplineType.FacingAngle:
                            v = 3;
                            break;

                        default:
                            throw new InvalidOperationException();
                        }
                        Writer.UnalignedWriteInt(v, 2);

                        if (this.Spline.SplineType == SplineType.FacingTarget)
                        {
                            fixed(byte *bytes = this.Spline.FacingTarget.Bytes)
                            {
                                Writer
                                .UnalignedWriteBit(bytes[7] != 0)
                                .UnalignedWriteBit(bytes[3] != 0)
                                .UnalignedWriteBit(bytes[4] != 0)
                                .UnalignedWriteBit(bytes[2] != 0)
                                .UnalignedWriteBit(bytes[1] != 0)
                                .UnalignedWriteBit(bytes[6] != 0)
                                .UnalignedWriteBit(bytes[0] != 0)
                                .UnalignedWriteBit(bytes[5] != 0);
                            }
                        }
                    }
                }

                Writer
                .UnalignedWriteBit(p_guid.Bytes[3] != 0);

                if (this.Flags != 0)
                {
                    Writer.UnalignedWriteInt((uint)this.Flags, 30);
                }

                Writer
                .UnalignedWriteBit(!this.HavePitch)
                .UnalignedWriteBit(this.HaveFallData);
                if (this.Flags2 != 0)
                {
                    Writer.UnalignedWriteInt((ushort)this.Flags2, 12);
                }
                Writer
                .UnalignedWriteBit(p_guid.Bytes[0] != 0)
                .UnalignedWriteBit(!(this.Orientation != 0.0f));     // !haveOrient

                if (this.HaveFallData)
                {
                    Writer.UnalignedWriteBit(this.HaveFallDirection);
                }

                Writer.UnalignedWriteBit(!this.HaveSplineElevation);
            }

            if (this.HaveGameObjectPosition)
            {
                fixed(byte *bytes = this.TransportGuid.Bytes)
                {
                    Writer
                    .UnalignedWriteBit(bytes[1] != 0)
                    .UnalignedWriteBit(this.HaveTransportTime3)
                    .UnalignedWriteBit(bytes[3] != 0)
                    .UnalignedWriteBit(bytes[2] != 0)
                    .UnalignedWriteBit(bytes[6] != 0)
                    .UnalignedWriteBit(bytes[5] != 0)
                    .UnalignedWriteBit(bytes[0] != 0)
                    .UnalignedWriteBit(bytes[4] != 0)
                    .UnalignedWriteBit(this.HaveTransportTime2)
                    .UnalignedWriteBit(bytes[7] != 0);
                }
            }

            // TODO: shorts here

            if (this.HaveAttackingTarget)
            {
                fixed(byte *bytes = this.AttackingTarget.Bytes)
                {
                    Writer
                    .UnalignedWriteBit(bytes[3] != 0)
                    .UnalignedWriteBit(bytes[4] != 0)
                    .UnalignedWriteBit(bytes[6] != 0)
                    .UnalignedWriteBit(bytes[0] != 0)
                    .UnalignedWriteBit(bytes[1] != 0)
                    .UnalignedWriteBit(bytes[7] != 0)
                    .UnalignedWriteBit(bytes[5] != 0)
                    .UnalignedWriteBit(bytes[2] != 0);
                }
            }

            Writer.FlushUnalignedBits();

            foreach (var val in this.UnkUInt32)
            {
                Writer.WriteUInt32(val);
            }

            if (this.HavePosition)
            {
                Writer
                .WriteSingle(this.Position.Z)
                .WriteSingle(this.Orientation)
                .WriteSingle(this.Position.X)
                .WriteSingle(this.Position.Y);
            }

            if (this.HaveVehicleData)
            {
                Writer
                .WriteUInt32(this.VehicleId)
                .WriteSingle(this.VehicleAimAdjustement);
            }

            if (this.HaveGameObjectPosition)
            {
                fixed(byte *bytes = this.TransportGuid.Bytes)
                {
                    Writer
                    .WriteXorByte(bytes[1])
                    .WriteXorByte(bytes[4])
                    .WriteSingle(this.TransportPosition.Z);

                    if (this.HaveTransportTime3)
                    {
                        Writer.WriteUInt32(this.TransportTime3);
                    }

                    Writer.WriteUInt32(this.TransportTime);

                    Writer
                    .WriteXorByte(bytes[5])
                    .WriteXorByte(bytes[6])
                    .WriteSingle(this.TransportPosition.X)
                    .WriteXorByte(bytes[2]);

                    if (this.HaveTransportTime2)
                    {
                        Writer.WriteUInt32(this.TransportTime2);
                    }

                    Writer
                    .WriteSByte(this.TransportSeat)
                    .WriteXorByte(bytes[3])
                    .WriteSingle(this.TransportPosition.Y)
                    .WriteSingle(this.TransportFacing)
                    .WriteXorByte(bytes[7])
                    .WriteXorByte(bytes[0]);
                }
            }

            if (this.Living)
            {
                if (this.HaveSpline2)
                {
                    if (this.HaveSpline)
                    {
                        foreach (var point in this.Spline.Points)
                        {
                            Writer.WriteSingle(point.Y).WriteSingle(point.X).WriteSingle(point.Z);
                        }

                        if (this.Spline.HaveDurationMultiplier)
                        {
                            Writer.WriteSingle(this.Spline.DurationMultiplier);
                        }

                        Writer.WriteSingle(this.Spline.UnknownFloat2);

                        if (this.Spline.SplineType == SplineType.FacingTarget)
                        {
                            fixed(byte *bytes = this.Spline.FacingTarget.Bytes)
                            {
                                Writer
                                .WriteXorByte(bytes[3])
                                .WriteXorByte(bytes[4])
                                .WriteXorByte(bytes[5])
                                .WriteXorByte(bytes[7])
                                .WriteXorByte(bytes[2])
                                .WriteXorByte(bytes[0])
                                .WriteXorByte(bytes[6])
                                .WriteXorByte(bytes[1]);
                            }
                        }

                        if (this.Spline.HaveUnknown1)
                        {
                            Writer.WriteUInt32(this.Spline.Unknown1);
                        }

                        Writer.WriteSingle(this.Spline.UnknownFloat3);
                        Writer.WriteUInt32(this.Spline.Unknown2);

                        if (this.Spline.SplineType == SplineType.FacingSpot)
                        {
                            Writer
                            .WriteSingle(this.Spline.FacingSpot.Y)
                            .WriteSingle(this.Spline.FacingSpot.Z)
                            .WriteSingle(this.Spline.FacingSpot.X);
                        }

                        Writer.WriteUInt32(this.Spline.CurrentTime);

                        if (this.Spline.SplineType == SplineType.FacingAngle)
                        {
                            Writer.WriteSingle(this.Spline.FacingAngle);
                        }
                    }

                    Writer
                    .WriteSingle(this.Spline.EndPoint.Z)
                    .WriteSingle(this.Spline.EndPoint.Y)
                    .WriteUInt32(this.Spline.FullTime)
                    .WriteSingle(this.Spline.EndPoint.X);
                }

                Writer.WriteSingle(this.Speeds[8]);

                // Transport Data
                if (this.HaveTransportData)
                {
                    fixed(byte *bytes = this.TransportGuid.Bytes)
                    {
                        Writer
                        .WriteXorByte(bytes[4])
                        .WriteSingle(this.TransportPosition.Z)
                        .WriteXorByte(bytes[7])
                        .WriteXorByte(bytes[5])
                        .WriteXorByte(bytes[1])
                        .WriteSingle(this.TransportPosition.X)
                        .WriteXorByte(bytes[3])
                        .WriteXorByte(bytes[6]);

                        if (this.HaveTransportTime3)
                        {
                            Writer.WriteUInt32(this.TransportTime3);
                        }

                        Writer
                        .WriteSingle(this.TransportPosition.Y)
                        .WriteSByte(this.TransportSeat)
                        .WriteSingle(this.TransportFacing);

                        if (this.HaveTransportTime2)
                        {
                            Writer.WriteUInt32(this.TransportTime2);
                        }

                        Writer
                        .WriteXorByte(bytes[2])
                        .WriteUInt32(this.TransportTime)
                        .WriteXorByte(bytes[0]);
                    }
                }

                Writer
                .WriteSingle(this.Speeds[7])
                .WriteSingle(this.Position.X);

                if (this.HavePitch)
                {
                    Writer.WriteSingle(this.Pitch);
                }

                // Fall Data
                if (this.HaveFallData)
                {
                    Writer.WriteUInt32(this.FallTime);
                    if (this.HaveFallDirection)
                    {
                        Writer
                        .WriteSingle(this.FallSinAngle)
                        .WriteSingle(this.FallHorizontalSpeed)
                        .WriteSingle(this.FallCosAngle);
                    }
                    Writer.WriteSingle(this.FallVerticalSpeed);
                }

                Writer
                .WriteXorByte(p_guid.Bytes[7])
                .WriteSingle(this.Speeds[4])
                .WriteXorByte(p_guid.Bytes[0])
                .WriteXorByte(p_guid.Bytes[5]);

                if (this.TimeStamp != 0)
                {
                    Writer.WriteUInt32(this.TimeStamp);
                }

                Writer
                .WriteSingle(this.Position.Z)
                .WriteSingle(this.Speeds[6])
                .WriteXorByte(p_guid.Bytes[1])
                .WriteSingle(this.Speeds[2])
                .WriteSingle(this.Speeds[5])
                .WriteSingle(this.Speeds[3])
                .WriteSingle(this.Speeds[0])
                .WriteXorByte(p_guid.Bytes[3])
                .WriteXorByte(p_guid.Bytes[4])
                .WriteXorByte(p_guid.Bytes[2])
                .WriteXorByte(p_guid.Bytes[6]);

                if (this.HaveSplineElevation)
                {
                    Writer.WriteSingle(this.SplineElevation);
                }

                Writer.WriteSingle(this.Position.Y);
                if (this.Orientation != 0.0f)
                {
                    Writer.WriteSingle(this.Orientation);
                }
                Writer.WriteSingle(this.Speeds[1]);
            }

            // floats here

            // transport time
            if (this.HaveTransportTime)
            {
                Writer.WriteUInt32(this.TransportTime);
            }

            // shorts here

            // go rotation?
            if (this.HaveGameObjectRotation)
            {
                Writer.WriteUInt64(this.GameObjectRotation.Pack());
            }

            // target guid?
            if (this.HaveAttackingTarget)
            {
                fixed(byte *bytes = this.AttackingTarget.Bytes)
                {
                    Writer
                    .WriteXorByte(bytes[3])
                    .WriteXorByte(bytes[5])
                    .WriteXorByte(bytes[0])
                    .WriteXorByte(bytes[7])
                    .WriteXorByte(bytes[2])
                    .WriteXorByte(bytes[4])
                    .WriteXorByte(bytes[6])
                    .WriteXorByte(bytes[1]);
                }
            }
        }
Exemple #6
0
        protected virtual void WriteElement(StreamHandler writer, MovementStatusElements element, MovementStatus status, byte[] guid, byte[] tguid)
        {
            if (element >= MovementStatusElements.GuidByte0 && element <= MovementStatusElements.GuidByte7)
            {
                WriteByteMask(writer, guid[element - MovementStatusElements.GuidByte0]);
                return;
            }

            if (element >= MovementStatusElements.TransportGuidByte0 &&
                element <= MovementStatusElements.TransportGuidByte7)
            {
                if (status.HaveTransportData)
                {
                    WriteByteMask(writer, tguid[element - MovementStatusElements.TransportGuidByte0]);
                }
                return;
            }

            if (element >= MovementStatusElements.GuidByte0_2 && element <= MovementStatusElements.GuidByte7_2)
            {
                WriteByteSeq(writer, guid[element - MovementStatusElements.GuidByte0_2]);
                return;
            }

            if (element >= MovementStatusElements.TransportGuidByte0_2 &&
                element <= MovementStatusElements.TransportGuidByte7_2)
            {
                if (status.HaveTransportData)
                {
                    WriteByteSeq(writer, tguid[element - MovementStatusElements.TransportGuidByte0_2]);
                }
                return;
            }

            switch (element)
            {
            case MovementStatusElements.Flags:
                writer.UnalignedWriteBit(status.Flags == 0);
                break;

            case MovementStatusElements.Flags_2:
                if (status.Flags != 0)
                {
                    writer.UnalignedWriteInt((uint)status.Flags, 30);
                }
                break;

            case MovementStatusElements.Flags2:
                writer.UnalignedWriteBit(status.Flags2 == 0);
                break;

            case MovementStatusElements.Flags2_2:
                if (status.Flags2 != 0)
                {
                    writer.UnalignedWriteInt((ushort)status.Flags2, 12);
                }
                break;

            case MovementStatusElements.Timestamp:
                writer.UnalignedWriteBit(status.TimeStamp == 0);
                break;

            case MovementStatusElements.Timestamp_2:
                if (status.TimeStamp != 0)
                {
                    writer.WriteUInt32(status.TimeStamp);
                }
                break;

            case MovementStatusElements.Pitch:
                writer.UnalignedWriteBit(!status.HavePitch);
                break;

            case MovementStatusElements.Pitch_2:
                if (status.HavePitch)
                {
                    writer.WriteSingle(status.Pitch);
                }
                break;

            case MovementStatusElements.HaveFallData:
                writer.UnalignedWriteBit(status.HaveFallData);
                break;

            case MovementStatusElements.HaveFallDirection:
                if (status.HaveFallData)
                {
                    writer.UnalignedWriteBit(status.HaveFallDirection);
                }
                break;

            case MovementStatusElements.HaveTransportData:
                writer.UnalignedWriteBit(status.HaveTransportData);
                break;

            case MovementStatusElements.TransportHaveTime2:
                if (status.HaveTransportData)
                {
                    writer.UnalignedWriteBit(status.HaveTransportTime2);
                }
                break;

            case MovementStatusElements.TransportHaveTime3:
                if (status.HaveTransportData)
                {
                    writer.UnalignedWriteBit(status.HaveTransportTime3);
                }
                break;

            case MovementStatusElements.HaveSpline:
                writer.UnalignedWriteBit(status.HaveSpline);
                break;

            case MovementStatusElements.HaveSpline2:
                writer.UnalignedWriteBit(status.HaveSpline2);
                break;

            case MovementStatusElements.SplineElev:
                writer.UnalignedWriteBit(!status.HaveSplineElevation);
                break;

            case MovementStatusElements.SplineElev_2:
                if (status.HaveSplineElevation)
                {
                    writer.WriteSingle(status.SplineElevation);
                }
                break;

            case MovementStatusElements.PositionX:
                writer.WriteSingle(status.Position.X);
                break;

            case MovementStatusElements.PositionY:
                writer.WriteSingle(status.Position.Y);
                break;

            case MovementStatusElements.PositionZ:
                writer.WriteSingle(status.Position.Z);
                break;

            case MovementStatusElements.PositionO:
                writer.UnalignedWriteBit(status.Orientation == 0.0f);
                break;

            case MovementStatusElements.PositionO_2:
                if (status.Orientation != 0.0f)
                {
                    writer.WriteSingle(status.Orientation);
                }
                break;

            case MovementStatusElements.FallTime:
                if (status.HaveFallData)
                {
                    writer.WriteUInt32(status.FallTime);
                }
                break;

            case MovementStatusElements.FallHorizontalSpeed:
                if (status.HaveFallDirection)
                {
                    writer.WriteSingle(status.FallHorizontalSpeed);
                }
                break;

            case MovementStatusElements.FallVerticalSpeed:
                if (status.HaveFallData)
                {
                    writer.WriteSingle(status.FallVerticalSpeed);
                }
                break;

            case MovementStatusElements.FallCosAngle:
                if (status.HaveFallDirection)
                {
                    writer.WriteSingle(status.FallCosAngle);
                }
                break;

            case MovementStatusElements.FallSinAngle:
                if (status.HaveFallDirection)
                {
                    writer.WriteSingle(status.FallSinAngle);
                }
                break;

            case MovementStatusElements.TransportSeat:
                if (status.HaveTransportData)
                {
                    writer.WriteSByte(status.TransportSeat);
                }
                break;

            case MovementStatusElements.TransportPositionO:
                if (status.HaveTransportData)
                {
                    writer.WriteSingle(status.TransportFacing);
                }
                break;

            case MovementStatusElements.TransportPositionX:
                if (status.HaveTransportData)
                {
                    writer.WriteSingle(status.TransportPosition.X);
                }
                break;

            case MovementStatusElements.TransportPositionY:
                if (status.HaveTransportData)
                {
                    writer.WriteSingle(status.TransportPosition.Y);
                }
                break;

            case MovementStatusElements.TransportPositionZ:
                if (status.HaveTransportData)
                {
                    writer.WriteSingle(status.TransportPosition.Z);
                }
                break;

            case MovementStatusElements.TransportTime:
                if (status.HaveTransportData)
                {
                    writer.WriteUInt32(status.TransportTime);
                }
                break;

            case MovementStatusElements.TransportTime2:
                if (status.HaveTransportTime2)
                {
                    writer.WriteUInt32(status.TransportTime2);
                }
                break;

            case MovementStatusElements.TransportTime3:
                if (status.HaveTransportTime3)
                {
                    writer.WriteUInt32(status.TransportTime3);
                }
                break;

            default:
                throw new InvalidOperationException("Unknown element: " + element);
            }
        }