Exemplo n.º 1
0
        private SkinnableSound addSound(HitSampleInfo hitSampleInfo)
        {
            var drawable = new SkinnableSound(hitSampleInfo);

            Sounds.Add(drawable);
            return(drawable);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Applies <see cref="SampleBank"/> and <see cref="SampleVolume"/> to a <see cref="HitSampleInfo"/> if necessary, returning the modified <see cref="HitSampleInfo"/>.
        /// </summary>
        /// <param name="hitSampleInfo">The <see cref="HitSampleInfo"/>. This will not be modified.</param>
        /// <returns>The modified <see cref="HitSampleInfo"/>. This does not share a reference with <paramref name="hitSampleInfo"/>.</returns>
        public virtual HitSampleInfo ApplyTo(HitSampleInfo hitSampleInfo)
        {
            var newSampleInfo = hitSampleInfo.Clone();

            newSampleInfo.Bank   = hitSampleInfo.Bank ?? SampleBank;
            newSampleInfo.Volume = hitSampleInfo.Volume > 0 ? hitSampleInfo.Volume : SampleVolume;
            return(newSampleInfo);
        }
Exemplo n.º 3
0
        private string toLegacyCustomSampleBank(HitSampleInfo hitSampleInfo)
        {
            if (hitSampleInfo is ConvertHitObjectParser.LegacyHitSampleInfo legacy)
            {
                return(legacy.CustomSampleBank.ToString(CultureInfo.InvariantCulture));
            }

            return("0");
        }
Exemplo n.º 4
0
        private void handleControlPoints(TextWriter writer)
        {
            if (beatmap.ControlPointInfo.Groups.Count == 0)
            {
                return;
            }

            writer.WriteLine("[TimingPoints]");

            foreach (var group in beatmap.ControlPointInfo.Groups)
            {
                var groupTimingPoint = group.ControlPoints.OfType <TimingControlPoint>().FirstOrDefault();

                // If the group contains a timing control point, it needs to be output separately.
                if (groupTimingPoint != null)
                {
                    writer.Write(FormattableString.Invariant($"{groupTimingPoint.Time},"));
                    writer.Write(FormattableString.Invariant($"{groupTimingPoint.BeatLength},"));
                    outputControlPointEffectsAt(groupTimingPoint.Time, true);
                }

                // Output any remaining effects as secondary non-timing control point.
                var difficultyPoint = beatmap.ControlPointInfo.DifficultyPointAt(group.Time);
                writer.Write(FormattableString.Invariant($"{group.Time},"));
                writer.Write(FormattableString.Invariant($"{-100 / difficultyPoint.SpeedMultiplier},"));
                outputControlPointEffectsAt(group.Time, false);
            }

            void outputControlPointEffectsAt(double time, bool isTimingPoint)
            {
                var samplePoint = beatmap.ControlPointInfo.SamplePointAt(time);
                var effectPoint = beatmap.ControlPointInfo.EffectPointAt(time);

                // Apply the control point to a hit sample to uncover legacy properties (e.g. suffix)
                HitSampleInfo tempHitSample = samplePoint.ApplyTo(new ConvertHitObjectParser.LegacyHitSampleInfo(string.Empty));

                // Convert effect flags to the legacy format
                LegacyEffectFlags effectFlags = LegacyEffectFlags.None;

                if (effectPoint.KiaiMode)
                {
                    effectFlags |= LegacyEffectFlags.Kiai;
                }
                if (effectPoint.OmitFirstBarLine)
                {
                    effectFlags |= LegacyEffectFlags.OmitFirstBarLine;
                }

                writer.Write(FormattableString.Invariant($"{(int)beatmap.ControlPointInfo.TimingPointAt(time).TimeSignature},"));
                writer.Write(FormattableString.Invariant($"{(int)toLegacySampleBank(tempHitSample.Bank)},"));
                writer.Write(FormattableString.Invariant($"{toLegacyCustomSampleBank(tempHitSample)},"));
                writer.Write(FormattableString.Invariant($"{tempHitSample.Volume},"));
                writer.Write(FormattableString.Invariant($"{(isTimingPoint ? '1' : '0')},"));
                writer.Write(FormattableString.Invariant($"{(int)effectFlags}"));
                writer.WriteLine();
            }
        }
            public override HitSampleInfo ApplyTo(HitSampleInfo hitSampleInfo)
            {
                var baseInfo = base.ApplyTo(hitSampleInfo);

                if (string.IsNullOrEmpty(baseInfo.Suffix) && CustomSampleBank > 1)
                {
                    baseInfo.Suffix = CustomSampleBank.ToString();
                }

                return(baseInfo);
            }
Exemplo n.º 6
0
        private PausableSkinnableSound addSound(HitSampleInfo hitSampleInfo, double lifetimeStart, double lifetimeEnd)
        {
            var drawable = new PausableSkinnableSound(hitSampleInfo)
            {
                LifetimeStart = lifetimeStart,
                LifetimeEnd   = lifetimeEnd
            };

            AddInternal(drawable);
            return(drawable);
        }
Exemplo n.º 7
0
        private void handleTimingPoints(TextWriter writer)
        {
            if (beatmap.ControlPointInfo.Groups.Count == 0)
            {
                return;
            }

            writer.WriteLine("[TimingPoints]");

            foreach (var group in beatmap.ControlPointInfo.Groups)
            {
                var timingPoint     = group.ControlPoints.OfType <TimingControlPoint>().FirstOrDefault();
                var difficultyPoint = beatmap.ControlPointInfo.DifficultyPointAt(group.Time);
                var samplePoint     = beatmap.ControlPointInfo.SamplePointAt(group.Time);
                var effectPoint     = beatmap.ControlPointInfo.EffectPointAt(group.Time);

                // Convert beat length the legacy format
                double beatLength;
                if (timingPoint != null)
                {
                    beatLength = timingPoint.BeatLength;
                }
                else
                {
                    beatLength = -100 / difficultyPoint.SpeedMultiplier;
                }

                // Apply the control point to a hit sample to uncover legacy properties (e.g. suffix)
                HitSampleInfo tempHitSample = samplePoint.ApplyTo(new HitSampleInfo());

                // Convert effect flags to the legacy format
                LegacyEffectFlags effectFlags = LegacyEffectFlags.None;
                if (effectPoint.KiaiMode)
                {
                    effectFlags |= LegacyEffectFlags.Kiai;
                }
                if (effectPoint.OmitFirstBarLine)
                {
                    effectFlags |= LegacyEffectFlags.OmitFirstBarLine;
                }

                writer.Write(FormattableString.Invariant($"{group.Time},"));
                writer.Write(FormattableString.Invariant($"{beatLength},"));
                writer.Write(FormattableString.Invariant($"{(int)beatmap.ControlPointInfo.TimingPointAt(group.Time).TimeSignature},"));
                writer.Write(FormattableString.Invariant($"{(int)toLegacySampleBank(tempHitSample.Bank)},"));
                writer.Write(FormattableString.Invariant($"{toLegacyCustomSampleBank(tempHitSample.Suffix)},"));
                writer.Write(FormattableString.Invariant($"{tempHitSample.Volume},"));
                writer.Write(FormattableString.Invariant($"{(timingPoint != null ? '1' : '0')},"));
                writer.Write(FormattableString.Invariant($"{(int)effectFlags}"));
                writer.WriteLine();
            }
        }
Exemplo n.º 8
0
        private IEnumerable <string> getLegacyLookupNames(HitSampleInfo hitSample)
        {
            var lookupNames = hitSample.LookupNames.SelectMany(getFallbackNames);

            if (!UseCustomSampleBanks && !string.IsNullOrEmpty(hitSample.Suffix))
            {
                // for compatibility with stable, exclude the lookup names with the custom sample bank suffix, if they are not valid for use in this skin.
                // using .EndsWith() is intentional as it ensures parity in all edge cases
                // (see LegacyTaikoSampleInfo for an example of one - prioritising the taiko prefix should still apply, but the sample bank should not).
                lookupNames = lookupNames.Where(name => !name.EndsWith(hitSample.Suffix, StringComparison.Ordinal));
            }

            foreach (string l in lookupNames)
            {
                yield return(l);
            }

            // also for compatibility, try falling back to non-bank samples (so-called "universal" samples) as the last resort.
            // going forward specifying banks shall always be required, even for elements that wouldn't require it on stable,
            // which is why this is done locally here.
            yield return(hitSample.Name);
        }
Exemplo n.º 9
0
            public LegacyTaikoSampleInfo(HitSampleInfo sampleInfo)
                : base(sampleInfo.Name, sampleInfo.Bank, sampleInfo.Suffix, sampleInfo.Volume)

            {
            }
Exemplo n.º 10
0
        private void handleControlPoints(TextWriter writer)
        {
            if (beatmap.ControlPointInfo.Groups.Count == 0)
            {
                return;
            }

            var legacyControlPoints = new LegacyControlPointInfo();

            foreach (var point in beatmap.ControlPointInfo.AllControlPoints)
            {
                legacyControlPoints.Add(point.Time, point.DeepClone());
            }

            writer.WriteLine("[TimingPoints]");

            SampleControlPoint     lastRelevantSamplePoint     = null;
            DifficultyControlPoint lastRelevantDifficultyPoint = null;

            bool isOsuRuleset = beatmap.BeatmapInfo.RulesetID == 0;

            // iterate over hitobjects and pull out all required sample and difficulty changes
            extractDifficultyControlPoints(beatmap.HitObjects);
            extractSampleControlPoints(beatmap.HitObjects);

            // handle scroll speed, which is stored as "slider velocity" in legacy formats.
            // this is relevant for scrolling ruleset beatmaps.
            if (!isOsuRuleset)
            {
                foreach (var point in legacyControlPoints.EffectPoints)
                {
                    legacyControlPoints.Add(point.Time, new DifficultyControlPoint {
                        SliderVelocity = point.ScrollSpeed
                    });
                }
            }

            foreach (var group in legacyControlPoints.Groups)
            {
                var groupTimingPoint = group.ControlPoints.OfType <TimingControlPoint>().FirstOrDefault();

                // If the group contains a timing control point, it needs to be output separately.
                if (groupTimingPoint != null)
                {
                    writer.Write(FormattableString.Invariant($"{groupTimingPoint.Time},"));
                    writer.Write(FormattableString.Invariant($"{groupTimingPoint.BeatLength},"));
                    outputControlPointAt(groupTimingPoint.Time, true);
                }

                // Output any remaining effects as secondary non-timing control point.
                var difficultyPoint = legacyControlPoints.DifficultyPointAt(group.Time);
                writer.Write(FormattableString.Invariant($"{group.Time},"));
                writer.Write(FormattableString.Invariant($"{-100 / difficultyPoint.SliderVelocity},"));
                outputControlPointAt(group.Time, false);
            }

            void outputControlPointAt(double time, bool isTimingPoint)
            {
                var samplePoint = legacyControlPoints.SamplePointAt(time);
                var effectPoint = legacyControlPoints.EffectPointAt(time);

                // Apply the control point to a hit sample to uncover legacy properties (e.g. suffix)
                HitSampleInfo tempHitSample = samplePoint.ApplyTo(new ConvertHitObjectParser.LegacyHitSampleInfo(string.Empty));

                // Convert effect flags to the legacy format
                LegacyEffectFlags effectFlags = LegacyEffectFlags.None;

                if (effectPoint.KiaiMode)
                {
                    effectFlags |= LegacyEffectFlags.Kiai;
                }
                if (effectPoint.OmitFirstBarLine)
                {
                    effectFlags |= LegacyEffectFlags.OmitFirstBarLine;
                }

                writer.Write(FormattableString.Invariant($"{(int)legacyControlPoints.TimingPointAt(time).TimeSignature},"));
                writer.Write(FormattableString.Invariant($"{(int)toLegacySampleBank(tempHitSample.Bank)},"));
                writer.Write(FormattableString.Invariant($"{toLegacyCustomSampleBank(tempHitSample)},"));
                writer.Write(FormattableString.Invariant($"{tempHitSample.Volume},"));
                writer.Write(FormattableString.Invariant($"{(isTimingPoint ? '1' : '0')},"));
                writer.Write(FormattableString.Invariant($"{(int)effectFlags}"));
                writer.WriteLine();
            }

            IEnumerable <DifficultyControlPoint> collectDifficultyControlPoints(IEnumerable <HitObject> hitObjects)
            {
                if (!isOsuRuleset)
                {
                    yield break;
                }

                foreach (var hitObject in hitObjects)
                {
                    yield return(hitObject.DifficultyControlPoint);

                    foreach (var nested in collectDifficultyControlPoints(hitObject.NestedHitObjects))
                    {
                        yield return(nested);
                    }
                }
            }

            void extractDifficultyControlPoints(IEnumerable <HitObject> hitObjects)
            {
                foreach (var hDifficultyPoint in collectDifficultyControlPoints(hitObjects).OrderBy(dp => dp.Time))
                {
                    if (!hDifficultyPoint.IsRedundant(lastRelevantDifficultyPoint))
                    {
                        legacyControlPoints.Add(hDifficultyPoint.Time, hDifficultyPoint);
                        lastRelevantDifficultyPoint = hDifficultyPoint;
                    }
                }
            }

            IEnumerable <SampleControlPoint> collectSampleControlPoints(IEnumerable <HitObject> hitObjects)
            {
                foreach (var hitObject in hitObjects)
                {
                    yield return(hitObject.SampleControlPoint);

                    foreach (var nested in collectSampleControlPoints(hitObject.NestedHitObjects))
                    {
                        yield return(nested);
                    }
                }
            }

            void extractSampleControlPoints(IEnumerable <HitObject> hitObject)
            {
                foreach (var hSamplePoint in collectSampleControlPoints(hitObject).OrderBy(sp => sp.Time))
                {
                    if (!hSamplePoint.IsRedundant(lastRelevantSamplePoint))
                    {
                        legacyControlPoints.Add(hSamplePoint.Time, hSamplePoint);
                        lastRelevantSamplePoint = hSamplePoint;
                    }
                }
            }
        }
Exemplo n.º 11
0
 static bool isDoubleSample(HitSampleInfo sample) => sample.Name == HitSampleInfo.HIT_CLAP || sample.Name == HitSampleInfo.HIT_FINISH;
Exemplo n.º 12
0
 private bool isHitnormal(HitSampleInfo sample) => sample.Name.Contains(HitSampleInfo.HIT_NORMAL);
Exemplo n.º 13
0
 private bool isHitsound(HitSampleInfo sample) => HitSampleInfo.AllAdditions.Any(sample.Name.Contains);