Exemple #1
0
    void PacketBuilder::WriteCreate(const MoveSpline& move_spline, ByteBuffer& data)
    {
        // WriteClientStatus(mov,data);
        // data.append<float>(&mov.m_float_values[SpeedWalk], SpeedMaxCount);
        // if (mov.SplineEnabled())
        {
            MoveSplineFlag splineFlags = move_spline.splineflags;

            data << splineFlags.raw();

            if (splineFlags.final_angle)
            {
                data << move_spline.facing.angle;
            }
            else if (splineFlags.final_target)
            {
                data << move_spline.facing.target;
            }
            else if (splineFlags.final_point)
            {
                data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z;
            }

            data << move_spline.timePassed();
            data << move_spline.Duration();
            data << move_spline.GetId();

            uint32 nodes = move_spline.getPath().size();
            data << nodes;
            data.append<Vector3>(&move_spline.getPath()[0], nodes);
            data << (move_spline.isCyclic() ? Vector3::zero() : move_spline.FinalDestination());
        }
    }
    void PacketBuilder::WriteCommonMonsterMovePart(const MoveSpline& move_spline, WorldPacket& data)
    {
        MoveSplineFlag splineflags = move_spline.splineflags;

        if (move_spline.transportGuid)
        {
            //DEBUG_LOG("Setting transport opcode for %s", move_spline.transport->GetGuidStr().c_str());
            data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT);
            data << PackedGuid(move_spline.transportGuid);
            data << uint8(move_spline.transportSeat);
            data << uint8(0);
            data << (Vector3)move_spline.transportPos;
        }
        else
        {
            data << uint8(0);
            data << move_spline.spline.getPoint(move_spline.spline.first());
        }

        data << move_spline.GetId();

        switch(splineflags & MoveSplineFlag::Mask_Final_Facing)
        {
            default:
                data << uint8(MonsterMoveNormal);
                break;
            case MoveSplineFlag::Final_Target:
                data << uint8(MonsterMoveFacingTarget);
                data << move_spline.facing.target;
                break;
            case MoveSplineFlag::Final_Angle:
                data << uint8(MonsterMoveFacingAngle);
                data << NormalizeOrientation(move_spline.facing.angle);
                break;
            case MoveSplineFlag::Final_Point:
                data << uint8(MonsterMoveFacingSpot);
                data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z;
                break;
        }

        // add fake Enter_Cycle flag - needed for client-side cyclic movement (client will erase first spline vertex after first cycle done)
        splineflags.enter_cycle = move_spline.isCyclic();
        data << uint32(splineflags & ~MoveSplineFlag::Mask_No_Monster_Move);

        if (splineflags.animation)
        {
            data << splineflags.getAnimationId();
            data << move_spline.effect_start_time;
        }

        data << move_spline.Duration();

        if (splineflags.parabolic)
        {
            data << move_spline.vertical_acceleration;
            data << move_spline.effect_start_time;
        }
    }
    void PacketBuilder::WriteCreateData(MoveSpline const& moveSpline, ByteBuffer& data)
    {
        if (!moveSpline.Finalized())
        {
            MoveSplineFlag splineFlags = moveSpline.splineflags;

            if ((splineFlags & MoveSplineFlag::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration())
                data << moveSpline.vertical_acceleration;   // added in 3.1

            data << moveSpline.timePassed();

            if (splineFlags.final_angle)
                data << moveSpline.facing.angle;
            else if (splineFlags.final_target)
            {
                ObjectGuid facingGuid = moveSpline.facing.target;
                data.WriteByteSeq(facingGuid[5]);
                data.WriteByteSeq(facingGuid[3]);
                data.WriteByteSeq(facingGuid[7]);
                data.WriteByteSeq(facingGuid[1]);
                data.WriteByteSeq(facingGuid[6]);
                data.WriteByteSeq(facingGuid[4]);
                data.WriteByteSeq(facingGuid[2]);
                data.WriteByteSeq(facingGuid[0]);
            }

            uint32 nodes = moveSpline.getPath().size();
            for (uint32 i = 0; i < nodes; ++i)
            {
                data << float(moveSpline.getPath()[i].z);
                data << float(moveSpline.getPath()[i].x);
                data << float(moveSpline.getPath()[i].y);
            }

            if (splineFlags.final_point)
                data << moveSpline.facing.f.x << moveSpline.facing.f.z << moveSpline.facing.f.y;

            data << float(1.f);                             // splineInfo.duration_mod_next; added in 3.1
            data << moveSpline.Duration();
            if (splineFlags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation))
                data << moveSpline.effect_start_time;       // added in 3.1

            data << float(1.f);                             // splineInfo.duration_mod; added in 3.1
        }

        if (!moveSpline.isCyclic())
        {
            Vector3 dest = moveSpline.FinalDestination();
            data << float(dest.z);
            data << float(dest.x);
            data << float(dest.y);
        }
        else
            data << Vector3::zero();

        data << moveSpline.GetId();
    }
    void PacketBuilder::WriteCommonMonsterMovePart(const MoveSpline& move_spline, WorldPacket& data)
    {
        MoveSplineFlag splineflags = move_spline.splineflags;
        /*if(unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
        {
            data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT);
            if(unit->GetVehicle())
                data << unit->GetVehicle()->GetBase()->GetPackGUID();
            else if(unit->GetTransport())
                data << unit->GetTransport()->GetPackGUID();
            else
                data << uint64(0);

            data << int8(unit->GetTransSeat());
        }*/

        data << uint8(0);
        data << move_spline.spline.getPoint(move_spline.spline.first());
        data << move_spline.GetId();

        switch(splineflags & MoveSplineFlag::Mask_Final_Facing)
        {
            case MoveSplineFlag::Final_Target:
                data << uint8(MonsterMoveFacingTarget);
                data << move_spline.facing.target;
                break;
            case MoveSplineFlag::Final_Angle:
                data << uint8(MonsterMoveFacingAngle);
                data << move_spline.facing.angle;
                break;
            case MoveSplineFlag::Final_Point:
                data << uint8(MonsterMoveFacingSpot);
                data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z;
                break;
            default:
                data << uint8(MonsterMoveNormal);
                break;
        }

        // add fake Enter_Cycle flag - needed for client-side cyclic movement (client will erase first spline vertex after first cycle done)
        splineflags.enter_cycle = move_spline.isCyclic();
        data << uint32(splineflags & ~MoveSplineFlag::Mask_No_Monster_Move);

        if(splineflags.animation)
        {
            data << splineflags.getAnimationId();
            data << move_spline.effect_start_time;
        }

        data << move_spline.Duration();

        if(splineflags.parabolic)
        {
            data << move_spline.vertical_acceleration;
            data << move_spline.effect_start_time;
        }
    }
    void PacketBuilder::WriteCreateBytes(const MoveSpline& move_spline, ByteBuffer& data)
    {
        if (!move_spline.Finalized())
        {
            MoveSplineFlag splineFlags = move_spline.splineflags;
            uint32 nodes = move_spline.getPath().size();
            bool hasSplineStartTime = move_spline.splineflags & (MoveSplineFlag::Trajectory | MoveSplineFlag::Animation);
            bool hasSplineVerticalAcceleration = (move_spline.splineflags & MoveSplineFlag::Trajectory) && move_spline.effect_start_time < move_spline.Duration();

            if (hasSplineVerticalAcceleration)
                data << float(move_spline.vertical_acceleration);   // added in 3.1

            data << int32(move_spline.timePassed());

            if (move_spline.splineflags & MoveSplineFlag::Final_Angle)
                data << float(NormalizeOrientation(move_spline.facing.angle));
            else if (move_spline.splineflags & MoveSplineFlag::Final_Target)
                 data.WriteGuidBytes<5, 3, 7, 1, 6, 4, 2, 0>(ObjectGuid(move_spline.facing.target));

            for (uint32 i = 0; i < nodes; ++i)
            {
                data << float(move_spline.getPath()[i].z);
                data << float(move_spline.getPath()[i].x);
                data << float(move_spline.getPath()[i].y);
            }

            if (move_spline.splineflags & MoveSplineFlag::Final_Point)
                data << float(move_spline.facing.f.x) << float(move_spline.facing.f.z) << float(move_spline.facing.f.y);

            data << float(1.f);
            data << int32(move_spline.Duration());
            if (hasSplineStartTime)
                data << int32(move_spline.effect_start_time);   // added in 3.1

            data << float(1.f);
        }

        if (!move_spline.isCyclic())
        {
            Vector3 dest = move_spline.FinalDestination();
            data << float(dest.z);
            data << float(dest.x);
            data << float(dest.y);
        }
        else
            data << Vector3::zero();

        data << uint32(move_spline.GetId());
    }
    void PacketBuilder::WriteCreateData(MoveSpline const& moveSpline, ByteBuffer& data, Unit* unit)
    {
        if (!moveSpline.Finalized())
        {
            MoveSplineFlag splineFlags = moveSpline.splineflags;
            uint8 splineType = 0;

            if (splineFlags.final_point)
                splineType = 2;
            else if (splineFlags.final_angle)
                splineType = 4;
            else if ((splineFlags & MoveSplineFlag::Mask_Final_Facing) == MoveSplineFlag::Final_Target)
                splineType = MonsterMoveFacingTarget;

            data << uint8(splineType);
            data << float(1.f);                             // splineInfo.duration_mod; added in 3.1

            uint32 nodes = moveSpline.getPath().size();
            for (uint32 i = 0; i < nodes; ++i)
            {
                data << float(moveSpline.getPath()[i].z);
                data << float(moveSpline.getPath()[i].x);
                data << float(moveSpline.getPath()[i].y);
            }

            data << float(1.f);                             // splineInfo.duration_mod_next; added in 3.1

            if (splineFlags.final_point)
                data << moveSpline.facing.f.z << moveSpline.facing.f.y << moveSpline.facing.f.x;

            if (splineFlags.final_angle)
                data << moveSpline.facing.angle;

            if ((splineFlags & MoveSplineFlag::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration())
                data << moveSpline.vertical_acceleration;   // added in 3.1

            if (splineFlags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation))
                data << moveSpline.effect_start_time;       // added in 3.1

            data << moveSpline.timePassed();
            data << moveSpline.Duration();
        }

        data << uint32(moveSpline.GetId());
        data << float(unit->GetPositionZ());
        data << float(unit->GetPositionX());
        data << float(unit->GetPositionY());
    }
    void PacketBuilder::WriteCreateData(MoveSpline const& moveSpline, ByteBuffer& data)
    {
        if (!moveSpline.Finalized())
        {
            MoveSplineFlag const& splineFlags = moveSpline.splineflags;
            MonsterMoveType type = GetMonsterMoveType(moveSpline);

            data << moveSpline.timePassed();
            data << float(1.f);                             // splineInfo.duration_mod_next; added in 3.1
            data << float(1.f);                             // splineInfo.duration_mod; added in 3.1

            uint32 nodes = moveSpline.getPath().size();
            for (uint32 i = 0; i < nodes; ++i)
            {
                data << float(moveSpline.getPath()[i].x);
                data << float(moveSpline.getPath()[i].z);
                data << float(moveSpline.getPath()[i].y);
            }

            if (splineFlags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation))
                data << moveSpline.effect_start_time;       // added in 3.1

            data << uint8(type);

            if (type == MonsterMoveFacingAngle)
                data << float(moveSpline.facing.angle);

            if (type == MonsterMoveFacingPoint)
                data << moveSpline.facing.f.x << moveSpline.facing.f.z << moveSpline.facing.f.y;

            if ((splineFlags & MoveSplineFlag::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration())
                data << float(moveSpline.vertical_acceleration);   // added in 3.1

            //    NYI block here
            data << moveSpline.Duration();

        }

        Vector3 destination = moveSpline.isCyclic() ? Vector3::zero() : moveSpline.FinalDestination();

        data << float(destination.x);
        data << float(destination.z);
        data << moveSpline.GetId();
        data << float(destination.y);

    }
    void PacketBuilder::WriteCommonMonsterMovePart(const MoveSpline& move_spline, WorldPacket& data)
    {
        MoveSplineFlag splineflags = move_spline.splineflags;

        data << uint8(0);                                       // sets/unsets MOVEMENTFLAG2_UNK7 (0x40)
        data << move_spline.spline.getPoint(move_spline.spline.first());
        data << move_spline.GetId();

        switch (splineflags & MoveSplineFlag::Mask_Final_Facing)
        {
            case MoveSplineFlag::Final_Target:
                data << uint8(MonsterMoveFacingTarget);
                data << move_spline.facing.target;
                break;
            case MoveSplineFlag::Final_Angle:
                data << uint8(MonsterMoveFacingAngle);
                data << move_spline.facing.angle;
                break;
            case MoveSplineFlag::Final_Point:
                data << uint8(MonsterMoveFacingSpot);
                data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z;
                break;
            default:
                data << uint8(MonsterMoveNormal);
                break;
        }

        // add fake Enter_Cycle flag - needed for client-side cyclic movement (client will erase first spline vertex after first cycle done)
        splineflags.enter_cycle = move_spline.isCyclic();
        data << uint32(splineflags & uint32(~MoveSplineFlag::Mask_No_Monster_Move));

        if (splineflags.animation)
        {
            data << splineflags.getAnimationId();
            data << move_spline.effect_start_time;
        }

        data << move_spline.Duration();

        if (splineflags.parabolic)
        {
            data << move_spline.vertical_acceleration;
            data << move_spline.effect_start_time;
        }
    }
    void PacketBuilder::WriteData(const MoveSpline& move_spline, ByteBuffer& data)
    {
        MoveSplineFlag splineFlags = move_spline.splineflags;
        uint32 nodes = move_spline.getPath().size();

        data << move_spline.timePassed();

        if (splineFlags.orientationFixed)
            data << move_spline.facing.angle;

        if (splineFlags.final_target)
        {
            uint64 Guid = move_spline.facing.target;

            uint8 guidBytes[] = { 5, 3, 7, 1, 6, 4, 2, 0 };
            data.WriteGuidBytes(Guid, guidBytes, 8, 0);
        }

        for (uint32 i = 0; i < nodes; i++)
        {
            data << move_spline.getPath()[0].z;
            data << move_spline.getPath()[0].x;
            data << move_spline.getPath()[0].y;
        }

        if(splineFlags.flying)
            data << move_spline.facing.f.x << move_spline.facing.f.z << move_spline.facing.f.y;

        data << float(1.f);
        data << uint32(0);

        data << move_spline.effect_start_time;

        data << float(1.f);

        data << move_spline.FinalDestination().z;
        data << move_spline.FinalDestination().x;
        data << move_spline.FinalDestination().y;
        data << move_spline.GetId();
    }
Exemple #10
0
    void PacketBuilder::WriteCommonMonsterMovePart(const MoveSpline& move_spline, WorldPacket& data)
    {
        MoveSplineFlag splineflags = move_spline.splineflags;

        /*if (mov.IsBoarded())
        {
            data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT);
            data << mov.GetTransport()->Owner.GetPackGUID();
        }*/

        data << move_spline.spline.getPoint(move_spline.spline.first());
        data << move_spline.GetId();

        switch (splineflags & MoveSplineFlag::Mask_Final_Facing)
        {
            default:
                data << uint8(MonsterMoveNormal);
                break;
            case MoveSplineFlag::Final_Target:
                data << uint8(MonsterMoveFacingTarget);
                data << move_spline.facing.target;
                break;
            case MoveSplineFlag::Final_Angle:
                data << uint8(MonsterMoveFacingAngle);
                data << move_spline.facing.angle;
                break;
            case MoveSplineFlag::Final_Point:
                data << uint8(MonsterMoveFacingSpot);
                data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z;
                break;
        }

        // add fake Enter_Cycle flag - needed for client-side cyclic movement (client will erase first spline vertex after first cycle done)
        splineflags.enter_cycle = move_spline.isCyclic();
        // add fake Runmode flag - client has strange issues without that flag
        data << uint32(splineflags & ~MoveSplineFlag::Mask_No_Monster_Move | MoveSplineFlag::Runmode);
        data << move_spline.Duration();
    }
    void PacketBuilder::WriteMonsterMove(const MoveSpline& moveSpline, WorldPacket& data, Unit* unit)
    {
        ObjectGuid guid = unit->GetGUID();
        ObjectGuid transport = unit->GetTransGUID();
        MonsterMoveType type = GetMonsterMoveType(moveSpline);
        G3D::Vector3 const& firstPoint = moveSpline.spline.getPoint(moveSpline.spline.first());

        data << float(firstPoint.z);
        data << float(firstPoint.x);
        data << uint32(moveSpline.GetId());
        data << float(firstPoint.y);
        data << float(0.f); // Most likely transport Y
        data << float(0.f); // Most likely transport Z
        data << float(0.f); // Most likely transport X

        data.WriteBit(1); // Parabolic speed // esi+4Ch
        data.WriteBit(guid[0]);
        data.WriteBits(type, 3);

        if (type == MonsterMoveFacingTarget)
        {
            ObjectGuid targetGuid = moveSpline.facing.target;
            data.WriteBit(targetGuid[6]);
            data.WriteBit(targetGuid[4]);
            data.WriteBit(targetGuid[3]);
            data.WriteBit(targetGuid[0]);
            data.WriteBit(targetGuid[5]);
            data.WriteBit(targetGuid[7]);
            data.WriteBit(targetGuid[1]);
            data.WriteBit(targetGuid[2]);
        }

        data.WriteBit(1);
        data.WriteBit(1);
        data.WriteBit(1);

        uint32 uncompressedSplineCount = moveSpline.splineflags & MoveSplineFlag::UncompressedPath ? moveSpline.splineflags.cyclic ? moveSpline.spline.getPointCount() - 3 : moveSpline.spline.getPointCount() - 2 : 1;
        data.WriteBits(uncompressedSplineCount,  20);

        data.WriteBit(!moveSpline.splineflags.raw());
        data.WriteBit(guid[3]);
        data.WriteBit(1);
        data.WriteBit(1);
        data.WriteBit(1);
        data.WriteBit(!moveSpline.Duration());
        data.WriteBit(guid[7]);
        data.WriteBit(guid[4]);
        data.WriteBit(1);
        data.WriteBit(guid[5]);

        int32 compressedSplineCount = moveSpline.splineflags & MoveSplineFlag::UncompressedPath ? 0 : moveSpline.spline.getPointCount() - 3;
        data.WriteBits(compressedSplineCount, 22); // WP count

        data.WriteBit(guid[6]);
        data.WriteBit(0); // Fake bit

        data.WriteBit(transport[7]);
        data.WriteBit(transport[1]);
        data.WriteBit(transport[3]);
        data.WriteBit(transport[0]);
        data.WriteBit(transport[6]);
        data.WriteBit(transport[4]);
        data.WriteBit(transport[5]);
        data.WriteBit(transport[2]);

        data.WriteBit(0); // Send no block
        data.WriteBit(0);
        data.WriteBit(guid[2]);
        data.WriteBit(guid[1]);

        data.FlushBits();

        if (compressedSplineCount)
            WriteLinearPath(moveSpline.spline, data);

        data.WriteByteSeq(guid[1]);
        data.WriteByteSeq(transport[6]);
        data.WriteByteSeq(transport[4]);
        data.WriteByteSeq(transport[1]);
        data.WriteByteSeq(transport[7]);
        data.WriteByteSeq(transport[0]);
        data.WriteByteSeq(transport[3]);
        data.WriteByteSeq(transport[5]);
        data.WriteByteSeq(transport[2]);

        if (moveSpline.splineflags & MoveSplineFlag::UncompressedPath)
        {
            if (moveSpline.splineflags.cyclic)
                WriteUncompressedCyclicPath(moveSpline.spline, data);
            else
                WriteUncompressedPath(moveSpline.spline, data);
        }
        else
        {
            G3D::Vector3 const& point = moveSpline.spline.getPoint(moveSpline.spline.getPointCount() - 2);
            data << point.y << point.x << point.z;
        }

        if (type == MonsterMoveFacingTarget)
        {
            ObjectGuid targetGuid = moveSpline.facing.target;
            data.WriteByteSeq(targetGuid[5]);
            data.WriteByteSeq(targetGuid[7]);
            data.WriteByteSeq(targetGuid[0]);
            data.WriteByteSeq(targetGuid[4]);
            data.WriteByteSeq(targetGuid[3]);
            data.WriteByteSeq(targetGuid[2]);
            data.WriteByteSeq(targetGuid[6]);
            data.WriteByteSeq(targetGuid[1]);
        }

        data.WriteByteSeq(guid[5]);

        if (type == MonsterMoveFacingAngle)
            data << float(moveSpline.facing.angle);

        data.WriteByteSeq(guid[3]);

        if (moveSpline.splineflags.raw())
            data << uint32(moveSpline.splineflags.raw());

        data.WriteByteSeq(guid[6]);

        if (type == MonsterMoveFacingPoint)
            data << moveSpline.facing.f.x << moveSpline.facing.f.y << moveSpline.facing.f.z;

        data.WriteByteSeq(guid[0]);
        data.WriteByteSeq(guid[7]);
        data.WriteByteSeq(guid[2]);
        data.WriteByteSeq(guid[4]);

        if (moveSpline.Duration())
            data << uint32(moveSpline.Duration());
    }
	void PacketBuilder::WriteMonsterMove(const MoveSpline& move_spline, WorldPacket& data)
	{
		ObjectGuid moverGuid;
		ObjectGuid transportGuid;
		MoveSplineFlag splineflags = move_spline.splineflags;
		G3D::Vector3 const& firstPoint = move_spline.spline.getPoint(move_spline.spline.first());

		uint8 splineType = 0;

		switch (splineflags & MoveSplineFlag::Mask_Final_Facing)
		{
		case MoveSplineFlag::Final_Target:
			splineType = MonsterMoveFacingTarget;
			break;
		case MoveSplineFlag::Final_Angle:
			splineType = MonsterMoveFacingAngle;
			break;
		case MoveSplineFlag::Final_Point:
			splineType = MonsterMoveFacingSpot;
			break;
		default:
			splineType = MonsterMoveNormal;
			break;
		}

		data << float(firstPoint.z);
		data << float(firstPoint.x);
		data << uint32(move_spline.GetId());
		data << float(firstPoint.y);
		data << float(0.f); // Most likely transport Y
		data << float(0.f); // Most likely transport Z
		data << float(0.f); // Most likely transport X

		data.WriteBit(1); // Parabolic speed 21
		data.WriteBit(moverGuid[0]); // 32
		data.WriteBits(splineType, 3); // 68

		if (splineType == MonsterMoveFacingTarget)
		{
			ObjectGuid targetGuid = move_spline.facing.target;

			data.WriteBit(targetGuid[6]); // 190
			data.WriteBit(targetGuid[4]); // 188
			data.WriteBit(targetGuid[3]); // 187
			data.WriteBit(targetGuid[0]); // 184
			data.WriteBit(targetGuid[5]); // 189
			data.WriteBit(targetGuid[7]); // 191
			data.WriteBit(targetGuid[1]); // 185
			data.WriteBit(targetGuid[2]); // 186
		}

		data.WriteBit(1); // 19
		data.WriteBit(1); // 69
		data.WriteBit(1); // 120

		uint32 uncompressedSplineCount = move_spline.splineflags & MoveSplineFlag::UncompressedPath ? move_spline.splineflags.cyclic ? move_spline.spline.getPointCount() - 2 : move_spline.spline.getPointCount() - 3 : 1;
		data.WriteBits(uncompressedSplineCount, 20);

		data.WriteBit(!move_spline.splineflags.raw()); // 16
		data.WriteBit(moverGuid[3]); // 35
		data.WriteBit(1); // 108
		data.WriteBit(1); // 22
		data.WriteBit(1); // 109

		data.WriteBit(!move_spline.Duration()); // 20
		data.WriteBit(moverGuid[7]); // 39
		data.WriteBit(moverGuid[4]); // 36
		data.WriteBit(1); // 18
		data.WriteBit(moverGuid[5]); // 37

		int32 compressedSplineCount = move_spline.splineflags & MoveSplineFlag::UncompressedPath ? 0 : move_spline.spline.getPointCount() - 3;
		data.WriteBits(compressedSplineCount, 22); // WP count

		data.WriteBit(moverGuid[6]); // 38

		data.WriteBit(0); // unk

		data.WriteBit(transportGuid[7]); // 119
		data.WriteBit(transportGuid[1]); // 113
		data.WriteBit(transportGuid[3]); // 115
		data.WriteBit(transportGuid[0]); // 112
		data.WriteBit(transportGuid[6]); // 118
		data.WriteBit(transportGuid[4]); // 116
		data.WriteBit(transportGuid[5]); // 117
		data.WriteBit(transportGuid[2]); // 114

		data.WriteBit(0); // 176 unk
		data.WriteBit(0); // 56 unk

		data.WriteBit(moverGuid[2]); // 34
		data.WriteBit(moverGuid[1]); // 33

		data.FlushBits();

		if (compressedSplineCount)
			WriteLinearPath(move_spline.spline, data);

		data.WriteByteSeq(moverGuid[1]);

		data.WriteByteSeq(transportGuid[6]); // 118
		data.WriteByteSeq(transportGuid[4]); // 116
		data.WriteByteSeq(transportGuid[1]); // 113
		data.WriteByteSeq(transportGuid[7]); // 119
		data.WriteByteSeq(transportGuid[0]); // 112
		data.WriteByteSeq(transportGuid[3]); // 115
		data.WriteByteSeq(transportGuid[5]); // 117
		data.WriteByteSeq(transportGuid[2]); // 114

		if (splineflags & MoveSplineFlag::UncompressedPath)
		{
			if (splineflags.cyclic)
				WriteCatmullRomCyclicPath(move_spline.spline, data);
			else
				WriteCatmullRomPath(move_spline.spline, data);
		}
		else
		{
			G3D::Vector3 const& point = move_spline.spline.getPoint(move_spline.spline.getPointCount() - 2);
			data << point.y << point.x << point.z;
		}
		
		if (splineType == MonsterMoveFacingTarget)
		{
			ObjectGuid targetGuid = move_spline.facing.target;

			data.WriteByteSeq(targetGuid[5]); // 189
			data.WriteByteSeq(targetGuid[7]); // 191
			data.WriteByteSeq(targetGuid[0]); // 184
			data.WriteByteSeq(targetGuid[4]); // 188
			data.WriteByteSeq(targetGuid[3]); // 187
			data.WriteByteSeq(targetGuid[2]); // 186
			data.WriteByteSeq(targetGuid[6]); // 190
			data.WriteByteSeq(targetGuid[1]); // 185
		}

		data.WriteByteSeq(moverGuid[5]); // 37

		if (splineType == MonsterMoveFacingAngle)
			data << float(move_spline.facing.angle); // 45

		data.WriteByteSeq(moverGuid[3]); // 35

		data.WriteBit(0);                // 16

		if (move_spline.splineflags.raw())
			data << uint32(move_spline.splineflags.raw()); // 69

		data.WriteByteSeq(moverGuid[6]); // 38

		if (splineType == MonsterMoveFacingSpot)
			data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z;

		data.WriteByteSeq(moverGuid[0]); // 32
		data.WriteByteSeq(moverGuid[7]); // 39
		data.WriteByteSeq(moverGuid[2]); // 34
		data.WriteByteSeq(moverGuid[4]); // 36

		if (move_spline.Duration())
			data << uint32(move_spline.Duration());
    }
    void PacketBuilder::WriteCreateData(MoveSpline const& moveSpline, ByteBuffer& data, Unit* unit)
    {
        if (/*!moveSpline.Finalized()*/true)
        {
            MoveSplineFlag splineFlags = moveSpline.splineflags;

            uint8 splineType = 0;
            switch (splineFlags & MoveSplineFlag::Mask_Final_Facing)
            {
                case MoveSplineFlag::Final_Target:
                    splineType = MonsterMoveFacingTarget;
                    break;
                case MoveSplineFlag::Final_Angle:
                    splineType = MonsterMoveFacingAngle;
                    break;
                case MoveSplineFlag::Final_Point:
                    splineType = MonsterMoveFacingSpot;
                    break;
                default:
                    splineType = MonsterMoveNormal;
                    break;
            }

            data << float(1.0f);                             // splineInfo.duration_mod_next; added in 3.1
            uint32 nodes = moveSpline.getPath().size();
            for (uint32 i = 0; i < nodes; ++i)
            {
                data << float(moveSpline.getPath()[i].z);
                data << float(moveSpline.getPath()[i].y);
                data << float(moveSpline.getPath()[i].x);
            }

            data << uint8(splineType);
            data << float(1.0f);                             // splineInfo.duration_mod; added in 3.1

            if (splineFlags.final_point)
                data << moveSpline.facing.f.x << moveSpline.facing.f.y << moveSpline.facing.f.z;

            if (splineFlags.parabolic)
                data << moveSpline.vertical_acceleration;   // added in 3.1

            if (splineFlags.final_angle)
                data << moveSpline.facing.angle;

            data << moveSpline.Duration();

            if (splineFlags.parabolic || splineFlags.animation)
                data << moveSpline.effect_start_time;       // added in 3.1

            data << moveSpline.timePassed();
        }

        if (!moveSpline.isCyclic())
        {
            Vector3 dest = moveSpline.FinalDestination();
            data << moveSpline.GetId();
            data << float(dest.x);
            data << float(dest.y);
            data << float(dest.z);
        }
        else
        {
            data << moveSpline.GetId();
            data << float(0.0f);
            data << float(0.0f);
            data << float(0.0f);
        }
    }