Example #1
0
    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::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::WriteCreateBits(MoveSpline const& moveSpline, ByteBuffer& data)
    {
        if (!data.WriteBit(!moveSpline.Finalized()))
            return;

        data.WriteBit(moveSpline.splineflags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation)); //   hasSplineStartTime = packet.ReadBit();
		data.WriteBit((moveSpline.splineflags & MoveSplineFlag::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration());
		data.WriteBit(0); // unk
		data.WriteBits(moveSpline.getPath().size(), 25); // splineCount = packet.ReadBits("Spline Waypoints", 22, index);
        data.WriteBits(uint8(moveSpline.spline.mode()), 2); // packet.ReadEnum<SplineMode>("Spline Mode", 2, index);
        data.WriteBits(moveSpline.splineflags.raw(), 20); // packet.ReadEnum<SplineFlag434>("Spline flags", 20, index);
    }
    void PacketBuilder::WriteCreateBits(MoveSpline const& moveSpline, ByteBuffer& data)
    {
        if (!data.WriteBit(!moveSpline.Finalized()))
            return;

        data.WriteBit(moveSpline.splineflags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation));
        data.WriteBit((moveSpline.splineflags & MoveSplineFlag::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration());
        data.WriteBit(0); // NYI Block
        data.WriteBits(moveSpline.getPath().size(), 20);
        data.WriteBits(moveSpline.spline.mode(), 2);
        data.WriteBits(moveSpline.splineflags.raw(), 25);
    }
    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::WriteCreateBits(MoveSpline const& moveSpline, ByteBuffer& data)
    {
        data.WriteBits(uint8(moveSpline.spline.mode()), 2);
        data.WriteBit(moveSpline.splineflags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation));
        data.WriteBits(moveSpline.getPath().size(), 22);
        switch (moveSpline.splineflags & MoveSplineFlag::Mask_Final_Facing)
        {
            case MoveSplineFlag::Final_Target:
            {
                uint64 targetGuid = moveSpline.facing.target;
                data.WriteBits(2, 2);
                uint8 guidMask[] = { 4, 3, 7, 2, 6, 1, 0, 5 };
                data.WriteGuidMask(moveSpline.facing.target, guidMask, 8, 0);
                break;
            }
            case MoveSplineFlag::Final_Angle:
                data.WriteBits(0, 2);
                break;
            case MoveSplineFlag::Final_Point:
                data.WriteBits(1, 2);
                break;
            default:
                data.WriteBits(3, 2);
                break;
        }

        data.WriteBit((moveSpline.splineflags & MoveSplineFlag::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration());
        data.WriteBits(moveSpline.splineflags.raw(), 25);
    }
    void PacketBuilder::WriteCreateBits(MoveSpline const& moveSpline, ByteBuffer& data)
    {
        data.WriteBits(uint8(moveSpline.spline.mode()), 2);
        data.WriteBit(moveSpline.splineflags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation));
        data.WriteBits(moveSpline.getPath().size(), 22);
        switch (moveSpline.splineflags & MoveSplineFlag::Mask_Final_Facing)
        {
            case MoveSplineFlag::Final_Target:
            {
                ObjectGuid targetGuid = moveSpline.facing.target;
                data.WriteBits(2, 2);
                data.WriteBit(targetGuid[4]);
                data.WriteBit(targetGuid[3]);
                data.WriteBit(targetGuid[7]);
                data.WriteBit(targetGuid[2]);
                data.WriteBit(targetGuid[6]);
                data.WriteBit(targetGuid[1]);
                data.WriteBit(targetGuid[0]);
                data.WriteBit(targetGuid[5]);
                break;
            }
            case MoveSplineFlag::Final_Angle:
                data.WriteBits(0, 2);
                break;
            case MoveSplineFlag::Final_Point:
                data.WriteBits(1, 2);
                break;
            default:
                data.WriteBits(3, 2);
                break;
        }

        data.WriteBit((moveSpline.splineflags & MoveSplineFlag::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration());
        data.WriteBits(moveSpline.splineflags.raw(), 25);
    }
Example #8
0
 void PacketBuilder::WriteCatmullRomPath(const MoveSpline& move_spline, ByteBuffer& data)
 {
     const Spline<int32> spline = move_spline._Spline();
     uint32 count = spline.getPointCount() - 3;
     data << count;
     for (uint32 i = 0; i < count; ++i)
         data << CalcTransportOffset(move_spline, spline.getPoint(2 + i));
 }
    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;
        }
    }
Example #10
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());
        }
    }
Example #11
0
 void PacketBuilder::WriteCatmullRomCyclicPath(const MoveSpline& move_spline, ByteBuffer& data)
 {
     const Spline<int32> spline = move_spline._Spline();
     uint32 count = spline.getPointCount() - 3;
     data << uint32(count + 1);
     data << spline.getPoint(1); // fake point, client will erase it from the spline after first cycle done
     for (uint32 i = 0; i < count; ++i)
         data << CalcTransportOffset(move_spline, spline.getPoint(1 + i));
 }
Example #12
0
    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::WriteCreateBits(MoveSpline const& moveSpline, ByteBuffer& data)
    {
        ASSERT(!moveSpline.Finalized());

        MoveSplineFlag flags = moveSpline.splineflags;

        data.WriteBit(true);
        data.WriteBit(flags.parabolic || flags.animation);
        data.WriteBits(uint8(moveSpline.spline.mode()), 2);
        data.WriteBits(moveSpline.getPath().size(), 20);
        data.WriteBits(flags.raw(), 25);
        data.WriteBit(flags.parabolic);
        data.WriteBit(false);
        if (false)
        {
            data.WriteBits(0, 2);
            data.WriteBits(0, 21);
        }
    }
    void PacketBuilder::WriteFacingTargetPart(MoveSpline const& moveSpline, ByteBuffer& data)
    {
        if (GetMonsterMoveType(moveSpline) == MonsterMoveFacingTarget && !moveSpline.Finalized())
        {
            ObjectGuid facingGuid = moveSpline.facing.target;
            data.WriteGuidMask(facingGuid, 4, 7, 0, 5, 1, 2, 3, 6);

            data.WriteGuidBytes(facingGuid, 4, 2, 0, 5, 6, 3, 1, 7);
        }
    }
    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::WriteCreateBits(MoveSpline const& moveSpline, ByteBuffer& data)
    {
        if (!data.WriteBit(!moveSpline.Finalized()))
            return;

        data.WriteBit(moveSpline.splineflags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation)); //   hasSplineStartTime = packet.ReadBit();

        data.WriteBits(uint8(moveSpline.spline.mode()), 2); // packet.ReadEnum<SplineMode>("Spline Mode", 2, index);
        data.WriteBits(moveSpline.splineflags.raw(), 20); // packet.ReadEnum<SplineFlag434>("Spline flags", 20, index);
        data.WriteBit(0); // unk
        data.WriteBits(moveSpline.getPath().size(), 25); // splineCount = packet.ReadBits("Spline Waypoints", 22, index);
        data.WriteBit((moveSpline.splineflags & MoveSplineFlag::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration());

        /*switch (moveSpline.splineflags & MoveSplineFlag::Mask_Final_Facing)
        {
            case MoveSplineFlag::Final_Target:
            {
                ObjectGuid targetGuid = moveSpline.facing.target;
                data.WriteBits(0, 2);
                data.WriteBit(targetGuid[4]);
                data.WriteBit(targetGuid[5]);
                data.WriteBit(targetGuid[0]);
                data.WriteBit(targetGuid[7]);
                data.WriteBit(targetGuid[1]);
                data.WriteBit(targetGuid[3]);
                data.WriteBit(targetGuid[2]);
                data.WriteBit(targetGuid[6]);
                break;
            }
            case MoveSplineFlag::Final_Angle:
                data.WriteBits(3, 2);
                break;
            case MoveSplineFlag::Final_Point:
                data.WriteBits(1, 2);
                break;
            default:
                data.WriteBits(2, 2);
                break;
        }*/
    }
    void PacketBuilder::WriteCreateGuid(MoveSpline const& moveSpline, ByteBuffer& data)
    {
        if (!moveSpline.Finalized() && (moveSpline.splineflags & MoveSplineFlag::Mask_Final_Facing == MoveSplineFlag::Final_Target))
        {
            ObjectGuid facingGuid = moveSpline.facing.target;

            uint8 bitOrder[8] = { 4, 7, 0, 5, 1, 2, 3, 6 };
            data.WriteBitInOrder(facingGuid, bitOrder);

            uint8 byteOrder[8] = { 4, 2, 0, 5, 6, 3, 1, 7 };
            data.WriteBytesSeq(facingGuid, byteOrder);
        }
    }
Example #18
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();
    }
Example #19
0
    void PacketBuilder::WriteCreateBits(const MoveSpline& move_spline, ByteBuffer& data)
    {
        if (!data.WriteBit(!move_spline.Finalized()))
            return;

        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();

        data.WriteBits(uint8(move_spline.spline.mode()), 2);
        data.WriteBit(hasSplineStartTime);
        data.WriteBits(nodes, 22);

        switch (move_spline.splineflags & MoveSplineFlag::Mask_Final_Facing)
        {
            case MoveSplineFlag::Final_Target:
            {
                data.WriteBits(2, 2);

                data.WriteGuidMask<4, 3, 7, 2, 6, 1, 0, 5>(ObjectGuid(move_spline.facing.target));
                break;
            }
            case MoveSplineFlag::Final_Angle:
                data.WriteBits(0, 2);
                break;
            case MoveSplineFlag::Final_Point:
                data.WriteBits(1, 2);
                break;
            default:
                data.WriteBits(3, 2);
                break;
        }

        data.WriteBit(hasSplineVerticalAcceleration);
        data.WriteBits(move_spline.splineflags.raw(), 25);
    }
Example #20
0
    void PacketBuilder::WriteBytes(const MoveSpline& move_spline, ByteBuffer& data)
    {
        MoveSplineFlag splineFlags = move_spline.splineflags;
        uint32 nodes = move_spline.getPath().size();

        data.WriteBits(SPLINEMODE_LINEAR, 2);
        data.WriteBit(false);
        data.WriteBits(nodes, 22);
        data.WriteBits(SPLINETYPE_NORMAL, 2);

        if (splineFlags.walkmode)
        {
            uint8 guidMask[] = { 4, 3, 7, 2, 6, 1, 0, 5 };
            data.WriteGuidMask(move_spline.facing.target, guidMask, 8);
        }
    }
    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());
    }
Example #22
0
    void PacketBuilder::WriteLinearPath(const MoveSpline& move_spline, ByteBuffer& data)
    {
        const Spline<int32> spline = move_spline._Spline();
        uint32 last_idx = spline.getPointCount() - 3;
        const Vector3 * real_path = &spline.getPoint(1);

        data << last_idx;
        data << CalcTransportOffset(move_spline, real_path[last_idx]);   // destination
        if (last_idx > 1)
        {
            Vector3 middle = (CalcTransportOffset(move_spline, real_path[0]) + CalcTransportOffset(move_spline, real_path[last_idx])) / 2.f;
            Vector3 offset;
            // first and last points already appended
            for (uint32 i = 1; i < last_idx; ++i)
            {
                offset = CalcTransportOffset(move_spline, middle) - CalcTransportOffset(move_spline, real_path[i]);
                data.appendPackXYZ(offset.x, offset.y, offset.z);
            }
        }
    }
    void PacketBuilder::WriteBytes(const MoveSpline& move_spline, ByteBuffer& data)
    {
        MoveSplineFlag splineFlags = move_spline.splineflags;
        uint32 nodes = move_spline.getPath().size();

        data.WriteBits(SPLINEMODE_LINEAR, 2);
        data.WriteBit(1);
        data.WriteBits(nodes, 22);
        data.WriteBits(SPLINETYPE_NORMAL, 2);

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

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

        data.WriteBit(0);
        data.WriteBits(0, 25);
    }
    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();
    }
    void PacketBuilder::WriteFacingTargetPart(MoveSpline const& moveSpline, ByteBuffer& data)
    {
        if (GetMonsterMoveType(moveSpline) == MonsterMoveFacingTarget && !moveSpline.Finalized())
        {
            ObjectGuid facingGuid = moveSpline.facing.target;
            data.WriteBit(facingGuid[4]);
            data.WriteBit(facingGuid[7]);
            data.WriteBit(facingGuid[0]);
            data.WriteBit(facingGuid[5]);
            data.WriteBit(facingGuid[1]);
            data.WriteBit(facingGuid[2]);
            data.WriteBit(facingGuid[3]);
            data.WriteBit(facingGuid[6]);

            data.WriteByteSeq(facingGuid[4]);
            data.WriteByteSeq(facingGuid[2]);
            data.WriteByteSeq(facingGuid[0]);
            data.WriteByteSeq(facingGuid[5]);
            data.WriteByteSeq(facingGuid[6]);
            data.WriteByteSeq(facingGuid[3]);
            data.WriteByteSeq(facingGuid[1]);
            data.WriteByteSeq(facingGuid[7]);
        }
    }
	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::WriteMonsterMove(const MoveSpline& move_spline, WorldPacket& data, Unit* unit)
    {
        ObjectGuid guid = unit->GetGUID();
        ObjectGuid transport = unit->GetTransGUID();
        uint32 type;

        data << float(0.f); // Most likely transport Y
        data << uint32(getMSTime());
        data << float(0.f); // Most likely transport Z
        data << float(0.f); // Most likely transport X

        if (!move_spline.isCyclic())
        {
            Vector3 dest = move_spline.FinalDestination();
            data << float(dest.x);
            data << float(dest.y);
            data << float(dest.z);
        }
        else
            data << Vector3::zero();
        
        data.WriteBit(guid[3]);
        data.WriteBit(!move_spline.splineflags.raw());
        data.WriteBit(guid[6]);

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

        switch (move_spline.splineflags & MoveSplineFlag::Mask_Final_Facing)
        {
            case MoveSplineFlag::Final_Target:
                type = 3;
                break;
            case MoveSplineFlag::Final_Angle:
                type = 4;
                break;
            case MoveSplineFlag::Final_Point:
                type = 2;
                break;
            default:
                type = 0;
                break;
        }

        data.WriteBits(type, 3);
        data.WriteBit(1);
        data.WriteBit(guid[2]);
        data.WriteBit(guid[7]);
        data.WriteBit(guid[5]);

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

        data.WriteBit(1);
        data.WriteBit(guid[4]);
        
        int32 splineWpCount = move_spline.splineflags & MoveSplineFlag::UncompressedPath ? 0 : move_spline.spline.getPointCount() - 3;
        //int32 splineWpCount = move_spline.splineflags & MoveSplineFlag::UncompressedPath ? 1 : move_spline.spline.getPointCount() - 3;
        data.WriteBits(splineWpCount, 22); // WP count
        data.WriteBit(1);
        data.WriteBit(0);

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

        data.WriteBit(1);
        data.WriteBit(1); // Parabolic speed // esi+4Ch
        data.WriteBit(1);

        //data.WriteBits(!splineWpCount ? move_spline.spline.getPointCount() - 2 : 1, 20);
        data.WriteBits(!splineWpCount ? move_spline.spline.getPointCount() - (move_spline.splineflags.cyclic ? 2 : 3) : 1, 20);

        data.WriteBit(guid[1]);
        data.WriteBit(0); // Send no block
        data.WriteBit(0);
        data.WriteBit(!move_spline.Duration());

        data.FlushBits();

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

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

        if (type == 4)
            data << float(move_spline.facing.angle);

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

        data.WriteByteSeq(guid[7]);

        if (!(move_spline.splineflags & MoveSplineFlag::UncompressedPath))
            WriteLinearPath(move_spline.spline, data);

        data.WriteByteSeq(guid[5]);
        data.WriteByteSeq(guid[1]);
        data.WriteByteSeq(guid[2]);

        if (move_spline.splineflags & MoveSplineFlag::UncompressedPath)
        {
            if (move_spline.splineflags.cyclic)
                WriteUncompressedCyclicPath(move_spline.spline, data);
            else
                WriteUncompressedPath(move_spline.spline, data);
        }
        else
        {
            uint32 last_idx = move_spline.spline.getPointCount() - 2;
            const Vector3 * real_path = &move_spline.spline.getPoint(1);
            data << real_path[last_idx].x << real_path[last_idx].y << real_path[last_idx].z; // destination
        }

        data.WriteByteSeq(guid[6]);

        if (move_spline.Duration())
            data << uint32(move_spline.Duration());

        if (type == 2)
            data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z;

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

    }
    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::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);
        }
    }