public int Launch() { MoveSpline move_spline = unit.moveSpline; bool transport = !unit.GetTransGUID().IsEmpty(); Vector4 real_position = new Vector4(); // 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 == transport) { real_position = move_spline.ComputePosition(); } else { Position pos; if (!transport) { pos = unit; } else { pos = unit.m_movementInfo.transport.pos; } real_position.X = pos.GetPositionX(); real_position.Y = pos.GetPositionY(); real_position.Z = pos.GetPositionZ(); real_position.W = unit.GetOrientation(); } // should i do the things that user should do? - no. if (args.path.Length == 0) { return(0); } // correct first vertex args.path[0] = new Vector3(real_position.X, real_position.Y, real_position.Z); args.initialOrientation = real_position.W; move_spline.onTransport = !unit.GetTransGUID().IsEmpty(); MovementFlag moveFlags = unit.m_movementInfo.GetMovementFlags(); if (!args.flags.hasFlag(SplineFlag.Backward)) { moveFlags = (moveFlags & ~MovementFlag.Backward) | MovementFlag.Forward; } else { moveFlags = (moveFlags & ~MovementFlag.Forward) | MovementFlag.Backward; } if (Convert.ToBoolean(moveFlags & MovementFlag.Root)) { moveFlags &= ~MovementFlag.MaskMoving; } if (!args.HasVelocity) { // If spline is initialized with SetWalk method it only means we need to select // walk move speed for it but not add walk flag to unit var moveFlagsForSpeed = moveFlags; if (args.walk) { moveFlagsForSpeed |= MovementFlag.Walking; } else { moveFlagsForSpeed &= ~MovementFlag.Walking; } args.velocity = unit.GetSpeed(SelectSpeedType(moveFlagsForSpeed)); } if (!args.Validate(unit)) { return(0); } unit.m_movementInfo.SetMovementFlags(moveFlags); move_spline.Initialize(args); MonsterMove packet = new MonsterMove(); packet.MoverGUID = unit.GetGUID(); packet.Pos = new Vector3(real_position.X, real_position.Y, real_position.Z); packet.InitializeSplineData(move_spline); if (transport) { packet.SplineData.Move.TransportGUID = unit.GetTransGUID(); packet.SplineData.Move.VehicleSeat = unit.GetTransSeat(); } unit.SendMessageToSet(packet, true); return(move_spline.Duration()); }
public int Launch() { MoveSpline move_spline = unit.MoveSpline; bool transport = !unit.GetTransGUID().IsEmpty(); Vector4 real_position = new(); // 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 == transport) { real_position = move_spline.ComputePosition(); } else { Position pos; if (!transport) { pos = unit; } else { pos = unit.m_movementInfo.transport.pos; } real_position.X = pos.GetPositionX(); real_position.Y = pos.GetPositionY(); real_position.Z = pos.GetPositionZ(); real_position.W = unit.GetOrientation(); } // should i do the things that user should do? - no. if (args.path.Length == 0) { return(0); } // correct first vertex args.path[0] = new Vector3(real_position.X, real_position.Y, real_position.Z); args.initialOrientation = real_position.W; args.flags.SetUnsetFlag(SplineFlag.EnterCycle, args.flags.HasFlag(SplineFlag.Cyclic)); move_spline.onTransport = transport; MovementFlag moveFlags = unit.m_movementInfo.GetMovementFlags(); if (!args.flags.HasFlag(SplineFlag.Backward)) { moveFlags = (moveFlags & ~MovementFlag.Backward) | MovementFlag.Forward; } else { moveFlags = (moveFlags & ~MovementFlag.Forward) | MovementFlag.Backward; } if (Convert.ToBoolean(moveFlags & MovementFlag.Root)) { moveFlags &= ~MovementFlag.MaskMoving; } if (!args.HasVelocity) { // If spline is initialized with SetWalk method it only means we need to select // walk move speed for it but not add walk flag to unit var moveFlagsForSpeed = moveFlags; if (args.walk) { moveFlagsForSpeed |= MovementFlag.Walking; } else { moveFlagsForSpeed &= ~MovementFlag.Walking; } args.velocity = unit.GetSpeed(SelectSpeedType(moveFlagsForSpeed)); Creature creature = unit.ToCreature(); if (creature != null) { if (creature.HasSearchedAssistance()) { args.velocity *= 0.66f; } } } // limit the speed in the same way the client does float speedLimit() { if (args.flags.HasFlag(SplineFlag.UnlimitedSpeed)) { return(float.MaxValue); } if (args.flags.HasFlag(SplineFlag.Falling) || args.flags.HasFlag(SplineFlag.Catmullrom) || args.flags.HasFlag(SplineFlag.Flying) || args.flags.HasFlag(SplineFlag.Parabolic)) { return(50.0f); } return(Math.Max(28.0f, unit.GetSpeed(UnitMoveType.Run) * 4.0f)); }; args.velocity = Math.Min(args.velocity, speedLimit()); if (!args.Validate(unit)) { return(0); } unit.m_movementInfo.SetMovementFlags(moveFlags); move_spline.Initialize(args); MonsterMove packet = new(); packet.MoverGUID = unit.GetGUID(); packet.Pos = new Vector3(real_position.X, real_position.Y, real_position.Z); packet.InitializeSplineData(move_spline); if (transport) { packet.SplineData.Move.TransportGUID = unit.GetTransGUID(); packet.SplineData.Move.VehicleSeat = unit.GetTransSeat(); } unit.SendMessageToSet(packet, true); return(move_spline.Duration()); }