示例#1
0
        internal void ApplySamplesets(HitCircleFruits fruit, int index)
        {
            HitSoundInfo hitSoundInfo = GetHitSoundInfo(index);

            fruit.SampleSet          = hitSoundInfo.SampleSet;
            fruit.SampleSetAdditions = hitSoundInfo.SampleSetAdditions;
        }
示例#2
0
        internal override HitCircle CreateHitCircle(Vector2 startPosition, int startTime, bool newCombo, HitObjectSoundType soundType, int comboOffset, SampleSet sampleSet, SampleSet addSet, CustomSampleSet customSampleSet, int volume, string sampleFile)
        {
            WarpSpacing(ref startPosition, startTime);

            HitCircleFruits h = new HitCircleFruits(hitObjectManager, startPosition, startTime, newCombo, soundType, GetNextFruit());

            h.Type              |= HitObjectType.NewCombo; //because sorting colours needs this to make each fruit a different colour.
            h.SampleSet          = sampleSet;
            h.SampleSetAdditions = addSet;
            h.CustomSampleSet    = customSampleSet;
            h.SampleVolume       = volume;
            h.ProcessSampleFile(sampleFile);
            return(h);
        }
        internal void CalculateStrains(DifficultyHitObjectFruits PreviousHitObject, double TimeRate)
        {
            // Rather simple, but more specialized things are inherently inaccurate due to the big difference playstyles and opinions make.
            // See Taiko feedback thread.
            double TimeElapsed = (double)(BaseHitObject.StartTime - PreviousHitObject.BaseHitObject.StartTime) / TimeRate;
            double Decay       = Math.Pow(DECAY_BASE, TimeElapsed / 1000);

            // Update new position with lazy movement.
            PlayerPositionOffset =
                OsuMathHelper.Clamp(
                    PreviousHitObject.ActualNormalizedPosition,
                    NormalizedPosition - (NORMALIZED_HITOBJECT_RADIUS - playerPositioningError),
                    NormalizedPosition + (NORMALIZED_HITOBJECT_RADIUS - playerPositioningError)) // Obtain new lazy position, but be stricter by allowing for an error of a certain degree of the player.
                - NormalizedPosition;                                                            // Subtract HitObject position to obtain offset

            LastMovement = DistanceTo(PreviousHitObject);
            double Addition = SpacingWeight(LastMovement);

            if (NormalizedPosition < PreviousHitObject.NormalizedPosition)
            {
                LastMovement = -LastMovement;
            }

            HitCircleFruits previousHitCircle = PreviousHitObject.BaseHitObject as HitCircleFruits;

            double additionBonus = 0;
            double sqrtTime      = Math.Sqrt(Math.Max(TimeElapsed, 25));

            // Direction changes give an extra point!
            if (Math.Abs(LastMovement) > 0.1)
            {
                if (Math.Abs(PreviousHitObject.LastMovement) > 0.1 && Math.Sign(LastMovement) != Math.Sign(PreviousHitObject.LastMovement))
                {
                    double bonus = DIRECTION_CHANGE_BONUS / sqrtTime;

                    // Weight bonus by how
                    double bonusFactor = Math.Min(playerPositioningError, Math.Abs(LastMovement)) / playerPositioningError;

                    // We want time to play a role twice here!
                    Addition += bonus * bonusFactor;

                    // Bonus for tougher direction switches and "almost" hyperdashes at this point
                    if (previousHitCircle != null && previousHitCircle.DistanceToHyperDash <= 10)
                    {
                        additionBonus += 0.3 * bonusFactor;
                    }
                }

                // Base bonus for every movement, giving some weight to streams.
                Addition += 7.5 * Math.Min(Math.Abs(LastMovement), NORMALIZED_HITOBJECT_RADIUS * 2) / (NORMALIZED_HITOBJECT_RADIUS * 6) / sqrtTime;
            }

            // Bonus for "almost" hyperdashes at corner points
            if (previousHitCircle != null && previousHitCircle.DistanceToHyperDash <= 10)
            {
                if (!previousHitCircle.HyperDash)
                {
                    additionBonus += 1.0;
                }
                else
                {
                    // After a hyperdash we ARE in the correct position. Always!
                    PlayerPositionOffset = 0;
                }

                Addition *= 1.0 + additionBonus * ((10 - previousHitCircle.DistanceToHyperDash) / 10);
            }

            Addition *= 850.0 / Math.Max(TimeElapsed, 25);

            Strain = PreviousHitObject.Strain * Decay + Addition;
        }
示例#4
0
        internal override void UpdateCalculations(bool force = true)
        {
            base.UpdateCalculations(force);

            // We need to abort here, otherwise we will run out of memory by creating too many tiny ticks for this slider.
            if (Length > 60000)
            {
                throw new ArgumentOutOfRangeException("Slider is too long. (Over 1 minute!)");
            }

            bool useCorrectSamplesets = hitObjectManager.Beatmap.PlayMode != PlayModes.CatchTheBeat ||
                                        hitObjectManager.Beatmap.BeatmapVersion >= 14;

            Fruits.Clear();

            HitCircleFruits f1 = new HitCircleFruits(hitObjectManager, Position, StartTime, NewCombo, unifiedSoundAddition ? SoundType : SoundTypeList[0], fruit);

            if (useCorrectSamplesets)
            {
                ApplySamplesets(f1, 0);
            }
            else
            {
                f1.SampleSetAdditions = SampleSetAdditionList.Count > 0 && SampleSetAdditionList[0] != Audio.SampleSet.None ? SampleSetAdditionList[0] : SampleSetAdditions;
            }
            f1.Type |= HitObjectType.NewCombo; //new colour

            Fruits.Add(f1);

            int lastTime = StartTime;

            HitFactoryFruits hitFactoryFruits = hitObjectManager.hitFactory as HitFactoryFruits;

            int fruitIndex = 1;

            for (int i = 0; i < sliderScoreTimingPoints.Count; i++)
            {
                int time = sliderScoreTimingPoints[i];

                if (time - lastTime > 80)
                {
                    float var = (time - lastTime);
                    while (var > 100)
                    {
                        var /= 2;
                    }


                    for (float j = lastTime + var; j < time; j += var)
                    {
                        HitCircleFruitsTickTiny f = new HitCircleFruitsTickTiny(hitObjectManager, PositionAtTime((int)j) + new Vector2(hitFactoryFruits.random.Next(-20, 20), 0), (int)j, false, SoundType, fruit);
                        Fruits.Add(f);
                    }
                }

                lastTime = time;

                if (i < sliderScoreTimingPoints.Count - 1)
                {
                    int repeatLocation = sliderRepeatPoints.BinarySearch(time);

                    if (repeatLocation >= 0)
                    {
                        HitCircleFruits f = new HitCircleFruits(hitObjectManager, repeatLocation % 2 == 1 ? Position : Position2, time, false, unifiedSoundAddition ? SoundType : SoundTypeList[repeatLocation + 1], fruit);
                        if (useCorrectSamplesets)
                        {
                            ApplySamplesets(f, fruitIndex);
                        }
                        Fruits.Add(f);

                        fruitIndex++;
                    }
                    else
                    {
                        HitCircleFruitsTick f = new HitCircleFruitsTick(hitObjectManager, PositionAtTime(time), time, false, SoundType, fruit);
                        Fruits.Add(f);
                    }
                }
            }

            HitCircleFruits f2 = new HitCircleFruits(hitObjectManager, EndPosition, EndTime, false, unifiedSoundAddition ? SoundType : SoundTypeList[SoundTypeList.Count - 1], fruit);

            if (useCorrectSamplesets)
            {
                ApplySamplesets(f2, SampleSetAdditionList.Count - 1);
            }
            else
            {
                f2.SampleSetAdditions = SampleSetAdditionList.Count > 0 && SampleSetAdditionList[1] != Audio.SampleSet.None ? SampleSetAdditionList[1] : SampleSetAdditions;
            }

            Fruits.Add(f2);
        }