Exemplo n.º 1
0
        private static int getClosestSnappedOffset(BeatmapElement element, TimingPoint closestPoint, out int closestSnapDivisor)
        {
            // Gets the closest snap value in the beat. If multiple snaps
            // are found, then we also return a closestSnapIndex with
            // a value different than -1, in which case the note's snap
            // does not change and instead gets presented into the user.
            decimal snap     = Convert.ToDecimal(element.GetClosestSnap());
            decimal rawSnap  = snap % BEAT_SNAP_DIVISOR_2;
            decimal snapDiff = snap - rawSnap;
            decimal result   = snapsArray.BinarySearchClosest(rawSnap);
            decimal diff     = Math.Abs(rawSnap - result);

            closestSnapDivisor = -1;

            // Diff = 0 or equal offsets means this element is exactly snapped.
            if (diff == 0 || closestPoint.Offset == element.Offset)
            {
                return(0);
            }

            // If we calculate that this object's new snap result
            // causes the offset not to be shifted, consider
            // it as snapped.
            decimal targetSnap = snapDiff + result;

            // Make the calculation by casting it to integer. If the offset are equal, these are snapped.
            int targetOffset = (int)(Convert.ToDecimal(closestPoint.Offset) + (targetSnap / BEAT_SNAP_DIVISOR_2 * Convert.ToDecimal(closestPoint.PointValue)));

            if ((int)element.Offset == targetOffset)
            {
                return(0);
            }

            return(targetOffset);
        }
Exemplo n.º 2
0
        private static int getSnapInBetween(BeatmapElement target1, BeatmapElement target2, double beatDuration)
        {
            double offsetDifference = target2.Offset - target1.Offset;
            double snap             = (offsetDifference / beatDuration) * BEAT_SNAP_DIVISOR;
            int    snapInt          = Convert.ToInt32(snap);
            double fluctuation      = Math.Abs(snap - snapInt);
            double targetOffset     = target1.Offset + (snapInt / BEAT_SNAP_DIVISOR * beatDuration);

            if (fluctuation < 0.1d || Math.Abs(target2.Offset - targetOffset) < 1)
            {
                // We can consider this note as snapped in the end.
                // TODO Determine the behavior here: let the object unsnapped
                // if it is a hitsound, or show an error message.
                return(snapInt);
            }
            else
            {
                // The note is definitely unsnapped. Take this note as the 0 snap and
                // reset the final snap variable.
                // TODO Either fill this area with an error message
                // or throw an exception, or find another idea to process unsnapped notes.
                Console.WriteLine("Detected an unsnapped object with type \"" + target1.GetType() + "\", " +
                                  "and offset " + target1.Offset);
                return(-1);
            }
        }
Exemplo n.º 3
0
        private static void setOffsetOfElementToNewSnap(TimingPoint closestRedPoint, BeatmapElement element)
        {
            decimal snap        = (decimal)element.GetSnap();
            decimal pointValue  = (decimal)closestRedPoint.PointValue;
            decimal finalResult = (decimal)closestRedPoint.Offset + (pointValue / (decimal)BEAT_SNAP_DIVISOR * snap);

            element.SetOffset((double)finalResult);
        }
Exemplo n.º 4
0
        public static double[] getRelativeSnap(List <TimingPoint> timingPoints, BeatmapElement target)
        {
            // First holds the true snap which is from the first point,
            // second holds the snap value from the closest timing point.
            double[] result = new double[2] {
                0, 0
            };

            // If this is the first timing point or the element is snapped on the first timing point,
            // its actual and relative snaps should always equal to 0. Check the condition
            // and return it immediately.
            if (timingPoints.Count == 0 || (target.Offset == timingPoints[0].Offset && !timingPoints[0].IsInherited))
            {
                return(result);
            }

            // Get the closest timing point to this target.
            TimingPoint closestPoint = SearchUtils.GetClosestTimingPoint(timingPoints, target.Offset);

            // Now, the beat snap divisor divides the beat to specific parts, and
            // we need to calculate both relative and actual snaps.
            // Actual snap would be closestPoint + relativeSnap while
            // relative snap is calculated by closest red point's point
            // value (a.k.a millis value between 2 beats, 60000 / BPM).

            // Diff of objects in millis calculated as decimal
            // for maximum precision.
            decimal diff = Convert.ToDecimal(target.Offset - closestPoint.Offset);

            // Relative snap value based on BEAT_SNAP_DIVISOR.
            decimal relativeSnap = diff * BEAT_SNAP_DIVISOR_2 / Convert.ToDecimal(closestPoint.PointValue);

            // Actual snap value.
            decimal actualSnap = Convert.ToDecimal(closestPoint.GetSnap()) + relativeSnap;

            // Set the results and return. First is actual snap
            // from the start of the map, second is relative
            // snap from the closest red point.
            result[0] = Convert.ToDouble(actualSnap);
            result[1] = Convert.ToDouble(relativeSnap);
            return(result);
        }