static void WriteCommonMonsterMovePart(MoveSpline move_spline, ref PacketWriter data) { MoveSplineFlag splineflags = move_spline.splineflags; data.WriteUInt8(0); // sets/unsets MOVEMENTFLAG2_UNK7 (0x40) data.WriteVec3(move_spline.spline.getPoint(move_spline.spline.first())); data.WriteUInt32(move_spline.GetId()); switch (splineflags.Raw() & MoveSplineFlag.eFlags.Mask_Final_Facing) { case MoveSplineFlag.eFlags.Final_Target: data.WriteUInt8(MonsterMoveType.FacingTarget); data.WriteUInt64(move_spline.facing.target); break; case MoveSplineFlag.eFlags.Final_Angle: data.WriteUInt8(MonsterMoveType.FacingAngle); data.WriteFloat(move_spline.facing.angle); break; case MoveSplineFlag.eFlags.Final_Point: data.WriteUInt8(MonsterMoveType.FacingSpot); data.WriteFloat(move_spline.facing.x); data.WriteFloat(move_spline.facing.y); data.WriteFloat(move_spline.facing.z); break; default: data.WriteUInt8(MonsterMoveType.Normal); 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.WriteUInt32(splineflags.Raw() & ~MoveSplineFlag.eFlags.Mask_No_Monster_Move); if (splineflags.animation) { data.WriteUInt8(splineflags.getAnimationId()); data.WriteInt32(move_spline.effect_start_time); } data.WriteInt32(move_spline.Duration()); if (splineflags.parabolic) { data.WriteFloat(move_spline.vertical_acceleration); data.WriteInt32(move_spline.effect_start_time); } }
public static void WriteCreateBits(MoveSpline moveSpline, ref PacketWriter data) { if (!moveSpline.Finalized()) { return; } data.WriteBit(moveSpline.Finalized()); data.WriteBits(moveSpline.getPath().Length, 22); data.WriteBits(moveSpline.splineflags.Raw(), 25); switch (moveSpline.splineflags.Raw() & MoveSplineFlag.eFlags.Mask_Final_Facing) { case MoveSplineFlag.eFlags.Final_Target: { ObjectGuid targetGuid = new ObjectGuid(moveSpline.facing.target); data.WriteBits(1, 2); data.WriteBit(targetGuid[0]); data.WriteBit(targetGuid[1]); data.WriteBit(targetGuid[6]); data.WriteBit(targetGuid[5]); data.WriteBit(targetGuid[2]); data.WriteBit(targetGuid[3]); data.WriteBit(targetGuid[4]); data.WriteBit(targetGuid[7]); break; } case MoveSplineFlag.eFlags.Final_Angle: data.WriteBits(0, 2); break; case MoveSplineFlag.eFlags.Final_Point: data.WriteBits(3, 2); break; default: data.WriteBits(2, 2); break; } data.WriteBits(moveSpline.spline.m_mode, 2); data.WriteBit(Convert.ToBoolean(moveSpline.splineflags.Raw() & MoveSplineFlag.eFlags.Parabolic) && moveSpline.effect_start_time < moveSpline.Duration()); }
public static void WriteMonsterMove(MoveSpline move_spline, ref PacketWriter data) { WriteCommonMonsterMovePart(move_spline, ref data); Spline spline = move_spline.spline; MoveSplineFlag splineflags = move_spline.splineflags; if (Convert.ToBoolean(splineflags.Raw() & MoveSplineFlag.eFlags.UncompressedPath)) { if (splineflags.cyclic) { WriteCatmullRomCyclicPath(spline, ref data); } else { WriteCatmullRomPath(spline, ref data); } } else { WriteLinearPath(spline, ref data); } }
public void Launch() { MoveSpline move_spline = unit.movespline; Vector4 real_position = new Vector4(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZ(), unit.GetOrientation()); // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes if (unit.GetTransGUID() != 0) { //real_position.x = unit.GetTransOffsetX(); //real_position.y = unit.GetTransOffsetY(); //real_position.z = unit.GetTransOffsetZ(); //real_position.orientation = unit.GetTransOffsetO(); } // there is a big chance that current position is unknown if current state is not finalized, need compute it // this also allows calculate spline position and update map position in much greater intervals // Don't compute for transport movement if the unit is in a motion between two transports if (!move_spline.Finalized() && move_spline.onTransport == (unit.GetTransGUID() != 0)) { real_position = move_spline.ComputePosition(); } // should i do the things that user should do? - no. if (args.path.Count() == 0) { return; } // correct first vertex args.path[0] = new Vector3(real_position.X, real_position.Y, real_position.Z); args.initialOrientation = real_position.O; move_spline.onTransport = (unit.GetTransGUID() != 0); MovementFlag moveFlags = unit.movementInfo.GetMovementFlags(); if (args.flags.walkmode) { moveFlags |= MovementFlag.Walk; } else { moveFlags &= ~MovementFlag.Walk; } moveFlags |= MovementFlag.Forward; if (!args.HasVelocity) { args.velocity = unit.GetSpeed(SelectSpeedType(moveFlags)); } if (!args.Validate(unit)) { return; } //if (Convert.ToBoolean(moveFlags & MovementFlag.Root)) //moveFlags &= ~MOVEMENTFLAG_MASK_MOVING; unit.movementInfo.SetMovementFlags(moveFlags); move_spline.Initialize(args); PacketWriter data = new PacketWriter(Opcodes.SMSG_MonsterMove); data.WritePackedGuid(unit.GetPackGUID()); if (unit.GetTransGUID() != 0) { data = new PacketWriter(Opcodes.SMSG_MonsterMoveTransport); data.WritePackedGuid(unit.GetPackGUID()); data.WritePackedGuid(unit.GetTransGUID()); data.WriteUInt8(0);//unit.GetTransSeat()); } MovementPacketBuilder.WriteMonsterMove(move_spline, ref data); unit.SendMessageToSet(data, true); }
public static void WriteCreateData(MoveSpline moveSpline, ref PacketWriter data) { if (!moveSpline.Finalized()) { MoveSplineFlag splineFlags = moveSpline.splineflags; if (splineFlags.final_target) { ObjectGuid facingGuid = new ObjectGuid(moveSpline.facing.target); data.WriteByteSeq(facingGuid[3]); data.WriteByteSeq(facingGuid[2]); data.WriteByteSeq(facingGuid[0]); data.WriteByteSeq(facingGuid[5]); data.WriteByteSeq(facingGuid[6]); data.WriteByteSeq(facingGuid[7]); data.WriteByteSeq(facingGuid[4]); data.WriteByteSeq(facingGuid[1]); } data.WriteInt32(moveSpline.timePassed()); data.WriteUInt32(moveSpline.Duration()); if (Convert.ToBoolean(splineFlags.Raw() & MoveSplineFlag.eFlags.Parabolic) && moveSpline.effect_start_time < moveSpline.Duration()) { data.WriteFloat(moveSpline.vertical_acceleration); } data.WriteFloat(1.0f); // splineInfo.duration_mod_next; added in 3.1 data.WriteFloat(1.0f); // splineInfo.duration_mod; added in 3.1 if (splineFlags.final_point) { data.WriteFloat(moveSpline.facing.x); data.WriteFloat(moveSpline.facing.y); data.WriteFloat(moveSpline.facing.z); } if (Convert.ToBoolean(splineFlags.Raw() & (MoveSplineFlag.eFlags.Parabolic | MoveSplineFlag.eFlags.Animation))) { data.WriteInt32(moveSpline.effect_start_time); // added in 3.1 } int nodes = moveSpline.getPath().Length; for (var i = 0; i < nodes; ++i) { data.WriteFloat(moveSpline.getPath()[i].Z); data.WriteFloat(moveSpline.getPath()[i].X); data.WriteFloat(moveSpline.getPath()[i].Y); } if (splineFlags.final_angle) { data.WriteFloat(moveSpline.facing.angle); } } if (!moveSpline.isCyclic()) { Vector3 dest = moveSpline.FinalDestination(); data.WriteFloat(dest.Z); data.WriteFloat(dest.X); data.WriteFloat(dest.Y); } else { data.WriteVec3(Vector3.Zero); } data.WriteUInt32(moveSpline.GetId()); }